Index: bootcd/isolinux/syslinux-6.03/com32/LICENCE
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/LICENCE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/LICENCE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+libcom32 and libutil are licensed under the MIT license:
+
+## -----------------------------------------------------------------------
+##
+##   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+##   Portions Copyright 2009 Intel Corporation; author: H. Peter Anvin
+##
+##   Permission is hereby granted, free of charge, to any person
+##   obtaining a copy of this software and associated documentation
+##   files (the "Software"), to deal in the Software without
+##   restriction, including without limitation the rights to use,
+##   copy, modify, merge, publish, distribute, sublicense, and/or
+##   sell copies of the Software, and to permit persons to whom
+##   the Software is furnished to do so, subject to the following
+##   conditions:
+##
+##   The above copyright notice and this permission notice shall
+##   be included in all copies or substantial portions of the Software.
+##
+##   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+##   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+##   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+##   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+##   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+##   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+##   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+##   OTHER DEALINGS IN THE SOFTWARE.
+##
+## -----------------------------------------------------------------------
+
+The files in the sample, modules and libgpl directories are mostly under the
+GNU GPL (see the file COPYING in the directory above.)
Index: bootcd/isolinux/syslinux-6.03/com32/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+SUBDIRS = libupload tools lib elflink/ldlinux gpllib libutil modules mboot \
+	  menu samples elflink rosh cmenu hdt gfxboot sysdump lua/src chain
+
+.PHONY: subdirs $(SUBDIRS)
+subdirs: $(SUBDIRS)
+$(SUBDIRS):
+	@mkdir -p $(OBJ)/$@
+	$(MAKE) -C $(OBJ)/$@ SRC="$(SRC)"/$@ OBJ="$(OBJ)"/$@/ \
+		-f $(SRC)/$@/Makefile $(MAKECMDGOALS)
+
+all tidy dist clean spotless install: subdirs
+
+# Parallel dependencies
+chain mboot menu: lib libutil gpllib
+cmenu: lib libutil
+elflink/ldlinux: lib
+gfxboot: lib libutil gpllib
+hdt: lib libupload cmenu gpllib libutil
+modules: lib libutil gpllib
+rosh: lib libutil
+samples: libutil elflink/ldlinux
+sysdump: lib libutil libupload gpllib
+lua/src: cmenu modules
Index: bootcd/isolinux/syslinux-6.03/com32/chain/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+##   Copyright 2010 Shao Miller
+##   Copyright 2010-2012 Michal Soltys
+##
+##   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.
+##
+## -----------------------------------------------------------------------
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+OBJS = chain.o partiter.o utility.o options.o mangle.o
+CFLAGS += -fno-strict-aliasing
+
+all: chain.c32
+
+chain.elf: $(OBJS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+%.o: %.c
+	$(CC) $(MAKEDEPS) $(CFLAGS) $(CHAINEXTOPT) -c -o $@ $<
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/chain/chain.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/chain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/chain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,643 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Please see doc/chain.txt for the detailed documentation.
+ */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <console.h>
+#include <consoles.h>
+#include <minmax.h>
+#include <stdbool.h>
+#include <dprintf.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/config.h>
+#include <syslinux/disk.h>
+#include <syslinux/video.h>
+#include "chain.h"
+#include "utility.h"
+#include "options.h"
+#include "partiter.h"
+#include "mangle.h"
+
+static int fixed_cnt = 128;   /* see comments in main() */
+
+static int overlap(const struct data_area *a, const struct data_area *b)
+{
+    return
+	a->base + a->size > b->base &&
+	b->base + b->size > a->base;
+}
+
+static int is_phys(uint8_t sdifs)
+{
+    return
+	sdifs == SYSLINUX_FS_SYSLINUX ||
+	sdifs == SYSLINUX_FS_EXTLINUX ||
+	sdifs == SYSLINUX_FS_ISOLINUX;
+}
+
+/*
+ * Search for a specific drive, based on the MBR signature.
+ * Return drive and iterator at 0th position.
+ */
+static int find_by_sig(uint32_t mbr_sig,
+			struct part_iter **_boot_part)
+{
+    struct part_iter *iter = NULL;
+    struct disk_info diskinfo;
+    int drive;
+
+    for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
+	if (disk_get_params(drive, &diskinfo))
+	    continue;		/* Drive doesn't exist */
+	if (!(iter = pi_begin(&diskinfo, opt.piflags)))
+	    continue;
+	/* Check for a matching MBR disk */
+	if (iter->type == typedos && iter->dos.disk_sig == mbr_sig)
+	    goto ok;
+	pi_del(&iter);
+    }
+    drive = -1;
+ok:
+    *_boot_part = iter;
+    return drive;
+}
+
+/*
+ * Search for a specific drive/partition, based on the GPT GUID.
+ * Return drive and iterator at proper position.
+ */
+static int find_by_guid(const struct guid *gpt_guid,
+			struct part_iter **_boot_part)
+{
+    struct part_iter *iter = NULL;
+    struct disk_info diskinfo;
+    int drive;
+
+    for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
+	if (disk_get_params(drive, &diskinfo))
+	    continue;		/* Drive doesn't exist */
+	if (!(iter = pi_begin(&diskinfo, opt.piflags)))
+	    continue;
+	/* Check for a matching GPT disk/partition guid */
+	if (iter->type == typegpt)
+	    do {
+		if (!memcmp(&iter->gpt.part_guid, gpt_guid, sizeof *gpt_guid))
+		    goto ok;
+	    } while (!pi_next(iter));
+	pi_del(&iter);
+    }
+    drive = -1;
+ok:
+    *_boot_part = iter;
+    return drive;
+}
+
+/*
+ * Search for a specific drive/partition, based on the GPT label.
+ * Return drive and iterator at proper position.
+ */
+static int find_by_label(const char *label, struct part_iter **_boot_part)
+{
+    struct part_iter *iter = NULL;
+    struct disk_info diskinfo;
+    int drive;
+
+    for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
+	if (disk_get_params(drive, &diskinfo))
+	    continue;		/* Drive doesn't exist */
+	if (!(iter = pi_begin(&diskinfo, opt.piflags)))
+	    continue;
+	/* Check for a matching GPT partition label */
+	if (iter->type == typegpt)
+	    while (!pi_next(iter)) {
+		if (!strcmp(label, iter->gpt.part_label))
+		    goto ok;
+	    }
+	pi_del(&iter);
+    }
+    drive = -1;
+ok:
+    *_boot_part = iter;
+    return drive;
+}
+
+static void do_boot(struct data_area *data, int ndata)
+{
+    struct syslinux_memmap *mmap;
+    struct syslinux_movelist *mlist = NULL;
+    addr_t endimage;
+    uint8_t driveno = opt.regs.edx.b[0];
+    uint8_t swapdrive = driveno & 0x80;
+    int i;
+
+    mmap = syslinux_memory_map();
+
+    if (!mmap) {
+	error("Cannot read system memory map.");
+	return;
+    }
+
+    endimage = 0;
+    for (i = 0; i < ndata; i++) {
+	if (data[i].base + data[i].size > endimage)
+	    endimage = data[i].base + data[i].size;
+    }
+    if (endimage > dosmax)
+	goto too_big;
+
+    for (i = 0; i < ndata; i++) {
+	if (syslinux_add_movelist(&mlist, data[i].base,
+				  (addr_t) data[i].data, data[i].size))
+	    goto enomem;
+    }
+
+    if (opt.swap && driveno != swapdrive) {
+	static const uint8_t swapstub_master[] = {
+	    /* The actual swap code */
+	    0x53,		/* 00: push bx */
+	    0x0f, 0xb6, 0xda,	/* 01: movzx bx,dl */
+	    0x2e, 0x8a, 0x57, 0x60,	/* 04: mov dl,[cs:bx+0x60] */
+	    0x5b,		/* 08: pop bx */
+	    0xea, 0, 0, 0, 0,	/* 09: jmp far 0:0 */
+	    0x90, 0x90,		/* 0E: nop; nop */
+	    /* Code to install this in the right location */
+	    /* Entry with DS = CS; ES = SI = 0; CX = 256 */
+	    0x26, 0x66, 0x8b, 0x7c, 0x4c,	/* 10: mov edi,[es:si+4*0x13] */
+	    0x66, 0x89, 0x3e, 0x0a, 0x00,	/* 15: mov [0x0A],edi */
+	    0x26, 0x8b, 0x3e, 0x13, 0x04,	/* 1A: mov di,[es:0x413] */
+	    0x4f,		/* 1F: dec di */
+	    0x26, 0x89, 0x3e, 0x13, 0x04,	/* 20: mov [es:0x413],di */
+	    0x66, 0xc1, 0xe7, 0x16,	/* 25: shl edi,16+6 */
+	    0x26, 0x66, 0x89, 0x7c, 0x4c,	/* 29: mov [es:si+4*0x13],edi */
+	    0x66, 0xc1, 0xef, 0x10,	/* 2E: shr edi,16 */
+	    0x8e, 0xc7,		/* 32: mov es,di */
+	    0x31, 0xff,		/* 34: xor di,di */
+	    0xf3, 0x66, 0xa5,	/* 36: rep movsd */
+	    0xbe, 0, 0,		/* 39: mov si,0 */
+	    0xbf, 0, 0,		/* 3C: mov di,0 */
+	    0x8e, 0xde,		/* 3F: mov ds,si */
+	    0x8e, 0xc7,		/* 41: mov es,di */
+	    0x66, 0xb9, 0, 0, 0, 0,	/* 43: mov ecx,0 */
+	    0x66, 0xbe, 0, 0, 0, 0,	/* 49: mov esi,0 */
+	    0x66, 0xbf, 0, 0, 0, 0,	/* 4F: mov edi,0 */
+	    0xea, 0, 0, 0, 0,	/* 55: jmp 0:0 */
+	    /* pad out to segment boundary */
+	    0x90, 0x90,		/* 5A: ... */
+	    0x90, 0x90, 0x90, 0x90,	/* 5C: ... */
+	};
+	static uint8_t swapstub[1024];
+	uint8_t *p;
+
+	/* Note: we can't rely on either INT 13h nor the dosmax
+	   vector to be correct at this stage, so we have to use an
+	   installer stub to put things in the right place.
+	   Round the installer location to a 1K boundary so the only
+	   possible overlap is the identity mapping. */
+	endimage = (endimage + 1023u) & ~1023u;
+
+	/* Create swap stub */
+	memcpy(swapstub, swapstub_master, sizeof swapstub_master);
+	*(uint16_t *) & swapstub[0x3a] = opt.regs.ds;
+	*(uint16_t *) & swapstub[0x3d] = opt.regs.es;
+	*(uint32_t *) & swapstub[0x45] = opt.regs.ecx.l;
+	*(uint32_t *) & swapstub[0x4b] = opt.regs.esi.l;
+	*(uint32_t *) & swapstub[0x51] = opt.regs.edi.l;
+	*(uint16_t *) & swapstub[0x56] = opt.regs.ip;
+	*(uint16_t *) & swapstub[0x58] = opt.regs.cs;
+	p = &swapstub[sizeof swapstub_master];
+
+	/* Mapping table; start out with identity mapping everything */
+	for (i = 0; i < 256; i++)
+	    p[i] = i;
+
+	/* And the actual swap */
+	p[driveno] = swapdrive;
+	p[swapdrive] = driveno;
+
+	/* Adjust registers */
+	opt.regs.ds = opt.regs.cs = endimage >> 4;
+	opt.regs.esi.l = opt.regs.es = 0;
+	opt.regs.ecx.l = sizeof swapstub >> 2;
+	opt.regs.ip = 0x10;	/* Installer offset */
+	opt.regs.ebx.b[0] = opt.regs.edx.b[0] = swapdrive;
+
+	if (syslinux_add_movelist(&mlist, endimage, (addr_t) swapstub,
+				  sizeof swapstub))
+	    goto enomem;
+
+	endimage += sizeof swapstub;
+    }
+
+    /* Tell the shuffler not to muck with this area... */
+    syslinux_add_memmap(&mmap, endimage, 0xa0000 - endimage, SMT_RESERVED);
+
+    /* Force text mode */
+    syslinux_force_text_mode();
+
+    puts("Booting...");
+    syslinux_shuffle_boot_rm(mlist, mmap, opt.keeppxe, &opt.regs);
+    error("Chainboot failed !");
+    return;
+
+too_big:
+    error("Loader file too large.");
+    return;
+
+enomem:
+    error("Out of memory.");
+    return;
+}
+
+int find_dp(struct part_iter **_iter)
+{
+    struct part_iter *iter = NULL;
+    struct disk_info diskinfo;
+    struct guid gpt_guid;
+    uint64_t fs_lba;
+    int drive, hd, partition;
+    const union syslinux_derivative_info *sdi;
+
+    sdi = syslinux_derivative_info();
+
+    if (!strncmp(opt.drivename, "mbr", 3)) {
+	if (find_by_sig(strtoul(opt.drivename + 4, NULL, 0), &iter) < 0) {
+	    error("Unable to find requested MBR signature.");
+	    goto bail;
+	}
+    } else if (!strncmp(opt.drivename, "guid", 4)) {
+	if (str_to_guid(opt.drivename + 5, &gpt_guid))
+	    goto bail;
+	if (find_by_guid(&gpt_guid, &iter) < 0) {
+	    error("Unable to find requested GPT disk or partition by guid.");
+	    goto bail;
+	}
+    } else if (!strncmp(opt.drivename, "label", 5)) {
+	if (!opt.drivename[6]) {
+	    error("No label specified.");
+	    goto bail;
+	}
+	if (find_by_label(opt.drivename + 6, &iter) < 0) {
+	    error("Unable to find requested GPT partition by label.");
+	    goto bail;
+	}
+    } else if ((opt.drivename[0] == 'h' || opt.drivename[0] == 'f') &&
+	       opt.drivename[1] == 'd') {
+	hd = opt.drivename[0] == 'h' ? 0x80 : 0;
+	opt.drivename += 2;
+	drive = hd | strtol(opt.drivename, NULL, 0);
+
+	if (disk_get_params(drive, &diskinfo))
+	    goto bail;
+	/* this will start iteration over FDD, possibly raw */
+	if (!(iter = pi_begin(&diskinfo, opt.piflags)))
+	    goto bail;
+
+    } else if (!strcmp(opt.drivename, "boot") || !strcmp(opt.drivename, "fs")) {
+	if (!is_phys(sdi->c.filesystem)) {
+	    error("When syslinux is not booted from physical disk (or its emulation),\n"
+		   "'boot' and 'fs' are meaningless.");
+	    goto bail;
+	}
+	/* offsets match, but in case it changes in the future */
+	if (sdi->c.filesystem == SYSLINUX_FS_ISOLINUX) {
+	    drive = sdi->iso.drive_number;
+	    fs_lba = *sdi->iso.partoffset;
+	} else {
+	    drive = sdi->disk.drive_number;
+	    fs_lba = *sdi->disk.partoffset;
+	}
+	if (disk_get_params(drive, &diskinfo))
+	    goto bail;
+	/* this will start iteration over disk emulation, possibly raw */
+	if (!(iter = pi_begin(&diskinfo, opt.piflags)))
+	    goto bail;
+
+	/* 'fs' => we should lookup the syslinux partition number and use it */
+	if (!strcmp(opt.drivename, "fs")) {
+	    do {
+		if (iter->abs_lba == fs_lba)
+		    break;
+	    } while (!pi_next(iter));
+	    /* broken part structure or other problems */
+	    if (iter->status) {
+		error("Unable to find partition with syslinux (fs).");
+		goto bail;
+	    }
+	}
+    } else {
+	error("Unparsable drive specification.");
+	goto bail;
+    }
+    /* main options done - only thing left is explicit partition specification,
+     * if we're still at the disk stage with the iterator AND user supplied
+     * partition number (including disk pseudo-partition).
+     */
+    if (!iter->index && opt.partition) {
+	partition = strtol(opt.partition, NULL, 0);
+	/* search for matching part#, including disk */
+	do {
+	    if (iter->index == partition)
+		break;
+	} while (!pi_next(iter));
+	if (iter->status) {
+	    error("Unable to find requested disk / partition combination.");
+	    goto bail;
+	}
+    }
+
+    if (!(iter->di.disk & 0x80) && iter->index) {
+	warn("Partitions on floppy devices may not work.");
+    }
+
+    *_iter = iter;
+
+    return 0;
+
+bail:
+    pi_del(&iter);
+    return -1;
+}
+
+static int setup_handover(const struct part_iter *iter,
+		   struct data_area *data)
+{
+    struct disk_dos_part_entry *ha;
+    uint32_t synth_size = sizeof *ha;
+
+    /*
+     * we have to cover both non-iterated but otherwise properly detected
+     * gpt/dos schemes as well as raw disks; checking index for 0 covers both
+     */
+    if (iter->index == 0) {
+	uint32_t len;
+	/* RAW handover protocol */
+	ha = malloc(synth_size);
+	if (!ha) {
+	    critm();
+	    goto bail;
+	}
+	len = ~0u;
+	if (iter->length < len)
+	    len = iter->length;
+	lba2chs(&ha->start, &iter->di, 0, L2C_CADD);
+	lba2chs(&ha->end, &iter->di, len - 1, L2C_CADD);
+	ha->active_flag = 0x80;
+	ha->ostype = 0xDA;	/* "Non-FS Data", anything is good here though ... */
+	ha->start_lba = 0;
+	ha->length = len;
+    } else if (iter->type == typegpt) {
+	uint32_t *plen;
+	/* GPT handover protocol */
+	synth_size += sizeof *plen + iter->gpt.pe_size;
+	ha = malloc(synth_size);
+	if (!ha) {
+	    critm();
+	    goto bail;
+	}
+	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
+	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
+	ha->active_flag = 0x80;
+	ha->ostype = 0xED;
+	/* All bits set by default */
+	ha->start_lba = ~0u;
+	ha->length = ~0u;
+	/* If these fit the precision, pass them on */
+	if (iter->abs_lba < ha->start_lba)
+	    ha->start_lba = iter->abs_lba;
+	if (iter->length < ha->length)
+	    ha->length = iter->length;
+	/* Next comes the GPT partition record length */
+	plen = (uint32_t *)(ha + 1);
+	plen[0] = iter->gpt.pe_size;
+	/* Next comes the GPT partition record copy */
+	memcpy(plen + 1, iter->record, plen[0]);
+#ifdef DEBUG
+	dprintf("GPT handover:\n");
+	disk_dos_part_dump(ha);
+	disk_gpt_part_dump((struct disk_gpt_part_entry *)(plen + 1));
+#endif
+    /* the only possible case left is dos scheme */
+    } else if (iter->type == typedos) {
+	/* MBR handover protocol */
+	ha = malloc(synth_size);
+	if (!ha) {
+	    critm();
+	    goto bail;
+	}
+	memcpy(ha, iter->record, synth_size);
+	/* make sure these match bios imaginations and are ebr agnostic */
+	lba2chs(&ha->start, &iter->di, iter->abs_lba, L2C_CADD);
+	lba2chs(&ha->end, &iter->di, iter->abs_lba + iter->length - 1, L2C_CADD);
+	ha->start_lba = iter->abs_lba;
+	ha->length = iter->length;
+
+#ifdef DEBUG
+	dprintf("MBR handover:\n");
+	disk_dos_part_dump(ha);
+#endif
+    } else {
+	/* shouldn't ever happen */
+	goto bail;
+    }
+
+    data->base = 0x7be;
+    data->size = synth_size;
+    data->data = (void *)ha;
+
+    return 0;
+bail:
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    struct part_iter *iter = NULL;
+    void *sbck = NULL;
+    struct data_area fdat, hdat, sdat, data[3];
+    int ndata = 0;
+
+    console_ansi_raw();
+
+    memset(&fdat, 0, sizeof fdat);
+    memset(&hdat, 0, sizeof hdat);
+    memset(&sdat, 0, sizeof sdat);
+
+    opt_set_defs();
+    if (opt_parse_args(argc, argv))
+	goto bail;
+
+#if 0
+    /* Get max fixed disk number */
+    fixed_cnt = *(uint8_t *)(0x475);
+
+    /*
+     * hmm, looks like we can't do that -
+     * some bioses/vms just set it to 1
+     * and go on living happily
+     * any better options than hardcoded 0x80 - 0xFF ?
+     */
+#endif
+
+    /* Get disk/part iterator matching user supplied options */
+    if (find_dp(&iter))
+	goto bail;
+
+    /* Perform initial partition entry mangling */
+    if (manglepe_fixchs(iter))
+	goto bail;
+    if (manglepe_hide(iter))
+	goto bail;
+
+    /* Load the boot file */
+    if (opt.file) {
+	fdat.base = (opt.fseg << 4) + opt.foff;
+
+	if (loadfile(opt.file, &fdat.data, &fdat.size)) {
+	    error("Couldn't read the boot file.");
+	    goto bail;
+	}
+	if (fdat.base + fdat.size > dosmax) {
+	    error("The boot file is too big to load at this address.");
+	    goto bail;
+	}
+    }
+
+    /* Load the sector */
+    if (opt.sect) {
+	sdat.base = (opt.sseg << 4) + opt.soff;
+	sdat.size = iter->di.bps;
+
+	if (sdat.base + sdat.size > dosmax) {
+	    error("The sector cannot be loaded at such high address.");
+	    goto bail;
+	}
+	if (!(sdat.data = disk_read_sectors(&iter->di, iter->abs_lba, 1))) {
+	    error("Couldn't read the sector.");
+	    goto bail;
+	}
+	if (opt.save) {
+	    if (!(sbck = malloc(sdat.size))) {
+		critm();
+		goto bail;
+	    }
+	    memcpy(sbck, sdat.data, sdat.size);
+	}
+	if (opt.file && opt.maps && overlap(&fdat, &sdat)) {
+	    warn("The sector won't be mmapped, as it would conflict with the boot file.");
+	    opt.maps = false;
+	}
+    }
+
+    /* Prep the handover */
+    if (opt.hand) {
+	if (setup_handover(iter, &hdat))
+	    goto bail;
+	/* Verify possible conflicts */
+	if ( ( opt.file && overlap(&fdat, &hdat)) ||
+	     ( opt.maps && overlap(&sdat, &hdat)) ) {
+	    warn("Handover area won't be prepared,\n"
+		  "as it would conflict with the boot file and/or the sector.");
+	    opt.hand = false;
+	}
+    }
+
+    /* Adjust registers */
+
+    mangler_init(iter);
+    mangler_handover(iter, &hdat);
+    mangler_grldr(iter);
+
+    /* Patching functions */
+
+    if (manglef_isolinux(&fdat))
+	goto bail;
+
+    if (manglef_grub(iter, &fdat))
+	goto bail;
+#if 0
+    if (manglef_drmk(&fdat))
+	goto bail;
+#endif
+    if (manglef_bpb(iter, &fdat))
+	goto bail;
+
+    if (mangles_bpb(iter, &sdat))
+	goto bail;
+
+    if (mangles_save(iter, &sdat, sbck))
+	goto bail;
+
+    if (manglesf_bss(&sdat, &fdat))
+	goto bail;
+
+    /* This *must* be after BPB saving or copying */
+    if (mangles_cmldr(&sdat))
+	goto bail;
+
+    /*
+     * Prepare boot-time mmap data. We should to it here, as manglers could
+     * potentially alter some of the data.
+     */
+
+    if (opt.file)
+	memcpy(data + ndata++, &fdat, sizeof fdat);
+    if (opt.maps)
+	memcpy(data + ndata++, &sdat, sizeof sdat);
+    if (opt.hand)
+	memcpy(data + ndata++, &hdat, sizeof hdat);
+
+#ifdef DEBUG
+    dprintf("iter->di dsk, bps: %X, %u\niter->di lbacnt, C*H*S: %"PRIu64", %u\n"
+	   "iter->di C, H, S: %u, %u, %u\n",
+	iter->di.disk, iter->di.bps,
+	iter->di.lbacnt, iter->di.cyl * iter->di.head * iter->di.spt,
+	iter->di.cyl, iter->di.head, iter->di.spt);
+    dprintf("iter idx: %d\n", iter->index);
+    dprintf("iter lba: %"PRIu64"\n", iter->abs_lba);
+    if (opt.hand)
+	dprintf("hand lba: %u\n",
+		((struct disk_dos_part_entry *)hdat.data)->start_lba);
+#endif
+
+    if (opt.warn) {
+	puts("Press any key to continue booting...");
+	wait_key();
+    }
+
+    if (ndata && !opt.brkchain) /* boot only if we actually chainload */
+	do_boot(data, ndata);
+    else
+	puts("Service-only run completed, exiting.");
+bail:
+    pi_del(&iter);
+    /* Free allocated areas */
+    free(fdat.data);
+    free(sdat.data);
+    free(hdat.data);
+    free(sbck);
+    return 255;
+}
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/chain.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/chain.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/chain.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   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 COM32_CHAIN_CHAIN_H
+#define COM32_CHAIN_CHAIN_H
+
+#include <syslinux/movebits.h>
+
+struct data_area {
+    void *data;
+    addr_t base;
+    addr_t size;
+};
+
+#endif
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/mangle.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/mangle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/mangle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,682 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <dprintf.h>
+#include <syslinux/config.h>
+#include "chain.h"
+#include "options.h"
+#include "utility.h"
+#include "partiter.h"
+#include "mangle.h"
+
+static const char cmldr_signature[8] = "cmdcons";
+
+/* Create boot info table: needed when you want to chainload
+ * another version of ISOLINUX (or another bootlaoder that needs
+ * the -boot-info-table switch of mkisofs)
+ * (will only work when run from ISOLINUX)
+ */
+int manglef_isolinux(struct data_area *data)
+{
+    const union syslinux_derivative_info *sdi;
+    unsigned char *isolinux_bin;
+    uint32_t *checksum, *chkhead, *chktail;
+    uint32_t file_lba = 0;
+
+    if (!(opt.file && opt.isolinux))
+	return 0;
+
+    sdi = syslinux_derivative_info();
+
+    if (sdi->c.filesystem != SYSLINUX_FS_ISOLINUX) {
+	error("The isolinux= option is only valid when run from ISOLINUX.");
+	goto bail;
+    }
+
+    /* Boot info table info (integers in little endian format)
+
+       Offset Name         Size      Meaning
+       8      bi_pvd       4 bytes   LBA of primary volume descriptor
+       12     bi_file      4 bytes   LBA of boot file
+       16     bi_length    4 bytes   Boot file length in bytes
+       20     bi_csum      4 bytes   32-bit checksum
+       24     bi_reserved  40 bytes  Reserved
+
+       The 32-bit checksum is the sum of all the 32-bit words in the
+       boot file starting at byte offset 64. All linear block
+       addresses (LBAs) are given in CD sectors (normally 2048 bytes).
+
+       LBA of primary volume descriptor should already be set to 16.
+       */
+
+    isolinux_bin = (unsigned char *)data->data;
+
+    /* Get LBA address of bootfile */
+    file_lba = get_file_lba(opt.file);
+
+    if (file_lba == 0) {
+	error("Failed to find LBA offset of the boot file.");
+	goto bail;
+    }
+    /* Set it */
+    *((uint32_t *) & isolinux_bin[12]) = file_lba;
+
+    /* Set boot file length */
+    *((uint32_t *) & isolinux_bin[16]) = data->size;
+
+    /* Calculate checksum */
+    checksum = (uint32_t *) & isolinux_bin[20];
+    chkhead = (uint32_t *) & isolinux_bin[64];
+    chktail = (uint32_t *) & isolinux_bin[data->size & ~3u];
+    *checksum = 0;
+    while (chkhead < chktail)
+	*checksum += *chkhead++;
+
+    /*
+     * Deal with possible fractional dword at the end;
+     * this *should* never happen...
+     */
+    if (data->size & 3) {
+	uint32_t xword = 0;
+	memcpy(&xword, chkhead, data->size & 3);
+	*checksum += xword;
+    }
+    return 0;
+bail:
+    return -1;
+}
+
+/*
+ * Legacy grub's stage2 chainloading
+ */
+int manglef_grub(const struct part_iter *iter, struct data_area *data)
+{
+    /* Layout of stage2 file (from byte 0x0 to 0x270) */
+    struct grub_stage2_patch_area {
+	/* 0x0 to 0x205 */
+	char unknown[0x206];
+	/* 0x206: compatibility version number major */
+	uint8_t compat_version_major;
+	/* 0x207: compatibility version number minor */
+	uint8_t compat_version_minor;
+
+	/* 0x208: install_partition variable */
+	struct {
+	    /* 0x208: sub-partition in sub-partition part2 */
+	    uint8_t part3;
+	    /* 0x209: sub-partition in top-level partition */
+	    uint8_t part2;
+	    /* 0x20a: top-level partiton number */
+	    uint8_t part1;
+	    /* 0x20b: BIOS drive number (must be 0) */
+	    uint8_t drive;
+	} __attribute__ ((packed)) install_partition;
+
+	/* 0x20c: deprecated (historical reason only) */
+	uint32_t saved_entryno;
+	/* 0x210: stage2_ID: will always be STAGE2_ID_STAGE2 = 0 in stage2 */
+	uint8_t stage2_id;
+	/* 0x211: force LBA */
+	uint8_t force_lba;
+	/* 0x212: version string (will probably be 0.97) */
+	char version_string[5];
+	/* 0x217: config filename */
+	char config_file[89];
+	/* 0x270: start of code (after jump from 0x200) */
+	char codestart[1];
+    } __attribute__ ((packed)) *stage2;
+
+    if (!(opt.file && opt.grub))
+	return 0;
+
+    if (data->size < sizeof *stage2) {
+	error("The file specified by grub=<loader> is too small to be stage2 of GRUB Legacy.");
+	goto bail;
+    }
+    stage2 = data->data;
+
+    /*
+     * Check the compatibility version number to see if we loaded a real
+     * stage2 file or a stage2 file that we support.
+     */
+    if (stage2->compat_version_major != 3
+	    || stage2->compat_version_minor != 2) {
+	error("The file specified by grub=<loader> is not a supported stage2 GRUB Legacy binary.");
+	goto bail;
+    }
+
+    /*
+     * GRUB Legacy wants the partition number in the install_partition
+     * variable, located at offset 0x208 of stage2.
+     * When GRUB Legacy is loaded, it is located at memory address 0x8208.
+     *
+     * It looks very similar to the "boot information format" of the
+     * Multiboot specification:
+     *   http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format
+     *
+     *   0x208 = part3: sub-partition in sub-partition part2
+     *   0x209 = part2: sub-partition in top-level partition
+     *   0x20a = part1: top-level partition number
+     *   0x20b = drive: BIOS drive number (must be 0)
+     *
+     * GRUB Legacy doesn't store the BIOS drive number at 0x20b, but at
+     * another location.
+     *
+     * Partition numbers always start from zero.
+     * Unused partition bytes must be set to 0xFF.
+     *
+     * We only care about top-level partition, so we only need to change
+     * "part1" to the appropriate value:
+     *   -1:   whole drive (default) (-1 = 0xFF)
+     *   0-3:  primary partitions
+     *   4-*:  logical partitions
+     */
+    stage2->install_partition.part1 = iter->index - 1;
+
+    /*
+     * Grub Legacy reserves 89 bytes (from 0x8217 to 0x826f) for the
+     * config filename. The filename passed via grubcfg= will overwrite
+     * the default config filename "/boot/grub/menu.lst".
+     */
+    if (opt.grubcfg) {
+	if (strlen(opt.grubcfg) >= sizeof stage2->config_file) {
+	    error("The config filename length can't exceed 88 characters.");
+	    goto bail;
+	}
+
+	strcpy((char *)stage2->config_file, opt.grubcfg);
+    }
+
+    return 0;
+bail:
+    return -1;
+}
+#if 0
+/*
+ * Dell's DRMK chainloading.
+ */
+int manglef_drmk(struct data_area *data)
+{
+    /*
+     * DRMK entry is different than MS-DOS/PC-DOS
+     * A new size, aligned to 16 bytes to ease use of ds:[bp+28].
+     * We only really need 4 new, usable bytes at the end.
+     */
+
+    if (!(opt.file && opt.drmk))
+	return 0;
+
+    uint32_t tsize = (data->size + 19) & 0xfffffff0;
+    const union syslinux_derivative_info *sdi;
+    uint64_t fs_lba;
+
+    sdi = syslinux_derivative_info();
+    /* We should lookup the Syslinux partition offset and use it */
+    fs_lba = *sdi->disk.partoffset;
+
+    /*
+     * fs_lba should be verified against the disk as some DRMK
+     * variants will check and fail if it does not match
+     */
+    dprintf("  fs_lba offset is %d\n", fs_lba);
+    /* DRMK only uses a DWORD */
+    if (fs_lba > 0xffffffff) {
+	error("LBA very large; Only using lower 32 bits; DRMK will probably fail.");
+    }
+    opt.regs.ss = opt.regs.fs = opt.regs.gs = 0;	/* Used before initialized */
+    if (!realloc(data->data, tsize)) {
+	error("Failed to realloc for DRMK.");
+	goto bail;
+    }
+    data->size = tsize;
+    /* ds:bp is assumed by DRMK to be the boot sector */
+    /* offset 28 is the FAT HiddenSectors value */
+    opt.regs.ds = (tsize >> 4) + (opt.fseg - 2);
+    /* "Patch" into tail of the new space */
+    *(uint32_t *)((char*)data->data + tsize - 4) = fs_lba;
+
+    return 0;
+bail:
+    return -1;
+}
+#endif
+/* Adjust BPB common function */
+static int mangle_bpb(const struct part_iter *iter, struct data_area *data, const char *tag)
+{
+    int type = bpb_detect(data->data, tag);
+    int off = drvoff_detect(type);
+
+    /* BPB: hidden sectors 64bit - exFAT only for now */
+    if (type == bpbEXF)
+	    *(uint64_t *) ((char *)data->data + 0x40) = iter->abs_lba;
+    /* BPB: hidden sectors 32bit*/
+    else if (bpbV34 <= type && type <= bpbV70) {
+	if (iter->abs_lba < ~0u)
+	    *(uint32_t *) ((char *)data->data + 0x1c) = iter->abs_lba;
+	else
+	    /* won't really help much, but ... */
+	    *(uint32_t *) ((char *)data->data + 0x1c) = ~0u;
+    /* BPB: hidden sectors 16bit*/
+    } else if (bpbV30 <= type && type <= bpbV32) {
+	if (iter->abs_lba < 0xFFFF)
+	    *(uint16_t *) ((char *)data->data + 0x1c) = iter->abs_lba;
+	else
+	    /* won't really help much, but ... */
+	    *(uint16_t *) ((char *)data->data + 0x1c) = (uint16_t)~0u;
+    }
+
+    /* BPB: legacy geometry */
+    if (bpbV30 <= type && type <= bpbV70) {
+	if (iter->di.cbios)
+	    *(uint32_t *)((char *)data->data + 0x18) = (iter->di.head << 16) | iter->di.spt;
+	else {
+	    if (iter->di.disk & 0x80)
+		*(uint32_t *)((char *)data->data + 0x18) = 0x00FF003F;
+	    else
+		*(uint32_t *)((char *)data->data + 0x18) = 0x00020012;
+	}
+    }
+    /* BPB: drive */
+    if (off >= 0) {
+	*(uint8_t *)((char *)data->data + off) = (opt.swap ? iter->di.disk & 0x80 : iter->di.disk);
+    }
+
+    return 0;
+}
+
+/*
+ * Adjust BPB of a BPB-compatible file
+ */
+int manglef_bpb(const struct part_iter *iter, struct data_area *data)
+{
+    if (!(opt.file && opt.filebpb))
+	return 0;
+
+    return mangle_bpb(iter, data, "file");
+}
+
+/*
+ * Adjust BPB of a sector
+ */
+int mangles_bpb(const struct part_iter *iter, struct data_area *data)
+{
+    if (!(opt.sect && opt.setbpb))
+	return 0;
+
+    return mangle_bpb(iter, data, "sect");
+}
+
+/*
+ * This function performs full BPB patching, analogously to syslinux's
+ * native BSS.
+ */
+int manglesf_bss(struct data_area *sec, struct data_area *fil)
+{
+    int type1, type2;
+    size_t cnt = 0;
+
+    if (!(opt.sect && opt.file && opt.bss))
+	return 0;
+
+    type1 = bpb_detect(fil->data, "bss/file");
+    type2 = bpb_detect(sec->data, "bss/sect");
+
+    if (!type1 || !type2) {
+	error("Couldn't determine the BPB type for option 'bss'.");
+	goto bail;
+    }
+    if (type1 != type2) {
+	error("Option 'bss' can't be used,\n"
+		"when a sector and a file have incompatible BPBs.");
+	goto bail;
+    }
+
+    /* Copy common 2.0 data */
+    memcpy((char *)fil->data + 0x0B, (char *)sec->data + 0x0B, 0x0D);
+
+    /* Copy 3.0+ data */
+    if (type1 <= bpbV30) {
+	cnt = 0x06;
+    } else if (type1 <= bpbV32) {
+	cnt = 0x08;
+    } else if (type1 <= bpbV34) {
+	cnt = 0x0C;
+    } else if (type1 <= bpbV40) {
+	cnt = 0x2E;
+    } else if (type1 <= bpbVNT) {
+	cnt = 0x3C;
+    } else if (type1 <= bpbV70) {
+	cnt = 0x42;
+    } else if (type1 <= bpbEXF) {
+	cnt = 0x60;
+    }
+    memcpy((char *)fil->data + 0x18, (char *)sec->data + 0x18, cnt);
+
+    return 0;
+bail:
+    return -1;
+}
+
+/*
+ * Save sector.
+ */
+int mangles_save(const struct part_iter *iter, const struct data_area *data, void *org)
+{
+    if (!(opt.sect && opt.save))
+	return 0;
+
+    if (memcmp(org, data->data, data->size)) {
+	if (disk_write_sectors(&iter->di, iter->abs_lba, data->data, 1)) {
+	    error("Cannot write the updated sector.");
+	    goto bail;
+	}
+	/* function can be called again */
+	memcpy(org, data->data, data->size);
+    }
+
+    return 0;
+bail:
+    return -1;
+}
+
+/*
+ * To boot the Recovery Console of Windows NT/2K/XP we need to write
+ * the string "cmdcons\0" to memory location 0000:7C03.
+ * Memory location 0000:7C00 contains the bootsector of the partition.
+ */
+int mangles_cmldr(struct data_area *data)
+{
+    if (!(opt.sect && opt.cmldr))
+	return 0;
+
+    memcpy((char *)data->data + 3, cmldr_signature, sizeof cmldr_signature);
+    return 0;
+}
+
+/* Set common registers */
+int mangler_init(const struct part_iter *iter)
+{
+    /* Set initial registry values */
+    if (opt.file) {
+	opt.regs.cs = opt.regs.ds = opt.regs.ss = opt.fseg;
+	opt.regs.ip = opt.fip;
+    } else {
+	opt.regs.cs = opt.regs.ds = opt.regs.ss = opt.sseg;
+	opt.regs.ip = opt.sip;
+    }
+
+    if (opt.regs.ip == 0x7C00 && !opt.regs.cs)
+	opt.regs.esp.l = 0x7C00;
+
+    /* DOS kernels want the drive number in BL instead of DL. Indulge them. */
+    opt.regs.ebx.b[0] = opt.regs.edx.b[0] = iter->di.disk;
+
+    return 0;
+}
+
+/* ds:si & ds:bp */
+int mangler_handover(const struct part_iter *iter, const struct data_area *data)
+{
+    if (opt.file && opt.maps && !opt.hptr) {
+	opt.regs.esi.l = opt.regs.ebp.l = opt.soff;
+	opt.regs.ds = opt.sseg;
+	opt.regs.eax.l = 0;
+    } else if (opt.hand) {
+	/* base is really 0x7be */
+	opt.regs.esi.l = opt.regs.ebp.l = data->base;
+	opt.regs.ds = 0;
+	if (iter->index && iter->type == typegpt)   /* must be iterated and GPT */
+	    opt.regs.eax.l = 0x54504721;	/* '!GPT' */
+	else
+	    opt.regs.eax.l = 0;
+    }
+
+    return 0;
+}
+
+/*
+ * GRLDR of GRUB4DOS wants the partition number in DH:
+ * -1:   whole drive (default)
+ * 0-3:  primary partitions
+ * 4-*:  logical partitions
+ */
+int mangler_grldr(const struct part_iter *iter)
+{
+    if (opt.grldr)
+	opt.regs.edx.b[1] = iter->index - 1;
+
+    return 0;
+}
+
+/*
+ * try to copy values from temporary iterator, if positions match
+ */
+static void mbrcpy(struct part_iter *diter, struct part_iter *siter)
+{
+    if (diter->dos.cebr_lba == siter->dos.cebr_lba &&
+	    diter->di.disk == siter->di.disk) {
+	memcpy(diter->data, siter->data, sizeof(struct disk_dos_mbr));
+    }
+}
+
+static int fliphide(struct part_iter *iter, struct part_iter *miter)
+{
+    struct disk_dos_part_entry *dp;
+    static const uint16_t mask =
+	(1 << 0x01) | (1 << 0x04) | (1 << 0x06) |
+	(1 << 0x07) | (1 << 0x0b) | (1 << 0x0c) | (1 << 0x0e);
+    uint8_t t;
+
+    dp = (struct disk_dos_part_entry *)iter->record;
+    t = dp->ostype;
+
+    if ((t <= 0x1f) && ((mask >> (t & ~0x10u)) & 1)) {
+	/* It's a hideable partition type */
+	if (miter->index == iter->index || opt.hide & HIDE_REV)
+	    t &= ~0x10u;	/* unhide */
+	else
+	    t |= 0x10u;	/* hide */
+    }
+    if (dp->ostype != t) {
+	dp->ostype = t;
+	return -1;
+    }
+    return 0;
+}
+
+/*
+ * miter - iterator we match against
+ * hide bits meaning:
+ * ..| - enable (1) / disable (0)
+ * .|. - all (1) / pri (0)
+ * |.. - unhide (1) / hide (0)
+ */
+int manglepe_hide(struct part_iter *miter)
+{
+    int wb = 0, werr = 0;
+    struct part_iter *iter = NULL;
+    int ridx;
+
+    if (!(opt.hide & HIDE_ON))
+	return 0;
+
+    if (miter->type != typedos) {
+	error("Option '[un]hide[all]' works only for legacy (DOS) partition scheme.");
+	return -1;
+    }
+
+    if (miter->index > 4 && !(opt.hide & HIDE_EXT))
+	warn("Specified partition is logical, so it can't be unhidden without 'unhideall'.");
+
+    if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.piflags)))
+	return -1;
+
+    while (!pi_next(iter) && !werr) {
+	ridx = iter->index0;
+	if (!(opt.hide & HIDE_EXT) && ridx > 3)
+	    break;  /* skip when we're constrained to pri only */
+
+	if (iter->index != -1)
+	    wb |= fliphide(iter, miter);
+
+	/*
+	 * we have to update mbr and each extended partition, but only if
+	 * changes (wb) were detected and there was no prior write error (werr)
+	 */
+	if (ridx >= 3 && wb && !werr) {
+	    mbrcpy(miter, iter);
+	    werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
+	    wb = 0;
+	}
+    }
+
+    if (iter->status < 0)
+	goto bail;
+
+    /* last update */
+    if (wb && !werr) {
+	mbrcpy(miter, iter);
+	werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
+    }
+    if (werr)
+	warn("Failed to write E/MBR during '[un]hide[all]'.");
+
+bail:
+    pi_del(&iter);
+    return 0;
+}
+
+static int updchs(struct part_iter *iter, int ext)
+{
+    struct disk_dos_part_entry *dp;
+    uint32_t ochs1, ochs2, lba;
+
+    dp = (struct disk_dos_part_entry *)iter->record;
+    if (!ext) {
+	/* primary or logical */
+	lba = (uint32_t)iter->abs_lba;
+    } else {
+	/* extended */
+	dp += 1;
+	lba = iter->dos.nebr_lba;
+    }
+    ochs1 = *(uint32_t *)dp->start;
+    ochs2 = *(uint32_t *)dp->end;
+
+    /*
+     * We have to be a bit more careful here in case of 0 start and/or length;
+     * start = 0 would be converted to the beginning of the disk (C/H/S =
+     * 0/0/1) or the [B]EBR, length = 0 would actually set the end CHS to be
+     * lower than the start CHS.
+     *
+     * Both are harmless in case of a hole (and in non-hole case will make
+     * partiter complain about corrupt layout if PIF_STRICT is set), but it
+     * makes everything look silly and not really correct.
+     *
+     * Thus the approach as seen below.
+     */
+
+    if (dp->start_lba || iter->index != -1) {
+	lba2chs(&dp->start, &iter->di, lba, L2C_CADD);
+    } else {
+	memset(&dp->start, 0, sizeof dp->start);
+    }
+
+    if ((dp->start_lba || iter->index != -1) && dp->length) {
+	lba2chs(&dp->end, &iter->di, lba + dp->length - 1, L2C_CADD);
+    } else {
+	memset(&dp->end, 0, sizeof dp->end);
+    }
+
+    return
+	*(uint32_t *)dp->start != ochs1 ||
+	*(uint32_t *)dp->end != ochs2;
+}
+
+/*
+ * miter - iterator we match against
+ */
+int manglepe_fixchs(struct part_iter *miter)
+{
+    int wb = 0, werr = 0;
+    struct part_iter *iter = NULL;
+    int ridx;
+
+    if (!opt.fixchs)
+	return 0;
+
+    if (miter->type != typedos) {
+	error("Option 'fixchs' works only for legacy (DOS) partition scheme.");
+	return -1;
+    }
+
+    if (!(iter = pi_begin(&miter->di, PIF_STEPALL | opt.piflags)))
+	return -1;
+
+    while (!pi_next(iter) && !werr) {
+	ridx = iter->index0;
+
+	wb |= updchs(iter, 0);
+	if (ridx > 3)
+	    wb |= updchs(iter, 1);
+
+	/*
+	 * we have to update mbr and each extended partition, but only if
+	 * changes (wb) were detected and there was no prior write error (werr)
+	 */
+	if (ridx >= 3 && wb && !werr) {
+	    mbrcpy(miter, iter);
+	    werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
+	    wb = 0;
+	}
+    }
+
+    if (iter->status < 0)
+	goto bail;
+
+    /* last update */
+    if (wb && !werr) {
+	mbrcpy(miter, iter);
+	werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
+    }
+    if (werr)
+	warn("Failed to write E/MBR during 'fixchs'.");
+
+bail:
+    pi_del(&iter);
+    return 0;
+}
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/mangle.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/mangle.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/mangle.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef COM32_CHAIN_MANGLE_H
+#define COM32_CHAIN_MANGLE_H
+
+#include "chain.h"
+#include "partiter.h"
+
+/* file's manglers */
+int manglef_isolinux(struct data_area *data);
+int manglef_grub(const struct part_iter *iter, struct data_area *data);
+int manglef_bpb(const struct part_iter *iter, struct data_area *data);
+/* int manglef_drmk(struct data_area *data);*/
+
+/* sector's manglers */
+int mangles_bpb(const struct part_iter *iter, struct data_area *data);
+int mangles_save(const struct part_iter *iter, const struct data_area *data, void *org);
+int mangles_cmldr(struct data_area *data);
+
+/* sector + file's manglers */
+int manglesf_bss(struct data_area *sec, struct data_area *fil);
+
+/* registers' manglers */
+int mangler_init(const struct part_iter *iter);
+int mangler_handover(const struct part_iter *iter, const struct data_area *data);
+int mangler_grldr(const struct part_iter *iter);
+
+/* partition layout's manglers */
+int manglepe_fixchs(struct part_iter *miter);
+int manglepe_hide(struct part_iter *miter);
+
+#endif
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/options.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/options.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/options.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,436 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/movebits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "chain.h"
+#include "partiter.h"
+#include "utility.h"
+#include "options.h"
+
+struct options opt;
+
+static int soi_s2n(char *ptr,
+			addr_t *seg,
+			addr_t *off,
+			addr_t *ip,
+			addr_t def)
+{
+    addr_t segval, offval, ipval, val;
+    char *p;
+
+    /* defaults */
+    segval = 0;
+    offval = def;
+    ipval = def;
+
+    segval = strtoul(ptr, &p, 0);
+    if (p[0] == ':' && p[1] && p[1] != ':')
+	offval = strtoul(p+1, &p, 0);
+    if (p[0] == ':' && p[1] && p[1] != ':')
+	ipval = strtoul(p+1, NULL, 0);
+
+    /* verify if load address is within [dosmin, dosmax) */
+    val = (segval << 4) + offval;
+
+    if (val < dosmin || val >= dosmax) {
+	error("Invalid seg:off:* address specified.");
+	goto bail;
+    }
+
+    /*
+     * verify if jump address is within [dosmin, dosmax) and offset is 16bit
+     * sane
+     */
+    val = (segval << 4) + ipval;
+
+    if (ipval > 0xFFFE || val < dosmin || val >= dosmax) {
+	error("Invalid seg:*:ip address specified.");
+	goto bail;
+    }
+
+    if (seg)
+	*seg = segval;
+    if (off)
+	*off = offval;
+    if (ip)
+	*ip  = ipval;
+
+    return 0;
+bail:
+    return -1;
+}
+
+static void usage(void)
+{
+    size_t i;
+    static const char *const usage[] = {
+"Usage:",
+"",
+"  disk + partition selection:",
+"        chain.c32 [options]",
+"        chain.c32 hd#[,#] [options]",
+"        chain.c32 fd#[,#] [options]",
+"        chain.c32 mbr=<id>[,#] [options]",
+"        chain.c32 guid=<guid>[,#] [options]",
+"        chain.c32 boot[,#] [options]",
+"",
+"  direct partition selection:",
+"        chain.c32 guid=<guid> [options]",
+"        chain.c32 label=<label> [options]",
+"        chain.c32 fs [options]",
+"",
+"You can use ':' instead of '=' and ' ' instead of ','.",
+"The default is 'boot,0'.",
+"",
+"Options:",
+"  sect[=<s[:o[:i]]>]   Load sector at <s:o>, jump to <s:i>",
+"                       - defaults to 0:0x7C00:0x7C00",
+"                       - omitted o/i values default to 0",
+"  maps                 Map loaded sector into real memory",
+"  setbpb               Fix BPB fields in loaded sector",
+"  filebpb              Apply 'setbpb' to loaded file",
+"  save                 Write adjusted sector back to disk",
+"  hand                 Prepare handover area",
+"  hptr                 Force ds:si and ds:bp to point to handover area",
+"  swap                 Swap drive numbers, if bootdisk is not fd0/hd0",
+"  nohide               Disable all hide variations (default)",
+"  hide                 Hide primary partitions, unhide selected partition",
+"  hideall              Hide *all* partitions, unhide selected partition",
+"  unhide               Unhide primary partitions",
+"  unhideall            Unhide *all* partitions",
+"  fixchs               Walk *all* partitions and fix E/MBRs' CHS values",
+"  keeppxe              Keep the PXE and UNDI stacks in memory (PXELINUX)",
+"  warn                 Wait for a keypress to continue chainloading",
+"  break                Don't chainload",
+"  strict[=<0|1|2>]     Set the level of strictness in sanity checks",
+"                       - strict w/o any value is the same as strict=2",
+"  relax                The same as strict=0",
+"  prefmbr              On hybrid MBR/GPT disks, prefer legacy layout",
+"",
+"  file=<file>          Load and execute <file>",
+"  seg=<s[:o[:i]]>      Load file at <s:o>, jump to <s:i>",
+"                       - defaults to 0:0x7C00:0x7C00",
+"                       - omitted o/i values default to 0",
+"  isolinux=<loader>    Load another version of ISOLINUX",
+"  ntldr=<loader>       Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR",
+"  reactos=<loader>     Load ReactOS's loader",
+"  cmldr=<loader>       Load Recovery Console of Windows NT/2K/XP/2003",
+"  freedos=<loader>     Load FreeDOS KERNEL.SYS",
+"  msdos=<loader>       Load MS-DOS 2.xx - 6.xx IO.SYS",
+"  msdos7=<loader>      Load MS-DOS 7+ IO.SYS",
+"  pcdos=<loader>       Load PC-DOS IBMBIO.COM",
+"  drmk=<loader>        Load DRMK DELLBIO.BIN",
+"  grub=<loader>        Load GRUB Legacy stage2",
+"  grubcfg=<config>     Set alternative config filename for GRUB Legacy",
+"  grldr=<loader>       Load GRUB4DOS grldr",
+"  bss=<sectimage>      Emulate syslinux's BSS",
+"  bs=<sectimage>       Emulate syslinux's BS",
+"",
+"Please see doc/chain.txt for the detailed documentation."
+};
+    for (i = 0; i < sizeof(usage)/sizeof(usage[0]); i++) {
+	if (i % 20 == 19) {
+	    puts("Press any key...");
+	    wait_key();
+	}
+	puts(usage[i]);
+    }
+}
+
+void opt_set_defs(void)
+{
+    memset(&opt, 0, sizeof opt);
+    opt.sect = true;	    /* by def. load sector */
+    opt.maps = true;	    /* by def. map sector */
+    opt.hand = true;	    /* by def. prepare handover */
+    opt.brkchain = false;   /* by def. do chainload */
+    opt.piflags = PIF_STRICT;	/* by def. be strict, but ignore disk sizes */
+    opt.foff = opt.soff = opt.fip = opt.sip = 0x7C00;
+    opt.drivename = "boot";
+#ifdef DEBUG
+    opt.warn = true;
+#endif
+}
+
+int opt_parse_args(int argc, char *argv[])
+{
+    int i;
+    size_t v;
+    char *p;
+
+    for (i = 1; i < argc; i++) {
+	if (!strncmp(argv[i], "file=", 5)) {
+	    opt.file = argv[i] + 5;
+	} else if (!strcmp(argv[i], "nofile")) {
+	    opt.file = NULL;
+	} else if (!strncmp(argv[i], "seg=", 4)) {
+	    if (soi_s2n(argv[i] + 4, &opt.fseg, &opt.foff, &opt.fip, 0))
+		goto bail;
+	} else if (!strncmp(argv[i], "bss=", 4)) {
+	    opt.file = argv[i] + 4;
+	    opt.bss = true;
+	    opt.maps = false;
+	    opt.setbpb = true;
+	} else if (!strncmp(argv[i], "bs=", 3)) {
+	    opt.file = argv[i] + 3;
+	    opt.sect = false;
+	    opt.filebpb = true;
+	} else if (!strncmp(argv[i], "isolinux=", 9)) {
+	    opt.file = argv[i] + 9;
+	    opt.isolinux = true;
+	    opt.hand = false;
+	    opt.sect = false;
+	} else if (!strncmp(argv[i], "ntldr=", 6)) {
+	    opt.fseg = 0x2000;  /* NTLDR wants this address */
+	    opt.foff = 0;
+	    opt.fip = 0;
+	    opt.file = argv[i] + 6;
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if (!strncmp(argv[i], "reactos=", 8)) {
+	    /*
+	     * settings based on commit
+	     *   ad4cf1470977f648ee1dd45e97939589ccb0393c
+	     * note, conflicts with:
+	     *   http://reactos.freedoors.org/Reactos%200.3.13/ReactOS-0.3.13-REL-src/boot/freeldr/notes.txt
+	     */
+	    opt.fseg = 0;
+	    opt.foff = 0x8000;
+	    opt.fip = 0x8100;
+	    opt.file = argv[i] + 8;
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if (!strncmp(argv[i], "cmldr=", 6)) {
+	    opt.fseg = 0x2000;  /* CMLDR wants this address */
+	    opt.foff = 0;
+	    opt.fip = 0;
+	    opt.file = argv[i] + 6;
+	    opt.cmldr = true;
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if (!strncmp(argv[i], "freedos=", 8)) {
+	    opt.fseg = 0x60;    /* FREEDOS wants this address */
+	    opt.foff = 0;
+	    opt.fip = 0;
+	    opt.sseg = 0x1FE0;
+	    opt.file = argv[i] + 8;
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if ( (v = 6, !strncmp(argv[i], "msdos=", v) ||
+		     !strncmp(argv[i], "pcdos=", v)) ||
+		    (v = 7, !strncmp(argv[i], "msdos7=", v)) ) {
+	    opt.fseg = 0x70;    /* MS-DOS 2.00 .. 6.xx wants this address */
+	    opt.foff = 0;
+	    opt.fip = v == 7 ? 0x200 : 0;  /* MS-DOS 7.0+ wants this ip */
+	    opt.sseg = 0x8000;
+	    opt.file = argv[i] + v;
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if (!strncmp(argv[i], "drmk=", 5)) {
+	    opt.fseg = 0x70;    /* DRMK wants this address */
+	    opt.foff = 0;
+	    opt.fip = 0;
+	    opt.sseg = 0x2000;
+	    opt.soff = 0;
+	    opt.sip = 0;
+	    opt.file = argv[i] + 5;
+	    /* opt.drmk = true; */
+	    opt.setbpb = true;
+	    opt.hand = false;
+	} else if (!strncmp(argv[i], "grub=", 5)) {
+	    opt.fseg = 0x800;	/* stage2 wants this address */
+	    opt.foff = 0;
+	    opt.fip = 0x200;
+	    opt.file = argv[i] + 5;
+	    opt.grub = true;
+	    opt.hand = false;
+	    opt.sect = false;
+	} else if (!strncmp(argv[i], "grubcfg=", 8)) {
+	    opt.grubcfg = argv[i] + 8;
+	} else if (!strncmp(argv[i], "grldr=", 6)) {
+	    opt.file = argv[i] + 6;
+	    opt.grldr = true;
+	    opt.hand = false;
+	    opt.sect = false;
+	} else if (!strcmp(argv[i], "keeppxe")) {
+	    opt.keeppxe = 3;
+	} else if (!strcmp(argv[i], "nokeeppxe")) {
+	    opt.keeppxe = 0;
+	} else if (!strcmp(argv[i], "maps")) {
+	    opt.maps = true;
+	} else if (!strcmp(argv[i], "nomaps")) {
+	    opt.maps = false;
+	} else if (!strcmp(argv[i], "hand")) {
+	    opt.hand = true;
+	} else if (!strcmp(argv[i], "nohand")) {
+	    opt.hand = false;
+	} else if (!strcmp(argv[i], "hptr")) {
+	    opt.hptr = true;
+	} else if (!strcmp(argv[i], "nohptr")) {
+	    opt.hptr = false;
+	} else if (!strcmp(argv[i], "swap")) {
+	    opt.swap = true;
+	} else if (!strcmp(argv[i], "noswap")) {
+	    opt.swap = false;
+	} else if (!strcmp(argv[i], "nohide")) {
+	    opt.hide = HIDE_OFF;
+	} else if (!strcmp(argv[i], "hide")) {
+	    opt.hide = HIDE_ON;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "hideall")) {
+	    opt.hide = HIDE_ON | HIDE_EXT;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "unhide")) {
+	    opt.hide = HIDE_ON | HIDE_REV;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "unhideall")) {
+	    opt.hide = HIDE_ON | HIDE_EXT | HIDE_REV;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "setbpb")) {
+	    opt.setbpb = true;
+	} else if (!strcmp(argv[i], "nosetbpb")) {
+	    opt.setbpb = false;
+	} else if (!strcmp(argv[i], "filebpb")) {
+	    opt.filebpb = true;
+	} else if (!strcmp(argv[i], "nofilebpb")) {
+	    opt.filebpb = false;
+	} else if (!strncmp(argv[i], "sect=", 5) ||
+		   !strcmp(argv[i], "sect")) {
+	    if (argv[i][4]) {
+		if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip, 0))
+		    goto bail;
+	    }
+	    opt.sect = true;
+	} else if (!strcmp(argv[i], "nosect")) {
+	    opt.sect = false;
+	    opt.maps = false;
+	} else if (!strcmp(argv[i], "save")) {
+	    opt.save = true;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "nosave")) {
+	    opt.save = false;
+	} else if (!strcmp(argv[i], "fixchs")) {
+	    opt.fixchs = true;
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strcmp(argv[i], "nofixchs")) {
+	    opt.fixchs = false;
+	} else if (!strcmp(argv[i], "relax") || !strcmp(argv[i], "nostrict")) {
+	    opt.piflags &= ~(PIF_STRICT | PIF_STRICTER);
+	} else if (!strcmp(argv[i], "norelax") || !strcmp(argv[i], "strict")) {
+	    opt.piflags |= PIF_STRICT | PIF_STRICTER;
+	} else if (!strncmp(argv[i], "strict=", 7)) {
+	    if (argv[i][7] < '0' || argv[i][7] > '2' || !argv[i][8]) {
+		error("Strict level must be 0, 1 or 2.");
+		goto bail;
+	    }
+	    opt.piflags &= ~(PIF_STRICT | PIF_STRICTER);
+	    switch (argv[i][7]) {
+		case '2': opt.piflags |= PIF_STRICTER;
+		case '1': opt.piflags |= PIF_STRICT; break;
+		default:;
+	    }
+	} else if (!strcmp(argv[i], "warn")) {
+	    opt.warn = true;
+	} else if (!strcmp(argv[i], "nowarn")) {
+	    opt.warn = false;
+	} else if (!strcmp(argv[i], "prefmbr")) {
+	    opt.piflags |= PIF_PREFMBR;
+	} else if (!strcmp(argv[i], "noprefmbr")) {
+	    opt.piflags &= ~PIF_PREFMBR;
+	} else if (!strcmp(argv[i], "nobreak")) {
+	    opt.brkchain = false;
+	} else if (!strcmp(argv[i], "break")) {
+	    opt.brkchain = true;
+	    opt.file = NULL;
+	    opt.maps = false;
+	    opt.hand = false;
+	} else if (((argv[i][0] == 'h' || argv[i][0] == 'f')
+		    && argv[i][1] == 'd')
+		   || !strncmp(argv[i], "mbr:", 4)
+		   || !strncmp(argv[i], "mbr=", 4)
+		   || !strncmp(argv[i], "guid:", 5)
+		   || !strncmp(argv[i], "guid=", 5)
+		   || !strncmp(argv[i], "label:", 6)
+		   || !strncmp(argv[i], "label=", 6)
+		   || !strcmp(argv[i], "boot")
+		   || !strncmp(argv[i], "boot,", 5)
+		   || !strcmp(argv[i], "fs")) {
+	    opt.drivename = argv[i];
+	    if (strncmp(argv[i], "label", 5))
+		p = strchr(opt.drivename, ',');
+	    else
+		p = NULL;
+	    if (p) {
+		*p = '\0';
+		opt.partition = p + 1;
+	    } else if (argv[i + 1] && argv[i + 1][0] >= '0'
+		    && argv[i + 1][0] <= '9') {
+		opt.partition = argv[++i];
+	    }
+	} else {
+	    usage();
+	    goto bail;
+	}
+    }
+
+    if (opt.grubcfg && !opt.grub) {
+	error("grubcfg=<filename> must be used together with grub=<loader>.");
+	goto bail;
+    }
+
+    if (opt.filebpb && !opt.file) {
+	error("Option 'filebpb' requires a file.");
+	goto bail;
+    }
+
+    if (opt.save && !opt.sect) {
+	error("Option 'save' requires a sector.");
+	goto bail;
+    }
+
+    if (opt.setbpb && !opt.sect) {
+	error("Option 'setbpb' requires a sector.");
+	goto bail;
+    }
+
+    if (opt.maps && !opt.sect) {
+	error("Option 'maps' requires a sector.");
+	goto bail;
+    }
+
+    return 0;
+bail:
+    return -1;
+}
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/options.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/options.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/options.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,81 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef COM32_CHAIN_OPTIONS_H
+#define COM32_CHAIN_OPTIONS_H
+
+#include <stdint.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+
+enum {HIDE_OFF = 0, HIDE_ON = 1, HIDE_EXT = 2, HIDE_REV = 4};
+
+struct options {
+    const char *drivename;
+    const char *partition;
+    const char *file;
+    const char *grubcfg;
+    addr_t fseg;
+    addr_t foff;
+    addr_t fip;
+    addr_t sseg;
+    addr_t soff;
+    addr_t sip;
+    int hide;
+    int piflags;
+    uint16_t keeppxe;
+    bool isolinux;
+    bool cmldr;
+    bool drmk;
+    bool grub;
+    bool grldr;
+    bool maps;
+    bool hand;
+    bool hptr;
+    bool swap;
+    bool sect;
+    bool save;
+    bool bss;
+    bool setbpb;
+    bool filebpb;
+    bool fixchs;
+    bool warn;
+    bool brkchain;
+    struct syslinux_rm_regs regs;
+};
+
+extern struct options opt;
+
+void opt_set_defs(void);
+int opt_parse_args(int argc, char *argv[]);
+
+#endif
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/partiter.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/partiter.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/partiter.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,714 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * partiter.c
+ *
+ * Provides disk / partition iteration.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <zlib.h>
+#include <syslinux/disk.h>
+#include "partiter.h"
+#include "utility.h"
+
+#define ost_is_ext(type) ((type) == 0x05 || (type) == 0x0F || (type) == 0x85)
+#define ost_is_nondata(type) (ost_is_ext(type) || (type) == 0x00)
+#define sane(s,l) ((s)+(l) > (s))
+
+/* virtual forwards */
+
+static void pi_dtor_(struct part_iter *);
+static int  pi_next_(struct part_iter *);
+static int  pi_dos_next(struct part_iter *);
+static int  pi_gpt_next(struct part_iter *);
+
+/* vtab and types */
+
+static struct itertype types[] = {
+   [0] = {
+	.dtor = &pi_dtor_,
+	.next = &pi_dos_next,
+}, [1] = {
+	.dtor = &pi_dtor_,
+	.next = &pi_gpt_next,
+}, [2] = {
+	.dtor = &pi_dtor_,
+	.next = &pi_next_,
+}};
+
+const struct itertype * const typedos = types;
+const struct itertype * const typegpt = types+1;
+const struct itertype * const typeraw = types+2;
+
+/* pi_dtor_() - common/raw iterator cleanup */
+static void pi_dtor_(struct part_iter *iter)
+{
+    /* syslinux's free is null resilient */
+    free(iter->data);
+}
+
+/* pi_ctor() - common/raw iterator initialization */
+static int pi_ctor(struct part_iter *iter,
+	const struct disk_info *di, int flags
+)
+{
+    memcpy(&iter->di, di, sizeof *di);
+    iter->flags = flags;
+    iter->index0 = -1;
+    iter->length = di->lbacnt;
+
+    iter->type = typeraw;
+    return 0;
+}
+
+/* pi_dos_ctor() - MBR/EBR iterator specific initialization */
+static int pi_dos_ctor(struct part_iter *iter,
+	const struct disk_info *di, int flags,
+	const struct disk_dos_mbr *mbr
+)
+{
+    if (pi_ctor(iter, di, flags))
+	return -1;
+
+    if (!(iter->data = malloc(sizeof *mbr))) {
+	critm();
+	goto bail;
+    }
+
+    memcpy(iter->data, mbr, sizeof *mbr);
+
+    iter->dos.bebr_index0 = -1;
+    iter->dos.disk_sig = mbr->disk_sig;
+
+    iter->type = typedos;
+    return 0;
+bail:
+    pi_dtor_(iter);
+    return -1;
+}
+
+/* pi_gpt_ctor() - GPT iterator specific initialization */
+static int pi_gpt_ctor(struct part_iter *iter,
+	const struct disk_info *di, int flags,
+	const struct disk_gpt_header *gpth, const struct disk_gpt_part_entry *gptl
+)
+{
+    uint64_t siz;
+
+    if (pi_ctor(iter, di, flags))
+	return -1;
+
+    siz = (uint64_t)gpth->part_count * gpth->part_size;
+
+    if (!(iter->data = malloc((size_t)siz))) {
+	critm();
+	goto bail;
+    }
+
+    memcpy(iter->data, gptl, (size_t)siz);
+
+    iter->gpt.pe_count = (int)gpth->part_count;
+    iter->gpt.pe_size = (int)gpth->part_size;
+    iter->gpt.ufirst = gpth->lba_first_usable;
+    iter->gpt.ulast = gpth->lba_last_usable;
+
+    memcpy(&iter->gpt.disk_guid, &gpth->disk_guid, sizeof gpth->disk_guid);
+    memcpy(&iter->gpt.part_guid, &gpth->disk_guid, sizeof gpth->disk_guid);
+
+    iter->type = typegpt;
+    return 0;
+bail:
+    pi_dtor_(iter);
+    return -1;
+}
+
+/* Logical partition must be sane, meaning:
+ * - must be data or empty
+ * - must have non-0 start and length
+ * - values must not wrap around 32bit
+ * - must be inside current EBR frame
+ */
+
+static int notsane_logical(const struct part_iter *iter)
+{
+    const struct disk_dos_part_entry *dp;
+    uint32_t end_log;
+
+    dp = ((struct disk_dos_mbr *)iter->data)->table;
+
+    if (!dp[0].ostype)
+	return 0;
+
+    if (ost_is_ext(dp[0].ostype)) {
+	error("The 1st EBR entry must be data or empty.");
+	return -1;
+    }
+
+    if (!(iter->flags & PIF_STRICT))
+	return 0;
+
+    end_log = dp[0].start_lba + dp[0].length;
+
+    if (!dp[0].start_lba ||
+	!dp[0].length ||
+	!sane(dp[0].start_lba, dp[0].length) ||
+	end_log > iter->dos.nebr_siz) {
+
+	error("Logical partition (in EBR) with invalid offset and/or length.");
+	return -1;
+    }
+
+    return 0;
+}
+
+/* Extended partition must be sane, meaning:
+ * - must be extended or empty
+ * - must have non-0 start and length
+ * - values must not wrap around 32bit
+ * - must be inside base EBR frame
+ */
+
+static int notsane_extended(const struct part_iter *iter)
+{
+    const struct disk_dos_part_entry *dp;
+    uint32_t end_ebr;
+
+    dp = ((struct disk_dos_mbr *)iter->data)->table;
+
+    if (!dp[1].ostype)
+	return 0;
+
+    if (!ost_is_nondata(dp[1].ostype)) {
+	error("The 2nd EBR entry must be extended or empty.");
+	return -1;
+    }
+
+    if (!(iter->flags & PIF_STRICT))
+	return 0;
+
+    end_ebr = dp[1].start_lba + dp[1].length;
+
+    if (!dp[1].start_lba ||
+	!dp[1].length ||
+	!sane(dp[1].start_lba, dp[1].length) ||
+	end_ebr > iter->dos.bebr_siz) {
+
+	error("Extended partition (EBR) with invalid offset and/or length.");
+	return -1;
+    }
+
+    return 0;
+}
+
+/* Primary partition must be sane, meaning:
+ * - must have non-0 start and length
+ * - values must not wrap around 32bit
+ */
+
+static int notsane_primary(const struct part_iter *iter)
+{
+    const struct disk_dos_part_entry *dp;
+    dp = ((struct disk_dos_mbr *)iter->data)->table + iter->index0;
+
+    if (!dp->ostype)
+	return 0;
+
+    if (!(iter->flags & PIF_STRICT))
+	return 0;
+
+    if (!dp->start_lba ||
+	!dp->length ||
+	!sane(dp->start_lba, dp->length) ||
+	((iter->flags & PIF_STRICTER) && (dp->start_lba + dp->length > iter->di.lbacnt))) {
+	error("Primary partition (in MBR) with invalid offset and/or length.");
+	return -1;
+    }
+
+    return 0;
+}
+
+static int notsane_gpt(const struct part_iter *iter)
+{
+    const struct disk_gpt_part_entry *gp;
+    gp = (const struct disk_gpt_part_entry *)
+	(iter->data + iter->index0 * iter->gpt.pe_size);
+
+    if (guid_is0(&gp->type))
+	return 0;
+
+    if (!(iter->flags & PIF_STRICT))
+	return 0;
+
+    if (gp->lba_first < iter->gpt.ufirst ||
+	gp->lba_last > iter->gpt.ulast) {
+	error("LBA sectors of GPT partition are beyond the range allowed in GPT header.");
+	return -1;
+    }
+
+    return 0;
+}
+
+static int dos_next_mbr(struct part_iter *iter, uint32_t *lba,
+			    struct disk_dos_part_entry **_dp)
+{
+    struct disk_dos_part_entry *dp;
+
+    while (++iter->index0 < 4) {
+	dp = ((struct disk_dos_mbr *)iter->data)->table + iter->index0;
+
+	if (notsane_primary(iter)) {
+	    iter->status = PI_INSANE;
+	    return -1;
+	}
+
+	if (ost_is_ext(dp->ostype)) {
+	    if (iter->dos.bebr_index0 >= 0) {
+		error("More than 1 extended partition.");
+		iter->status = PI_INSANE;
+		return -1;
+	    }
+	    /* record base EBR index */
+	    iter->dos.bebr_index0 = iter->index0;
+	}
+	if (!ost_is_nondata(dp->ostype) || (iter->flags & PIF_STEPALL)) {
+	    *lba = dp->start_lba;
+	    *_dp = dp;
+	    break;
+	}
+    }
+
+    return 0;
+}
+
+static int prep_base_ebr(struct part_iter *iter)
+{
+    struct disk_dos_part_entry *dp;
+
+    if (iter->dos.bebr_index0 < 0)	/* if we don't have base extended partition at all */
+	return -1;
+    else if (!iter->dos.bebr_lba) { /* if not initialized yet */
+	dp = ((struct disk_dos_mbr *)iter->data)->table + iter->dos.bebr_index0;
+
+	iter->dos.bebr_lba = dp->start_lba;
+	iter->dos.bebr_siz = dp->length;
+
+	iter->dos.nebr_lba = dp->start_lba;
+	iter->dos.nebr_siz = dp->length;
+
+	iter->index0--;
+    }
+    return 0;
+}
+
+static int dos_next_ebr(struct part_iter *iter, uint32_t *lba,
+			    struct disk_dos_part_entry **_dp)
+{
+    struct disk_dos_part_entry *dp;
+
+    if (prep_base_ebr(iter) < 0) {
+	iter->status = PI_DONE;
+	return -1;
+    }
+
+    while (++iter->index0 < 1024 && iter->dos.nebr_lba) {
+	free(iter->data);
+	if (!(iter->data =
+		    disk_read_sectors(&iter->di, iter->dos.nebr_lba, 1))) {
+	    error("Couldn't load EBR.");
+	    iter->status = PI_ERRLOAD;
+	    return -1;
+	}
+
+	/* check sanity of loaded data */
+	if (notsane_logical(iter) || notsane_extended(iter)) {
+	    iter->status = PI_INSANE;
+	    return -1;
+	}
+
+	dp = ((struct disk_dos_mbr *)iter->data)->table;
+
+	iter->dos.cebr_lba = iter->dos.nebr_lba;
+	iter->dos.cebr_siz = iter->dos.nebr_siz;
+
+	/* setup next frame values */
+	if (dp[1].ostype) {
+	    iter->dos.nebr_lba = iter->dos.bebr_lba + dp[1].start_lba;
+	    iter->dos.nebr_siz = dp[1].length;
+	} else {
+	    iter->dos.nebr_lba = 0;
+	    iter->dos.nebr_siz = 0;
+	}
+
+	if (!dp[0].ostype)
+	    iter->dos.logskipcnt++;
+
+	if (dp[0].ostype || (iter->flags & PIF_STEPALL)) {
+	    *lba = dp[0].start_lba ? iter->dos.cebr_lba + dp[0].start_lba : 0;
+	    *_dp = dp;
+	    return 0;
+	}
+	/*
+	 * This way it's possible to continue, if some crazy soft left a "hole"
+	 * - EBR with a valid extended partition without a logical one. In
+	 * such case, linux will not reserve a number for such hole - so we
+	 * don't increase index0. If PIF_STEPALL flag is set, we will never
+	 * reach this place.
+	 */
+    }
+    iter->status = PI_DONE;
+    return -1;
+}
+
+static void gpt_conv_label(struct part_iter *iter)
+{
+    const struct disk_gpt_part_entry *gp;
+    const int16_t *orig_lab;
+
+    gp = (const struct disk_gpt_part_entry *)
+	(iter->data + iter->index0 * iter->gpt.pe_size);
+    orig_lab = (const int16_t *)gp->name;
+
+    /* caveat: this is very crude conversion */
+    for (int i = 0; i < PI_GPTLABSIZE/2; i++) {
+	iter->gpt.part_label[i] = (char)orig_lab[i];
+    }
+    iter->gpt.part_label[PI_GPTLABSIZE/2] = 0;
+}
+
+static inline int valid_crc(uint32_t crc, const uint8_t *buf, unsigned int siz)
+{
+    return crc == crc32(crc32(0, NULL, 0), buf, siz);
+}
+
+static int valid_crc_hdr(void *buf)
+{
+    struct disk_gpt_header *gh = buf;
+    uint32_t crc = gh->chksum;
+    int valid;
+
+    gh->chksum = 0;
+    valid = crc == crc32(crc32(0, NULL, 0), buf, gh->hdr_size);
+    gh->chksum = crc;
+    return valid;
+}
+
+static int pi_next_(struct part_iter *iter)
+{
+    iter->status = PI_DONE;
+    return iter->status;
+}
+
+static int pi_dos_next(struct part_iter *iter)
+{
+    uint32_t abs_lba = 0;
+    struct disk_dos_part_entry *dos_part = NULL;
+
+    if (iter->status)
+	return iter->status;
+
+    /* look for primary partitions */
+    if (iter->index0 < 4 &&
+	    dos_next_mbr(iter, &abs_lba, &dos_part) < 0)
+	return iter->status;
+
+    /* look for logical partitions */
+    if (iter->index0 >= 4 &&
+	    dos_next_ebr(iter, &abs_lba, &dos_part) < 0)
+	return iter->status;
+
+    /*
+     * note special index handling:
+     * in case PIF_STEPALL is set - this makes the index consistent with
+     * non-PIF_STEPALL iterators
+     */
+
+    if (!dos_part->ostype)
+	iter->index = -1;
+    else
+	iter->index = iter->index0 + 1 - iter->dos.logskipcnt;
+    iter->abs_lba = abs_lba;
+    iter->length = dos_part->length;
+    iter->record = (char *)dos_part;
+
+#ifdef DEBUG
+    disk_dos_part_dump(dos_part);
+#endif
+
+    return iter->status;
+}
+
+static int pi_gpt_next(struct part_iter *iter)
+{
+    const struct disk_gpt_part_entry *gpt_part = NULL;
+
+    if (iter->status)
+	return iter->status;
+
+    while (++iter->index0 < iter->gpt.pe_count) {
+	gpt_part = (const struct disk_gpt_part_entry *)
+	    (iter->data + iter->index0 * iter->gpt.pe_size);
+
+	if (notsane_gpt(iter)) {
+	    iter->status = PI_INSANE;
+	    return iter->status;
+	}
+
+	if (!guid_is0(&gpt_part->type) || (iter->flags & PIF_STEPALL))
+	    break;
+    }
+    /* no more partitions ? */
+    if (iter->index0 == iter->gpt.pe_count) {
+	iter->status = PI_DONE;
+	return iter->status;
+    }
+    /* gpt_part is guaranteed to be valid here */
+    iter->index = iter->index0 + 1;
+    iter->abs_lba = gpt_part->lba_first;
+    iter->length = gpt_part->lba_last - gpt_part->lba_first + 1;
+    iter->record = (char *)gpt_part;
+    memcpy(&iter->gpt.part_guid, &gpt_part->uid, sizeof(struct guid));
+    gpt_conv_label(iter);
+
+#ifdef DEBUG
+    disk_gpt_part_dump(gpt_part);
+#endif
+
+    return iter->status;
+}
+
+static struct part_iter *pi_alloc(void)
+{
+    struct part_iter *iter;
+    if (!(iter = malloc(sizeof *iter)))
+	critm();
+    else
+	memset(iter, 0, sizeof *iter);
+    return iter;
+}
+
+/* pi_del() - delete iterator */
+void pi_del(struct part_iter **_iter)
+{
+    if(!_iter || !*_iter)
+	return;
+    pi_dtor(*_iter);
+    free(*_iter);
+    *_iter = NULL;
+}
+
+static void try_gpt_we(const char *str, int sec)
+{
+    if (sec)
+	error(str);
+    else
+	warn(str);
+}
+
+static struct disk_gpt_header *try_gpt_hdr(const struct disk_info *di, int sec)
+{
+    const char *desc = sec ? "backup" : "primary";
+    uint64_t gpt_cur = sec ? di->lbacnt - 1 : 1;
+    struct disk_gpt_header *gpth;
+    char errbuf[64];
+
+    gpth = disk_read_sectors(di, gpt_cur, 1);
+    if (!gpth) {
+	sprintf(errbuf, "Unable to read %s GPT header.", desc);
+	try_gpt_we(errbuf, sec);
+	return NULL;
+    }
+    if(!valid_crc_hdr(gpth)) {
+	sprintf(errbuf, "Invalid checksum of %s GPT header.", desc);
+	try_gpt_we(errbuf, sec);
+	free(gpth);
+	return NULL;
+    }
+    return gpth;
+}
+
+static struct disk_gpt_part_entry *try_gpt_list(const struct disk_info *di, const struct disk_gpt_header *gpth, int alt)
+{
+    int pri = gpth->lba_cur < gpth->lba_alt;
+    const char *desc = alt ? "alternative" : "main";
+    struct disk_gpt_part_entry *gptl;
+    char errbuf[64];
+    uint64_t gpt_lsiz;	    /* size of GPT partition list in bytes */
+    uint64_t gpt_lcnt;	    /* size of GPT partition in sectors */
+    uint64_t gpt_loff;	    /* offset to GPT partition list in sectors */
+
+    gpt_lsiz = (uint64_t)gpth->part_size * gpth->part_count;
+    gpt_lcnt = (gpt_lsiz + di->bps - 1) / di->bps;
+    if (!alt) {
+	/* prefer header value for partition table if not asking for alternative */
+	gpt_loff = gpth->lba_table;
+    } else {
+	/* try to read alternative, we have to calculate its position */
+	if (!pri)
+	    gpt_loff = gpth->lba_alt + 1;
+	else
+	    gpt_loff = gpth->lba_alt - gpt_lcnt;
+    }
+
+    gptl = disk_read_sectors(di, gpt_loff, gpt_lcnt);
+    if (!gptl) {
+	sprintf(errbuf, "Unable to read %s GPT partition list.", desc);
+	try_gpt_we(errbuf, alt);
+	return NULL;
+    }
+    if (!valid_crc(gpth->table_chksum, (const uint8_t *)gptl, gpt_lsiz)) {
+	sprintf(errbuf, "Invalid checksum of %s GPT partition list.", desc);
+	try_gpt_we(errbuf, alt);
+	free(gptl);
+	return NULL;
+    }
+    return gptl;
+}
+
+static int notsane_gpt_hdr(const struct disk_info *di, const struct disk_gpt_header *gpth, int flags)
+{
+    uint64_t gpt_loff;	    /* offset to GPT partition list in sectors */
+    uint64_t gpt_lsiz;	    /* size of GPT partition list in bytes */
+    uint64_t gpt_lcnt;	    /* size of GPT partition in sectors */
+    uint64_t gpt_sec;	    /* secondary gpt header */
+
+    if (!(flags & PIF_STRICT))
+	return 0;
+
+    if (gpth->lba_alt < gpth->lba_cur)
+	gpt_sec = gpth->lba_cur;
+    else
+	gpt_sec = gpth->lba_alt;
+    gpt_loff = gpth->lba_table;
+    gpt_lsiz = (uint64_t)gpth->part_size * gpth->part_count;
+    gpt_lcnt = (gpt_lsiz + di->bps - 1) / di->bps;
+
+    /*
+     * disk_read_sectors allows reading of max 255 sectors, so we use
+     * it as a sanity check base. EFI doesn't specify max (AFAIK).
+     */
+    if (gpt_loff < 2 || !gpt_lsiz || gpt_lcnt > 255u ||
+	    gpth->lba_first_usable > gpth->lba_last_usable ||
+	    !sane(gpt_loff, gpt_lcnt) ||
+	    (gpt_loff + gpt_lcnt > gpth->lba_first_usable && gpt_loff <= gpth->lba_last_usable) ||
+	     gpt_loff + gpt_lcnt > gpt_sec ||
+	    ((flags & PIF_STRICTER) && (gpt_sec >= di->lbacnt)) ||
+	    gpth->part_size < sizeof(struct disk_gpt_part_entry))
+	return -1;
+
+    return 0;
+}
+
+/* pi_begin() - validate and and get proper iterator for a disk described by di */
+struct part_iter *pi_begin(const struct disk_info *di, int flags)
+{
+    int isgpt = 0, ret = -1;
+    struct part_iter *iter;
+    struct disk_dos_mbr *mbr = NULL;
+    struct disk_gpt_header *gpth = NULL;
+    struct disk_gpt_part_entry *gptl = NULL;
+
+    /* Preallocate iterator */
+    if (!(iter = pi_alloc()))
+	goto out;
+
+    /* Read MBR */
+    if (!(mbr = disk_read_sectors(di, 0, 1))) {
+	error("Unable to read the first disk sector.");
+	goto out;
+    }
+
+    /* Check for MBR magic */
+    if (mbr->sig != disk_mbr_sig_magic) {
+	warn("No MBR magic, treating disk as raw.");
+	/* looks like RAW */
+	ret = pi_ctor(iter, di, flags);
+	goto out;
+    }
+
+    /* Check for GPT protective MBR */
+    for (size_t i = 0; i < 4; i++)
+	isgpt |= (mbr->table[i].ostype == 0xEE);
+    isgpt = isgpt && !(flags & PIF_PREFMBR);
+
+    /* Try to read GPT header */
+    if (isgpt) {
+	gpth = try_gpt_hdr(di, 0);
+	if (!gpth)
+	    /*
+	     * this read might fail if bios reports different disk size (different vm/pc)
+	     * not much we can do here to avoid it
+	     */
+	    gpth = try_gpt_hdr(di, 1);
+	if (!gpth)
+	    goto out;
+    }
+
+    if (gpth && gpth->rev.uint32 == 0x00010000 &&
+	    !memcmp(gpth->sig, disk_gpt_sig_magic, sizeof gpth->sig)) {
+	/* looks like GPT v1.0 */
+#ifdef DEBUG
+	dprintf("Looks like a GPT v1.0 disk.\n");
+	disk_gpt_header_dump(gpth);
+#endif
+	if (notsane_gpt_hdr(di, gpth, flags)) {
+	    error("GPT header values are corrupted.");
+	    goto out;
+	}
+
+	gptl = try_gpt_list(di, gpth, 0);
+	if (!gptl)
+	    gptl = try_gpt_list(di, gpth, 1);
+	if (!gptl)
+	    goto out;
+
+	/* looks like GPT */
+	ret = pi_gpt_ctor(iter, di, flags, gpth, gptl);
+    } else {
+	/* looks like MBR */
+	ret = pi_dos_ctor(iter, di, flags, mbr);
+    }
+out:
+    if (ret < 0) {
+	free(iter);
+	iter = NULL;
+    }
+    free(mbr);
+    free(gpth);
+    free(gptl);
+
+    return iter;
+}
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/partiter.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/partiter.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/partiter.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * partiter.h
+ *
+ * Provides disk / partition iteration.
+ */
+
+#ifndef COM32_CHAIN_PARTITER_H
+#define COM32_CHAIN_PARTITER_H
+
+#include <stdint.h>
+#include <syslinux/disk.h>
+
+/* status */
+
+enum {PI_ERRLOAD = -31, PI_INSANE, PI_OK = 0, PI_DONE};
+
+/* flags */
+
+enum {PIF_STEPALL = 1, PIF_PREFMBR = 2, PIF_STRICT = 4, PIF_STRICTER = 8};
+
+struct itertype;
+struct part_iter;
+
+struct itertype {
+	void (*dtor)(struct part_iter *);
+	int  (*next)(struct part_iter *);
+};
+
+#define PI_GPTLABSIZE ((int)sizeof(((struct disk_gpt_part_entry *)0)->name))
+
+struct part_iter {
+    const struct itertype *type;
+    char *data;
+    char *record;
+    uint64_t abs_lba;
+    uint64_t length;
+    int index0;	    /* including holes, from -1 (disk, then parts from 0) */
+    int index;	    /* excluding holes, from  0 (disk, then parts from 1), -1 means hole, if PIF_STEPALL is set */
+    int flags;	    /* flags, see #defines above */
+    int status;	    /* current status, see enums above */
+    struct disk_info di;
+    union {
+	struct {
+	    uint32_t disk_sig;	  /* 32bit disk signature as stored in MBR */
+
+	    uint32_t bebr_lba;	  /* absolute lba of base extended partition */
+	    uint32_t bebr_siz;	  /* size of base extended partition */
+
+	    uint32_t cebr_lba;	  /* absolute lba of curr ext. partition */
+	    uint32_t cebr_siz;	  /* size of curr ext. partition */
+	    uint32_t nebr_lba;	  /* absolute lba of next ext. partition */
+	    uint32_t nebr_siz;	  /* size of next ext. partition */
+
+	    int bebr_index0;	  /* index of (0-3) of base ext. part., -1 if not present in MBR */
+	    int logskipcnt;	  /* how many logical holes were skipped */
+	} dos;
+	struct {
+	    struct guid disk_guid;
+	    struct guid part_guid;
+	    char part_label[PI_GPTLABSIZE/2+1];
+	    int pe_count;
+	    int pe_size;
+	    uint64_t ufirst;
+	    uint64_t ulast;
+	} gpt;
+    };
+};
+
+extern const struct itertype * const typedos;
+extern const struct itertype * const typegpt;
+extern const struct itertype * const typeraw;
+
+struct part_iter *pi_begin(const struct disk_info *, int flags);
+void pi_del(struct part_iter **);
+
+/* inline virtuals */
+static inline int pi_next(struct part_iter *iter)
+{
+    return iter->type->next(iter);
+}
+
+static inline void pi_dtor(struct part_iter *iter)
+{
+    iter->type->dtor(iter);
+}
+
+#endif
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/utility.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/utility.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/utility.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,256 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <fs.h>
+#include <syslinux/disk.h>
+#include <syslinux/pmapi.h>
+#include "utility.h"
+
+static const char *bpbtypes[] = {
+    [0] =  "unknown",
+    [1] =  "2.0",
+    [2] =  "3.0",
+    [3] =  "3.2",
+    [4] =  "3.4",
+    [5] =  "4.0",
+    [6] =  "8.0 (NT+)",
+    [7] =  "7.0",
+    [8] =  "exFAT",
+};
+
+void wait_key(void)
+{
+    int cnt;
+    char junk;
+
+    /* drain */
+    do {
+	errno = 0;
+	cnt = read(0, &junk, 1);
+    } while (cnt > 0 || (cnt < 0 && errno == EAGAIN));
+
+    /* wait */
+    do {
+	errno = 0;
+	cnt = read(0, &junk, 1);
+    } while (!cnt || (cnt < 0 && errno == EAGAIN));
+}
+
+int guid_is0(const struct guid *guid)
+{
+    return
+	!(guid->data1 ||
+	  guid->data2 ||
+	  guid->data3 ||
+	  guid->data4);
+}
+
+/*
+ * mode explanation:
+ *
+ * cnul - "strict" mode, never returning higher value than obtained from cbios
+ * cadd - if the disk is larger than reported geometry /and/ if the geometry has
+ *        less cylinders than 1024 - it means that the total size is somewhere
+ *        between cs and cs+1; in this particular case, we bump the cs to be able
+ *        to return matching chs triplet
+ * cmax - assume we can use any cylinder value
+ *
+ * by default cadd seems most reasonable, giving consistent results with e.g.
+ * sfdisk's behavior
+ */
+void lba2chs(disk_chs *dst, const struct disk_info *di, uint64_t lba, int mode)
+{
+    uint32_t c, h, s, t;
+    uint32_t cs, hs, ss;
+
+    /*
+     * Not much reason here, but if we have no valid CHS geometry, we assume
+     * "typical" ones to have something to return.
+     */
+    if (di->cbios) {
+	cs = di->cyl;
+	hs = di->head;
+	ss = di->spt;
+	if (mode == L2C_CADD) {
+	    if (cs < 1024 && di->lbacnt > cs*hs*ss)
+		cs++;
+	} else if (mode == L2C_CMAX)
+	    cs = 1024;
+    } else {
+	if (di->disk & 0x80) {
+	    cs = 1024;
+	    hs = 255;
+	    ss = 63;
+	} else {
+	    cs = 80;
+	    hs = 2;
+	    ss = 18;
+	}
+    }
+
+    if (lba >= cs*hs*ss) {
+	s = ss;
+	h = hs - 1;
+	c = cs - 1;
+    } else {
+	s = (lba % ss) + 1;
+	t = lba / ss;
+	h = t % hs;
+	c = t / hs;
+    }
+
+    (*dst)[0] = h;
+    (*dst)[1] = s | ((c & 0x300) >> 2);
+    (*dst)[2] = c;
+}
+
+uint32_t get_file_lba(const char *filename)
+{
+    struct com32_filedata fd;
+    uint32_t lba = 0;
+    int size = 65536;
+    char *buf;
+
+    buf = lmalloc(size);
+    if (!buf)
+	return 0;
+
+    /* Put the filename in the bounce buffer */
+    strlcpy(buf, filename, size);
+
+    if (open_file(buf, O_RDONLY, &fd) <= 0) {
+	goto fail;		/* Filename not found */
+    }
+
+    /* Since the first member is the LBA, we simply cast */
+    lba = *((uint32_t *) MK_PTR(0, fd.handle));
+
+    /* Call comapi_close() to free the structure */
+    close_file(fd.handle);
+
+fail:
+    lfree(buf);
+    return lba;
+}
+
+/* drive offset detection */
+int drvoff_detect(int type)
+{
+    if (bpbV40 <= type && type <= bpbVNT) {
+	return 0x24;
+    } else if (type == bpbV70) {
+	return 0x40;
+    } else if (type == bpbEXF) {
+	return 0x6F;
+    }
+
+    return -1;
+}
+
+/*
+ * heuristics could certainly be improved
+ */
+int bpb_detect(const uint8_t *sec, const char *tag)
+{
+    int a, b, c, jmp = -1, rev = 0;
+
+    /* exFAT mess first (media descriptor is 0 here) */
+    if (!memcmp(sec + 0x03, "EXFAT   ", 8)) {
+	rev = bpbEXF;
+	goto out;
+    }
+
+    /* media descriptor check */
+    if ((sec[0x15] & 0xF0) != 0xF0)
+	goto out;
+
+    if (sec[0] == 0xEB)	/* jump short */
+	jmp = 2 + *(int8_t *)(sec + 1);
+    else if (sec[0] == 0xE9) /* jump near */
+	jmp = 3 + *(int16_t *)(sec + 1);
+
+    if (jmp < 0)    /* no boot code at all ? */
+	goto nocode;
+
+    /* sanity */
+    if (jmp < 0x18 || jmp > 0x1F0)
+	goto out;
+
+    /* detect by jump */
+    if (jmp >= 0x18 && jmp < 0x1E)
+	rev = bpbV20;
+    else if (jmp >= 0x1E && jmp < 0x20)
+	rev = bpbV30;
+    else if (jmp >= 0x20 && jmp < 0x24)
+	rev = bpbV32;
+    else if (jmp >= 0x24 && jmp < 0x46)
+	rev = bpbV34;
+
+    /* TODO: some better V2 - V3.4 checks ? */
+
+    if (rev)
+	goto out;
+    /*
+     * BPB info:
+     * 2.0 ==       0x0B - 0x17
+     * 3.0 == 2.0 + 0x18 - 0x1D
+     * 3.2 == 3.0 + 0x1E - 0x1F
+     * 3.4 ==!2.0 + 0x18 - 0x23
+     * 4.0 == 3.4 + 0x24 - 0x45
+     *  NT ==~3.4 + 0x24 - 0x53
+     * 7.0 == 3.4 + 0x24 - 0x59
+     */
+
+nocode:
+    a = memcmp(sec + 0x03, "NTFS", 4);
+    b = memcmp(sec + 0x36, "FAT", 3);
+    c = memcmp(sec + 0x52, "FAT", 3);	/* ext. DOS 7+ bs */
+
+    if ((sec[0x26] & 0xFE) == 0x28 && !b) {
+	rev = bpbV40;
+    } else if (sec[0x26] == 0x80 && !a) {
+	rev = bpbVNT;
+    } else if ((sec[0x42] & 0xFE) == 0x28 && !c) {
+	rev = bpbV70;
+    }
+
+out:
+    printf("BPB detection (%s): %s\n", tag, bpbtypes[rev]);
+    return rev;
+}
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/chain/utility.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/chain/utility.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/chain/utility.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2010 Shao Miller
+ *   Copyright 2010-2012 Michal Soltys
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef COM32_CHAIN_UTILITY_H
+#define COM32_CHAIN_UTILITY_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <syslinux/disk.h>
+#include <syslinux/movebits.h>
+
+/* most (all ?) bpb "types" known to humankind as of 2012 */
+enum {bpbUNK, bpbV20, bpbV30, bpbV32, bpbV34, bpbV40, bpbVNT, bpbV70, bpbEXF};
+
+/* see utility.c for details */
+enum {L2C_CNUL, L2C_CADD, L2C_CMAX};
+
+/* first usable and first unusable offsets */
+#define dosmin ((addr_t)0x500u)
+#define dosmax ((addr_t)(*(uint16_t *) 0x413 << 10))
+
+void wait_key(void);
+void lba2chs(disk_chs *dst, const struct disk_info *di, uint64_t lba, int mode);
+uint32_t get_file_lba(const char *filename);
+int drvoff_detect(int type);
+int bpb_detect(const uint8_t *bpb, const char *tag);
+int guid_is0(const struct guid *guid);
+
+static inline int warn(const char *x)
+{
+    return fprintf(stderr, "WARN: %s\n", x);
+}
+
+static inline int error(const char *x)
+{
+    return fprintf(stderr, "ERR: %s\n", x);
+}
+
+static inline int crit(const char *x)
+{
+    return fprintf(stderr, "CRIT: %s @%s:%d\n", x, __FILE__, __LINE__);
+}
+
+#define critm()  crit("Malloc failure.")
+
+#endif
+
+/* vim: set ts=8 sts=4 sw=4 noet: */
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/CHANGES
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/CHANGES	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/CHANGES	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+Changes in v1.2
+---------------
+* Allowed menu's to have names. Submenu's can be referred to by names
+  instead of their index in the menu system. This allows user to refer
+  to submenus which are not yet part of the menusystem.
+* help pages can be longer than one screen
+* menugen.py: Python script for converting .menu files to C source code
+  .menu files can be used to descibe most static uses of menu system,
+  including SubMenus, Checkboxes, RadioButtons, User Authentication and
+  Context sensitive help. You can also restrict use of certain items
+  to users with certain credentials.
+
+  See MENU_FORMAT for the format of .menu files
+
+* display.c32: Takes the name of the text file to display and displays it
+  allowing user to scroll through the text.
+
+  USAGE: display.c32 <filename>
+
+  <filename> must be an absolute filename (including the /isolinux part)
+
+Changes in v1.1
+---------------
+* Additional handler type: Keys handler
+* Menuitem handlers now have a return value of type t_handler_return.
+  For all simple cases, you just return ACTION_VALID or ACTION_INVALID
+  (For some types of menu items, handlers are ignored, and for
+   others the return value is ignored)
+* add_menu takes an extra argument (to better control memory footprint)
+  You can just set it to -1 to choose the default value
+* Now the menu system support long menu's using scroll bars.
+* Support for passwords and context sensitive help is added.
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/HISTORY
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/HISTORY	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/HISTORY	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,20 @@
+
+GCC & 32-bit code
+-----------------
+Due to the limitations of the COM file format,
+(64KB limit on memory footprint) the code has been changed
+so that the code compiles to a 32-bit COMBOOT program.
+Since the code makes use of BIOS calls, this code cannot be
+compiled into a format which can execute under Linux. As a
+side effect, there is no nice way to debug this code. In order
+to debug this code, you will have to run the code under syslinux.
+
+GCC & 16-bit code
+-----------------
+The code was ported to GCC by Peter Anvin.
+
+OpenWatcom & 16-bit code
+------------------------
+Originally this code was written for the Openwatcom compiler
+and generated .COM files, which could execute under DOS as well as
+SYSLINUX.
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/MANUAL
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/MANUAL	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/MANUAL	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,348 @@
+          Overview of writing code using the menu system
+          ----------------------------------------------
+
+This file contains implementation and developer documentation.
+For simple cases, you should start by using simple.c as a template.
+complex.c illustrates most of the features available in the menu system.
+
+Menu Features currently supported are:
+* menu items,
+* submenus,
+* disabled items,
+* checkboxes,
+* invisible items (useful for dynamic menus), and
+* Radio menus,
+* Context sensitive help
+* Authenticated users
+
+The keys used are:
+
+* Arrow Keys, PgUp, PgDn, Home, End Keys
+* Space to switch state of a checkbox
+* Enter to choose the item
+* Escape to exit from it
+* Shortcut keys
+
+1. Overview
+-----------
+
+The code usually consists of many stages.
+
+ * Configuring the menusytem
+ * Installing global handlers [optional]
+ * Populating the menusystem
+ * Executing the menusystem
+ * Processing the result
+
+1.1 Configuring the menusystem
+------------------------------
+This includes setting the window the menu system should use,
+the choice of colors, the title of the menu etc. In most functions
+calls, a value of -1 indicates that the default value be used.
+For details about what the arguments are look at function
+declarations in menu.h
+
+<code>
+  // Choose the default title and setup default values for all attributes....
+  init_menusystem(NULL);
+  set_window_size(1,1,23,78); // Leave one row/col border all around
+
+  // Choose the default values for all attributes and char's
+  // -1 means choose defaults (Actually the next 4 lines are not needed)
+  set_normal_attr (-1,-1,-1,-1);
+  set_status_info (-1,-1);
+  set_title_info  (-1,-1);
+  set_misc_info(-1,-1,-1,-1);
+</code>
+
+1.2 Populating the menusystem
+-----------------------------
+This involves adding a menu to the system, and the options which
+should appear in the menu. An example is given below.
+
+<code>
+  MAINMENU = add_menu(" Menu Title ",-1);
+  CHECKED = 1;
+  add_item("option1","Status 1",OPT_RUN,"kernel1 arg1=val1",0);
+  add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
+  add_item("othermenu","Status 3",OPT_SUBMENU,"menuname",0);
+  add_sep();
+  add_item("checkbox,"Checkbox Info",OPT_CHECKBOX,NULL,CHECKED);
+  add_item("Exit ","Status String",OPT_EXITMENU,NULL,0);
+</code>
+
+The call to add_menu has two arguments, the first being the title of
+the menu and the second an upper bound on the number of items in the menu.
+Putting a -1, will use the default (see MENUSIZE in menu.h). If you try
+to add more items than specified, the extra items will not appear in
+the menu. The accuracy of this number affects the memory required
+to run the system.
+
+If you do not want to keep track of the return values, you can also use
+the following variant of add_menu
+
+<code>
+add_named_menu("main"," Menu Title ",-1)
+</code>
+
+This creates a new menu as before and gives it a name "main". When using named
+menus, you get an alternate way for adding submenu's. See below for details.
+
+The call to add_item has five arguments.
+The first argument is the text which appears in the menu itself.
+The second argument is the text displayed in the status line.
+The third argument indicates the type of this menuitem. It is one of
+the following
+
+ * OPT_RUN : executable content
+ * OPT_EXITMENU : exits menu to parent
+ * OPT_SUBMENU : if selected, displays a submenu
+ * OPT_CHECKBOX : associates a boolean with this item which can be toggled
+ * OPT_RADIOMENU: associates this with a radio menu.
+      After execution, the data field of this item will point
+      to the option selected.
+ * OPT_SEP : A menu seperator (visually divide menu into parts)
+ * OPT_RADIOITEM: this item is one of the options in a RADIOMENU
+ * OPT_INACTIVE : A disabled item (user cannot select this)
+ * OPT_INVISIBLE: This item will not be displayed.
+
+The fourth argument is the value of the data field always a string.
+Usually this string is just copied and nothing is done with it. Two
+cases, where it is used.
+
+In case of a radiomenu the input string is ignored and the "data" field
+points to the menuitem chosen (Dont forget to typecast this pointer to
+(t_menuitem *) when reading this info).
+
+In case of a submenu, this string if non-trivial is interpreted as the
+name of the submenu which should be linked there. This interpretation
+happens when the menu is first run and not when the menu system is being
+created. This allows the user to create the menusystem in an arbitrary
+order.
+
+
+The fifth argument is a number whose meaning depends on the type of the
+item. For a CHECKBOX it should be 0/1 setting the initial state of the
+checkbox. For a SUBMENU it should be the index of the menu which should
+be displayed if this option is chosen. Incase the data field is non-trivial,
+this number is ignored and computed later. For a RADIOMENU it should be the
+index of the menu which contains all the options (All items in that menu
+not of type RADIOITEM are ignored). For all other types, this
+argument has no meaning at all.
+
+A call to add_sep is a convenient shorthand for calling add_item
+with the type set to OPT_SEP.
+
+1.3 Executing the menusystem
+----------------------------
+This is the simplest of all. Just call showmenus, with the index
+of the main menu as its argument. It returns a pointer to the menu
+item which was selected by the user.
+
+<code>
+   choice = showmenus(MAIN); // Initial menu is the one with index MAIN
+   // or choice = showmenus(find_menu_num("main")); // Initial menu is the one named "main"
+</code>
+
+1.4 Processing the result
+-------------------------
+This pointer will either be NULL (user hit Escape) or always point
+to a menuitem which can be "executed", i.e. it will be of type OPT_RUN.
+Usually at this point, all we need to do is to ask syslinux to run
+the command associated with this menuitem. The following code executes
+the command stored in choice->data (there is no other use for the data
+field, except for radiomenu's)
+
+<code>
+  if (choice)
+  {
+        if (choice->action == OPT_RUN)
+        {
+            if (syslinux) runcommand(choice->data);
+            else csprint(choice->data,0x07);
+            return 1;
+        }
+        csprint("Error in programming!",0x07);
+  }
+</code>
+
+2. Advanced features
+--------------------
+Everycall to add_item actually returns a pointer to the menuitem
+created. This can be useful when using any of the advanced features.
+
+2.1 extra_data
+--------------
+For example, every menuitem has an "extra_data" field (a pointer)
+which the user can use to point any data he/she pleases. The menusystem
+itself does not use this field in anyway.
+
+2.2 helpid
+----------
+Every item also has a field called "helpid". It is meant to hold some
+kind of identifier which can be referenced and used to generate
+a context sensitive help system. This can be set after a call to
+add_item as follows
+<code>
+  add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
+  set_item_options('A',4516);
+</code>
+
+The first is the shortcut key for this entry. You can put -1 to ensure
+that the shortcut key is not reset. The second is some unsigned integer.
+If this value is 0xFFFF, then the helpid is not changed.
+
+2.3 Installing global handlers
+------------------------------
+It is possible to register handlers for the menu system. These are
+user functions which are called by the menusystem in certain
+situations. Usually the handlers get a pointer to the menusystem
+datastructure as well as a pointer to the current item selected.
+Some handlers may get additional information. Some handlers are
+required to return values while others are not required to do so.
+
+Currently the menusystem support three types of global handlers
+* timeout handler
+* screen handler
+* keys handler
+
+2.3.1 timeout handler
+---------------------
+This is installed using a call to "reg_ontimeout(fn,numsteps,stepsize)"
+function. fn is a pointer to a function which takes no arguments and
+returns one of CODE_WAIT, CODE_ENTER, CODE_ESCAPE. This function is
+called when numsteps*stepsize Centiseconds have gone by without any
+user input. If the function returns CODE_WAIT then the menusystem
+waits for user input (for another numsteps*stepsize Centiseconds). If
+CODE_ENTER or CODE_ESCAPE is returned, then the system pretends that
+the user hit ENTER or ESCAPE on the keyboard and acts accordingly.
+
+2.3.2 Screen handler
+--------------------
+This is installed using a call to "reg_handler(HDLR_SCREEN,fn)". fn is
+a pointer to a function which takes a pointer to the menusystem
+datastructure and the current item selected and returns nothing.
+This is called everytime a menu is drawn (i.e. everytime user changes
+the current selection). This is meant for displaying any additional
+information which reflects the current state of the system.
+
+2.3.3 Keys handler
+------------------
+This is installed using a call to "reg_handler(HDLR_KEYS,fn)". fn is
+a pointer to a function which takes a pointer to the menusystem
+datastructure, the current item and the scan code of a key and returns
+nothing. This function is called when the user presses a key which
+the menusystem does not know to dealwith. In any case, when this call
+returns the screen should not have changed in any way. Usually,
+one can change the active page and display any output needed and
+reset the active page when you return from this call.
+
+complex.c implements a key_handler, which implements a simple
+context sensitive help system, by displaying the contents of a
+file whose name is based on the helpid of the active item.
+
+Also, complex.c's handler allows certain users to make changes
+to edit the commands associated with a menu item.
+
+2.4 Installing item level handlers
+----------------------------------
+In addition to global handlers, one can also install handlers for each
+individual item. A handler for an individual item is a function which
+takes a pointer to the menusystem datastructure and a pointer to the
+current item and return a structure of type t_handler_return. Currently
+it has two bit fields "valid" and "refresh".
+
+This handler is called when the user hits "enter" on a RUN item, or
+changes the status of a CHECKBOX, or called *after* a radio menu choice
+has been set. In all other cases, installing a handler has no effect.
+
+The handler can change any of the internal datastructures it pleases.
+For e.g. in a radiomenu handler, one can change the text displayed
+on the menuitem depending on which choice was selected (see complex.c
+for an example). The return values are ignored for RADIOMENU's.
+
+In case of RUN items: the return values are used as follows. If the
+return value of "valid" was false, then this user choice is ignored.
+This is useful if the handler has useful side effects. For e.g.
+complex.c has a Login item, whose handler always return INVALID. It
+sets a global variable to the name of the user logged in, and enables
+some menu items, and makes some invisible items visible.
+
+* If the handler does not change the visibility status of any items,
+  the handler should set "refresh" to 0.
+* If the handler changes the visibility status of items in the current
+  menu set "refresh" to 1.
+* If you are changing the visibility status of items in menu's currently
+  not displayed, then you can set "refresh" to 0.
+* Changing the visibility status of items in another menu
+  which is currently displayed, is not supported. If you do it,
+  the screen contents may not reflect the change until you get to the
+  menu which was changed. When you do get to that menu, you may notice
+  pieces of the old menu still on the screen.
+
+In case of CHECKBOXES: the return value of "valid" is ignored. Because,
+the handler can change the value of checkbox if the user selected value
+is not appropriate. only the value of "refresh" is honored. In this case
+all the caveats in the previous paragraph apply.
+
+menu.h defines two instances of t_handler_return
+ACTION_VALID and ACTION_INVALID for common use. These set the valid flag
+to 1 and 0 respectively and the refresh flag to 0.
+
+3. Things to look out for
+-------------------------
+When you define the menu system, always declare it in the opposite
+order, i.e. all lower level menu's should be defined before the higher
+level menus. This is because in order to define the MAINMENU, you need
+to know the index assigned to all its submenus.
+
+4. Additional Modules
+---------------------
+You can make use of the following additional modules, in writing your
+handlers.
+
+* Passwords
+* Help
+
+4.1 Passwords
+-------------
+This module was written by Th. Gebhardt. This is basically a modification
+of the DES crypt function obtained by removing the dependence of the
+original crypt function on C libraries. The following functions are
+defined
+
+  init_passwords(PWDFILE)
+      // Read in the password database from the file
+  authenticate_user(user,pwd)
+      // Checks if user,pwd is valid
+  isallowed(user,perm)
+      // Checks if the user has a specified permission
+  close_passwords()
+      // Unloads password database from memory
+
+  See the sample password file for more details about the file format
+  and the implementation of permissions.
+
+See complex.c for a example of how to use this.
+
+4.2 Help
+--------
+This can be used to set up a context sensitive help system. The following
+functions are defined
+
+   init_help(HELPBASEDIR)
+       // Initialises the help system. All help files will be loaded
+       // from the directory specified.
+   runhelpsystem(context)
+       // Displays the contents of HELPBASEDIR/hlp<context>.txt
+
+In order to have a functioning help system, you just need to create
+the hlp<NNNNN>.txt files and initialize the help system by specifying
+the base directory.
+
+The first line of this file assumed to be the title of the help screen.
+You can use ^N and ^O to change attributes absolutely and relatively,
+i.e. [^O]46 (i.e. Ctrl-O followed by chars 4 and 6) will set the
+attribute to 46, while [^N]08 will XOR the current attribute with
+specified number, thus in this case the first [^N]08 will turn on
+highlighting and the second one will turn it off.
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/MENU_FORMAT
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/MENU_FORMAT	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/MENU_FORMAT	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,262 @@
+A .menu file can be used to describe basic menu structures which can be converted
+into C code which can then be compiled into a .c32 file for use with SYSLINUX.
+The format of a .menu file is similar to an ini file, but with important
+differences.
+
+Lines starting with # and ; are treated as comments. Blank lines are used to
+separate the attributes of one menu item from another. Multiple blank lines are
+equivalent to a single one.  In other contexts Blank lines are not significant.
+
+Menus
+-----
+Each menu declaration starts with a line containing the name of menu in [ ].
+This is the "nickname" of the menu and should be different for different menus.
+This is not visible to the user of the menu system. The initial menu must
+be called "main"
+
+The menu declaration is followed by lines which set the attributes of the menu.
+This is followed by a blank line and followed by declaration of menu items in
+that menu.
+
+All lines which occur before the first menu declaration is considered as
+a global declaration.
+
+Abstract Format
+---------------
+
+The overall format should look like this
+
+--------------------------------------------------------
+<GLOBAL SETTINGS>
+
+[menuname1]
+
+<MENU SETTINGS>
+
+<ITEM 1>
+
+...
+
+<ITEM N>
+
+[menuname2]
+
+<MENU SETTINGS>
+
+<ITEM A>
+
+<ITEM B>
+
+----------------------------------------------------------
+
+GLOBAL SETTINGS
+---------------
+The following global settings are now supported. Many of the keywords
+accept what we call a "DOT COMMAND" as argument. Simply put they are
+instructions to the menu system to perform certain actions.
+The syntax and semantics of DOT COMMANDS are given later in the section
+titled "DOT COMMANDS".
+
+videomode: (default 0xFF)  [Use with care]
+   The textmode in which the whole menu system should operate.
+   Must be a number (use 0x notation for hexadecimal).
+   Lookup Ralph Brown Interrupt List and search for Video Mode
+   to find a number to put here.
+
+   setting to 0xFF will mean, menu system will use the current
+   video mode.
+
+title:
+   The title of the whole menu system
+
+top, left, bot, right: (default 0,0,21,79)
+   The area of the screen used by the menu system. The remaining
+   part of the screen can be used by the user for anything.
+
+helpdir: (default /isolinux/help)
+   Location of the directory where help information is stored. The
+   help files must be called "hlpNNNNN.txt" where NNNNN is the helpid.
+
+pwdfile: (default /isolinux/passwd)
+   The name of the password file which contains user, password and permissions
+   See "passwd" file for details regarding format of this file
+
+editrow: (default 23)
+   the row on the screen where one can edit the command line. This must
+   be outside the menu area. Set this to a negative number to disable
+   editing the command line. In case of authenticated users, the current
+   user must have "editcmd" permissions to edit the command line
+
+pwdrow: (default 23)
+   The row on the screen used for user authentication. Must be outside
+   menu area (can be same as editrow). Set to negative to disable
+   user authentication
+
+skipif: (default 0)
+   The OR of the bits in the Shift-flags any of which can cause the menu system
+   to be skipped all together (0 means menu system always runs). It can also
+   be a combination of "Alt","Ctrl","Shift","Caps","Ins","Scroll".
+   When menu system starts it checks if any of the specified keys are On/pressed.
+   If true, the system exits immediately and executes the skipcmd.
+
+   e.g. setting it to "shift-alt-caps" means menu will be skipped if alt OR shift
+   is pressed OR caps is on. setting to "0" means menu will always run.
+
+skipcmd: (default .exit)
+   valid terminal commands: .exit .ignore or any syslinux command
+   command to execute if menu system is skipped. This must be a non-trivial
+   syslinux command if skipcondn is not "0". ".exit" means menu system
+   quits back to the boot prompt.
+
+startfile: (default "")
+   if non-empty the system will display the contents of this file before launching
+   the menusystem. This happens only if the menusystem is not skipped. Can be used
+   to display licensing, usage or welcome messages. A file with given name
+   is expected to be found in the helpdir directory.
+
+exitcmd: (default .exit)
+   valid terminal commands: .exit .repeat or any syslinux command
+   The default command to execute when user quits the menu system.
+
+exitcmdroot: (default =exitcmd)
+   Same as exitcmd except applies when current user has "root" privileges. If not
+   specified, it is assumed to be the same as exitcmd
+
+timeout: (default 3000)
+   The amount of time (in multiple of 0.1 seconds) to wait for user keypress. If no
+   key pressed for specified duration then the timeoutcmd is executed.
+
+totaltimeout: (default 0)
+   The total amount of time (in multiples of 0.1 seconds) the system will wait for
+   user to make a decision. If no decision has been made in the specified duration
+   totaltimeoutcmd will be executed
+
+   NOTE: This does not include the time spent browsing the help system or
+   the time taken for the user to enter his/her authentication credentials.
+
+timeoutcmd: (default .beep)
+   valid terminal commands: .wait .enter .escape or any syslinux command
+   command to execute when we timeout waiting for user input. The commands
+   .enter and .escape tell the menu system to pretend the user typed ENTER or
+   ESCAPE on the keyboard, while .wait tells the menusystem to wait for one
+   more time period
+
+totaltimeoutcmd: (default .wait)
+   choices are the same as for timeoutcmd
+
+MENU SETTINGS
+-------------
+
+title: (must be specified)
+   Title of this menu
+
+row,col: [Usage not recomended]
+   position in screen where this menu should be placed. By default the
+   system will choose an appropriate location.
+
+ITEM ATTRIBUTES
+---------------
+
+item:
+      The string displayed to the user. Characters enclosed in < > are highlighted.
+
+shortcut: (default -1) valid values A-Za-z0-9 or -1 [Usage not recommended]
+      Sets the shortcut key for this item. If set to -1, the system scans for the first
+      highlighted letter in the given range and sets that as the shortcut key.
+
+info: (default same as data)
+      Additional textual information displayed in the status bar
+
+type:
+      the type of entry this item represents. This is one of the following:
+
+      run:       choosing this will run something in SYSLINUX
+                 use data to specify the actual command to execute
+      exitmenu:  exit to parent menu
+      submenu:   choosing will open up submenu
+                 use data to specify the "nickname" of the menu
+                 which should come here
+      sep:       Position a separator here
+      inactive:  menu item is disabled
+      checkbox:  this is a checkbox
+                 use state to set initial state
+      invisible: User does not see this item
+      radioitem: One choice in a radiomenu
+      radiomenu: Allow user to choose one of many choices
+                 (initial choice is always NULL)
+      login:     Selecting this will allow user to login to system
+
+data:
+      for run items, the syslinux command to execute
+      for submenus and radiomenus, nickname of menu
+      for checkboxes, string to be added to kernel command line (if set)
+      for radioitems, string to be added to kernel command line (if chosen)
+
+ipappend:
+      ipappend flag to pass to PXELINUX (harmless for other variants of SYSLINUX)
+      See syslinux documentation for meaning of the FLAGS
+
+helpid: (default 65535 which is not a valid id)
+      associates a context for the help system.
+
+state: (default 0)
+      Initial state of a checkbox (for other items this has no meaning)
+
+perms: (default "")
+      string containing the name of the permission which user must
+      have to activate this item. For eg. if this item is a submenu
+      then user needs the permission in order to open the submenu
+
+argsmenu: (default "")
+      Name of the menu to be scanned for setting additional arguments to
+      pass to command line when this item is chosen for execution. Submenus
+      of specified menu are also scanned. Only checkboxes and radiomenu's
+      are scanned. Items of other type in this menu is silently ignored.
+
+
+DOT COMMANDS
+------------
+Dot commands are basically instructions to the menu system to do certain things.
+
+A "single command" is one of the following
+
+[NT] A syslinux command (any DOT command not starting with a "." is assumed to be this)
+[NT] .beep [n]
+[NT] .help <file>
+[NT] .nop
+[T]  .exit or .quit (equivalent)
+[T]  .repeat or .wait or .ignore (all three are equivalent)
+
+A dot command is a sequence of "single commands" separated by a "%". When a dot command
+is executed the system executes all the given "single commands" in the specified order.
+All the commands marked "[T]" are terminal commands, i.e. when the system encounters
+such a command it stops processing the dot command and returns the terminal command
+which caused the termination to the caller (who usually interprets the command
+appropriately).
+
+All commands marked with [NT] are non-terminal commands, i.e. once these commands are
+processed the system continues to process the remaining "single commands" specified in
+the "DOT COMMAND".
+
+Note: The case of a syslinux command is tricky. When executed, the command should never return
+(if the specified kernel exists) so the fact that we consider it a [NT] should be taken with
+a pinch of salt. However, if the syslinux command does return (in case of no kernel), then
+remaining "single commands" are processed. In particular "ker1 arg1 % ker2 arg2 % ker3 args"
+has the effect of executing the first kernel which exists
+
+.nop:
+   Does nothing.
+.beep:
+   .beep [n] produces a beep n times. n must be between 0 and 9. If not specified n=1.
+   (hence .beep 0 is equivalent to .nop)
+.help:
+   .help <file>
+   Displays the help file <file> which is assumed to be in the "help" directory. Its name
+   does not have to be in the form "hlpNNNNN.txt" (as required by the context sensitive help).
+   Executing this command will mean the appropriate help screen is displayed till the user hits
+   ESCAPE
+
+The meaning of the Terminal commands can vary with the context in which it is used. For example,
+a ".enter" or ".escape" does not have any meaning in the "onerrorcmd" context but it has a meaning
+in the "ontimeout" context. In case the user gives a Terminal command which does not make sense, it
+is upto the code (in this case adv_menu.tpl) to do what it pleases.
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,74 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 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.
+##
+## -----------------------------------------------------------------------
+
+##
+## Makefile for the complex menu system
+##
+
+NOGPL := 1
+
+LIBS  = libmenu/libmenu.c32 \
+        $(objdir)/com32/libutil/libutil.c32 \
+        $(objdir)/com32/lib/libcom32.c32
+
+C_LIBS	  = libmenu/libmenu.c32
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+CFLAGS	  += -I$(SRC)/libmenu
+
+LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
+	libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o \
+	$(objdir)/com32/libutil/libutil.c32 $(objdir)/com32/lib/libcom32.c32
+
+CMENUS = $(patsubst %.c,%.c32,$(wildcard $(SRC)/*.c))
+IMENUS = $(patsubst %.menu,%.c32,$(wildcard $(SRC)/*.menu))
+
+MENUS = $(LIBS) $(subst $(SRC)/,,$(CMENUS) $(IMENUS))
+
+.SUFFIXES: .S .c .o .elf .c32 .menu
+
+.PRECIOUS: %.c
+%.c: %.menu adv_menu.tpl
+	$(PYTHON) $(SRC)/menugen.py --input=$< --output=$@ --template=$(SRC)/adv_menu.tpl
+
+all:	makeoutputdirs menus
+
+makeoutputdirs:
+	@mkdir -p $(OBJ)/libmenu
+
+libmenu/libmenu.elf: $(LIBMENU)
+	$(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) \
+		-o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.lst *.elf */*.o */*.elf .*.d */.*.d
+
+libclean:
+	rm -f libmenu/*.c32
+
+clean: tidy menuclean
+	rm -f *.lss *.com
+
+menuclean:
+	rm -f $(patsubst %.menu,%.c,$(wildcard *.menu))
+
+spotless: clean libclean menuclean
+	rm -f *~ \#* *.c32
+
+menus: $(MENUS)
+
+install:	# Don't install samples
+
+-include .*.d */.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,95 @@
+          Text User Interface using comboot
+          ---------------------------------
+
+This is a menu system written by Murali Krishnan Ganapathy and ported
+from OpenWatcom to gcc by HPA. It is currently being maintained by the
+original author.
+
+To configure the menus, you need to set up a menu configuration file
+to have the menu items you desire, then build the menu system using
+make.  You can use either simple.c or complex.c as a starting point
+for your own menu configuration file; If your menu system is only going
+to have entries corresponding to things which can be executed directly,
+then you can create a file in ".menu" format instead of the C code.
+
+See MENU_FORMAT for the syntax of .menu files
+
+The resulting code is a 32-bit COMBOOT code, and hence can be executed
+only under syslinux. You can use tools like bochs to help debug your
+code.
+
+Menu Features currently supported are:
+* menu items,
+* submenus,
+* disabled items,
+* checkboxes,
+* invisible items (useful for dynamic menus), and
+* Radio menus,
+* Context sensitive help
+* Authenticated users
+* Editing commands associated with items
+
+The keys used are:
+
+* Arrow Keys, PgUp, PgDn, Home, End Keys
+* Space to switch state of a checkbox
+* Enter to choose the item
+* Escape to exit from it
+* Shortcut keys
+
+Features
+--------
+This is a general purpose menu system implemented using only BIOS calls,
+so it can be executed in a COMBOOT environment as well. It is highly
+customizable. Some features include:
+
+* Status line
+    Display any help information associated with each menu item.
+* Window
+    Specify a window within which the menu system draws all its menu's.
+    It is upto the user to ensure that the menu's fit within the window.
+* Positioning submenus
+    By default, each submenu is positioned just below the corresponding
+    entry of the parent menu. However, the user may position each menu
+    at a specific location of his choice. This is useful, when the menu's
+    have lots of options.
+* Registering handlers for each menu item
+    This is mainly used for checkboxes and radiomenu's, where a selection may
+    result in disabling other menu items/checkboxes
+* Global Screen Handler
+    This is called every time the menu is redrawn. The user can display
+    additional information (usually outside the window where the menu is
+    being displayed). See the complex.c for an example, where the global
+    handler is used to display the choices made so far.
+* Global Keys Handler
+    This is called every time the user presses a key which the menu
+    system does not understand. This can be used to display context
+    sensitive help. See complex.c for how to use this hook to implement
+    a context sensitive help system as well as "On the fly" editing
+    of commands associated with menus.
+* Shortcut Keys
+    With each item one can register a shortcut key from [A-Za-z0-9].
+    Pressing a key within that range, will take you to the next item
+    with that shortcut key (so you can have multiple items with the
+    same shortcut key). The default shortcut key for each item, is
+    the lower case version of the first char of the item in the range
+    [A-Za-z0-9].
+* Escape Keys
+    Each item entry can have a substring enclosed in < and >. This part
+    is highlighted. Can be used to highlight the shortcut keys. By default
+    if an item has a <, then the first char inside < and > in the range
+    [A-Za-z0-9] is converted to lower case and set as the shortcut key.
+* Ontimeout handler
+    The user can register an ontimeout handler, which gets called if
+    no key has been pressed for a user specific amount of time (default 5 min).
+    For an example see the complex.c file.
+
+Credits
+-------
+* The Watcom developers and Peter Anvin for figuring out an OS
+  independent startup code.
+* Thomas for porting the crypt function and removing all C library
+  dependencies
+* Peter Anvin for porting the code to GCC
+
+- Murali (gmurali+guicd@cs.uchicago.edu)
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/TODO
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/TODO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/TODO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2 @@
+* Write COMBOOT code to read .menu files and parse them directly
+  - take the name of menu file to parse from commandline
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/adv_menu.tpl
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/adv_menu.tpl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/adv_menu.tpl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,465 @@
+All the lines in this file not in between --something BEGINS-- and --something ENDS--
+is ignored completely and will not make it into the generated C file
+
+This file has sections of C code each section delimited by --secname BEGINS--
+and --secname ENDS--. In the generated C code certain section may be used multiple
+times. Currently the different section which must be defined are
+
+header, system, item, login and footer
+
+Any additional sections you define will be processed but will probably not make it
+to the C code if you do not modify menugen.py to use it.
+
+header and footer go through unmolested. The remaining are % substituted using
+python rules. Basically it means %(var)s gets replaced by the value of the variable
+"var" which is a processed form of what is read from the .menu file
+
+NOTE: There is absolutely no C code in the python script, so you are free to
+modify this template to suit your needs
+
+--header BEGINS--
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2006 Murali Krishnan Ganapathy - 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 NULL
+#define NULL ((void *) 0)
+#endif
+
+#include "cmenu.h"
+#include "help.h"
+#include "passwords.h"
+#include "com32io.h"
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define MAX_CMD_LINE_LENGTH 514
+
+typedef struct s_xtra {
+  long ipappend; // Stores the ipappend flag to send (useful for PXELINUX only)
+  char *argsmenu; // Stores the name of menu which contains options for the given RUN item
+  char *perms; // stores the permissions required to activate the item
+} t_xtra;
+
+typedef t_xtra *pt_xtra; // Pointer to extra datastructure
+
+// Types of dot commands for which caller takes responsibility of handling
+// In some case some commands may not make sense, it is up to the caller
+// to handle cases which do not make sense
+typedef enum {QUIT_CMD, REPEAT_CMD, ENTER_CMD, ESCAPE_CMD} t_dotcmd;
+
+
+/*----------------- Global Variables */
+
+// default user
+#define GUEST_USER "guest"
+
+// for local commands. return value of execdotcmd
+#define QUIT_CMD 0
+#define RPT_CMD 1
+
+char username[12]; // Name of user currently using the system
+
+int PWD_ROW; // Line number where user authentication happens
+int EDIT_ROW; // row where User Tab
+
+char loginstr[] = "<L>ogin  ";
+char logoutstr[30];
+
+int vmode; // The video mode we want to be in
+char timeoutcmd[MAX_CMD_LINE_LENGTH]; // Command to execute on timeout
+char totaltimeoutcmd[MAX_CMD_LINE_LENGTH]; // Command to execute on totaltimeout
+
+char QUITSTR[] = ".quit"; // same as exit
+char IGNORESTR[]=".ignore"; // same as repeat, wait
+
+/*----------------  End globals */
+
+// returns pointer to first non-space char
+// and advances end of str by removing trailing spaces
+char * strip(char *str)
+{
+  char *p,*s,*e;
+  if (!str) return NULL;
+  p = str;
+  s = NULL;
+  e = NULL;
+  while (*p) {
+    if (*p != ' ') {
+       // mark start of string or record the last visited non-space char
+       if (!s) s=p; else e=p;
+    }
+    p++;
+  }
+  *(++e)='\0'; // kill string earlier
+  return s;
+}
+
+// executes a list of % separated commands
+// non-dot commands are assumed to be syslinux commands
+// All syslinux commands are appended with the contents of kerargs
+// If it fails (kernel not found) then the next one is tried in the
+// list
+// returns QUIT_CMD or RPT_CMD
+t_dotcmd execdotcmd(const char *cmd, char *defcmd, const char *kerargs)
+{
+   char cmdline[MAX_CMD_LINE_LENGTH];
+   char dotcmd[MAX_CMD_LINE_LENGTH];
+   char *curr,*next,*p,*args;
+   char ctr;
+
+   strcpy(dotcmd,cmd);
+   next = dotcmd;
+   cmdline[0] = '\0';
+   while (*next) { // if something to do
+      curr = next;
+      p = strchr(next,'%');
+      if (p) {
+         *p--='\0'; next=p+2;
+         while (*p == ' ') p--;
+         *(++p)='\0'; // remove trailing spaces
+      } else {
+        if (*defcmd) { // execute defcmd next
+            next=defcmd;
+            defcmd=NULL; // exec def cmd only once
+        } else next=NULL;
+      }
+      // now we just need to execute the command "curr"
+      curr = strip(curr);
+      if (curr[0] != '.') { // just run the kernel
+         strcpy(cmdline,curr);
+         if (kerargs) strcat(cmdline,kerargs);
+         runsyslinuximage(cmdline,0); // No IPAppend
+      } else { // We have a DOT command
+        // split command into command and args (may be empty)
+        args = curr;
+        while ( (*args != ' ') && (*args != '\0') ) args++;
+        if (*args) { // found a space
+           *args++ = '\0';
+           while (*args == ' ') args++; // skip over spaces
+        }
+        if ( (strcmp(curr,".exit")==0) ||
+             (strcmp(curr,".quit")==0)
+           )
+           return QUIT_CMD;
+        if ( (strcmp(curr,".repeat")==0) ||
+             (strcmp(curr,".ignore")==0) ||
+             (strcmp(curr,".wait")==0)
+           )
+           return RPT_CMD;
+        if (strcmp(curr,".beep")==0) {
+           if ((args) && ('0' <= args[0]) && (args[0] <= '9'))
+              ctr = args[0]-'0';
+           else ctr=1;
+           for (;ctr>0; ctr--) beep();
+        }
+        if (strcmp(curr,".help")==0) runhelp(args);
+      }
+   }
+   return RPT_CMD; // by default we do not quit
+}
+
+
+TIMEOUTCODE timeout(const char *cmd)
+{
+  t_dotcmd c;
+  c = execdotcmd(cmd,".wait",NULL);
+  switch(c) {
+    case ENTER_CMD:
+         return CODE_ENTER;
+    case ESCAPE_CMD:
+         return CODE_ESCAPE;
+    default:
+         return CODE_WAIT;
+  }
+}
+
+TIMEOUTCODE ontimeout(void)
+{
+   return timeout(timeoutcmd);
+}
+
+TIMEOUTCODE ontotaltimeout(void)
+{
+   return timeout(totaltimeoutcmd);
+}
+
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode)
+{
+   int nc, nr;
+
+   if (getscreensize(1, &nr, &nc)) {
+       /* Unknown screen size? */
+       nc = 80;
+       nr = 24;
+   }
+
+   if ( (scancode == KEY_F1) && (mi->helpid != 0xFFFF) ) { // If scancode of F1 and non-trivial helpid
+      runhelpsystem(mi->helpid);
+   }
+
+   // If user hit TAB, and item is an "executable" item
+   // and user has privileges to edit it, edit it in place.
+   if ((scancode == KEY_TAB) && (mi->action == OPT_RUN) &&
+       (EDIT_ROW < nr) && (EDIT_ROW > 0) &&
+       (isallowed(username,"editcmd") || isallowed(username,"root"))) {
+     // User typed TAB and has permissions to edit command line
+     gotoxy(EDIT_ROW,1);
+     csprint("Command line:",0x07);
+     editstring(mi->data,ACTIONLEN);
+     gotoxy(EDIT_ROW,1);
+     cprint(' ',0x07,nc-1);
+   }
+}
+
+t_handler_return login_handler(t_menusystem *ms, t_menuitem *mi)
+{
+  (void)mi; // Unused
+  char pwd[40];
+  char login[40];
+  int nc, nr;
+  t_handler_return rv;
+
+  (void)ms;
+
+  rv = ACTION_INVALID;
+  if (PWD_ROW < 0) return rv; // No need to authenticate
+
+  if (mi->item == loginstr) { /* User wants to login */
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nc = 80;
+        nr = 24;
+    }
+
+    gotoxy(PWD_ROW,1);
+    csprint("Enter Username: ",0x07);
+    getstring(login, sizeof username);
+    gotoxy(PWD_ROW,1);
+    cprint(' ',0x07,nc);
+    csprint("Enter Password: ",0x07);
+    getpwd(pwd, sizeof pwd);
+    gotoxy(PWD_ROW,1);
+    cprint(' ',0x07,nc);
+
+    if (authenticate_user(login,pwd))
+    {
+      strcpy(username,login);
+      strcpy(logoutstr,"<L>ogout ");
+      strcat(logoutstr,username);
+      mi->item = logoutstr; // Change item to read "Logout"
+      rv.refresh = 1; // refresh the screen (as item contents changed)
+    }
+    else strcpy(username,GUEST_USER);
+  }
+  else // User needs to logout
+  {
+    strcpy(username,GUEST_USER);
+    strcpy(logoutstr,"");
+    mi->item = loginstr;
+  }
+
+  return rv;
+}
+
+t_handler_return check_perms(t_menusystem *ms, t_menuitem *mi)
+{
+   char *perms;
+   pt_xtra x;
+
+   (void) ms; // To keep compiler happy
+
+   x = (pt_xtra) mi->extra_data;
+   perms = ( x ? x->perms : NULL);
+   if (!perms) return ACTION_VALID;
+
+   if (isallowed(username,"root") || isallowed(username,perms)) // If allowed
+      return ACTION_VALID;
+   else return ACTION_INVALID;
+}
+
+// Compute the full command line to add and if non-trivial
+// prepend the string prepend to final command line
+// Assume cmdline points to buffer long enough to hold answer
+void gencommand(pt_menuitem mi, char *cmdline)
+{
+   pt_xtra x;
+   cmdline[0] = '\0';
+   strcat(cmdline,mi->data);
+   x = (pt_xtra) mi->extra_data;
+   if ( (x) && (x->argsmenu)) gen_append_line(x->argsmenu,cmdline);
+}
+
+
+// run the given command together with additional options which may need passing
+void runcommand(pt_menuitem mi)
+{
+   char *line;
+   pt_xtra x;
+   long ipappend;
+
+   line = (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH);
+   gencommand(mi,line);
+   x = (pt_xtra) mi->extra_data;
+   ipappend = (x ? x->ipappend : 0);
+
+   runsyslinuximage(line,ipappend);
+   free(line);
+}
+
+// set the extra info for the specified menu item.
+void set_xtra(pt_menuitem mi, const char *argsmenu, const char *perms, unsigned int helpid, long ipappend)
+{
+   pt_xtra xtra;
+   int bad_argsmenu, bad_perms, bad_ipappend;
+
+   mi->extra_data = NULL; // initalize
+   mi->helpid = helpid; // set help id
+
+   if (mi->action != OPT_RUN) return;
+
+   bad_argsmenu = bad_perms = bad_ipappend = 0;
+   if ( (argsmenu==NULL) || (strlen(argsmenu)==0)) bad_argsmenu = 1;
+   if ( (perms==NULL) || (strlen(perms)==0)) bad_perms = 1;
+   if ( ipappend==0) bad_ipappend = 1;
+
+   if (bad_argsmenu && bad_perms && bad_ipappend) return;
+
+   xtra = (pt_xtra) malloc(sizeof(t_xtra));
+   mi->extra_data = (void *) xtra;
+   xtra->argsmenu = xtra->perms = NULL;
+   xtra->ipappend = ipappend;
+   if (!bad_argsmenu) {
+      xtra->argsmenu = (char *) malloc(sizeof(char)*(strlen(argsmenu)+1));
+      strcpy(xtra->argsmenu,argsmenu);
+   }
+   if (!bad_perms) {
+      xtra->perms = (char *) malloc(sizeof(char)*(strlen(perms)+1));
+      strcpy(xtra->perms,perms);
+      mi->handler = &check_perms;
+   }
+}
+
+int main(void)
+{
+  pt_menuitem curr;
+  char quit;
+  char exitcmd[MAX_CMD_LINE_LENGTH];
+  char exitcmdroot[MAX_CMD_LINE_LENGTH];
+  char onerrcmd[MAX_CMD_LINE_LENGTH];
+  char startfile[MAX_CMD_LINE_LENGTH];
+  char *ecmd; // effective exit command or onerrorcmd
+  char skipbits;
+  char skipcmd[MAX_CMD_LINE_LENGTH];
+  int timeout; // time in multiples of 0.1 seconds
+  int totaltimeout; // time in multiples of 0.1 seconds
+  t_dotcmd dotrv; // to store the return value of execdotcmd
+  int temp;
+
+  strcpy(username,GUEST_USER);
+--header ENDS--
+--system BEGINS--
+/* ---- Initializing menu system parameters --- */
+  vmode = %(videomode)s;
+  skipbits = %(skipcondn)s;
+  PWD_ROW = %(pwdrow)s;
+  EDIT_ROW = %(editrow)s;
+  strcpy(onerrcmd,"%(onerrorcmd)s");
+  strcpy(exitcmd,"%(exitcmd)s");
+  strcpy(exitcmdroot,"%(exitcmdroot)s");
+  // If not specified exitcmdroot = exitcmd
+  if (exitcmdroot[0] == '\0') strcpy(exitcmdroot,exitcmd);
+  // Timeout stuff
+  timeout = %(timeout)s;
+  strcpy(timeoutcmd,"%(timeoutcmd)s");
+  totaltimeout = %(totaltimeout)s;
+  strcpy(totaltimeoutcmd,"%(totaltimeoutcmd)s");
+  strcpy(startfile,"%(startfile)s");
+
+  init_help("%(helpdir)s");
+  init_passwords("%(pwdfile)s");
+  init_menusystem("%(title)s");
+  set_window_size(%(top)s,%(left)s,%(bot)s,%(right)s);
+
+  // Register the ontimeout handler, with a time out of 10 seconds
+  reg_ontimeout(ontimeout,timeout*10,0);
+  reg_ontotaltimeout(ontotaltimeout,totaltimeout*10);
+
+  // Register menusystem handlers
+  reg_handler(HDLR_KEYS,&keys_handler);
+/* ---- End of initialization --- */
+--system ENDS--
+--item BEGINS--
+
+  curr = add_item("%(item)s","%(info)s",%(type)s,"%(data)s",%(state)d);
+  set_xtra(curr,"%(argsmenu)s","%(perms)s",%(helpid)d,%(ipappend)d); // Set associated extra info
+  set_shortcut(%(shortcut)s);
+--item ENDS--
+--login BEGINS--
+
+  curr = add_item(loginstr,"Login/Logout of authentication system",OPT_RUN,NULL,0);
+  curr->helpid = %(helpid)d;
+  curr->handler = &login_handler;
+--login ENDS--
+--menu BEGINS--
+
+/* ------- MENU %(name)s ----- */
+  add_named_menu("%(name)s","%(title)s",-1);
+--menu ENDS--
+--footer BEGINS--
+/* ------- END OF MENU declarations ----- */
+
+// Check if we should skip the menu altogether
+  quit = 0; // Dont skip the menu
+  if (getshiftflags() & skipbits) { // we must skip the menu altogther and execute skipcmd
+    dotrv = execdotcmd(skipcmd,".beep%.exit",NULL); // Worst case we beep and exit
+    if (dotrv == QUIT_CMD) quit = 1;
+  }
+
+// Switch vide mode if required
+   if (vmode != 0xFF) setvideomode(vmode);
+
+// Do we have a startfile to display?
+   if (startfile[0] != '\0') runhelp(startfile);
+
+// The main loop
+  while (quit == 0) { // As long as quit is zero repeat
+     curr = showmenus(find_menu_num("main")); // Initial menu is the one called "main"
+
+     if (curr) {
+        if (curr->action == OPT_RUN) {
+           ecmd = (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH);
+           gencommand(curr,ecmd);
+           temp = (curr->extra_data ? ((pt_xtra)curr->extra_data)->ipappend : 0);
+           runsyslinuximage(ecmd,temp);
+           // kernel not found so execute the appropriate dot command
+           dotrv = execdotcmd(onerrcmd,".quit",ecmd); // pass bad cmdline as arg
+           if (dotrv== QUIT_CMD) quit = 1;
+           free(ecmd); ecmd = NULL;
+        }
+        else csprint("Error in programming!",0x07);
+     } else {
+        // find effective exit command
+        ecmd = ( isallowed(username,"root") ? exitcmdroot : exitcmd);
+        dotrv = execdotcmd(ecmd,".repeat",NULL);
+        quit = (dotrv == QUIT_CMD ? 1 : 0); // should we exit now
+     }
+  }
+
+// Deallocate space used and quit
+  close_passwords();
+  close_help();
+  close_menusystem();
+  return 0;
+}
+
+--footer ENDS--
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/complex.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/complex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/complex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,450 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 NULL
+#define NULL ((void *) 0)
+#endif
+
+#include "cmenu.h"
+#include "com32io.h"
+#include "help.h"
+#include "passwords.h"
+#include "des.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getkey.h>
+
+/* Global variables */
+char infoline[160];
+char buffer[80];
+
+// Different network options
+static char nonet[] = "<n>etwork [none]";
+static char dhcpnet[] = "<n>etwork [dhcp]";
+static char statnet[] = "<n>etwork [static]";
+
+static char loginstr[] = "<L>ogin  ";
+static char logoutstr[] = "<L>ogout ";
+
+struct {
+    unsigned int baseurl:1;	// Do we need to specify by url
+    unsigned int mountcd:1;	// Should we mount the cd
+    unsigned int winrep:1;	// Want to repair windows?
+    unsigned int linrep:1;	// Want to repair linux?
+} flags;
+
+// Some menu options
+t_menuitem *baseurl, *mountcd, *network, *runprep, *winrep, *linrep;
+t_menuitem *stat, *dhcp, *none, *prepopt, *secret;
+
+// all the menus we are going to declare
+unsigned char TESTING, RESCUE, MAIN, PREPMENU, NETMENU, LONGMENU, SECRETMENU;
+
+char username[12];		// Name of user currently using the system
+
+/* End globals */
+
+TIMEOUTCODE ontimeout(void)
+{
+    beep();
+    return CODE_WAIT;
+}
+
+#define INFLINE 22
+#define PWDLINE 3
+#define PWDPROMPT 21
+#define PWDCOLUMN 60
+#define PWDATTR 0x74
+#define EDITPROMPT 21
+
+void keys_handler(t_menusystem * ms __attribute__ (( unused )), t_menuitem * mi, int scancode)
+{
+    int nc, nr;
+
+    if ((scancode) == KEY_F1 && mi->helpid != 0xFFFF) {	// If scancode of F1
+	runhelpsystem(mi->helpid);
+    }
+    // If user hit TAB, and item is an "executable" item
+    // and user has privileges to edit it, edit it in place.
+    if ((scancode == KEY_TAB) && (mi->action == OPT_RUN) &&
+	(isallowed(username, "editcmd") || isallowed(username, "root"))) {
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nc = 80;
+        nr = 24;
+    }
+	// User typed TAB and has permissions to edit command line
+	gotoxy(EDITPROMPT, 1);
+	csprint("Command line:", 0x07);
+	editstring(mi->data, ACTIONLEN);
+	gotoxy(EDITPROMPT, 1);
+    clear_line();
+    }
+}
+
+t_handler_return login_handler(t_menusystem * ms, t_menuitem * mi)
+{
+    (void)mi;			// Unused
+    char pwd[40];
+    char login[40];
+    int nc, nr;
+    t_handler_return rv;
+
+    (void)ms;
+
+    if (mi->item == loginstr) {	/* User wants to login */
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nc = 80;
+        nr = 24;
+    }
+	gotoxy(PWDPROMPT, 1);
+	csprint("Enter Username: ", 0x07);
+	getstring(login, sizeof username);
+	gotoxy(PWDPROMPT, 1);
+    clear_line();
+	csprint("Enter Password: ", 0x07);
+	getpwd(pwd, sizeof pwd);
+	gotoxy(PWDPROMPT, 1);
+    clear_line();
+
+	if (authenticate_user(login, pwd)) {
+	    strcpy(username, login);
+	    mi->item = logoutstr;	// Change item to read "Logout"
+	} else
+	    strcpy(username, GUEST_USER);
+    } else			// User needs to logout
+    {
+	strcpy(username, GUEST_USER);
+	mi->item = loginstr;
+    }
+
+    if (strcmp(username, GUEST_USER) == 0) {
+	prepopt->action = OPT_INACTIVE;
+	secret->action = OPT_INVISIBLE;
+    } else {
+	prepopt->action = OPT_SUBMENU;
+	prepopt->itemdata.radiomenunum = PREPMENU;
+	secret->action = OPT_SUBMENU;
+	secret->itemdata.submenunum = SECRETMENU;
+    }
+    rv.valid = 0;
+    rv.refresh = 1;
+    rv.reserved = 0;
+    return rv;
+}
+
+void msys_handler(t_menusystem * ms, t_menuitem * mi)
+{
+    int nc, nr;
+    void *v;
+
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nc = 80;
+        nr = 24;
+    }
+    gotoxy(PWDLINE, PWDCOLUMN);
+    csprint("User: ", PWDATTR);
+    cprint(ms->fillchar, ms->fillattr, sizeof username);
+    gotoxy(PWDLINE, PWDCOLUMN + 6);
+    csprint(username, PWDATTR);
+
+    if (mi->parindex != PREPMENU)	// If we are not in the PREP MENU
+    {
+	gotoxy(INFLINE, 0);
+    reset_colors();
+    clear_line();
+	gotoxy(INFLINE + 1, 0);
+    clear_line();
+	return;
+    }
+    strcpy(infoline, " ");
+    if (flags.baseurl)
+	strcat(infoline, "baseurl=http://192.168.11.12/gui ");
+    if (flags.mountcd)
+	strcat(infoline, "mountcd=yes ");
+    v = (void *)network->data;
+    if (v != NULL)		// Some network option specified
+    {
+	strcat(infoline, "network=");
+	strcat(infoline, (char *)(((t_menuitem *) v)->data));
+    }
+    if (flags.winrep)
+	strcat(infoline, "repair=win ");
+    if (flags.linrep)
+	strcat(infoline, "repair=lin ");
+
+    gotoxy(INFLINE, 0);
+    reset_colors();
+    clear_line();
+    gotoxy(INFLINE + 1, 0);
+    clear_line();
+    gotoxy(INFLINE, 0);
+    csprint("Kernel Arguments:", 0x07);
+    gotoxy(INFLINE, 17);
+    csprint(infoline, 0x07);
+}
+
+t_handler_return network_handler(t_menusystem * ms, t_menuitem * mi)
+{
+    // mi=network since this is handler only for that.
+    (void)ms;			// Unused
+
+    if (mi->data == (void *)none)
+	mi->item = nonet;
+    if (mi->data == (void *)stat)
+	mi->item = statnet;
+    if (mi->data == (void *)dhcp)
+	mi->item = dhcpnet;
+    return ACTION_INVALID;	// VALID or INVALID does not matter
+}
+
+t_handler_return checkbox_handler(t_menusystem * ms, t_menuitem * mi)
+{
+    (void)ms;			/* Unused */
+
+    t_handler_return rv;
+
+    if (mi->action != OPT_CHECKBOX)
+	return ACTION_INVALID;
+
+    if (strcmp(mi->data, "baseurl") == 0)
+	flags.baseurl = (mi->itemdata.checked ? 1 : 0);
+    if (strcmp(mi->data, "winrepair") == 0) {
+	if (mi->itemdata.checked) {
+	    flags.winrep = 1;
+	    linrep->action = OPT_INACTIVE;
+	} else {
+	    flags.winrep = 0;
+	    linrep->action = OPT_CHECKBOX;
+	}
+    }
+    if (strcmp(mi->data, "linrepair") == 0) {
+	if (mi->itemdata.checked) {
+	    flags.linrep = 1;
+	    winrep->action = OPT_INACTIVE;
+	} else {
+	    flags.winrep = 0;
+	    winrep->action = OPT_CHECKBOX;
+	}
+    }
+    if (strcmp(mi->data, "mountcd") == 0)
+	flags.mountcd = (mi->itemdata.checked ? 1 : 0);
+
+    rv.valid = 0;
+    rv.refresh = 1;
+    rv.reserved = 0;
+    return rv;
+}
+
+int main(void)
+{
+    t_menuitem *curr;
+    char cmd[160];
+    char ip[30];
+
+    // Set default username as guest
+    strcpy(username, GUEST_USER);
+
+    // Switch video mode here
+    // setvideomode(0x18); // or whatever mode you want
+
+    // Choose the default title and setup default values for all attributes....
+    init_passwords("/isolinux/password");
+    init_help("/isolinux/help");
+    init_menusystem(NULL);
+    set_window_size(1, 1, 20, 78);	// Leave some space around
+
+    // Choose the default values for all attributes and char's
+    // -1 means choose defaults (Actually the next 4 lines are not needed)
+    //set_normal_attr (-1,-1,-1,-1);
+    //set_status_info (-1,-1); // Display status on the last line
+    //set_title_info  (-1,-1);
+    //set_misc_info(-1,-1,-1,-1);
+
+    // Register the menusystem handler
+    reg_handler(HDLR_SCREEN, &msys_handler);
+    reg_handler(HDLR_KEYS, &keys_handler);
+    // Register the ontimeout handler, with a time out of 10 seconds
+    reg_ontimeout(ontimeout, 10, 0);
+
+    NETMENU = add_menu(" Init Network ", -1);
+    none = add_item("<N>one", "Dont start network", OPT_RADIOITEM, "no ", 0);
+    dhcp = add_item("<d>hcp", "Use DHCP", OPT_RADIOITEM, "dhcp ", 0);
+    stat =
+	add_item("<s>tatic", "Use static IP I will specify later",
+		 OPT_RADIOITEM, "static ", 0);
+
+    TESTING = add_menu(" Testing ", -1);
+    set_menu_pos(5, 55);
+    add_item("<M>emory Test", "Perform extensive memory testing", OPT_RUN,
+	     "memtest", 0);
+    add_item("<I>nvisible", "You dont see this", OPT_INVISIBLE, "junk", 0);
+    add_item("<E>xit this menu", "Go one level up", OPT_EXITMENU, "exit", 0);
+
+    RESCUE = add_menu(" Rescue Options ", -1);
+    add_item("<L>inux Rescue", "linresc", OPT_RUN, "linresc", 0);
+    add_item("<D>os Rescue", "dosresc", OPT_RUN, "dosresc", 0);
+    add_item("<W>indows Rescue", "winresc", OPT_RUN, "winresc", 0);
+    add_item("<E>xit this menu", "Go one level up", OPT_EXITMENU, "exit", 0);
+
+    PREPMENU = add_menu(" Prep options ", -1);
+    baseurl =
+	add_item("<b>aseurl by IP?", "Specify gui baseurl by IP address",
+		 OPT_CHECKBOX, "baseurl", 0);
+    mountcd =
+	add_item("<m>ountcd?", "Mount the cdrom drive?", OPT_CHECKBOX,
+		 "mountcd", 0);
+    network =
+	add_item(dhcpnet, "How to initialise network device?", OPT_RADIOMENU,
+		 NULL, NETMENU);
+    add_sep();
+    winrep =
+	add_item("Reinstall <w>indows",
+		 "Re-install the windows side of a dual boot setup",
+		 OPT_CHECKBOX, "winrepair", 0);
+    linrep =
+	add_item("Reinstall <l>inux",
+		 "Re-install the linux side of a dual boot setup", OPT_CHECKBOX,
+		 "linrepair", 0);
+    add_sep();
+    runprep =
+	add_item("<R>un prep now", "Execute prep with the above options",
+		 OPT_RUN, "prep", 0);
+    add_item("<E>xit this menu", "Go up one level", OPT_EXITMENU, "exitmenu",
+	     0);
+    baseurl->handler = &checkbox_handler;
+    mountcd->handler = &checkbox_handler;
+    winrep->handler = &checkbox_handler;
+    linrep->handler = &checkbox_handler;
+    network->handler = &network_handler;
+    flags.baseurl = 0;
+    flags.mountcd = 0;
+    flags.winrep = 0;
+    flags.linrep = 0;
+
+    SECRETMENU = add_menu(" Secret Menu ", -1);
+    add_item("secret 1", "Secret", OPT_RUN, "A", 0);
+    add_item("secret 2", "Secret", OPT_RUN, "A", 0);
+
+    LONGMENU = add_menu(" Long Menu ", 40);	// Override default here
+    add_item("<A>a", "Aa", OPT_RUN, "A", 0);
+    add_item("<B>b", "Ab", OPT_RUN, "A", 0);
+    add_item("<C>", "A", OPT_RUN, "A", 0);
+    add_item("<D>", "A", OPT_RUN, "A", 0);
+    add_item("<E>", "A", OPT_RUN, "A", 0);
+    add_item("<F>", "A", OPT_RUN, "A", 0);
+    add_item("<G>", "A", OPT_RUN, "A", 0);
+    add_item("<H>", "A", OPT_RUN, "A", 0);
+    add_item("<I>", "A", OPT_RUN, "A", 0);
+    add_item("<J>", "A", OPT_RUN, "A", 0);
+    add_item("<K>", "A", OPT_RUN, "A", 0);
+    add_item("<L>", "A", OPT_RUN, "A", 0);
+    add_item("<J>", "A", OPT_RUN, "A", 0);
+    add_item("<K>", "A", OPT_RUN, "A", 0);
+    add_item("<L>", "A", OPT_RUN, "A", 0);
+    add_item("<M>", "A", OPT_RUN, "A", 0);
+    add_item("<N>", "A", OPT_RUN, "A", 0);
+    add_item("<O>", "A", OPT_RUN, "A", 0);
+    add_item("<P>", "A", OPT_RUN, "A", 0);
+    add_item("<Q>", "A", OPT_RUN, "A", 0);
+    add_item("<R>", "A", OPT_RUN, "A", 0);
+    add_item("<S>", "A", OPT_RUN, "A", 0);
+    add_item("<T>", "A", OPT_RUN, "A", 0);
+    add_item("<U>", "A", OPT_RUN, "A", 0);
+    add_item("<V>", "A", OPT_RUN, "A", 0);
+    add_item("<W>", "A", OPT_RUN, "A", 0);
+    add_item("<X>", "A", OPT_RUN, "A", 0);
+    add_item("<Y>", "A", OPT_RUN, "A", 0);
+    add_item("<Z>", "A", OPT_RUN, "A", 0);
+    add_item("<1>", "A", OPT_RUN, "A", 0);
+    add_item("<2>", "A", OPT_RUN, "A", 0);
+    add_item("<3>", "A", OPT_RUN, "A", 0);
+    add_item("<4>", "A", OPT_RUN, "A", 0);
+    add_item("<5>", "A", OPT_RUN, "A", 0);
+    add_item("<6>", "A", OPT_RUN, "A", 0);
+    add_item("<7>", "A", OPT_RUN, "A", 0);
+    add_item("<8>", "A", OPT_RUN, "A", 0);
+    add_item("<9>", "A", OPT_RUN, "A", 0);
+
+    MAIN = add_menu(" Main Menu ", 8);
+    curr = add_item(loginstr, "Login as a privileged user", OPT_RUN, NULL, 0);
+    set_item_options(-1, 23);
+    curr->handler = &login_handler;
+
+    add_item("<P>repare", "prep", OPT_RUN, "prep", 0);
+    set_item_options(-1, 24);
+    prepopt =
+	add_item("<P>rep options...",
+		 "Options for prep image: Requires authenticated user",
+		 OPT_INACTIVE, NULL, PREPMENU);
+    set_item_options(-1, 25);
+
+    add_item("<R>escue options...", "Troubleshoot a system", OPT_SUBMENU, NULL,
+	     RESCUE);
+    set_item_options(-1, 26);
+    add_item("<T>esting...", "Options to test hardware", OPT_SUBMENU, NULL,
+	     TESTING);
+    set_item_options(-1, 27);
+    add_item("<L>ong Menu...", "test menu system", OPT_SUBMENU, NULL, LONGMENU);
+    set_item_options(-1, 28);
+    secret =
+	add_item("<S>ecret Menu...", "Secret menu", OPT_INVISIBLE, NULL,
+		 SECRETMENU);
+    set_item_options(-1, 29);
+    add_item("<E>xit to prompt", "Exit the menu system", OPT_EXITMENU, "exit",
+	     0);
+    set_item_options(-1, 30);
+    csprint("Press any key within 5 seconds to show menu...", 0x07);
+    if (get_key(stdin, 50) == KEY_NONE)	// Granularity of 100 milliseconds
+    {
+	csprint("Sorry! Time's up.\r\n", 0x07);
+	return 1;
+    }
+    curr = showmenus(MAIN);
+    if (curr) {
+	if (curr->action == OPT_RUN) {
+	    strcpy(cmd, curr->data);
+	    if (curr == runprep) {
+		strcat(cmd, infoline);
+		if (network->data == (void *)stat)	// We want static
+		{
+		    csprint("Enter IP address (last two octets only): ", 0x07);
+		    strcpy(ip, "Junk");
+		    editstring(ip, sizeof ip);
+		    strcat(cmd, "ipaddr=192.168.");
+		    strcat(cmd, ip);
+		}
+	    }
+	    if (issyslinux())
+		runsyslinuxcmd(cmd);
+	    else
+		csprint(cmd, 0x07);
+	    return 1;		// Should not happen when run from SYSLINUX
+	}
+    }
+    // If user quits the menu system, control comes here
+    // If you want to execute some specific command uncomment the next two lines
+
+    // if (syslinux) runcommand(YOUR_COMMAND_HERE);
+    // else csprint(YOUR_COMMAND_HERE,0x07);
+
+    // Deallocate space used for these data structures
+    close_passwords();
+    close_help();
+    close_menusystem();
+
+    // Return to prompt
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/display.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/display.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/display.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2006 Murali Krishnan Ganapathy - 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 NULL
+#define NULL ((void *) 0)
+#endif
+
+#include "help.h"
+#include "com32io.h"
+#include "cmenu.h"
+#include "tui.h"
+#include <stdlib.h>
+#include <com32.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    if (argc < 2) {
+	csprint("Usage: display.c32 <textfile>\n", 0x07);
+	exit(1);
+    }
+
+    init_help(NULL);		// No base dir, so all filenames must be absolute
+    runhelp(argv[1]);
+    close_help();
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/cmenu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/cmenu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/cmenu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,294 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/* This program can be compiled for DOS with the OpenWatcom compiler
+ * (http://www.openwatcom.org/):
+ *
+ * wcl -3 -osx -mt <filename>.c
+ */
+
+#ifndef __MENU_H__
+#define __MENU_H__
+
+#include "com32io.h"
+#include "tui.h"
+#include "syslnx.h"
+#include <string.h>
+#include <unistd.h>
+
+// TIMEOUT PARAMETERS
+/* If no key is pressed within TIMEOUTNUMSTEPS * TIMEOUTSTEPSIZE milliseconds
+   and if a timeout handler is registered, then that will be called.
+   The handler should either either take control from there on, or return without
+   producing any change in the current video settings.
+
+   For e.g. the handler could
+   * Could just quit the menu program
+   * beep and return.
+
+   TIMEOUTSTEPSIZE is the interval for which the program sleeps without checking for
+   any keystroke. So increasing this will make the response of the system slow.
+   Decreasing this will make a lot of interrupt calls using up your CPU. Default
+   value of TIMEOUTSTEPSIZE of 0.1 seconds should be right in most cases.
+
+   TIMEOUTNUMSTEPS of 3000 corresponds to a wait time of 300 seconds or 5 minutes
+*/
+
+#define TIMEOUTSTEPSIZE 10
+#define TIMEOUTNUMSTEPS 30000L
+
+// Attributes
+#define NORMALATTR    0x17
+#define NORMALHLITE   0x1F	// Normal Highlight attribute
+#define REVERSEATTR   0x70
+#define REVERSEHLITE  0x78	// Reverse Hightlight attribute
+#define INACTATTR     0x18
+#define INACTHLITE    0x10	// Inactive Highlight attribute
+#define REVINACTATTR  0x78
+#define REVINACTHLITE 0x70	// Reverse Inactive Highlight attr
+
+#define STATUSATTR    0x74
+#define STATUSHLITE   0x7B	// Status highlight
+
+#define FILLCHAR      ' '
+#define FILLATTR      NORMALATTR
+#define SHADOWATTR    0x00
+#define SPACECHAR     ' '
+
+#define TFILLCHAR     ' '
+#define TITLEATTR     0x70
+
+#define ENABLEHLITE   '<'	// Char which turns on highlight
+#define DISABLEHLITE  '>'	// Char which turns off highlight
+#define NOHLITE       0		// The offset into attrib array for non-hilite
+#define HLITE         1		// The offset for Hlite attrib
+
+#define MOREABOVE    '^'		// char to print when more menu items available above
+#define MOREBELOW    'v'		// more items available below
+
+// Attributes of the menu system
+#define MAXMENUS      250	// Maximum number of menu's allowed
+#define MAXMENUSIZE   100	// Default value for max num of entries in each menu
+#define MAXMENUHEIGHT 20	// Maximum number of entries displayed
+#define MENUBOXTYPE   BOX_SINSIN	// Default box type Look at tui.h for other values
+
+// Upper bounds on lengths
+// We copy the given string, so user can reuse the space used to store incoming arguments.
+#define MENULEN       78	// Each menu entry is atmost MENULEN chars
+#define STATLEN       78	// Maximum length of status string
+#define TITLELEN      78	// Maximum length of title string
+#define ACTIONLEN     255	// Maximum length of an action string
+
+// Layout of menu
+#define MENUROW       3		// Row where menu is displayed (relative to window)
+#define MENUCOL       4		// Col where menu is displayed (relative to window)
+#define MENUPAGE      1		// show in display page 1
+#define STATLINE      24	// Line number where status line starts (relative to window)
+
+// Used for printing debugging messages
+#define DEBUGLINE     23	// debugging info goes here
+
+// Other Chars
+#define RADIOMENUCHAR '>'	// > symbol for radio menu?
+#define CHECKED       '\140'	// Check mark
+#define UNCHECKED     '\146'	// Light bullet
+#define RADIOSEL      '.'	// Current Radio Selection
+#define RADIOUNSEL    ' '	// Radio option not selected
+
+typedef unsigned char uchar;
+
+// Types of menu's
+#define NORMALMENU 1
+#define RADIOMENU  2
+
+typedef enum { OPT_INACTIVE, OPT_SUBMENU, OPT_RUN, OPT_EXITMENU, OPT_CHECKBOX,
+    OPT_RADIOMENU, OPT_SEP, OPT_INVISIBLE,
+    OPT_RADIOITEM
+} t_action;
+
+typedef union {
+    uchar submenunum;		// For submenu's
+    uchar checked;		// For check boxes
+    uchar radiomenunum;		// Item mapping to a radio menu
+} t_itemdata;
+
+struct s_menuitem;
+struct s_menu;
+struct s_menusystem;
+
+typedef struct {
+    unsigned int valid:1;	// Is action valid?
+    unsigned int refresh:1;	// Should we recompute menu stuff?
+    unsigned int reserved:6;	// For future expansion
+} t_handler_return;
+
+t_handler_return ACTION_VALID, ACTION_INVALID;	// Specific values
+
+typedef t_handler_return(*t_item_handler) (struct s_menusystem *,
+					   struct s_menuitem *);
+typedef void (*t_menusystem_handler) (struct s_menusystem *,
+				      struct s_menuitem *);
+typedef void (*t_keys_handler) (struct s_menusystem *, struct s_menuitem *,
+				unsigned int scancode);
+    // Last parameter = HIGH BYTE = scan code , LOW BYTE = ASCII CODE
+
+typedef enum { HDLR_SCREEN, HDLR_KEYS } t_handler;
+// Types of handlers for menu system
+
+// TIMEOUT is the list of possible values which can be returned by the handler
+// instructing the menusystem what to do. The default is CODE_WAIT
+typedef enum { CODE_WAIT, CODE_ENTER, CODE_ESCAPE } TIMEOUTCODE;
+typedef TIMEOUTCODE(*t_timeout_handler) (void);
+
+typedef struct s_menuitem {
+    char *item;
+    char *status;
+    char *data;			// string containing kernel to run.. but...
+    // for radio menu's this is a pointer to the item selected or NULL (initially)
+    // for submenu's this string could be name of menu
+    void *extra_data;		// Any other data user can point to
+    unsigned int helpid;	// Used for Context sensitive help
+    t_item_handler handler;	// Pointer to function of type menufn
+    t_action action;
+    t_itemdata itemdata;	// Data depends on action value
+    uchar shortcut;		// one of [A-Za-z0-9] shortcut for this menu item
+    uchar index;		// Index within the menu array
+    uchar parindex;		// Index of the menu in which this item appears.
+
+} t_menuitem;
+
+typedef t_menuitem *pt_menuitem;	// Pointer to type menuitem
+
+typedef struct s_menu {
+    pt_menuitem *items;		// pointer to array of pointer to menuitems
+    char *title;		// Title string for menu
+    char *name;			// menu can be referred to by this string
+    int maxmenusize;		// the size of array allocated
+    uchar numitems;		// how many items do we actually have
+    uchar menuwidth;
+    uchar row, col;		// Position where this menu should be displayed
+    uchar menuheight;		// Maximum number of items to be displayed
+} t_menu;
+
+typedef t_menu *pt_menu;	// Pointer to type menu
+
+typedef struct s_menusystem {
+    pt_menu menus[MAXMENUS];
+    char *title;
+    t_menusystem_handler handler;	// Menu system handler
+    t_keys_handler keys_handler;	// Handler for unknown keys
+    t_timeout_handler ontimeout;	// Timeout handler
+    unsigned long tm_numsteps;
+    // Time to wait for key press=numsteps * stepsize milliseconds
+    unsigned int tm_stepsize;	// Timeout step size (in milliseconds)
+    // Total timeout max time spent idle before we call handler
+    unsigned long tm_total_timeout;	// (in milli seconds)
+    unsigned long tm_sofar_timeout;	// All accumulated timeout
+    // total timeout handler
+    t_timeout_handler ontotaltimeout;	// Total timeout handler
+
+    int maxmenuheight;
+    uchar nummenus;
+    uchar normalattr[2];	// [0] is non-hlite attr, [1] is hlite attr
+    uchar reverseattr[2];
+    uchar inactattr[2];
+    uchar revinactattr[2];
+    uchar statusattr[2];
+    uchar fillchar;
+    uchar fillattr;
+    uchar spacechar;
+    uchar tfillchar;
+    uchar titleattr;
+    uchar shadowattr;
+    uchar statline;
+    uchar menupage;
+    int maxrow, minrow, numrows;	// Number of rows in the window
+    int maxcol, mincol, numcols;	// Number of columns in the window
+
+    // Menu box look
+    char box_horiz, box_ltrt, box_rtlt;	// Some chars of the box, for redrawing portions of the box
+
+} t_menusystem;
+
+typedef t_menusystem *pt_menusystem;	// Pointer to type menusystem
+
+pt_menuitem showmenus(uchar startmenu);
+
+pt_menusystem init_menusystem(const char *title);
+
+void close_menusystem(void);	// Deallocate memory used
+
+void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal,
+		     uchar inactiveselected);
+
+void set_normal_hlite(uchar normal, uchar selected, uchar inactivenormal,
+		      uchar inactiveselected);
+
+void set_status_info(uchar statusattr, uchar statushlite, uchar statline);
+
+void set_title_info(uchar tfillchar, uchar titleattr);
+
+void set_misc_info(uchar fillchar, uchar fillattr, uchar spacechar,
+		   uchar shadowattr);
+
+void set_window_size(uchar top, uchar left, uchar bot, uchar right);	// Set the window which menusystem should use
+
+void set_menu_options(uchar maxmenuheight);
+// maximum height of a menu
+
+void reg_handler(t_handler htype, void *handler);	// Register handler
+
+void unreg_handler(t_handler htype);
+
+void reg_ontimeout(t_timeout_handler, unsigned int numsteps,
+		   unsigned int stepsize);
+// Set timeout handler, set 0 for default values.
+// So stepsize=0 means numsteps is measured in centiseconds.
+void unreg_ontimeout(void);
+
+void reg_ontotaltimeout(t_timeout_handler, unsigned long numcentiseconds);
+void unreg_ontotaltimeout(void);
+
+// Find the number of the menu given the name
+// Returns -1 if not found
+uchar find_menu_num(const char *name);
+
+// Create a new menu and return its position
+uchar add_menu(const char *title, int maxmenusize);
+
+// Create a named menu and return its position
+uchar add_named_menu(const char *name, const char *title, int maxmenusize);
+
+void set_menu_pos(uchar row, uchar col);	// Set the position of this menu.
+
+// Add item to the "current" menu
+pt_menuitem add_item(const char *item, const char *status, t_action action,
+		     const char *data, uchar itemdata);
+
+// Set shortcut key and help id
+void set_item_options(uchar shortcut, int helpid);
+
+// Set the shortcut key for the current item
+static inline void set_shortcut(uchar shortcut)
+{
+    set_item_options(shortcut, 0xFFFF);
+}
+
+// Add a separator to the "current" menu
+pt_menuitem add_sep(void);
+
+// Generate string based on state of checkboxes and radioitem in given menu
+// and append string to existing contents of "line"
+// line must have enough space allocated
+void gen_append_line(const char *menu_name, char *line);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,78 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <string.h>
+#include <com32.h>
+#include "com32io.h"
+#include "tui.h"
+#include "syslnx.h"
+
+com32sys_t inreg, outreg;	// Global register sets for use
+
+void getpos(char *row, char *col, char page)
+{
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x03;
+    REG_BH(inreg) = page;
+    __intcall(0x10, &inreg, &outreg);
+    *row = REG_DH(outreg);
+    *col = REG_DL(outreg);
+}
+
+char inputc(char *scancode)
+{
+    syslinux_idle();		/* So syslinux can perform periodic activity */
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x10;
+    __intcall(0x16, &inreg, &outreg);
+    if (scancode)
+	*scancode = REG_AH(outreg);
+    return REG_AL(outreg);
+}
+
+void getcursorshape(char *start, char *end)
+{
+    char page = 0; // XXX TODO
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x03;
+    REG_BH(inreg) = page;
+    __intcall(0x10, &inreg, &outreg);
+    *start = REG_CH(outreg);
+    *end = REG_CL(outreg);
+}
+
+void setcursorshape(char start, char end)
+{
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x01;
+    REG_CH(inreg) = start;
+    REG_CL(inreg) = end;
+    __intcall(0x10, &inreg, &outreg);
+}
+
+void setvideomode(char mode)
+{
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x00;
+    REG_AL(inreg) = mode;
+    __intcall(0x10, &inreg, &outreg);
+}
+
+// Get char displayed at current position
+unsigned char getcharat(char page)
+{
+    memset(&inreg, 0, sizeof inreg);
+    REG_AH(inreg) = 0x08;
+    REG_BH(inreg) = page;
+    __intcall(0x16, &inreg, &outreg);
+    return REG_AL(outreg);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/com32io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,66 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 __COM32IO_H__
+#define __COM32IO_H__
+
+#include <com32.h>
+#include <stdio.h>
+#include <libansi.h>
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/* Bits representing ShiftFlags, See Int16/Function 2 or Mem[0x417] to get this info */
+
+#define INSERT_ON     (1<<7)
+#define CAPSLOCK_ON   (1<<6)
+#define NUMLOCK_ON    (1<<5)
+#define SCRLLOCK_ON   (1<<4)
+#define ALT_PRESSED   (1<<3)
+#define CTRL_PRESSED  (1<<2)
+// actually 1<<1 is Left Shift, 1<<0 is right shift
+#define SHIFT_PRESSED (1<<1 | 1 <<0)
+
+/* BIOS Assisted output routines */
+
+void getpos(char *row, char *col, char page);
+
+char inputc(char *scancode);	// Return ASCII char by val, and scancode by reference
+
+void setcursorshape(char start, char end);	// Set cursor shape
+void getcursorshape(char *start, char *end);	// Get shape for current page
+
+// Get char displayed at current position in specified page
+unsigned char getcharat(char page);
+
+static inline unsigned char readbiosb(unsigned int ofs)
+{
+    return *((unsigned char *)MK_PTR(0, ofs));
+}
+
+static inline char getshiftflags(void)
+{
+    return readbiosb(0x417);
+}
+
+void scrollupwindow(char top, char left, char bot, char right, char attr, char numlines);	//Scroll up given window
+
+void setvideomode(char mode);	// Set the video mode.
+
+static inline char getvideomode(void)	// Get the current video mode
+{
+    return readbiosb(0x449);
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1064 @@
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * All rights reserved.
+ *
+ * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
+ *	this file should now *only* export crypt(), in order to make
+ *	binaries of libcrypt exportable from the USA
+ *
+ * Adapted for FreeBSD-4.0 by Mark R V Murray
+ *	this file should now *only* export crypt_des(), in order to make
+ *	a module that can be optionally included in libcrypt.
+ *
+ * Adapted for pxelinux menu environment by Th.Gebhardt
+ *      removed dependencies of standard C libs
+ *      added LOWSPACE option (using common space for different arrays)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <davidb@werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ *	B. Schneier, Applied Cryptography: protocols, algorithms,
+ *	and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author).  A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * ARCHITECTURE ASSUMPTIONS:
+ *	It is assumed that the 8-byte arrays passed by reference can be
+ *	addressed as arrays of u_int32_t's (ie. the CPU is not picky about
+ *	alignment).
+ */
+
+#define LOWSPACE
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+typedef unsigned long my_u_int32_t;
+typedef unsigned char my_u_char_t;
+
+/* Re-entrantify me -- all this junk needs to be in
+ * struct crypt_data to make this really reentrant... */
+static my_u_char_t inv_key_perm[64];
+static my_u_char_t inv_comp_perm[56];
+static my_u_char_t u_sbox[8][64];
+static my_u_char_t un_pbox[32];
+static my_u_int32_t en_keysl[16], en_keysr[16];
+static my_u_int32_t de_keysl[16], de_keysr[16];
+
+#ifndef LOWSPACE
+static my_u_int32_t ip_maskl[8][256], ip_maskr[8][256];
+static my_u_int32_t fp_maskl[8][256], fp_maskr[8][256];
+static my_u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
+static my_u_int32_t comp_maskl[8][128], comp_maskr[8][128];
+#endif
+
+static my_u_int32_t saltbits;
+static my_u_int32_t old_salt;
+static my_u_int32_t old_rawkey0, old_rawkey1;
+
+#ifdef LOWSPACE
+static my_u_int32_t common[8][256];
+#endif
+
+/* Static stuff that stays resident and doesn't change after
+ * being initialized, and therefore doesn't need to be made
+ * reentrant. */
+static my_u_char_t init_perm[64], final_perm[64];
+static my_u_char_t m_sbox[4][4096];
+
+#ifndef LOWSPACE
+static my_u_int32_t psbox[4][256];
+#endif
+
+/* A pile of data */
+static const my_u_char_t ascii64[] =
+    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static const my_u_char_t IP[64] = {
+    58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
+    62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
+    57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+    61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
+};
+
+static const my_u_char_t key_perm[56] = {
+    57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
+    10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+    63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
+    14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
+};
+
+static const my_u_char_t key_shifts[16] = {
+    1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static const my_u_char_t comp_perm[48] = {
+    14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
+    23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
+    41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+    44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ *	No E box is used, as it's replaced by some ANDs, shifts, and ORs.
+ */
+
+static const my_u_char_t sbox[8][64] = {
+    {
+     14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+     0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+     4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+     15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
+    {
+     15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+     3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+     0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+     13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
+    {
+     10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+     13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+     13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+     1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
+    {
+     7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+     13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+     10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+     3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
+    {
+     2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+     14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+     4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+     11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
+    {
+     12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+     10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+     9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+     4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
+    {
+     4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+     13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+     1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+     6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
+    {
+     13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+     1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+     7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+     2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
+};
+
+static const my_u_char_t pbox[32] = {
+    16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
+    2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
+};
+
+static const my_u_int32_t bits32[32] = {
+    0x80000000, 0x40000000, 0x20000000, 0x10000000,
+    0x08000000, 0x04000000, 0x02000000, 0x01000000,
+    0x00800000, 0x00400000, 0x00200000, 0x00100000,
+    0x00080000, 0x00040000, 0x00020000, 0x00010000,
+    0x00008000, 0x00004000, 0x00002000, 0x00001000,
+    0x00000800, 0x00000400, 0x00000200, 0x00000100,
+    0x00000080, 0x00000040, 0x00000020, 0x00000010,
+    0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static const my_u_int32_t bits28[28] = {
+    0x08000000, 0x04000000, 0x02000000, 0x01000000,
+    0x00800000, 0x00400000, 0x00200000, 0x00100000,
+    0x00080000, 0x00040000, 0x00020000, 0x00010000,
+    0x00008000, 0x00004000, 0x00002000, 0x00001000,
+    0x00000800, 0x00000400, 0x00000200, 0x00000100,
+    0x00000080, 0x00000040, 0x00000020, 0x00000010,
+    0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static const my_u_int32_t bits24[24] = {
+    0x00800000, 0x00400000, 0x00200000, 0x00100000,
+    0x00080000, 0x00040000, 0x00020000, 0x00010000,
+    0x00008000, 0x00004000, 0x00002000, 0x00001000,
+    0x00000800, 0x00000400, 0x00000200, 0x00000100,
+    0x00000080, 0x00000040, 0x00000020, 0x00000010,
+    0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static const my_u_char_t bits8[8] =
+    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+// static const my_u_int32_t *bits28, *bits24;
+
+static int ascii_to_bin(char ch)
+{
+    if (ch > 'z')
+	return (0);
+    if (ch >= 'a')
+	return (ch - 'a' + 38);
+    if (ch > 'Z')
+	return (0);
+    if (ch >= 'A')
+	return (ch - 'A' + 12);
+    if (ch > '9')
+	return (0);
+    if (ch >= '.')
+	return (ch - '.');
+    return (0);
+}
+
+static void des_init(void)
+{
+
+#ifdef LOWSPACE
+    int i, j, b;
+#else
+    int i, j, b, k, inbit, obit;
+    my_u_int32_t *p, *il, *ir, *fl, *fr;
+#endif
+    static int des_initialised = 0;
+
+    if (des_initialised == 1)
+	return;
+
+    old_rawkey0 = old_rawkey1 = 0L;
+    saltbits = 0L;
+    old_salt = 0L;
+    //      bits24 = (bits28 = bits32 + 4) + 4;
+
+    /*
+     * Invert the S-boxes, reordering the input bits.
+     */
+    for (i = 0; i < 8; i++)
+	for (j = 0; j < 64; j++) {
+	    b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
+	    u_sbox[i][j] = sbox[i][b];
+	}
+
+    /*
+     * Convert the inverted S-boxes into 4 arrays of 8 bits.
+     * Each will handle 12 bits of the S-box input.
+     */
+    for (b = 0; b < 4; b++)
+	for (i = 0; i < 64; i++)
+	    for (j = 0; j < 64; j++)
+		m_sbox[b][(i << 6) | j] =
+		    (my_u_char_t) ((u_sbox[(b << 1)][i] << 4) |
+				   u_sbox[(b << 1) + 1][j]);
+
+    /*
+     * Set up the initial & final permutations into a useful form, and
+     * initialise the inverted key permutation.
+     */
+    for (i = 0; i < 64; i++) {
+	init_perm[final_perm[i] = IP[i] - 1] = (my_u_char_t) i;
+	inv_key_perm[i] = 255;
+    }
+
+    /*
+     * Invert the key permutation and initialise the inverted key
+     * compression permutation.
+     */
+    for (i = 0; i < 56; i++) {
+	inv_key_perm[key_perm[i] - 1] = (my_u_char_t) i;
+	inv_comp_perm[i] = 255;
+    }
+
+    /*
+     * Invert the key compression permutation.
+     */
+    for (i = 0; i < 48; i++) {
+	inv_comp_perm[comp_perm[i] - 1] = (my_u_char_t) i;
+    }
+
+    /*
+     * Set up the OR-mask arrays for the initial and final permutations,
+     * and for the key initial and compression permutations.
+     */
+
+#ifndef LOWSPACE
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 256; i++) {
+	    *(il = &ip_maskl[k][i]) = 0L;
+	    *(ir = &ip_maskr[k][i]) = 0L;
+	    *(fl = &fp_maskl[k][i]) = 0L;
+	    *(fr = &fp_maskr[k][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j]) {
+		    if ((obit = init_perm[inbit]) < 32)
+			*il |= bits32[obit];
+		    else
+			*ir |= bits32[obit - 32];
+		    if ((obit = final_perm[inbit]) < 32)
+			*fl |= bits32[obit];
+		    else
+			*fr |= bits32[obit - 32];
+		}
+	    }
+	}
+	for (i = 0; i < 128; i++) {
+	    *(il = &key_perm_maskl[k][i]) = 0L;
+	    *(ir = &key_perm_maskr[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_key_perm[inbit]) == 255)
+			continue;
+		    if (obit < 28)
+			*il |= bits28[obit];
+		    else
+			*ir |= bits28[obit - 28];
+		}
+	    }
+	    *(il = &comp_maskl[k][i]) = 0L;
+	    *(ir = &comp_maskr[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 7 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_comp_perm[inbit]) == 255)
+			continue;
+		    if (obit < 24)
+			*il |= bits24[obit];
+		    else
+			*ir |= bits24[obit - 24];
+		}
+	    }
+	}
+    }
+#endif
+
+    /*
+     * Invert the P-box permutation, and convert into OR-masks for
+     * handling the output of the S-box arrays setup above.
+     */
+    for (i = 0; i < 32; i++)
+	un_pbox[pbox[i] - 1] = (my_u_char_t) i;
+
+#ifndef LOWSPACE
+    for (b = 0; b < 4; b++)
+	for (i = 0; i < 256; i++) {
+	    *(p = &psbox[b][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		if (i & bits8[j])
+		    *p |= bits32[un_pbox[8 * b + j]];
+	    }
+	}
+#endif
+    des_initialised = 1;
+}
+
+#ifdef LOWSPACE
+
+static void setup_ip_maskl(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *il;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 256; i++) {
+	    *(il = &common[k][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j]) {
+		    if ((obit = init_perm[inbit]) < 32)
+			*il |= bits32[obit];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_ip_maskr(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *ir;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 256; i++) {
+	    *(ir = &common[k][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j]) {
+		    if ((obit = init_perm[inbit]) >= 32)
+			*ir |= bits32[obit - 32];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_fp_maskl(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *fl;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 256; i++) {
+	    *(fl = &common[k][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j]) {
+		    if ((obit = final_perm[inbit]) < 32)
+			*fl |= bits32[obit];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_fp_maskr(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *fr;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 256; i++) {
+	    *(fr = &common[k][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j]) {
+		    if ((obit = final_perm[inbit]) >= 32)
+			*fr |= bits32[obit - 32];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_key_perm_maskl(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *il;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 128; i++) {
+	    *(il = &common[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_key_perm[inbit]) == 255)
+			continue;
+		    if (obit < 28)
+			*il |= bits28[obit];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_key_perm_maskr(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *ir;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 128; i++) {
+	    *(ir = &common[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 8 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_key_perm[inbit]) == 255)
+			continue;
+		    if (obit >= 28)
+			*ir |= bits28[obit - 28];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_comp_maskl(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *il;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 128; i++) {
+	    *(il = &common[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 7 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_comp_perm[inbit]) == 255)
+			continue;
+		    if (obit < 24)
+			*il |= bits24[obit];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_comp_maskr(void)
+{
+    int i, j, k, inbit, obit;
+    my_u_int32_t *ir;
+
+    for (k = 0; k < 8; k++) {
+	for (i = 0; i < 128; i++) {
+	    *(ir = &common[k][i]) = 0L;
+	    for (j = 0; j < 7; j++) {
+		inbit = 7 * k + j;
+		if (i & bits8[j + 1]) {
+		    if ((obit = inv_comp_perm[inbit]) == 255)
+			continue;
+		    if (obit >= 24)
+			*ir |= bits24[obit - 24];
+		}
+	    }
+	}
+    }
+}
+
+static void setup_psbox(void)
+{
+    int i, j, b;
+    my_u_int32_t *p;
+
+    for (b = 0; b < 4; b++)
+	for (i = 0; i < 256; i++) {
+	    *(p = &common[b][i]) = 0L;
+	    for (j = 0; j < 8; j++) {
+		if (i & bits8[j])
+		    *p |= bits32[un_pbox[8 * b + j]];
+	    }
+	}
+}
+
+#endif
+
+static void setup_salt(my_u_int32_t salt)
+{
+    my_u_int32_t obit, saltbit;
+    int i;
+
+    if (salt == old_salt)
+	return;
+    old_salt = salt;
+
+    saltbits = 0L;
+    saltbit = 1;
+    obit = 0x800000;
+    for (i = 0; i < 24; i++) {
+	if (salt & saltbit)
+	    saltbits |= obit;
+	saltbit <<= 1;
+	obit >>= 1;
+    }
+}
+
+static my_u_int32_t char_to_int(const char *key)
+{
+    my_u_int32_t byte0, byte1, byte2, byte3;
+    byte0 = (my_u_int32_t) (my_u_char_t) key[0];
+    byte1 = (my_u_int32_t) (my_u_char_t) key[1];
+    byte2 = (my_u_int32_t) (my_u_char_t) key[2];
+    byte3 = (my_u_int32_t) (my_u_char_t) key[3];
+
+    return byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3;
+}
+
+static int des_setkey(const char *key)
+{
+    my_u_int32_t k0, k1, rawkey0, rawkey1;
+    int shifts, round;
+
+    des_init();
+
+    /*  rawkey0 = ntohl(*(const my_u_int32_t *) key);
+     *  rawkey1 = ntohl(*(const my_u_int32_t *) (key + 4));
+     */
+
+    rawkey0 = char_to_int(key);
+    rawkey1 = char_to_int(key + 4);
+
+    if ((rawkey0 | rawkey1)
+	&& rawkey0 == old_rawkey0 && rawkey1 == old_rawkey1) {
+	/*
+	 * Already setup for this key.
+	 * This optimisation fails on a zero key (which is weak and
+	 * has bad parity anyway) in order to simplify the starting
+	 * conditions.
+	 */
+	return (0);
+    }
+    old_rawkey0 = rawkey0;
+    old_rawkey1 = rawkey1;
+
+    /*
+     *      Do key permutation and split into two 28-bit subkeys.
+     */
+
+#ifdef LOWSPACE
+    setup_key_perm_maskl();
+    k0 = common[0][rawkey0 >> 25]
+	| common[1][(rawkey0 >> 17) & 0x7f]
+	| common[2][(rawkey0 >> 9) & 0x7f]
+	| common[3][(rawkey0 >> 1) & 0x7f]
+	| common[4][rawkey1 >> 25]
+	| common[5][(rawkey1 >> 17) & 0x7f]
+	| common[6][(rawkey1 >> 9) & 0x7f]
+	| common[7][(rawkey1 >> 1) & 0x7f];
+    setup_key_perm_maskr();
+    k1 = common[0][rawkey0 >> 25]
+	| common[1][(rawkey0 >> 17) & 0x7f]
+	| common[2][(rawkey0 >> 9) & 0x7f]
+	| common[3][(rawkey0 >> 1) & 0x7f]
+	| common[4][rawkey1 >> 25]
+	| common[5][(rawkey1 >> 17) & 0x7f]
+	| common[6][(rawkey1 >> 9) & 0x7f]
+	| common[7][(rawkey1 >> 1) & 0x7f];
+#else
+    k0 = key_perm_maskl[0][rawkey0 >> 25]
+	| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
+	| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
+	| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
+	| key_perm_maskl[4][rawkey1 >> 25]
+	| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
+	| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
+	| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
+    k1 = key_perm_maskr[0][rawkey0 >> 25]
+	| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
+	| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
+	| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
+	| key_perm_maskr[4][rawkey1 >> 25]
+	| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
+	| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
+	| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
+#endif
+
+    /*
+     *      Rotate subkeys and do compression permutation.
+     */
+    shifts = 0;
+    for (round = 0; round < 16; round++) {
+	my_u_int32_t t0, t1;
+
+	shifts += key_shifts[round];
+
+	t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+	t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+#ifdef LOWSPACE
+	setup_comp_maskl();
+	de_keysl[15 - round] = en_keysl[round] = common[0][(t0 >> 21) & 0x7f]
+	    | common[1][(t0 >> 14) & 0x7f]
+	    | common[2][(t0 >> 7) & 0x7f]
+	    | common[3][t0 & 0x7f]
+	    | common[4][(t1 >> 21) & 0x7f]
+	    | common[5][(t1 >> 14) & 0x7f]
+	    | common[6][(t1 >> 7) & 0x7f]
+	    | common[7][t1 & 0x7f];
+
+	setup_comp_maskr();
+	de_keysr[15 - round] = en_keysr[round] = common[0][(t0 >> 21) & 0x7f]
+	    | common[1][(t0 >> 14) & 0x7f]
+	    | common[2][(t0 >> 7) & 0x7f]
+	    | common[3][t0 & 0x7f]
+	    | common[4][(t1 >> 21) & 0x7f]
+	    | common[5][(t1 >> 14) & 0x7f]
+	    | common[6][(t1 >> 7) & 0x7f]
+	    | common[7][t1 & 0x7f];
+#else
+	de_keysl[15 - round] =
+	    en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
+	    | comp_maskl[1][(t0 >> 14) & 0x7f]
+	    | comp_maskl[2][(t0 >> 7) & 0x7f]
+	    | comp_maskl[3][t0 & 0x7f]
+	    | comp_maskl[4][(t1 >> 21) & 0x7f]
+	    | comp_maskl[5][(t1 >> 14) & 0x7f]
+	    | comp_maskl[6][(t1 >> 7) & 0x7f]
+	    | comp_maskl[7][t1 & 0x7f];
+
+	de_keysr[15 - round] =
+	    en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
+	    | comp_maskr[1][(t0 >> 14) & 0x7f]
+	    | comp_maskr[2][(t0 >> 7) & 0x7f]
+	    | comp_maskr[3][t0 & 0x7f]
+	    | comp_maskr[4][(t1 >> 21) & 0x7f]
+	    | comp_maskr[5][(t1 >> 14) & 0x7f]
+	    | comp_maskr[6][(t1 >> 7) & 0x7f]
+	    | comp_maskr[7][t1 & 0x7f];
+#endif
+    }
+    return (0);
+}
+
+static int
+do_des(my_u_int32_t l_in, my_u_int32_t r_in, my_u_int32_t * l_out,
+       my_u_int32_t * r_out, int count)
+{
+    /*
+     *      l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+     */
+    my_u_int32_t l, r, *kl, *kr, *kl1, *kr1;
+    my_u_int32_t f, r48l, r48r;
+    int round;
+
+    if (count == 0) {
+	return (1);
+    } else if (count > 0) {
+	/*
+	 * Encrypting
+	 */
+	kl1 = en_keysl;
+	kr1 = en_keysr;
+    } else {
+	/*
+	 * Decrypting
+	 */
+	count = -count;
+	kl1 = de_keysl;
+	kr1 = de_keysr;
+    }
+
+    /*
+     *      Do initial permutation (IP).
+     */
+
+#ifdef LOWSPACE
+    setup_ip_maskl();
+    l = common[0][l_in >> 24]
+	| common[1][(l_in >> 16) & 0xff]
+	| common[2][(l_in >> 8) & 0xff]
+	| common[3][l_in & 0xff]
+	| common[4][r_in >> 24]
+	| common[5][(r_in >> 16) & 0xff]
+	| common[6][(r_in >> 8) & 0xff]
+	| common[7][r_in & 0xff];
+    setup_ip_maskr();
+    r = common[0][l_in >> 24]
+	| common[1][(l_in >> 16) & 0xff]
+	| common[2][(l_in >> 8) & 0xff]
+	| common[3][l_in & 0xff]
+	| common[4][r_in >> 24]
+	| common[5][(r_in >> 16) & 0xff]
+	| common[6][(r_in >> 8) & 0xff]
+	| common[7][r_in & 0xff];
+#else
+    l = ip_maskl[0][l_in >> 24]
+	| ip_maskl[1][(l_in >> 16) & 0xff]
+	| ip_maskl[2][(l_in >> 8) & 0xff]
+	| ip_maskl[3][l_in & 0xff]
+	| ip_maskl[4][r_in >> 24]
+	| ip_maskl[5][(r_in >> 16) & 0xff]
+	| ip_maskl[6][(r_in >> 8) & 0xff]
+	| ip_maskl[7][r_in & 0xff];
+    r = ip_maskr[0][l_in >> 24]
+	| ip_maskr[1][(l_in >> 16) & 0xff]
+	| ip_maskr[2][(l_in >> 8) & 0xff]
+	| ip_maskr[3][l_in & 0xff]
+	| ip_maskr[4][r_in >> 24]
+	| ip_maskr[5][(r_in >> 16) & 0xff]
+	| ip_maskr[6][(r_in >> 8) & 0xff]
+	| ip_maskr[7][r_in & 0xff];
+#endif
+
+    while (count--) {
+	/*
+	 * Do each round.
+	 */
+	kl = kl1;
+	kr = kr1;
+	round = 16;
+	while (round--) {
+	    /*
+	     * Expand R to 48 bits (simulate the E-box).
+	     */
+	    r48l = ((r & 0x00000001) << 23)
+		| ((r & 0xf8000000) >> 9)
+		| ((r & 0x1f800000) >> 11)
+		| ((r & 0x01f80000) >> 13)
+		| ((r & 0x001f8000) >> 15);
+
+	    r48r = ((r & 0x0001f800) << 7)
+		| ((r & 0x00001f80) << 5)
+		| ((r & 0x000001f8) << 3)
+		| ((r & 0x0000001f) << 1)
+		| ((r & 0x80000000) >> 31);
+	    /*
+	     * Do salting for crypt() and friends, and
+	     * XOR with the permuted key.
+	     */
+	    f = (r48l ^ r48r) & saltbits;
+	    r48l ^= f ^ *kl++;
+	    r48r ^= f ^ *kr++;
+	    /*
+	     * Do sbox lookups (which shrink it back to 32 bits)
+	     * and do the pbox permutation at the same time.
+	     */
+
+#ifdef LOWSPACE
+	    setup_psbox();
+	    f = common[0][m_sbox[0][r48l >> 12]]
+		| common[1][m_sbox[1][r48l & 0xfff]]
+		| common[2][m_sbox[2][r48r >> 12]]
+		| common[3][m_sbox[3][r48r & 0xfff]];
+#else
+	    f = psbox[0][m_sbox[0][r48l >> 12]]
+		| psbox[1][m_sbox[1][r48l & 0xfff]]
+		| psbox[2][m_sbox[2][r48r >> 12]]
+		| psbox[3][m_sbox[3][r48r & 0xfff]];
+#endif
+	    /*
+	     * Now that we've permuted things, complete f().
+	     */
+	    f ^= l;
+	    l = r;
+	    r = f;
+	}
+	r = l;
+	l = f;
+    }
+    /*
+     * Do final permutation (inverse of IP).
+     */
+
+#ifdef LOWSPACE
+    setup_fp_maskl();
+    *l_out = common[0][l >> 24]
+	| common[1][(l >> 16) & 0xff]
+	| common[2][(l >> 8) & 0xff]
+	| common[3][l & 0xff]
+	| common[4][r >> 24]
+	| common[5][(r >> 16) & 0xff]
+	| common[6][(r >> 8) & 0xff]
+	| common[7][r & 0xff];
+    setup_fp_maskr();
+    *r_out = common[0][l >> 24]
+	| common[1][(l >> 16) & 0xff]
+	| common[2][(l >> 8) & 0xff]
+	| common[3][l & 0xff]
+	| common[4][r >> 24]
+	| common[5][(r >> 16) & 0xff]
+	| common[6][(r >> 8) & 0xff]
+	| common[7][r & 0xff];
+#else
+    *l_out = fp_maskl[0][l >> 24]
+	| fp_maskl[1][(l >> 16) & 0xff]
+	| fp_maskl[2][(l >> 8) & 0xff]
+	| fp_maskl[3][l & 0xff]
+	| fp_maskl[4][r >> 24]
+	| fp_maskl[5][(r >> 16) & 0xff]
+	| fp_maskl[6][(r >> 8) & 0xff]
+	| fp_maskl[7][r & 0xff];
+    *r_out = fp_maskr[0][l >> 24]
+	| fp_maskr[1][(l >> 16) & 0xff]
+	| fp_maskr[2][(l >> 8) & 0xff]
+	| fp_maskr[3][l & 0xff]
+	| fp_maskr[4][r >> 24]
+	| fp_maskr[5][(r >> 16) & 0xff]
+	| fp_maskr[6][(r >> 8) & 0xff]
+	| fp_maskr[7][r & 0xff];
+#endif
+    return (0);
+}
+
+#if 0
+static int des_cipher(const char *in, char *out, my_u_int32_t salt, int count)
+{
+    my_u_int32_t l_out, r_out, rawl, rawr;
+    int retval;
+    union {
+	my_u_int32_t *ui32;
+	const char *c;
+    } trans;
+
+    des_init();
+
+    setup_salt(salt);
+
+    trans.c = in;
+    rawl = ntohl(*trans.ui32++);
+    rawr = ntohl(*trans.ui32);
+
+    retval = do_des(rawl, rawr, &l_out, &r_out, count);
+
+    trans.c = out;
+    *trans.ui32++ = htonl(l_out);
+    *trans.ui32 = htonl(r_out);
+    return (retval);
+}
+#endif
+
+void setkey(const char *key)
+{
+    int i, j;
+    char *p, packed_keys[8];
+
+    p = packed_keys;
+
+    for (i = 0; i < 8; i++) {
+	p[i] = 0;
+	for (j = 0; j < 8; j++)
+	    if (*key++ & 1)
+		p[i] |= bits8[j];
+    }
+    des_setkey(p);
+}
+
+void encrypt(char *block, int flag)
+{
+    my_u_int32_t io[2];
+    my_u_char_t *p;
+    int i, j;
+
+    des_init();
+
+    setup_salt(0L);
+    p = (my_u_char_t *)block;
+    for (i = 0; i < 2; i++) {
+	io[i] = 0L;
+	for (j = 0; j < 32; j++)
+	    if (*p++ & 1)
+		io[i] |= bits32[j];
+    }
+    do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
+    for (i = 0; i < 2; i++)
+	for (j = 0; j < 32; j++)
+	    block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0;
+}
+
+char *crypt(const char *key, const char *setting)
+{
+    my_u_int32_t count, salt, l, r0, r1, keybuf[2];
+    my_u_char_t *p, *q;
+    static char output[21];
+
+    des_init();
+
+    /*
+     * Copy the key, shifting each character up by one bit
+     * and padding with zeros.
+     */
+    q = (my_u_char_t *) keybuf;
+    while (q - (my_u_char_t *) keybuf - 8) {
+	*q++ = *key << 1;
+	if (*(q - 1))
+	    key++;
+    }
+    if (des_setkey((char *)keybuf))
+	return (NULL);
+
+#if 0
+    if (*setting == _PASSWORD_EFMT1) {
+	int i;
+	/*
+	 * "new"-style:
+	 *      setting - underscore, 4 bytes of count, 4 bytes of salt
+	 *      key - unlimited characters
+	 */
+	for (i = 1, count = 0L; i < 5; i++)
+	    count |= ascii_to_bin(setting[i]) << ((i - 1) * 6);
+
+	for (i = 5, salt = 0L; i < 9; i++)
+	    salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6);
+
+	while (*key) {
+	    /*
+	     * Encrypt the key with itself.
+	     */
+	    if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1))
+		return (NULL);
+	    /*
+	     * And XOR with the next 8 characters of the key.
+	     */
+	    q = (my_u_char_t *) keybuf;
+	    while (q - (my_u_char_t *) keybuf - 8 && *key)
+		*q++ ^= *key++ << 1;
+
+	    if (des_setkey((char *)keybuf))
+		return (NULL);
+	}
+	strncpy(output, setting, 9);
+
+	/*
+	 * Double check that we weren't given a short setting.
+	 * If we were, the above code will probably have created
+	 * wierd values for count and salt, but we don't really care.
+	 * Just make sure the output string doesn't have an extra
+	 * NUL in it.
+	 */
+	output[9] = '\0';
+	p = (my_u_char_t *) output + strlen(output);
+    } else
+#endif
+    {
+	/*
+	 * "old"-style:
+	 *      setting - 2 bytes of salt
+	 *      key - up to 8 characters
+	 */
+	count = 25;
+
+	salt = (ascii_to_bin(setting[1]) << 6)
+	    | ascii_to_bin(setting[0]);
+
+	output[0] = setting[0];
+	/*
+	 * If the encrypted password that the salt was extracted from
+	 * is only 1 character long, the salt will be corrupted.  We
+	 * need to ensure that the output string doesn't have an extra
+	 * NUL in it!
+	 */
+	output[1] = setting[1] ? setting[1] : output[0];
+
+	p = (my_u_char_t *) output + 2;
+    }
+    setup_salt(salt);
+    /*
+     * Do it.
+     */
+    if (do_des(0L, 0L, &r0, &r1, (int)count))
+	return (NULL);
+    /*
+     * Now encode the result...
+     */
+    l = (r0 >> 8);
+    *p++ = ascii64[(l >> 18) & 0x3f];
+    *p++ = ascii64[(l >> 12) & 0x3f];
+    *p++ = ascii64[(l >> 6) & 0x3f];
+    *p++ = ascii64[l & 0x3f];
+
+    l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+    *p++ = ascii64[(l >> 18) & 0x3f];
+    *p++ = ascii64[(l >> 12) & 0x3f];
+    *p++ = ascii64[(l >> 6) & 0x3f];
+    *p++ = ascii64[l & 0x3f];
+
+    l = r1 << 2;
+    *p++ = ascii64[(l >> 12) & 0x3f];
+    *p++ = ascii64[(l >> 6) & 0x3f];
+    *p++ = ascii64[l & 0x3f];
+    *p = 0;
+
+    return (output);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/des.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,8 @@
+
+#ifndef _DES_H_
+#define _DES_H_
+
+// des crypt
+extern char *crypt(const char *key, const char *salt);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,231 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "help.h"
+#include <stdio.h>
+#include "string.h"
+#include "com32io.h"
+#include <syslinux/loadfile.h>	// to read entire file into memory
+
+int nc, nr; // Number of columns/rows of the screen
+char helpbasedir[HELPDIRLEN];	// name of help directory limited to HELPDIRLEN
+
+// Find the occurence of the count'th \n in buffer (or NULL) if not found
+static char *findline(char *buffer, int count)
+{
+    int ctr;
+    char *p = buffer - 1;
+
+    if (count < 1)
+	return buffer;
+    for (ctr = 0; ctr < count; ctr++) {
+	p = strchr(p + 1, '\n');
+	if (p == NULL)
+	    return NULL;
+    }
+    return p;
+}
+
+// return the number of lines in buffer
+static int countlines(char *buffer)
+{
+    int ans;
+    const char *p;
+
+    p = buffer - 1;
+    ans = 1;
+    while (p) {
+	p = strchr(p + 1, '\n');
+	ans++;
+    }
+    return ans;
+}
+
+// Print numlines of text starting from buf
+static void printtext(char *buf, int from)
+{
+    char *f, *t;
+    int nlines, i;
+
+    // clear window to print
+    nlines = nr - HELP_BODY_ROW - HELP_BOTTOM_MARGIN - 1;
+
+    f = findline(buf, from);
+    if (!f)
+	return;			// nothing to print
+    if (*f == '\n')
+	f++;			// start of from+1st line
+    t = f;
+
+    for (i = 0; i < nlines; i++) {
+        gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
+        clear_end_of_line();
+        putchar(SO);
+        gotoxy(HELP_BODY_ROW + i, nc - 1);
+        putch(LEFT_BORDER, 0x07);
+        putchar(SI);
+
+        gotoxy(HELP_BODY_ROW + i, HELP_LEFT_MARGIN);
+        while (*t != '\n') {
+            if (*t == '\0')
+                return;
+            putchar(*t);
+            t++;
+        }
+        putchar('\n');
+        t++;
+    }
+}
+
+void showhelp(const char *filename)
+{
+    char ph;
+    char *title, *text;
+    union {
+	char *buffer;
+	void *vbuf;
+    } buf;			// This is to avoild type-punning issues
+
+    char line[512];
+    size_t size;
+    int scan;
+    int rv, numlines, curr_line;
+
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nc = 80;
+        nr = 24;
+    }
+    ph = nr - HELP_BODY_ROW;
+    cls();
+
+    /* Turn autowrap off, to avoid scrolling the menu */
+    printf(CSI "?7l");
+
+    if (filename == NULL) {	// print file contents
+        strcpy(line, "Filename not given");
+        goto puke;
+    }
+
+    rv = loadfile(filename, (void **)&buf.vbuf, &size);	// load entire file into memory
+    if (rv < 0) {		// Error reading file or no such file
+        sprintf(line, "Error reading file or file not found\n file=%s", filename);
+        goto puke;
+    }
+
+    title = buf.buffer;
+    text = findline(title, 1);	// end of first line
+    *text++ = '\0';		// end the title string and increment text
+
+    // Now we have a file just print it.
+    numlines = countlines(text);
+    curr_line = 0;
+    scan = KEY_ESC + 1;		// anything except ESCAPE
+
+    /* top, left, bottom, right, attr */
+    drawbox(0, 0, nr - 1, nc - 1, 0x07);
+    while (scan != KEY_ESC) {
+    /* Title */
+    gotoxy(1, (nc - strlen(title)) / 2);
+    fputs(title, stdout);
+    drawhorizline(2, HELP_LEFT_MARGIN - 1, nc - HELP_RIGHT_MARGIN, 0x07, 0);	// dumb==0
+    /* Text */
+	printtext(text, curr_line);
+    gotoxy(HELP_BODY_ROW - 1, nc - HELP_RIGHT_MARGIN);
+	if (curr_line > 0)
+	    putchar(HELP_MORE_ABOVE);
+	else
+	    putchar(' ');
+	gotoxy(nr - HELP_BOTTOM_MARGIN - 1, nc - HELP_RIGHT_MARGIN);
+	if (curr_line < numlines - ph)
+	    putchar(HELP_MORE_BELOW);
+	else
+	    putchar(' ');
+
+    scan = get_key(stdout, 0); // wait for user keypress
+
+	switch (scan) {
+	case KEY_HOME:
+	    curr_line = 0;
+	    break;
+	case KEY_END:
+	    curr_line = numlines;
+	    break;
+	case KEY_UP:
+	    curr_line--;
+	    break;
+	case KEY_DOWN:
+	    curr_line++;
+	    break;
+	case KEY_PGUP:
+	    curr_line -= ph;
+	    break;
+	case KEY_PGDN:
+	    curr_line += ph;
+	    break;
+	default:
+	    break;
+	}
+	if (curr_line > numlines - ph)
+	    curr_line = numlines - ph;
+	if (curr_line < 0)
+	    curr_line = 0;
+    }
+out:
+    cls();
+    return;
+
+puke:
+    gotoxy(HELP_BODY_ROW, HELP_LEFT_MARGIN);
+    fputs(line, stdout);
+    while (1) {
+        scan = get_key(stdin, 0);
+        if (scan == KEY_ESC)
+            break;
+    }
+    goto out;
+}
+
+void runhelp(const char *filename)
+{
+    char fullname[HELPDIRLEN + 16];
+
+	cls();
+    cursoroff();
+    if (helpbasedir[0] != 0) {
+	strcpy(fullname, helpbasedir);
+	strcat(fullname, "/");
+	strcat(fullname, filename);
+	showhelp(fullname);
+    } else
+	showhelp(filename);	// Assume filename is absolute
+}
+
+void runhelpsystem(unsigned int helpid)
+{
+    char filename[15];
+
+    sprintf(filename, "hlp%05d.txt", helpid);
+    runhelp(filename);
+}
+
+void init_help(const char *helpdir)
+{
+    if (helpdir != NULL)
+	strcpy(helpbasedir, helpdir);
+    else
+	helpbasedir[0] = 0;
+}
+
+void close_help(void)
+{
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/help.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 __HELP_H_
+#define __HELP_H_
+
+#include "cmenu.h"
+#include "com32io.h"
+#include "tui.h"
+#include <string.h>
+
+// How many rows for the title
+#define HELP_TITLE_HEIGHT 1
+#define HELP_BODY_ROW (HELP_TITLE_HEIGHT+3)
+#define HELP_LEFT_MARGIN 2
+#define HELP_RIGHT_MARGIN 2	// Assume all lines dont cross this
+#define HELP_BOTTOM_MARGIN 1	// Number of lines not use from bottom of screen
+
+#define HELPBOX BOX_SINSIN
+#define HELPDIRLEN  64
+#define HELPPAGE 2
+
+#define HELP_MORE_ABOVE '^'	// to print when more is available above
+#define HELP_MORE_BELOW 'v'	// same as above but for below
+
+// Display one screen of help information
+void showhelp(const char *filename);
+
+// Start the help system using id helpid
+void runhelpsystem(unsigned int helpid);
+
+// Start help system with specified file
+void runhelp(const char *filename);
+
+// Directory where help files are located
+void init_help(const char *helpdir);
+// Free internal datastructures
+void close_help(void);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/menu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1273 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "cmenu.h"
+#include "com32io.h"
+#include <stdlib.h>
+#include <console.h>
+
+// Local Variables
+static pt_menusystem ms;    // Pointer to the menusystem
+char TITLESTR[] =
+    "COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy";
+char TITLELONG[] = " TITLE too long ";
+char ITEMLONG[] = " ITEM too long ";
+char ACTIONLONG[] = " ACTION too long ";
+char STATUSLONG[] = " STATUS too long ";
+char EMPTYSTR[] = "";
+
+/* Forward declarations */
+int calc_visible(pt_menu menu, int first);
+int next_visible(pt_menu menu, int index);
+int prev_visible(pt_menu menu, int index);
+int next_visible_sep(pt_menu menu, int index);
+int prev_visible_sep(pt_menu menu, int index);
+int calc_first_early(pt_menu menu, int curr);
+int calc_first_late(pt_menu menu, int curr);
+int isvisible(pt_menu menu, int first, int curr);
+
+/* Basic Menu routines */
+
+// This is same as inputc except it honors the ontimeout handler
+// and calls it when needed. For the callee, there is no difference
+// as this will not return unless a key has been pressed.
+static int getch(void)
+{
+    t_timeout_handler th;
+    int key;
+    unsigned long i;
+
+    // Wait until keypress if no handler specified
+    if ((ms->ontimeout == NULL) && (ms->ontotaltimeout == NULL))
+        return get_key(stdin, 0);
+
+    th = ms->ontimeout;
+    for (;;) {
+        for (i = 0; i < ms->tm_numsteps; i++) {
+            key = get_key(stdin, ms->tm_stepsize);
+            if (key != KEY_NONE)
+                return key;
+
+            if ((ms->tm_total_timeout == 0) || (ms->ontotaltimeout == NULL))
+                continue;   // Dont bother with calculations if no handler
+            ms->tm_sofar_timeout += ms->tm_stepsize;
+            if (ms->tm_sofar_timeout >= ms->tm_total_timeout) {
+                th = ms->ontotaltimeout;
+                ms->tm_sofar_timeout = 0;
+                break;      // Get out of the for loop
+            }
+        }
+        if (!th)
+            continue;       // no handler
+        key = th();
+        switch (key) {
+        case CODE_ENTER:    // Pretend user hit enter
+            return KEY_ENTER;
+        case CODE_ESCAPE:   // Pretend user hit escape
+            return KEY_ESC;
+        default:
+            break;
+        }
+    }
+    return KEY_NONE;
+}
+
+int find_shortcut(pt_menu menu, uchar shortcut, int index)
+// Find the next index with specified shortcut key
+{
+    int ans;
+    pt_menuitem mi;
+
+    // Garbage in garbage out
+    if ((index < 0) || (index >= menu->numitems))
+    return index;
+    ans = index + 1;
+    // Go till end of menu
+    while (ans < menu->numitems) {
+    mi = menu->items[ans];
+    if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
+        || (mi->shortcut != shortcut))
+        ans++;
+    else
+        return ans;
+    }
+    // Start at the beginning and try again
+    ans = 0;
+    while (ans < index) {
+    mi = menu->items[ans];
+    if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP)
+        || (mi->shortcut != shortcut))
+        ans++;
+    else
+        return ans;
+    }
+    return index;       // Sorry not found
+}
+
+/* Redraw background and title */
+static void reset_ui(void)
+{
+    uchar tpos;
+
+    cls();
+    clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol,
+                ms->fillchar, ms->fillattr);
+
+    tpos = (ms->numcols - strlen(ms->title) - 1) >> 1;  // center it on line
+    gotoxy(ms->minrow, ms->mincol);
+    cprint(ms->tfillchar, ms->titleattr, ms->numcols);
+    gotoxy(ms->minrow, ms->mincol + tpos);
+    csprint(ms->title, ms->titleattr);
+
+    cursoroff();
+}
+
+/*
+ * Print a menu item
+ *
+ * attr[0] is non-hilite attr, attr[1] is highlight attr
+ */
+void printmenuitem(const char *str, uchar * attr)
+{
+    int hlite = NOHLITE;    // Initially no highlighting
+
+    while (*str) {
+        switch (*str) {
+            case BELL:      // No Bell Char
+                break;
+            case ENABLEHLITE:   // Switch on highlighting
+                hlite = HLITE;
+                break;
+            case DISABLEHLITE:  // Turn off highlighting
+                hlite = NOHLITE;
+                break;
+            default:
+                putch(*str, attr[hlite]);
+        }
+        str++;
+    }
+}
+
+
+/**
+ * print_line - Print a whole line in a menu
+ * @menu:   current menu to handle
+ * @curr:   index of the current entry highlighted
+ * @top:    top coordinate of the @menu
+ * @left:   left coordinate of the @menu
+ * @x:      index in the menu of curr
+ * @row:    row currently displayed
+ * @radio:  radio item?
+ **/
+static void print_line(pt_menu menu, int curr, uchar top, uchar left,
+                       int x, int row, bool radio)
+{
+    pt_menuitem ci;
+    char fchar[6], lchar[6];    // The first and last char in for each entry
+    const char *str;            // Item string (cf printmenuitem)
+    char sep[MENULEN];          // Separator (OPT_SEP)
+    uchar *attr;                // Attribute
+    int menuwidth = menu->menuwidth + 3;
+
+    if (row >= menu->menuheight)
+        return;
+
+    ci = menu->items[x];
+
+    memset(sep, ms->box_horiz, menuwidth);
+    sep[menuwidth - 1] = 0;
+
+    // Setup the defaults now
+    if (radio) {
+        fchar[0] = '\b';
+        fchar[1] = SO;
+        fchar[2] = (x == curr ? RADIOSEL : RADIOUNSEL);
+        fchar[3] = SI;
+        fchar[4] = '\0';    // Unselected ( )
+        lchar[0] = '\0';    // Nothing special after
+        attr = ms->normalattr;  // Always same attribute
+    } else {
+        lchar[0] = fchar[0] = ' ';
+        lchar[1] = fchar[1] = '\0'; // fchar and lchar are just spaces
+        attr = (x == curr ? ms->reverseattr : ms->normalattr);  // Normal attributes
+    }
+    str = ci->item;     // Pointer to item string
+    switch (ci->action) // set up attr,str,fchar,lchar for everything
+    {
+    case OPT_INACTIVE:
+        if (radio)
+            attr = ms->inactattr;
+        else
+            attr = (x == curr ? ms->revinactattr : ms->inactattr);
+        break;
+    case OPT_SUBMENU:
+        if (radio)
+            break;      // Not supported for radio menu
+        lchar[0] = '>';
+        lchar[1] = 0;
+        break;
+    case OPT_RADIOMENU:
+        if (radio)
+            break;      // Not supported for radio menu
+        lchar[0] = RADIOMENUCHAR;
+        lchar[1] = 0;
+        break;
+    case OPT_CHECKBOX:
+        if (radio)
+            break;      // Not supported for radio menu
+        lchar[0] = '\b';
+        lchar[1] = SO;
+        lchar[2] = (ci->itemdata.checked ? CHECKED : UNCHECKED);
+        lchar[3] = SI;
+        lchar[4] = 0;
+        break;
+    case OPT_SEP:
+        fchar[0] = '\b';
+        fchar[1] = SO;
+        fchar[2] = LEFT_MIDDLE_BORDER;
+        fchar[3] = MIDDLE_BORDER;
+        fchar[4] = MIDDLE_BORDER;
+        fchar[5] = 0;
+        memset(sep, MIDDLE_BORDER, menuwidth);
+        sep[menuwidth - 1] = 0;
+        str = sep;
+        lchar[0] = MIDDLE_BORDER;
+        lchar[1] = RIGHT_MIDDLE_BORDER;
+        lchar[2] = SI;
+        lchar[3] = 0;
+        break;
+    case OPT_EXITMENU:
+        if (radio)
+            break;      // Not supported for radio menu
+        fchar[0] = '<';
+        fchar[1] = 0;
+        break;
+    default:        // Just to keep the compiler happy
+        break;
+    }
+
+    // Wipe area with spaces
+    gotoxy(top + row, left - 2);
+    cprint(ms->spacechar, attr[NOHLITE], menuwidth + 2);
+
+    // Print first part
+    gotoxy(top + row, left - 2);
+    csprint(fchar, attr[NOHLITE]);
+
+    // Print main part
+    gotoxy(top + row, left);
+    printmenuitem(str, attr);
+
+    // Print last part
+    gotoxy(top + row, left + menuwidth - 1);
+    csprint(lchar, attr[NOHLITE]);
+}
+
+// print the menu starting from FIRST
+// will print a maximum of menu->menuheight items
+static void printmenu(pt_menu menu, int curr, uchar top, uchar left, uchar first, bool radio)
+{
+    int x, row;         // x = index, row = position from top
+    int numitems, menuwidth;
+    pt_menuitem ci;
+
+    numitems = calc_visible(menu, first);
+    if (numitems > menu->menuheight)
+    numitems = menu->menuheight;
+
+    menuwidth = menu->menuwidth + 3;
+    clearwindow(top, left - 2, top + numitems + 1, left + menuwidth + 1,
+        ms->fillchar, ms->shadowattr);
+    drawbox(top - 1, left - 3, top + numitems, left + menuwidth,
+        ms->normalattr[NOHLITE]);
+
+    // Menu title
+    x = (menuwidth - strlen(menu->title) - 1) >> 1;
+    gotoxy(top - 1, left + x);
+    printmenuitem(menu->title, ms->normalattr);
+
+    // All lines in the menu
+    row = -1;           // 1 less than inital value of x
+    for (x = first; x < menu->numitems; x++) {
+        ci = menu->items[x];
+        if (ci->action == OPT_INVISIBLE)
+            continue;
+        row++;
+        if (row >= numitems)
+            break;      // Already have enough number of items
+        print_line(menu, curr, top, left, x, row, radio);
+    }
+    // Check if we need to MOREABOVE and MOREBELOW to be added
+    // reuse x
+    row = 0;
+    x = next_visible_sep(menu, 0);  // First item
+    if (!isvisible(menu, first, x)) // There is more above
+    {
+    row = 1;
+    gotoxy(top, left + menuwidth);
+    cprint(MOREABOVE, ms->normalattr[NOHLITE], 1);
+    }
+    x = prev_visible_sep(menu, menu->numitems); // last item
+    if (!isvisible(menu, first, x)) // There is more above
+    {
+    row = 1;
+    gotoxy(top + numitems - 1, left + menuwidth);
+    cprint(MOREBELOW, ms->normalattr[NOHLITE], 1);
+    }
+    // Add a scroll box
+    x = ((numitems - 1) * curr) / (menu->numitems);
+    if ((x > 0) && (row == 1)) {
+    gotoxy(top + x, left + menuwidth);
+    csprint("\016\141\017", ms->normalattr[NOHLITE]);
+    }
+    if (ms->handler)
+    ms->handler(ms, menu->items[curr]);
+}
+
+void cleanupmenu(pt_menu menu, uchar top, uchar left, int numitems)
+{
+    if (numitems > menu->menuheight)
+    numitems = menu->menuheight;
+    clearwindow(top, left - 2, top + numitems + 1, left + menu->menuwidth + 4, ms->fillchar, ms->fillattr); // Clear the shadow
+    clearwindow(top - 1, left - 3, top + numitems, left + menu->menuwidth + 3, ms->fillchar, ms->fillattr); // main window
+}
+
+
+/* Handle one menu */
+static pt_menuitem getmenuoption(pt_menu menu, uchar top, uchar left, uchar startopt, bool radio)
+     // Return item chosen or NULL if ESC was hit.
+{
+    int prev, prev_first, curr, i, first, tmp;
+    int asc = 0;
+    bool redraw = true; // Need to draw the menu the first time
+    uchar numitems;
+    pt_menuitem ci;     // Current item
+    t_handler_return hr;    // Return value of handler
+
+    numitems = calc_visible(menu, 0);
+    // Setup status line
+    gotoxy(ms->minrow + ms->statline, ms->mincol);
+    cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
+
+    // Initialise current menu item
+    curr = next_visible(menu, startopt);
+    prev = curr;
+
+    gotoxy(ms->minrow + ms->statline, ms->mincol);
+    cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
+    gotoxy(ms->minrow + ms->statline, ms->mincol);
+    printmenuitem(menu->items[curr]->status, ms->statusattr);
+    first = calc_first_early(menu, curr);
+    prev_first = first;
+    while (1)           // Forever
+    {
+    /* Redraw everything if:
+     *  + we need to scroll (take care of scroll bars, ...)
+     *  + menuoption
+     */
+    if (prev_first != first || redraw) {
+        printmenu(menu, curr, top, left, first, radio);
+    } else {
+        /* Redraw only the highlighted entry */
+        print_line(menu, curr, top, left, prev, prev - first, radio);
+        print_line(menu, curr, top, left, curr, curr - first, radio);
+    }
+    redraw = false;
+    prev = curr;
+    prev_first = first;
+    ci = menu->items[curr];
+    asc = getch();
+    switch (asc) {
+        case KEY_CTRL('L'):
+        redraw = true;
+        break;
+    case KEY_HOME:
+        curr = next_visible(menu, 0);
+        first = calc_first_early(menu, curr);
+        break;
+    case KEY_END:
+        curr = prev_visible(menu, numitems - 1);
+        first = calc_first_late(menu, curr);
+        break;
+    case KEY_PGDN:
+        for (i = 0; i < 5; i++)
+        curr = next_visible(menu, curr + 1);
+        first = calc_first_late(menu, curr);
+        break;
+    case KEY_PGUP:
+        for (i = 0; i < 5; i++)
+        curr = prev_visible(menu, curr - 1);
+        first = calc_first_early(menu, curr);
+        break;
+    case KEY_UP:
+        curr = prev_visible(menu, curr - 1);
+        if (curr < first)
+        first = calc_first_early(menu, curr);
+        break;
+    case KEY_DOWN:
+        curr = next_visible(menu, curr + 1);
+        if (!isvisible(menu, first, curr))
+        first = calc_first_late(menu, curr);
+        break;
+    case KEY_LEFT:
+    case KEY_ESC:
+        return NULL;
+        break;
+    case KEY_RIGHT:
+    case KEY_ENTER:
+        if (ci->action == OPT_INACTIVE)
+        break;
+        if (ci->action == OPT_CHECKBOX)
+        break;
+        if (ci->action == OPT_SEP)
+        break;
+        if (ci->action == OPT_EXITMENU)
+        return NULL;    // As if we hit Esc
+        // If we are going into a radio menu, dont call handler, return ci
+        if (ci->action == OPT_RADIOMENU)
+        return ci;
+        if (ci->handler != NULL)    // Do we have a handler
+        {
+        hr = ci->handler(ms, ci);
+        if (hr.refresh) // Do we need to refresh
+        {
+            // Cleanup menu using old number of items
+            cleanupmenu(menu, top, left, numitems);
+            // Recalculate the number of items
+            numitems = calc_visible(menu, 0);
+            // Reprint the menu
+            printmenu(menu, curr, top, left, first, radio);
+        }
+        if (hr.valid)
+            return ci;
+        } else
+        return ci;
+        break;
+    case SPACECHAR:
+        if (ci->action != OPT_CHECKBOX)
+        break;
+        ci->itemdata.checked = !ci->itemdata.checked;
+        if (ci->handler != NULL)    // Do we have a handler
+        {
+        hr = ci->handler(ms, ci);
+        if (hr.refresh) // Do we need to refresh
+        {
+            // Cleanup menu using old number of items
+            cleanupmenu(menu, top, left, numitems);
+            // Recalculate the number of items
+            numitems = calc_visible(menu, 0);
+            // Reprint the menu
+            printmenu(menu, curr, top, left, first, radio);
+        }
+        }
+        break;
+    default:
+        // Check if this is a shortcut key
+        if (((asc >= 'A') && (asc <= 'Z')) ||
+        ((asc >= 'a') && (asc <= 'z')) ||
+        ((asc >= '0') && (asc <= '9'))) {
+        tmp = find_shortcut(menu, asc, curr);
+        if ((tmp > curr) && (!isvisible(menu, first, tmp)))
+            first = calc_first_late(menu, tmp);
+        if (tmp < curr)
+            first = calc_first_early(menu, tmp);
+        curr = tmp;
+        } else {
+        if (ms->keys_handler)   // Call extra keys handler
+            ms->keys_handler(ms, menu->items[curr], asc);
+
+            /* The handler may have changed the UI, reset it on exit */
+            reset_ui();
+            // Cleanup menu using old number of items
+            cleanupmenu(menu, top, left, numitems);
+            // Recalculate the number of items
+            numitems = calc_visible(menu, 0);
+            // Reprint the menu
+            printmenu(menu, curr, top, left, first, radio);
+        }
+        break;
+    }
+    // Update status line
+    /* Erase the previous status */
+    gotoxy(ms->minrow + ms->statline, ms->mincol);
+    cprint(ms->spacechar, ms->statusattr[NOHLITE], ms->numcols);
+    /* Print the new status */
+    gotoxy(ms->minrow + ms->statline, ms->mincol);
+    printmenuitem(menu->items[curr]->status, ms->statusattr);
+    }
+    return NULL;        // Should never come here
+}
+
+/* Handle the entire system of menu's. */
+pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt,
+              uchar menutype)
+     /*
+      * cmenu
+      *    Which menu should be currently displayed
+      * top,left
+      *    What is the position of the top,left corner of the menu
+      * startopt
+      *    which menu item do I start with
+      * menutype
+      *    NORMALMENU or RADIOMENU
+      *
+      * Return Value:
+      *    Returns a pointer to the final item chosen, or NULL if nothing chosen.
+      */
+{
+    pt_menuitem opt, choice;
+    uchar startat, mt;
+    uchar row, col;
+
+    if (cmenu == NULL)
+    return NULL;
+
+startover:
+    // Set the menu height
+    cmenu->menuheight = ms->maxrow - top - 3;
+    if (cmenu->menuheight > ms->maxmenuheight)
+    cmenu->menuheight = ms->maxmenuheight;
+    if (menutype == NORMALMENU)
+    opt = getmenuoption(cmenu, top, left, startopt, false);
+    else            // menutype == RADIOMENU
+    opt = getmenuoption(cmenu, top, left, startopt, true);
+
+    if (opt == NULL) {
+    // User hit Esc
+    cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+    return NULL;
+    }
+    // Are we done with the menu system?
+    if ((opt->action != OPT_SUBMENU) && (opt->action != OPT_RADIOMENU)) {
+    cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+    return opt;     // parent cleanup other menus
+    }
+    // Either radiomenu or submenu
+    // Do we have a valid menu number? The next hack uses the fact that
+    // itemdata.submenunum = itemdata.radiomenunum (since enum data type)
+    if (opt->itemdata.submenunum >= ms->nummenus)   // This is Bad....
+    {
+    gotoxy(12, 12); // Middle of screen
+    csprint("ERROR: Invalid submenu requested.", 0x07);
+    cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+    return NULL;        // Pretend user hit esc
+    }
+    // Call recursively for submenu
+    // Position the submenu below the current item,
+    // covering half the current window (horizontally)
+    row = ms->menus[(unsigned int)opt->itemdata.submenunum]->row;
+    col = ms->menus[(unsigned int)opt->itemdata.submenunum]->col;
+    if (row == 0xFF)
+    row = top + opt->index + 2;
+    if (col == 0xFF)
+    col = left + 3 + (cmenu->menuwidth >> 1);
+    mt = (opt->action == OPT_SUBMENU ? NORMALMENU : RADIOMENU);
+    startat = 0;
+    if ((opt->action == OPT_RADIOMENU) && (opt->data != NULL))
+    startat = ((t_menuitem *) opt->data)->index;
+
+    choice = runmenusystem(row, col,
+               ms->menus[(unsigned int)opt->itemdata.submenunum],
+               startat, mt);
+    if (opt->action == OPT_RADIOMENU) {
+    if (choice != NULL)
+        opt->data = (void *)choice; // store choice in data field
+    if (opt->handler != NULL)
+        opt->handler(ms, opt);
+    choice = NULL;      // Pretend user hit esc
+    }
+    if (choice == NULL)     // User hit Esc in submenu
+    {
+    // Startover
+    startopt = opt->index;
+    goto startover;
+    } else {
+    cleanupmenu(cmenu, top, left, calc_visible(cmenu, 0));
+    return choice;
+    }
+}
+
+// Finds the indexof the menu with given name
+uchar find_menu_num(const char *name)
+{
+    int i;
+    pt_menu m;
+
+    if (name == NULL)
+    return (uchar) (-1);
+    for (i = 0; i < ms->nummenus; i++) {
+    m = ms->menus[i];
+    if ((m->name) && (strcmp(m->name, name) == 0))
+        return i;
+    }
+    return (uchar) (-1);
+}
+
+// Run through all items and if they are submenus
+// with a non-trivial "action" and trivial submenunum
+// replace submenunum with the menu with name "action"
+void fix_submenus(void)
+{
+    int i, j;
+    pt_menu m;
+    pt_menuitem mi;
+
+    i = 0;
+    for (i = 0; i < ms->nummenus; i++) {
+    m = ms->menus[i];
+    for (j = 0; j < m->numitems; j++) {
+        mi = m->items[j];
+        // if item is a submenu and has non-empty non-trivial data string
+        if (mi->data && strlen(mi->data) > 0 &&
+        ((mi->action == OPT_SUBMENU)
+         || (mi->action == OPT_RADIOMENU))) {
+        mi->itemdata.submenunum = find_menu_num(mi->data);
+        }
+    }
+    }
+}
+
+/* User Callable functions */
+
+pt_menuitem showmenus(uchar startmenu)
+{
+    pt_menuitem rv;
+
+    fix_submenus();     // Fix submenu numbers incase nick names were used
+
+    /* Turn autowrap off, to avoid scrolling the menu */
+    printf(CSI "?7l");
+
+    // Setup screen for menusystem
+    reset_ui();
+
+    // Go, main menu cannot be a radio menu
+    rv = runmenusystem(ms->minrow + MENUROW, ms->mincol + MENUCOL,
+               ms->menus[(unsigned int)startmenu], 0, NORMALMENU);
+
+    // Hide the garbage we left on the screen
+    cls();
+    gotoxy(ms->minrow, ms->mincol);
+    cursoron();
+
+    // Return user choice
+    return rv;
+}
+
+pt_menusystem init_menusystem(const char *title)
+{
+    int i;
+
+    ms = NULL;
+    ms = (pt_menusystem) malloc(sizeof(t_menusystem));
+    if (ms == NULL)
+    return NULL;
+    ms->nummenus = 0;
+    // Initialise all menu pointers
+    for (i = 0; i < MAXMENUS; i++)
+    ms->menus[i] = NULL;
+
+    ms->title = (char *)malloc(TITLELEN + 1);
+    if (title == NULL)
+    strcpy(ms->title, TITLESTR);    // Copy string
+    else
+    strcpy(ms->title, title);
+
+    // Timeout settings
+    ms->tm_stepsize = TIMEOUTSTEPSIZE;
+    ms->tm_numsteps = TIMEOUTNUMSTEPS;
+
+    ms->normalattr[NOHLITE] = NORMALATTR;
+    ms->normalattr[HLITE] = NORMALHLITE;
+
+    ms->reverseattr[NOHLITE] = REVERSEATTR;
+    ms->reverseattr[HLITE] = REVERSEHLITE;
+
+    ms->inactattr[NOHLITE] = INACTATTR;
+    ms->inactattr[HLITE] = INACTHLITE;
+
+    ms->revinactattr[NOHLITE] = REVINACTATTR;
+    ms->revinactattr[HLITE] = REVINACTHLITE;
+
+    ms->statusattr[NOHLITE] = STATUSATTR;
+    ms->statusattr[HLITE] = STATUSHLITE;
+
+    ms->statline = STATLINE;
+    ms->tfillchar = TFILLCHAR;
+    ms->titleattr = TITLEATTR;
+
+    ms->fillchar = FILLCHAR;
+    ms->fillattr = FILLATTR;
+    ms->spacechar = SPACECHAR;
+    ms->shadowattr = SHADOWATTR;
+
+    ms->menupage = MENUPAGE;    // Usually no need to change this at all
+
+    // Initialise all handlers
+    ms->handler = NULL;
+    ms->keys_handler = NULL;
+    ms->ontimeout = NULL;   // No timeout handler
+    ms->tm_total_timeout = 0;
+    ms->tm_sofar_timeout = 0;
+    ms->ontotaltimeout = NULL;
+
+    // Setup ACTION_{,IN}VALID
+    ACTION_VALID.valid = 1;
+    ACTION_VALID.refresh = 0;
+    ACTION_INVALID.valid = 0;
+    ACTION_INVALID.refresh = 0;
+
+    // Figure out the size of the screen we are in now.
+    // By default we use the whole screen for our menu
+    if (getscreensize(1, &ms->numrows, &ms->numcols)) {
+        /* Unknown screen size? */
+        ms->numcols = 80;
+        ms->numrows = 24;
+    }
+    ms->minrow = ms->mincol = 0;
+    ms->maxcol = ms->numcols - 1;
+    ms->maxrow = ms->numrows - 1;
+
+    // How many entries per menu can we display at a time
+    ms->maxmenuheight = ms->maxrow - ms->minrow - 3;
+    if (ms->maxmenuheight > MAXMENUHEIGHT)
+    ms->maxmenuheight = MAXMENUHEIGHT;
+
+    console_ansi_raw();
+
+    return ms;
+}
+
+void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal,
+             uchar inactiveselected)
+{
+    if (normal != 0xFF)
+    ms->normalattr[0] = normal;
+    if (selected != 0xFF)
+    ms->reverseattr[0] = selected;
+    if (inactivenormal != 0xFF)
+    ms->inactattr[0] = inactivenormal;
+    if (inactiveselected != 0xFF)
+    ms->revinactattr[0] = inactiveselected;
+}
+
+void set_normal_hlite(uchar normal, uchar selected, uchar inactivenormal,
+              uchar inactiveselected)
+{
+    if (normal != 0xFF)
+    ms->normalattr[1] = normal;
+    if (selected != 0xFF)
+    ms->reverseattr[1] = selected;
+    if (inactivenormal != 0xFF)
+    ms->inactattr[1] = inactivenormal;
+    if (inactiveselected != 0xFF)
+    ms->revinactattr[1] = inactiveselected;
+}
+
+void set_status_info(uchar statusattr, uchar statushlite, uchar statline)
+{
+    if (statusattr != 0xFF)
+    ms->statusattr[NOHLITE] = statusattr;
+    if (statushlite != 0xFF)
+    ms->statusattr[HLITE] = statushlite;
+    // statline is relative to minrow
+    if (statline >= ms->numrows)
+    statline = ms->numrows - 1;
+    ms->statline = statline;    // relative to ms->minrow, 0 based
+}
+
+void set_title_info(uchar tfillchar, uchar titleattr)
+{
+    if (tfillchar != 0xFF)
+    ms->tfillchar = tfillchar;
+    if (titleattr != 0xFF)
+    ms->titleattr = titleattr;
+}
+
+void set_misc_info(uchar fillchar, uchar fillattr, uchar spacechar,
+           uchar shadowattr)
+{
+    if (fillchar != 0xFF)
+    ms->fillchar = fillchar;
+    if (fillattr != 0xFF)
+    ms->fillattr = fillattr;
+    if (spacechar != 0xFF)
+    ms->spacechar = spacechar;
+    if (shadowattr != 0xFF)
+    ms->shadowattr = shadowattr;
+}
+
+void set_menu_options(uchar maxmenuheight)
+{
+    if (maxmenuheight != 0xFF)
+    ms->maxmenuheight = maxmenuheight;
+}
+
+// Set the window which menusystem should use
+void set_window_size(uchar top, uchar left, uchar bot, uchar right)
+{
+    int nr, nc;
+
+    if ((top > bot) || (left > right))
+    return;         // Sorry no change will happen here
+
+    if (getscreensize(1, &nr, &nc)) {
+        /* Unknown screen size? */
+        nr = 80;
+        nc = 24;
+    }
+    if (bot >= nr)
+    bot = nr - 1;
+    if (right >= nc)
+    right = nc - 1;
+    ms->minrow = top;
+    ms->mincol = left;
+    ms->maxrow = bot;
+    ms->maxcol = right;
+    ms->numcols = right - left + 1;
+    ms->numrows = bot - top + 1;
+    if (ms->statline >= ms->numrows)
+    ms->statline = ms->numrows - 1; // Clip statline if need be
+}
+
+void reg_handler(t_handler htype, void *handler)
+{
+    // If bad value set to default screen handler
+    switch (htype) {
+    case HDLR_KEYS:
+    ms->keys_handler = (t_keys_handler) handler;
+    break;
+    default:
+    ms->handler = (t_menusystem_handler) handler;
+    break;
+    }
+}
+
+void unreg_handler(t_handler htype)
+{
+    switch (htype) {
+    case HDLR_KEYS:
+    ms->keys_handler = NULL;
+    break;
+    default:
+    ms->handler = NULL;
+    break;
+    }
+}
+
+void reg_ontimeout(t_timeout_handler handler, unsigned int numsteps,
+           unsigned int stepsize)
+{
+    ms->ontimeout = handler;
+    if (numsteps != 0)
+    ms->tm_numsteps = numsteps;
+    if (stepsize != 0)
+    ms->tm_stepsize = stepsize;
+}
+
+void unreg_ontimeout(void)
+{
+    ms->ontimeout = NULL;
+}
+
+void reg_ontotaltimeout(t_timeout_handler handler,
+            unsigned long numcentiseconds)
+{
+    if (numcentiseconds != 0) {
+    ms->ontotaltimeout = handler;
+    ms->tm_total_timeout = numcentiseconds * 10;    // to convert to milliseconds
+    ms->tm_sofar_timeout = 0;
+    }
+}
+
+void unreg_ontotaltimeout(void)
+{
+    ms->ontotaltimeout = NULL;
+}
+
+int next_visible(pt_menu menu, int index)
+{
+    int ans;
+    if (index < 0)
+    ans = 0;
+    else if (index >= menu->numitems)
+    ans = menu->numitems - 1;
+    else
+    ans = index;
+    while ((ans < menu->numitems - 1) &&
+       ((menu->items[ans]->action == OPT_INVISIBLE) ||
+        (menu->items[ans]->action == OPT_SEP)))
+    ans++;
+    return ans;
+}
+
+int prev_visible(pt_menu menu, int index)   // Return index of prev visible
+{
+    int ans;
+    if (index < 0)
+    ans = 0;
+    else if (index >= menu->numitems)
+    ans = menu->numitems - 1;
+    else
+    ans = index;
+    while ((ans > 0) &&
+       ((menu->items[ans]->action == OPT_INVISIBLE) ||
+        (menu->items[ans]->action == OPT_SEP)))
+    ans--;
+    return ans;
+}
+
+int next_visible_sep(pt_menu menu, int index)
+{
+    int ans;
+    if (index < 0)
+    ans = 0;
+    else if (index >= menu->numitems)
+    ans = menu->numitems - 1;
+    else
+    ans = index;
+    while ((ans < menu->numitems - 1) &&
+       (menu->items[ans]->action == OPT_INVISIBLE))
+    ans++;
+    return ans;
+}
+
+int prev_visible_sep(pt_menu menu, int index)   // Return index of prev visible
+{
+    int ans;
+    if (index < 0)
+    ans = 0;
+    else if (index >= menu->numitems)
+    ans = menu->numitems - 1;
+    else
+    ans = index;
+    while ((ans > 0) && (menu->items[ans]->action == OPT_INVISIBLE))
+    ans--;
+    return ans;
+}
+
+int calc_visible(pt_menu menu, int first)
+{
+    int ans, i;
+
+    if (menu == NULL)
+    return 0;
+    ans = 0;
+    for (i = first; i < menu->numitems; i++)
+    if (menu->items[i]->action != OPT_INVISIBLE)
+        ans++;
+    return ans;
+}
+
+// is curr visible if first entry is first?
+int isvisible(pt_menu menu, int first, int curr)
+{
+    if (curr < first)
+    return 0;
+    return (calc_visible(menu, first) - calc_visible(menu, curr) <
+        menu->menuheight);
+}
+
+// Calculate the first entry to be displayed
+// so that curr is visible and make curr as late as possible
+int calc_first_late(pt_menu menu, int curr)
+{
+    int ans, i, nv;
+
+    nv = calc_visible(menu, 0);
+    if (nv <= menu->menuheight)
+    return 0;
+    // Start with curr and go back menu->menuheight times
+    ans = curr + 1;
+    for (i = 0; i < menu->menuheight; i++)
+    ans = prev_visible_sep(menu, ans - 1);
+    return ans;
+}
+
+// Calculate the first entry to be displayed
+// so that curr is visible and make curr as early as possible
+int calc_first_early(pt_menu menu, int curr)
+{
+    int ans, i, nv;
+
+    nv = calc_visible(menu, 0);
+    if (nv <= menu->menuheight)
+    return 0;
+    // Start with curr and go back till >= menu->menuheight
+    // items are visible
+    nv = calc_visible(menu, curr);  // Already nv of them are visible
+    ans = curr;
+    for (i = 0; i < menu->menuheight - nv; i++)
+    ans = prev_visible_sep(menu, ans - 1);
+    return ans;
+}
+
+// Create a new menu and return its position
+uchar add_menu(const char *title, int maxmenusize)
+{
+    int num, i;
+    pt_menu m;
+
+    num = ms->nummenus;
+    if (num >= MAXMENUS)
+    return -1;
+    m = NULL;
+    m = (pt_menu) malloc(sizeof(t_menu));
+    if (m == NULL)
+    return -1;
+    ms->menus[num] = m;
+    m->numitems = 0;
+    m->name = NULL;
+    m->row = 0xFF;
+    m->col = 0xFF;
+    if (maxmenusize < 1)
+    m->maxmenusize = MAXMENUSIZE;
+    else
+    m->maxmenusize = maxmenusize;
+    m->items = (pt_menuitem *) malloc(sizeof(pt_menuitem) * (m->maxmenusize));
+    for (i = 0; i < m->maxmenusize; i++)
+    m->items[i] = NULL;
+
+    m->title = (char *)malloc(MENULEN + 1);
+    if (title) {
+    if (strlen(title) > MENULEN - 2)
+        strcpy(m->title, TITLELONG);
+    else
+        strcpy(m->title, title);
+    } else
+    strcpy(m->title, EMPTYSTR);
+    m->menuwidth = strlen(m->title);
+    ms->nummenus++;
+    return ms->nummenus - 1;
+}
+
+void set_menu_name(const char *name)    // Set the "name" of this menu
+{
+    pt_menu m;
+
+    m = ms->menus[ms->nummenus - 1];
+    if (m->name)        // Free up previous name
+    {
+    free(m->name);
+    m->name = NULL;
+    }
+
+    if (name) {
+    m->name = (char *)malloc(strlen(name) + 1);
+    strcpy(m->name, name);
+    }
+}
+
+// Create a new named menu and return its position
+uchar add_named_menu(const char *name, const char *title, int maxmenusize)
+{
+    add_menu(title, maxmenusize);
+    set_menu_name(name);
+    return ms->nummenus - 1;
+}
+
+void set_menu_pos(uchar row, uchar col) // Set the position of this menu.
+{
+    pt_menu m;
+
+    m = ms->menus[ms->nummenus - 1];
+    m->row = row;
+    m->col = col;
+}
+
+pt_menuitem add_sep(void)       // Add a separator to current menu
+{
+    pt_menuitem mi;
+    pt_menu m;
+
+    m = (ms->menus[ms->nummenus - 1]);
+    mi = NULL;
+    mi = (pt_menuitem) malloc(sizeof(t_menuitem));
+    if (mi == NULL)
+    return NULL;
+    m->items[(unsigned int)m->numitems] = mi;
+    mi->handler = NULL;     // No handler
+    mi->item = mi->status = mi->data = NULL;
+    mi->action = OPT_SEP;
+    mi->index = m->numitems++;
+    mi->parindex = ms->nummenus - 1;
+    mi->shortcut = 0;
+    mi->helpid = 0;
+    return mi;
+}
+
+// Add item to the "current" menu
+pt_menuitem add_item(const char *item, const char *status, t_action action,
+             const char *data, uchar itemdata)
+{
+    pt_menuitem mi;
+    pt_menu m;
+    const char *str;
+    uchar inhlite = 0;      // Are we inside hlite area
+
+    m = (ms->menus[ms->nummenus - 1]);
+    mi = NULL;
+    mi = (pt_menuitem) malloc(sizeof(t_menuitem));
+    if (mi == NULL)
+    return NULL;
+    m->items[(unsigned int)m->numitems] = mi;
+    mi->handler = NULL;     // No handler
+
+    // Allocate space to store stuff
+    mi->item = (char *)malloc(MENULEN + 1);
+    mi->status = (char *)malloc(STATLEN + 1);
+    mi->data = (char *)malloc(ACTIONLEN + 1);
+
+    if (item) {
+    if (strlen(item) > MENULEN) {
+        strcpy(mi->item, ITEMLONG);
+    } else {
+        strcpy(mi->item, item);
+    }
+    if (strlen(mi->item) > m->menuwidth)
+        m->menuwidth = strlen(mi->item);
+    } else
+    strcpy(mi->item, EMPTYSTR);
+
+    if (status) {
+    if (strlen(status) > STATLEN) {
+        strcpy(mi->status, STATUSLONG);
+    } else {
+        strcpy(mi->status, status);
+    }
+    } else
+    strcpy(mi->status, EMPTYSTR);
+
+    mi->action = action;
+    str = mi->item;
+    mi->shortcut = 0;
+    mi->helpid = 0xFFFF;
+    inhlite = 0;        // We have not yet seen an ENABLEHLITE char
+    // Find the first char in [A-Za-z0-9] after ENABLEHLITE and not arg to control char
+    while (*str) {
+    if (*str == ENABLEHLITE) {
+        inhlite = 1;
+    }
+    if (*str == DISABLEHLITE) {
+        inhlite = 0;
+    }
+    if ((inhlite == 1) &&
+        (((*str >= 'A') && (*str <= 'Z')) ||
+         ((*str >= 'a') && (*str <= 'z')) ||
+         ((*str >= '0') && (*str <= '9')))) {
+        mi->shortcut = *str;
+        break;
+    }
+    ++str;
+    }
+    if ((mi->shortcut >= 'A') && (mi->shortcut <= 'Z')) // Make lower case
+    mi->shortcut = mi->shortcut - 'A' + 'a';
+
+    if (data) {
+    if (strlen(data) > ACTIONLEN) {
+        strcpy(mi->data, ACTIONLONG);
+    } else {
+        strcpy(mi->data, data);
+    }
+    } else
+    strcpy(mi->data, EMPTYSTR);
+
+    switch (action) {
+    case OPT_SUBMENU:
+    mi->itemdata.submenunum = itemdata;
+    break;
+    case OPT_CHECKBOX:
+    mi->itemdata.checked = itemdata;
+    break;
+    case OPT_RADIOMENU:
+    mi->itemdata.radiomenunum = itemdata;
+    if (mi->data)
+        free(mi->data);
+    mi->data = NULL;    // No selection made
+    break;
+    default:            // to keep the compiler happy
+    break;
+    }
+    mi->index = m->numitems++;
+    mi->parindex = ms->nummenus - 1;
+    return mi;
+}
+
+// Set the shortcut key for the current item
+void set_item_options(uchar shortcut, int helpid)
+{
+    pt_menuitem mi;
+    pt_menu m;
+
+    m = (ms->menus[ms->nummenus - 1]);
+    if (m->numitems <= 0)
+    return;
+    mi = m->items[(unsigned int)m->numitems - 1];
+
+    if (shortcut != 0xFF)
+    mi->shortcut = shortcut;
+    if (helpid != 0xFFFF)
+    mi->helpid = helpid;
+}
+
+// Free internal datasutructures
+void close_menusystem(void)
+{
+}
+
+// append_line_helper(pt_menu menu,char *line)
+void append_line_helper(int menunum, char *line)
+{
+    pt_menu menu;
+    pt_menuitem mi, ri;
+    char *app;
+    int ctr;
+
+    menu = ms->menus[menunum];
+    for (ctr = 0; ctr < (int)menu->numitems; ctr++) {
+    mi = menu->items[ctr];
+    app = NULL;     //What to append
+    switch (mi->action) {
+    case OPT_CHECKBOX:
+        if (mi->itemdata.checked)
+        app = mi->data;
+        break;
+    case OPT_RADIOMENU:
+        if (mi->data) { // Some selection has been made
+        ri = (pt_menuitem) (mi->data);
+        app = ri->data;
+        }
+        break;
+    case OPT_SUBMENU:
+        append_line_helper(mi->itemdata.submenunum, line);
+        break;
+    default:
+        break;
+    }
+    if (app) {
+        strcat(line, " ");
+        strcat(line, app);
+    }
+    }
+}
+
+// Generate string based on state of checkboxes and radioitem in given menu
+// Assume line points to large enough buffer
+void gen_append_line(const char *menu_name, char *line)
+{
+    int menunum;
+
+    menunum = find_menu_num(menu_name);
+    if (menunum < 0)
+    return;         // No such menu
+    append_line_helper(menunum, line);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,159 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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,
+ *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "passwords.h"
+#include "des.h"
+#include "string.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "tui.h"
+
+#define MAX_LINE 512
+// Max line length in a pwdfile
+p_pwdentry userdb[MAX_USERS];	// Array of pointers
+int numusers;			// Actual number of users
+
+// returns true or false, i.e. 1 or 0
+char authenticate_user(const char *username, const char *pwd)
+{
+    char salt[12];
+    int i;
+
+    for (i = 0; i < numusers; i++) {
+	if (userdb[i] == NULL)
+	    continue;
+	if (strcmp(username, userdb[i]->username) == 0) {
+	    strcpy(salt, userdb[i]->pwdhash);
+	    salt[2] = '\0';
+	    if (strcmp(userdb[i]->pwdhash, crypt(pwd, salt)) == 0)
+		return 1;
+	}
+    }
+    return 0;
+}
+
+// Does user USERNAME  have permission PERM
+char isallowed(const char *username, const char *perm)
+{
+    int i;
+    char *dperm;
+    char *tmp;
+
+    // If no users, then everybody is allowed to do everything
+    if (numusers == 0)
+	return 1;
+    if (strcmp(username, GUEST_USER) == 0)
+	return 0;
+    dperm = (char *)malloc(strlen(perm) + 3);
+    strcpy(dperm + 1, perm);
+    dperm[0] = ':';
+    dperm[strlen(perm) + 1] = ':';
+    dperm[strlen(perm) + 2] = 0;
+    // Now dperm = ":perm:"
+    for (i = 0; i < numusers; i++) {
+	if (strcmp(userdb[i]->username, username) == 0)	// Found the user
+	{
+	    if (userdb[i]->perms == NULL)
+		return 0;	// No permission
+	    tmp = strstr(userdb[i]->perms, dperm);	// Search for permission
+	    free(dperm);	// Release memory
+	    if (tmp == NULL)
+		return 0;
+	    else
+		return 1;
+	}
+    }
+    // User not found return 0
+    free(dperm);
+    return 0;
+}
+
+// Initialise the list of of user passwords permissions from file
+void init_passwords(const char *filename)
+{
+    int i;
+    char line[MAX_LINE], *p, *user, *pwdhash, *perms;
+    FILE *f;
+
+    for (i = 0; i < MAX_USERS; i++)
+	userdb[i] = NULL;
+    numusers = 0;
+
+    if (!filename)
+	return;			// No filename specified
+
+    f = fopen(filename, "r");
+    if (!f)
+	return;			// File does not exist
+
+    // Process each line
+    while (fgets(line, sizeof line, f)) {
+	// Replace EOLN with \0
+	p = strchr(line, '\r');
+	if (p)
+	    *p = '\0';
+	p = strchr(line, '\n');
+	if (p)
+	    *p = '\0';
+
+	// If comment line or empty ignore line
+	p = line;
+	while (*p == ' ')
+	    p++;		// skip initial spaces
+	if ((*p == '#') || (*p == '\0'))
+	    continue;		// Skip comment lines
+
+	user = p;		// This is where username starts
+	p = strchr(user, ':');
+	if (p == NULL)
+	    continue;		// Malformed line skip
+	*p = '\0';
+	pwdhash = p + 1;
+	if (*pwdhash == 0)
+	    continue;		// Malformed line (no password specified)
+	p = strchr(pwdhash, ':');
+	if (p == NULL) {	// No perms specified
+	    perms = NULL;
+	} else {
+	    *p = '\0';
+	    perms = p + 1;
+	    if (*perms == 0)
+		perms = NULL;
+	}
+	// At this point we have user,pwdhash and perms setup
+	userdb[numusers] = (p_pwdentry) malloc(sizeof(pwdentry));
+	strcpy(userdb[numusers]->username, user);
+	strcpy(userdb[numusers]->pwdhash, pwdhash);
+	if (perms == NULL)
+	    userdb[numusers]->perms = NULL;
+	else {
+	    userdb[numusers]->perms = (char *)malloc(strlen(perms) + 3);
+	    (userdb[numusers]->perms)[0] = ':';
+	    strcpy(userdb[numusers]->perms + 1, perms);
+	    (userdb[numusers]->perms)[strlen(perms) + 1] = ':';
+	    (userdb[numusers]->perms)[strlen(perms) + 2] = 0;
+	    // Now perms field points to ":perms:"
+	}
+	numusers++;
+    }
+    fclose(f);
+}
+
+void close_passwords(void)
+{
+    int i;
+
+    for (i = 0; i < numusers; i++)
+	if (userdb[i] != NULL)
+	    free(userdb[i]);
+    numusers = 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/passwords.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,27 @@
+#ifndef _PASSWORDS_H_
+#define _PASSWORDS_H_
+
+char authenticate_user(const char *username, const char *pwd);
+
+char isallowed(const char *username, const char *perm);
+
+// Initialise the list of of user passwords permissions from file
+void init_passwords(const char *filename);
+// Free all space used for internal data structures
+void close_passwords(void);
+
+#define MAX_USERS 128		// Maximum number of users
+#define USERNAME_LENGTH 12	// Max length of user name
+#define PWDHASH_LENGTH  40	// Max lenght of pwd hash
+
+typedef struct {
+    char username[USERNAME_LENGTH + 1];
+    char pwdhash[PWDHASH_LENGTH + 1];
+    char *perms;		// pointer to string containing ":" delimited permissions
+} pwdentry;
+
+typedef pwdentry *p_pwdentry;
+
+#define GUEST_USER "guest"
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,65 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <graphics.h>
+#include "syslnx.h"
+#include <syslinux/config.h>
+#include <syslinux/video.h>
+
+com32sys_t inreg, outreg;	// Global registers for this module
+
+void runsyslinuxcmd(const char *cmd)
+{
+    char *bounce;
+
+    bounce = lmalloc(strlen(cmd) + 1);
+    if (!bounce)
+	return;
+
+    strcpy(bounce, cmd);
+    load_kernel(bounce);
+}
+
+void gototxtmode(void)
+{
+    syslinux_force_text_mode();
+}
+
+void syslinux_idle(void)
+{
+    __idle();
+}
+
+unsigned int getversion(char *deriv, unsigned int *numfun)
+{
+    if (deriv)
+	*deriv = __syslinux_version.filesystem;
+    if (numfun)
+	*numfun = __syslinux_version.max_api;
+    return __syslinux_version.version;
+}
+
+char issyslinux(void)
+{
+    return !!getversion(NULL, NULL);
+}
+
+void runsyslinuximage(const char *cmd, long ipappend)
+{
+    (void)ipappend;		// XXX: Unused?!
+
+    getversion(NULL, NULL);
+    runsyslinuxcmd(cmd);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/syslnx.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,64 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 __SYSLNX_H__
+#define __SYSLNX_H__
+
+#include <com32.h>
+
+//Macros which help user not have to remember the structure of register
+// Data structure
+
+#define REG_AH(x) ((x).eax.b[1])
+#define REG_AL(x) ((x).eax.b[0])
+#define REG_AX(x) ((x).eax.w[0])
+#define REG_EAX(x) ((x).eax.l)
+
+#define REG_BH(x) ((x).ebx.b[1])
+#define REG_BL(x) ((x).ebx.b[0])
+#define REG_BX(x) ((x).ebx.w[0])
+#define REG_EBX(x) ((x).ebx.l)
+
+#define REG_CH(x) ((x).ecx.b[1])
+#define REG_CL(x) ((x).ecx.b[0])
+#define REG_CX(x) ((x).ecx.w[0])
+#define REG_ECX(x) ((x).ecx.l)
+
+#define REG_DH(x) ((x).edx.b[1])
+#define REG_DL(x) ((x).edx.b[0])
+#define REG_DX(x) ((x).edx.w[0])
+#define REG_EDX(x) ((x).edx.l)
+
+#define REG_DS(x) ((x).ds)
+#define REG_ES(x) ((x).es)
+#define REG_FS(x) ((x).fs)
+#define REG_GS(x) ((x).gs)
+
+#define REG_SI(x) ((x).esi.w[0])
+#define REG_ESI(x) ((x).esi.l)
+
+#define REG_DI(x) ((x).edi.w[0])
+#define REG_EDI(x) ((x).edi.l)
+
+char issyslinux(void);		/* Check if syslinux is running */
+
+void runsyslinuxcmd(const char *cmd);	/* Run specified command */
+
+void gototxtmode(void);		/* Change mode to text mode */
+
+void syslinux_idle(void);	/* Call syslinux idle loop */
+
+/* Run command line with ipappend, returns if kernel image not found
+   If syslinux version too old, then defaults to runsyslinuxcmd */
+void runsyslinuximage(const char *cmd, long ipappend);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,258 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2006 Murali Krishnan Ganapathy - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "tui.h"
+#include <string.h>
+#include <com32.h>
+#include <stdlib.h>
+#include "com32io.h"
+
+com32sys_t inreg, outreg;	// Global register sets for use
+
+char bkspstr[] = " \b$";
+char eolstr[] = "\n$";
+
+// Reads a line of input from stdin. Replace CR with NUL byte
+// password <> 0 implies not echoed on screen
+// showoldvalue <> 0 implies currentvalue displayed first
+// If showoldvalue <> 0 then caller responsibility to ensure that
+// str is NULL terminated.
+void getuserinput(char *stra, unsigned int size, unsigned int password,
+		  unsigned int showoldvalue)
+{
+    unsigned int c;
+    char *p, *q;		// p = current char of string, q = tmp
+    char *last;			// The current last char of string
+    char *str;			// pointer to string which is going to be allocated
+    char row, col;
+    char start, end;		// Cursor shape
+    char fudge;			// How many chars should be removed from output
+    char insmode;		// Are we in insert or overwrite
+
+    getpos(&row, &col, 0);	// Get current position
+    getcursorshape(&start, &end);
+    insmode = 1;
+
+    str = (char *)malloc(size + 1);	// Allocate memory to store user input
+    memset(str, 0, size + 1);	// Zero it out
+    if (password != 0)
+	showoldvalue = 0;	// Password's never displayed
+
+    if (showoldvalue != 0)
+	strcpy(str, stra);	// If show old value copy current value
+
+    last = str;
+    while (*last) {
+	last++;
+    }				// Find the terminating null byte
+    p = str + strlen(str);
+
+    if (insmode == 0)
+	setcursorshape(1, 7);	// Block cursor
+    else
+	setcursorshape(6, 7);	// Normal cursor
+
+    // Invariants: p is the current char
+    // col is the corresponding column on the screen
+    if (password == 0)		// Not a password, print initial value
+    {
+	gotoxy(row, col);
+	csprint(str, GETSTRATTR);
+    }
+    while (1) {			// Do forever
+	c = get_key(stdin, 0);
+	if (c == KEY_ENTER)
+	    break;		// User hit Enter getout of loop
+	if (c == KEY_ESC)	// User hit escape getout and nullify string
+	{
+	    *str = 0;
+	    break;
+	}
+	fudge = 0;
+	// if scan code is regognized do something
+	// else if char code is recognized do something
+	// else ignore
+	switch (c) {
+	case KEY_HOME:
+	    p = str;
+	    break;
+	case KEY_END:
+	    p = last;
+	    break;
+	case KEY_LEFT:
+	    if (p > str)
+		p--;
+	    break;
+	case KEY_CTRL(KEY_LEFT):
+	    if (p == str)
+		break;
+	    if (*p == ' ')
+		while ((p > str) && (*p == ' '))
+		    p--;
+	    else {
+		if (*(p - 1) == ' ') {
+		    p--;
+		    while ((p > str) && (*p == ' '))
+			p--;
+		}
+	    }
+	    while ((p > str) && ((*p == ' ') || (*(p - 1) != ' ')))
+		p--;
+	    break;
+	case KEY_RIGHT:
+	    if (p < last)
+		p++;
+	    break;
+	case KEY_CTRL(KEY_RIGHT):
+	    if (*p == 0)
+		break;		// At end of string
+	    if (*p != ' ')
+		while ((*p != 0) && (*p != ' '))
+		    p++;
+	    while ((*p != 0) && ((*p == ' ') && (*(p + 1) != ' ')))
+		p++;
+	    if (*p == ' ')
+		p++;
+	    break;
+	case KEY_DEL:
+	case KEY_DELETE:
+	    q = p;
+	    while (*(q + 1)) {
+		*q = *(q + 1);
+		q++;
+	    }
+	    if (last > str)
+		last--;
+	    fudge = 1;
+	    break;
+	case KEY_INSERT:
+	    insmode = 1 - insmode;	// Switch mode
+	    if (insmode == 0)
+		setcursorshape(1, 7);	// Block cursor
+	    else
+		setcursorshape(6, 7);	// Normal cursor
+	    break;
+	case KEY_BACKSPACE:		// Move over by one
+		q = p;
+		while (q <= last) {
+		    *(q - 1) = *q;
+		    q++;
+		}
+		if (last > str)
+		    last--;
+		if (p > str)
+		    p--;
+		fudge = 1;
+		break;
+	case KEY_CTRL('U'):	/* Ctrl-U: kill input */
+		fudge = last - str;
+		while (p > str)
+		    *p-- = 0;
+		p = str;
+		*p = 0;
+		last = str;
+		break;
+	default:		// Handle insert and overwrite mode
+		if ((c >= ' ') && (c < 128) &&
+		    ((unsigned int)(p - str) < size - 1)) {
+		    if (insmode == 0) {	// Overwrite mode
+			if (p == last)
+			    last++;
+			*last = 0;
+			*p++ = c;
+		    } else {	// Insert mode
+			if (p == last) {	// last char
+			    last++;
+			    *last = 0;
+			    *p++ = c;
+			} else {	// Non-last char
+			    q = last++;
+			    while (q >= p) {
+				*q = *(q - 1);
+				q--;
+			    }
+			    *p++ = c;
+			}
+		    }
+		} else
+		    beep();
+	    break;
+	}
+	// Now the string has been modified, print it
+	if (password == 0) {
+	    gotoxy(row, col);
+	    csprint(str, GETSTRATTR);
+	    if (fudge > 0)
+		cprint(' ', GETSTRATTR, fudge);
+	    gotoxy(row, col + (p - str));
+	}
+    } /* while */
+    *p = '\0';
+    if (password == 0)
+	csprint("\r\n", GETSTRATTR);
+    setcursorshape(start, end);	// Block cursor
+    // If user hit ESCAPE so return without any changes
+    if (c != KEY_ESC)
+	strcpy(stra, str);
+    free(str);
+}
+
+//////////////////////////////Box Stuff
+
+// Draw box and lines
+void drawbox(const char top, const char left, const char bot,
+	     const char right, const char attr)
+{
+    unsigned char x;
+	putchar(SO);
+    // Top border
+    gotoxy(top, left);
+    putch(TOP_LEFT_CORNER_BORDER, attr);
+    cprint(TOP_BORDER, attr, right - left - 1);
+    putch(TOP_RIGHT_CORNER_BORDER, attr);
+    // Bottom border
+    gotoxy(bot, left);
+    putch(BOTTOM_LEFT_CORNER_BORDER, attr);
+    cprint(BOTTOM_BORDER, attr, right - left - 1);
+    putch(BOTTOM_RIGHT_CORNER_BORDER, attr);
+    // Left & right borders
+    for (x = top + 1; x < bot; x++) {
+	gotoxy(x, left);
+	putch(LEFT_BORDER, attr);
+	gotoxy(x, right);
+	putch(RIGHT_BORDER, attr);
+    }
+	putchar(SI);
+}
+
+void drawhorizline(const char top, const char left, const char right,
+		   const char attr, char dumb)
+{
+    unsigned char start, end;
+    if (dumb == 0) {
+	start = left + 1;
+	end = right - 1;
+    } else {
+	start = left;
+	end = right;
+    }
+    gotoxy(top, start);
+	putchar(SO);
+    cprint(MIDDLE_BORDER, attr, end - start + 1);
+    if (dumb == 0) {
+	gotoxy(top, left);
+	putch(MIDDLE_BORDER, attr);
+	gotoxy(top, right);
+	putch(MIDDLE_BORDER, attr);
+    }
+	putchar(SI);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/libmenu/tui.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 __TUI_H__
+#define __TUI_H__
+
+#include <com32.h>
+#include <getkey.h>
+#include <consoles.h>
+#include "syslnx.h"
+#include "com32io.h"
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define SO '\016'
+#define SI '\017'
+
+#define TOP_LEFT_CORNER_BORDER '\154'
+#define TOP_BORDER '\161'
+#define TOP_RIGHT_CORNER_BORDER '\153'
+#define BOTTOM_LEFT_CORNER_BORDER '\155'
+#define BOTTOM_BORDER '\161'
+#define BOTTOM_RIGHT_CORNER_BORDER '\152'
+#define LEFT_BORDER '\170'
+#define RIGHT_BORDER '\170'
+#define LEFT_MIDDLE_BORDER '\164'
+#define MIDDLE_BORDER '\161'
+#define RIGHT_MIDDLE_BORDER '\165'
+
+#define BELL 0x07
+#define GETSTRATTR 0x07
+
+// Generic user input,
+// password = 0 iff chars echoed on screen
+// showoldvalue <> 0 iff current displayed for editing
+void getuserinput(char *str, unsigned int size,
+		  unsigned int password, unsigned int showoldvalue);
+
+static inline void getstring(char *str, unsigned int size)
+{
+    getuserinput(str, size, 0, 0);
+}
+
+static inline void editstring(char *str, unsigned int size)
+{
+    getuserinput(str, size, 0, 1);
+}
+
+static inline void getpwd(char *str, unsigned int size)
+{
+    getuserinput(str, size, 1, 0);
+}
+
+void drawbox(const char, const char, const char, const char,
+	     const char);
+
+// Draw a horizontal line
+// dumb == 1, means just draw the line
+// dumb == 0 means check the first and last positions and depending on what is
+//    currently on the screen make it a LTRT and/or RTLT appropriately.
+void drawhorizline(const char, const char, const char, const char,
+		   const char dumb);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/menugen.py
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/menugen.py	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/menugen.py	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,307 @@
+#!/usr/bin/env python
+
+import sys, re, getopt
+
+class Menusystem:
+
+   types = {"run"      : "OPT_RUN",
+            "inactive" : "OPT_INACTIVE",
+            "checkbox" : "OPT_CHECKBOX",
+            "radiomenu": "OPT_RADIOMENU",
+            "sep"      : "OPT_SEP",
+            "invisible": "OPT_INVISIBLE",
+            "radioitem": "OPT_RADIOITEM",
+            "exitmenu" : "OPT_EXITMENU",
+            "login"    : "login", # special type
+            "submenu"  : "OPT_SUBMENU"}
+
+   entry_init = { "item" : "",
+                  "info" : "",
+                  "data" : "",
+                  "ipappend" : 0, # flag to send in case of PXELINUX
+                  "helpid" : 65535, # 0xFFFF
+                  "shortcut":"-1",
+                  "state"  : 0, # initial state of checkboxes
+                  "argsmenu": "", # name of menu containing arguments
+                  "perms"  : "", # permission required to execute this entry
+                  "_updated" : None, # has this dictionary been updated
+                  "type" : "run" }
+
+   menu_init = {  "title" : "",
+                  "row" : "0xFF", # let system decide position
+                  "col" : "0xFF",
+                  "_updated" : None,
+                  "name" : "" }
+
+   system_init ={ "videomode" : "0xFF",
+                  "title" : "Menu System",
+                  "top" : "1",
+                  "left" : "1" ,
+                  "bot" : "21",
+                  "right":"79",
+                  "helpdir" : "/isolinux/help",
+                  "pwdfile" : "",
+                  "pwdrow"  : "23",
+                  "editrow" : "23",
+                  "skipcondn"  : "0",
+                  "skipcmd" : ".exit",
+                  "startfile": "",
+                  "onerrorcmd":".repeat",
+                  "exitcmd"  : ".exit",
+                  "exitcmdroot"  : "",
+                  "timeout"  : "600",
+                  "timeoutcmd":".beep",
+                  "totaltimeout" : "0",
+                  "totaltimeoutcmd" : ".wait"
+                 }
+
+   shift_flags = { "alt"  : "ALT_PRESSED",
+                   "ctrl" : "CTRL_PRESSED",
+                   "shift": "SHIFT_PRESSED",
+                   "caps" : "CAPSLOCK_ON",
+                   "num"  : "NUMLOCK_ON",
+                   "ins"  : "INSERT_ON"
+                 }
+
+   reqd_templates = ["item","login","menu","system"]
+
+   def __init__(self,template):
+       self.state = "system"
+       self.code_template_filename = template
+       self.menus = []
+       self.init_entry()
+       self.init_menu()
+       self.init_system()
+       self.vtypes = " OR ".join(list(self.types.keys()))
+       self.vattrs = " OR ".join([x for x in list(self.entry.keys()) if x[0] != "_"])
+       self.mattrs = " OR ".join([x for x in list(self.menu.keys()) if x[0] != "_"])
+
+   def init_entry(self):
+       self.entry = self.entry_init.copy()
+
+   def init_menu(self):
+       self.menu = self.menu_init.copy()
+
+   def init_system(self):
+       self.system = self.system_init.copy()
+
+   def add_menu(self,name):
+       self.add_item()
+       self.init_menu()
+       self.menu["name"] = name
+       self.menu["_updated"] = 1
+       self.menus.append( (self.menu,[]) )
+
+   def add_item(self):
+       if self.menu["_updated"]: # menu details have changed
+          self.menus[-1][0].update(self.menu)
+          self.init_menu()
+       if self.entry["_updated"]:
+          if not self.entry["info"]:
+             self.entry["info"] = self.entry["data"]
+          if not self.menus:
+             print("Error before line %d" % self.lineno)
+             print("REASON: menu must be declared before a menu item is declared")
+             sys.exit(1)
+          self.menus[-1][1].append(self.entry)
+       self.init_entry()
+
+   def set_item(self,name,value):
+       if name not in self.entry:
+          msg = ["Unknown attribute %s in line %d" % (name,self.lineno)]
+          msg.append("REASON: Attribute must be one of %s" % self.vattrs)
+          return "\n".join(msg)
+       if name=="type" and value not in self.types:
+          msg = [ "Unrecognized type %s in line %d" % (value,self.lineno)]
+          msg.append("REASON: Valid types are %s" % self.vtypes)
+          return "\n".join(msg)
+       if name=="shortcut":
+          if (value != "-1") and not re.match("^[A-Za-z0-9]$",value):
+             msg = [ "Invalid shortcut char '%s' in line %d" % (value,self.lineno) ]
+             msg.append("REASON: Valid values are [A-Za-z0-9]")
+             return "\n".join(msg)
+          elif value != "-1": value = "'%s'" % value
+       elif name in ["state","helpid","ipappend"]:
+          try:
+              value = int(value)
+          except:
+              return "Value of %s in line %d must be an integer" % (name,self.lineno)
+       self.entry[name] = value
+       self.entry["_updated"] = 1
+       return ""
+
+   def set_menu(self,name,value):
+       if name not in self.menu:
+          return "Error: Unknown keyword %s" % name
+       self.menu[name] = value
+       self.menu["_updated"] = 1
+       return ""
+
+   def set_system(self,name,value):
+       if name not in self.system:
+          return "Error: Unknown keyword %s" % name
+       if name == "skipcondn":
+          try: # is skipcondn a number?
+             a = int(value)
+          except: # it is a "-" delimited sequence
+             value = value.lower()
+             parts = [ self.shift_flags.get(x.strip(),None) for x in value.split("-") ]
+             self.system["skipcondn"] = " | ".join([_f for _f in parts if _f])
+       else:
+          self.system[name] = value
+
+   def set(self,name,value):
+       # remove quotes if given
+       if (value[0] == value[-1]) and (value[0] in ['"',"'"]): # remove quotes
+          value = value[1:-1]
+       if self.state == "system":
+          err = self.set_system(name,value)
+          if not err: return
+       if self.state == "menu":
+          err = self.set_menu(name,value)
+          # change state to entry it menu returns error
+          if err:
+             err = None
+             self.state = "item"
+       if self.state == "item":
+          err = self.set_item(name,value)
+
+       if not err: return
+
+       # all errors so return item's error message
+       print(err)
+       sys.exit(1)
+
+   def print_entry(self,entry,fd):
+       entry["type"] = self.types[entry["type"]]
+       if entry["type"] == "login": #special type
+          fd.write(self.templates["login"] % entry)
+       else:
+          fd.write(self.templates["item"] % entry)
+
+   def print_menu(self,menu,fd):
+       if menu["name"] == "main": self.foundmain = 1
+       fd.write(self.templates["menu"] % menu)
+       if (menu["row"] != "0xFF") or (menu["col"] != "0xFF"):
+          fd.write('  set_menu_pos(%(row)s,%(col)s);\n' % menu)
+
+
+   def output(self,filename):
+       curr_template = None
+       contents = []
+       self.templates = {}
+       regbeg = re.compile(r"^--(?P<name>[a-z]+) BEGINS?--\n$")
+       regend = re.compile(r"^--[a-z]+ ENDS?--\n$")
+       ifd = open(self.code_template_filename,"r")
+       for line in ifd.readlines():
+           b = regbeg.match(line)
+           e = regend.match(line)
+           if e: # end of template
+              if curr_template:
+                 self.templates[curr_template] = "".join(contents)
+              curr_template = None
+              continue
+           if b:
+              curr_template = b.group("name")
+              contents = []
+              continue
+           if not curr_template: continue # lines between templates are ignored
+           contents.append(line)
+       ifd.close()
+
+       missing = None
+       for x in self.reqd_templates:
+           if x not in self.templates: missing = x
+       if missing:
+           print("Template %s required but not defined in %s" % (missing,self.code_template_filename))
+
+       if filename == "-":
+          fd = sys.stdout
+       else: fd = open(filename,"w")
+       self.foundmain = None
+       fd.write(self.templates["header"])
+       fd.write(self.templates["system"] % self.system)
+       for (menu,items) in self.menus:
+           self.print_menu(menu,fd)
+           for entry in items: self.print_entry(entry,fd)
+       fd.write(self.templates["footer"])
+       fd.close()
+       if not self.foundmain:
+          print("main menu not found")
+          print(self.menus)
+          sys.exit(1)
+
+   def input(self,filename):
+       if filename == "-":
+          fd = sys.stdin
+       else: fd = open(filename,"r")
+       self.lineno = 0
+       self.state = "system"
+       for line in fd.readlines():
+         self.lineno = self.lineno + 1
+         if line and line[-1] in ["\r","\n"]: line = line[:-1]
+         if line and line[-1] in ["\r","\n"]: line = line[:-1]
+         line = line.strip()
+         if line and line[0] in ["#",";"]: continue
+
+         try:
+           # blank line -> starting a new entry
+           if not line:
+              if self.state == "item": self.add_item()
+              continue
+
+           # starting a new section?
+           if line[0] == "[" and line[-1] == "]":
+              self.state = "menu"
+              self.add_menu(line[1:-1])
+              continue
+
+           # add property of current entry
+           pos = line.find("=") # find the first = in string
+           if pos < 0:
+              print("Syntax error in line %d" % self.lineno)
+              print("REASON: non-section lines must be of the form ATTRIBUTE=VALUE")
+              sys.exit(1)
+           attr = line[:pos].strip().lower()
+           value = line[pos+1:].strip()
+           self.set(attr,value)
+         except:
+            print("Error while parsing line %d: %s" % (self.lineno,line))
+            raise
+       fd.close()
+       self.add_item()
+
+def usage():
+    print(sys.argv[0]," [options]")
+    print("--input=<file>    is the name of the .menu file declaring the menu structure")
+    print("--output=<file>   is the name of generated C source")
+    print("--template=<file> is the name of template to be used")
+    print()
+    print("input and output default to - (stdin and stdout respectively)")
+    print("template defaults to adv_menu.tpl")
+    sys.exit(1)
+
+def main():
+    tfile = "adv_menu.tpl"
+    ifile = "-"
+    ofile = "-"
+    opts,args = getopt.getopt(sys.argv[1:], "hi:o:t:",["input=","output=","template=","help"])
+    if args:
+       print("Unknown options %s" % args)
+       usage()
+    for o,a in opts:
+        if o in ["-i","--input"]:
+           ifile = a
+        elif o in ["-o", "--output"]:
+           ofile = a
+        elif o in ["-t","--template"]:
+           tfile = a
+        elif o in ["-h","--help"]:
+           usage()
+
+    inst = Menusystem(tfile)
+    inst.input(ifile)
+    inst.output(ofile)
+
+if __name__ == "__main__":
+   main()
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/password
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/password	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/password	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+# This file should be available as /isolinux/password
+# for complex.c to use.
+#
+# All lines starting with # and empty lines are ignored
+#
+# All non-comment lines here are of the form
+# USERNAME:PWDHASH:PERM1:PERM2:...:
+#
+# where USERNAME is maximum of 12 chars,
+# PWDHASH is maximum of 40 chars (DES ENCRYPTED)
+# PERM1,... are arbitrary strings
+#
+# The current lines correspond to
+# user1:secret1, user2:secret2, user3:secret3
+
+user1:LcMRo3YZGtP0c:editcmd
+user2:FqewzyxP78a7A:
+user3:MKjmc.IHoXBNU:root
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/simple.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/simple.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/simple.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* -*- c -*- ------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2005 Murali Krishnan Ganapathy - 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 NULL
+#define NULL ((void *) 0)
+#endif
+
+#include "cmenu.h"
+#include "com32io.h"
+#include <string.h>
+
+int main(void)
+{
+    t_menuitem *curr;
+
+    // Change the video mode here
+    // setvideomode(0)
+
+    // Choose the default title and setup default values for all attributes....
+    init_menusystem(NULL);
+    set_window_size(1, 1, 23, 78);	// Leave one row/col border all around
+
+    // Choose the default values for all attributes and char's
+    // -1 means choose defaults (Actually the next 4 lines are not needed)
+    //set_normal_attr (-1,-1,-1,-1);
+    //set_status_info (-1,-1);
+    //set_title_info  (-1,-1);
+    //set_misc_info(-1,-1,-1,-1);
+
+    // menuindex = add_named_menu("name"," Menu Title ",-1);
+    // add_item("Item string","Status String",TYPE,"any string",NUM)
+    //   TYPE = OPT_RUN | OPT_EXITMENU | OPT_SUBMENU | OPT_CHECKBOX | OPT_INACTIVE
+    //   "any string" useful for storing kernel names
+    //   In case of OPT_SUBMENU, "any string" can be set to "name" of menu to be linked
+    //   in which case value NUM is ignored
+    //   NUM = index of submenu if OPT_SUBMENU,
+    //         0/1 default checked state if OPT_CHECKBOX
+    //         unused otherwise.
+
+    add_named_menu("testing", " Testing ", -1);
+    add_item("Self Loop", "Go to testing", OPT_SUBMENU, "testing", 0);
+    add_item("Memory Test", "Perform extensive memory testing", OPT_RUN,
+	     "memtest", 0);
+    add_item("Exit this menu", "Go one level up", OPT_EXITMENU, "exit", 0);
+
+    add_named_menu("rescue", " Rescue Options ", -1);
+    add_item("Linux Rescue", "linresc", OPT_RUN, "linresc", 0);
+    add_item("Dos Rescue", "dosresc", OPT_RUN, "dosresc", 0);
+    add_item("Windows Rescue", "winresc", OPT_RUN, "winresc", 0);
+    add_item("Exit this menu", "Go one level up", OPT_EXITMENU, "exit", 0);
+
+    add_named_menu("main", " Main Menu ", -1);
+    add_item("Prepare", "prep", OPT_RUN, "prep", 0);
+    add_item("Rescue options...", "Troubleshoot a system", OPT_SUBMENU,
+	     "rescue", 0);
+    add_item("Testing...", "Options to test hardware", OPT_SUBMENU, "testing",
+	     0);
+    add_item("Exit to prompt", "Exit the menu system", OPT_EXITMENU, "exit", 0);
+
+    curr = showmenus(find_menu_num("main"));	// Initial menu is the one called "main"
+
+    if (curr) {
+	if (curr->action == OPT_RUN) {
+	    if (issyslinux())
+		runsyslinuxcmd(curr->data);
+	    else
+		csprint(curr->data, 0x07);
+	    return 1;
+	}
+	csprint("Error in programming!", 0x07);
+    }
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/test.menu
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/test.menu	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/test.menu	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+# choose default title
+title = "A test of the test.menu file"
+top = 1
+left = 1
+bot = 23
+right = 78
+
+[testing]
+title = " Testing "
+
+item="Self Loop"
+info="Go to Testing"
+type=submenu
+data=testing
+
+item="Memory Test"
+info="Perform extensive memory testing"
+data="memtest"
+
+item="Exit this menu"
+info="Go one level up"
+type=exitmenu
+
+[rescue]
+title = " Rescue Options "
+row = 10
+col = 10
+
+item="Linux Rescue"
+data="linresc"
+
+item="Dos Rescue"
+data="dosresc"
+
+item="Windows Rescue"
+data="winresc"
+
+item="Exit this menu"
+info="Go one level up"
+type=exitmenu
+
+[main]
+title = " Main Menu "
+
+item="Prepare"
+data="prep"
+
+item="Rescue options..."
+info="Troubleshoot a system"
+type=submenu
+data="rescue"
+
+item="Testing..."
+info="Options to test hardware"
+type=submenu
+data="testing"
+
+item="Exit this menu"
+info="Go one level up"
+type=exitmenu
Index: bootcd/isolinux/syslinux-6.03/com32/cmenu/test2.menu
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/cmenu/test2.menu	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/cmenu/test2.menu	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,142 @@
+
+title=" COMBOOT Menu System "
+
+# location of help directory
+helpdir="/isolinux/help"
+pwdfile="/isolinux/password"
+
+# skip the menu if shift is pressed or Caps is on
+# if the menu is skipped run "skipcmd"
+# in our case we run the OS on the first harddisk
+skipcondn=shift-caps
+skipcmd="chain.c32 hd 0"
+
+# person with root privileges can exit menu
+# others just repeat
+exitcmd=".exit"
+onerrorcmd=".beep 2 % % .help hlp00025.txt % .exit"
+
+startfile="hlp00026.txt"
+
+timeoutcmd=".wait"
+totaltimeoutcmd="chain.c32 hd 0"
+
+[netmenu]
+title=" Init Network "
+
+item="<N>one"
+info="Dont start network"
+type=radioitem
+data="network=no"
+
+item="<d>hcp"
+info="Use DHCP"
+type=radioitem
+data="network=dhcp"
+
+[testing]
+title=" Testing "
+
+item="<M>emory Test"
+info="Perform extensive memory testing"
+data="memtest"
+helpid=25
+ipappend=3
+
+item="<I>nvisible"
+info="You dont see this"
+type=invisible
+
+item="<E>xit menu"
+info="Go one level up"
+type=exitmenu
+
+[rescue]
+title=" Rescue Options "
+
+item="<L>inux Rescue"
+info="Run linresc"
+data="linresc"
+
+item="<D>os Rescue"
+info="dosresc"
+data="dosresc"
+
+item="<W>indows Rescue"
+info="winresc"
+data="winresc"
+
+item="<E>xit this menu"
+info="Go one level up"
+type=exitmenu
+
+[prep]
+title=" Prep options "
+
+item="<b>aseurl by IP?"
+info="Specify gui baseurl by IP address"
+type=checkbox
+data="baseurl=http://192.168.0.1"
+
+item="<m>ountcd?"
+info="Mount the cdrom drive?"
+type=checkbox
+data="mountcd"
+
+item="Network Initialization"
+info="How to initialise network device?"
+type=radiomenu
+data="netmenu"
+
+type=sep
+
+item="Reinstall <w>indows"
+info="Re-install the windows side of a dual boot setup"
+type=checkbox
+data="repair=win"
+
+item="Reinstall <l>inux"
+info="Re-install the linux side of a dual boot setup"
+type=checkbox
+data="repair=lin"
+
+type=sep
+
+item="<R>un prep now"
+info="Execute prep with the above options"
+data="prep"
+argsmenu="prep"
+
+item="<E>xit this menu"
+info="Go up one level"
+type=exitmenu
+
+[main]
+
+title=" Main Menu "
+
+type=login
+
+item="<P>repare"
+info="prep"
+data="prep"
+
+item="<P>rep options..."
+info="Options for prep"
+type=submenu
+data="prep"
+
+item="<R>escue options..."
+info="Troubleshoot a system"
+type=submenu
+data="rescue"
+helpid=26
+
+item="<T>esting..."
+info="Options to test hardware"
+type=submenu
+data="testing"
+
+item="<E>xit to prompt"
+info="Exit the menu system"
+type=exitmenu
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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.
+##
+## -----------------------------------------------------------------------
+
+MODULES = 
+TESTFILES =
+
+all: $(MODULES) $(TESTFILES)
+
+test_memalign.elf : test_memalign.o  $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+test_com32.elf: CFLAGS += -DELF_DEBUG
+test_com32.elf: test_com32.o ../lib/libcom32min.a $(LIBGCC)
+	$(LD) -n $(LDFLAGS) -o $@ test_com32.o $(LIBGCC) --whole-archive ../lib/libcom32min.a -Map test_com32.map
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.map
+
+clean: tidy
+	rm -f *.lss *.c32 *.lnx *.com
+
+spotless: clean
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2011-2013 Intel Corporation - 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.
+##
+## -----------------------------------------------------------------------
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib -fvisibility=hidden
+LIBS = --whole-archive $(objdir)/com32/lib/libcom32min.a
+
+OBJS = ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o adv.o \
+	execute.o chainboot.o kernel.o get_key.o advwrite.o setadv.o \
+	loadhigh.o msg.o
+
+BTARGET = $(LDLINUX)
+
+ifdef EFI_BUILD
+%.e$(BITS): %.elf
+	$(OBJCOPY) --strip-debug --strip-unneeded $< $@
+SONAME = $(patsubst %.elf,%.e$(BITS),$(@F))
+else
+SONAME = $(patsubst %.elf,%.c32,$(@F))
+endif
+
+all: $(BTARGET) ldlinux_lnx.a
+
+ldlinux.elf : $(OBJS)
+	$(LD) $(LDFLAGS) -soname $(SONAME) -o $@ $^ $(LIBS)
+
+LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
+LNXLIBOBJS = get_key.lo
+ldlinux_lnx.a: $(LNXLIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $(LNXLIBOBJS)
+	$(RANLIB) $@
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst .*.d 
+
+clean: tidy
+	rm -f *.lss *.lnx *.com
+
+spotless: clean
+	rm -f *~ \#* $(BTARGET)
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)
+	install -m 644 $(BTARGET) $(INSTALLROOT)$(AUXDIR)
+
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/adv.c
+ *
+ * Access the syslinux auxilliary data vector
+ */
+
+#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
+#include <klibc/compiler.h>
+#include <syslinux/adv.h>
+
+void __constructor __syslinux_init(void)
+{
+	firmware->adv_ops->init();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/advwrite.c
+ *
+ * Write back the ADV
+ */
+
+#include <klibc/compiler.h>
+#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
+
+__export int syslinux_adv_write(void)
+{
+    return firmware->adv_ops->write();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2012 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * chainbooting - replace the current bootloader completely.  This
+ * is BIOS-specific.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <dprintf.h>
+
+#include <com32.h>
+#include <sys/exec.h>
+#include <sys/io.h>
+#include "core.h"
+#include "menu.h"
+#include "fs.h"
+#include "config.h"
+#include "localboot.h"
+#include "bios.h"
+
+#include <syslinux/boot.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+#include <syslinux/config.h>
+
+void chainboot_file(const char *file, uint32_t type)
+{
+    uint8_t keeppxe = 0;
+    const union syslinux_derivative_info *sdi;
+    struct syslinux_rm_regs regs;
+    struct syslinux_movelist *fraglist = NULL;
+    struct syslinux_memmap *mmap = NULL;
+    struct com32_filedata fd;
+    com32sys_t reg;
+    char *stack;
+    void *buf;
+    int rv, max, size;
+    
+    max = 0xA0000;		/* Maximum load */
+    buf = malloc(max);
+    if (!buf)
+	goto bail;
+    
+    rv = open_file(file, O_RDONLY, &fd);
+    if (rv == -1)
+	goto bail;
+    
+    reg.eax.l = max;
+    reg.ebx.l = 0;
+    reg.edx.w[0] = 0;
+    reg.edi.l = (uint32_t)buf;
+    reg.ebp.l = -1;	/* XXX: limit? */
+    reg.esi.w[0] = rv;
+
+    pm_load_high(&reg);
+
+    size = reg.edi.l - (unsigned long)buf;
+    if (size > 0xA0000 - 0x7C00) {
+	printf("Too large for a boostrap (need LINUX instead of KERNEL?)\n");
+	goto bail;
+    }
+
+    mmap = syslinux_memory_map();
+    if (!mmap)
+	goto bail;
+
+    sdi = syslinux_derivative_info();
+
+    memset(&regs, 0, sizeof(regs));
+    regs.ip = 0x7c00;
+
+    if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX ||
+	sdi->c.filesystem == SYSLINUX_FS_EXTLINUX) {
+	if (syslinux_add_movelist(&fraglist, 0x800 - 18,
+				  (addr_t)sdi->r.esbx, 16))
+	    goto bail;
+
+	/* DS:SI points to partition info */
+	regs.esi.l = 0x800 - 18;
+    }
+
+    /*
+     * For a BSS boot sector we have to transfer the
+     * superblock.
+     */
+    if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX &&
+	type == IMAGE_TYPE_BSS && this_fs->fs_ops->copy_super(buf))
+	goto bail;
+
+    if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+	keeppxe = 0x03;		/* Chainloading + keep PXE */
+	stack = (char *)sdi->r.fssi;
+
+	/*
+	 * Set up the registers with their initial values
+	 */
+
+	regs.eax.l = *(uint32_t *)&stack[36];
+	regs.ecx.l = *(uint32_t *)&stack[32];
+	regs.edx.l = *(uint32_t *)&stack[28];
+	regs.ebx.l = *(uint32_t *)&stack[24];
+	regs.esp.l = sdi->rr.r.esi.w[0] + 44;
+	regs.ebp.l = *(uint32_t *)&stack[16];
+	regs.esi.l = *(uint32_t *)&stack[12];
+	regs.edi.l = *(uint32_t *)&stack[8];
+	regs.es = *(uint16_t *)&stack[4];
+	regs.ss = sdi->rr.r.fs;
+	regs.ds = *(uint16_t *)&stack[6];
+	regs.fs = *(uint16_t *)&stack[2];
+	regs.gs = *(uint16_t *)&stack[0];
+    } else {
+	const uint16_t *esdi = (const uint16_t *)sdi->disk.esdi_ptr;
+
+	regs.esp.l = (uint16_t)(unsigned long)StackBuf + 44;
+
+	/*
+	 * DON'T DO THIS FOR PXELINUX...
+	 * For PXE, ES:BX -> PXENV+, and this would
+	 * corrupt that use.
+	 *
+	 * Restore ES:DI -> $PnP (if we were ourselves
+	 * called that way...)
+	 */
+	regs.edi.w[0] = esdi[0]; /* New DI */
+	regs.es       = esdi[2]; /* New ES */
+
+	regs.edx.l    = sdi->rr.r.edx.b[0]; /* Drive number -> DL */
+    }
+
+    if (syslinux_add_movelist(&fraglist, 0x7c00, (addr_t)buf, size))
+	goto bail;
+
+    syslinux_shuffle_boot_rm(fraglist, mmap, keeppxe, &regs);
+
+bail:
+    if (fraglist)
+	syslinux_free_movelist(fraglist);
+    if (mmap)
+	syslinux_free_memmap(mmap);
+    if (buf)
+	free(buf);
+    return;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,486 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <setjmp.h>
+#include <netinet/in.h>
+#include <limits.h>
+#include <minmax.h>
+#include <linux/list.h>
+#include <sys/exec.h>
+#include <sys/module.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include "getkey.h"
+#include "menu.h"
+#include "cli.h"
+#include "config.h"
+
+static struct list_head cli_history_head;
+
+void clear_screen(void)
+{
+    //dprintf("enter");
+    fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+}
+
+static int mygetkey_timeout(clock_t *kbd_to, clock_t *tto)
+{
+    clock_t t0, t1;
+    int key;
+
+    t0 = times(NULL);
+    key = get_key(stdin, *kbd_to ? *kbd_to : *tto);
+
+    /* kbdtimeout only applies to the first character */
+    if (*kbd_to)
+	*kbd_to = 0;
+
+    t1 = times(NULL) - t0;
+    if (*tto) {
+	/* Timed out. */
+	if (*tto <= (long long)t1)
+	    key = KEY_NONE;
+	else {
+	    /* Did it wrap? */
+	    if (*tto > totaltimeout)
+		key = KEY_NONE;
+
+	    *tto -= t1;
+	}
+    }
+
+    return key;
+}
+
+static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
+				       clock_t *tto)
+{
+    int key;
+    int i = 0;
+    char buf[MAX_CMDLINE_LEN];
+    const char *p = NULL;
+    struct cli_command *last_found;
+    struct cli_command *last_good = NULL;
+
+    last_found = list_entry(cli_history_head.next, typeof(*last_found), list);
+
+    memset(buf, 0, MAX_CMDLINE_LEN);
+
+    printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+    while (1) {
+	key = mygetkey_timeout(kbd_to, tto);
+
+	if (key == KEY_CTRL('C')) {
+	    return NULL;
+	} else if (key == KEY_CTRL('R')) {
+	    if (i == 0)
+		continue; /* User typed nothing yet */
+	    /* User typed 'CTRL-R' again, so try the next */
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	} else if (key >= ' ' && key <= 'z') {
+	        buf[i++] = key;
+	} else {
+	    /* Treat other input chars as terminal */
+	    break;
+	}
+
+	while (last_found) {
+	    p = strstr(last_found->command, buf);
+	    if (p)
+	        break;
+
+	    if (list_is_last(&last_found->list, &cli_history_head))
+		break;
+
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	}
+
+	if (!p && !last_good) {
+	    return NULL;
+	} else if (!p) {
+	    continue;
+	} else {
+	    last_good = last_found;
+            *cursor = p - last_good->command;
+	}
+
+	printf("\033[?7l\033[?25l");
+	/* Didn't handle the line wrap case here */
+	printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
+		buf, last_good->command ? : "");
+	printf("\033[K\r");
+    }
+
+    return last_good ? last_good->command : NULL;
+}
+
+
+
+const char *edit_cmdline(const char *input, int top /*, int width */ ,
+			 int (*pDraw_Menu) (int, int, int),
+			 void (*show_fkey) (int), bool *timedout)
+{
+    char cmdline[MAX_CMDLINE_LEN] = { };
+    int key, len, prev_len, cursor;
+    int redraw = 0;
+    int x, y;
+    bool done = false;
+    const char *ret;
+    int width = 0;
+    struct cli_command *comm_counter = NULL;
+    clock_t kbd_to = kbdtimeout;
+    clock_t tto = totaltimeout;
+
+    if (!width) {
+	int height;
+	if (getscreensize(1, &height, &width))
+	    width = 80;
+    }
+
+    len = cursor = 0;
+    prev_len = 0;
+    x = y = 0;
+
+    /*
+     * Before we start messing with the x,y coordinates print 'input'
+     * so that it follows whatever text has been written to the screen
+     * previously.
+     */
+    printf("%s ", input);
+
+    while (!done) {
+	if (redraw > 1) {
+	    /* Clear and redraw whole screen */
+	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+	       to avoid confusing the Linux console */
+	    clear_screen();
+	    if (pDraw_Menu)
+		    (*pDraw_Menu) (-1, top, 1);
+	    prev_len = 0;
+	    printf("\033[2J\033[H");
+	    // printf("\033[0m\033[2J\033[H");
+	}
+
+	if (redraw > 0) {
+	    int dy, at;
+
+	    prev_len = max(len, prev_len);
+
+	    /* Redraw the command line */
+	    printf("\033[?25l");
+	    printf("\033[1G%s ", input);
+
+	    x = strlen(input);
+	    y = 0;
+	    at = 0;
+	    while (at < prev_len) {
+		putchar(at >= len ? ' ' : cmdline[at]);
+		at++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    x = 0;
+		    y++;
+		}
+	    }
+	    printf("\033[K\r");
+
+	    dy = y - (cursor + strlen(input) + 1) / width;
+	    x = (cursor + strlen(input) + 1) % width;
+
+	    if (dy) {
+		printf("\033[%dA", dy);
+		y -= dy;
+	    }
+	    if (x)
+		printf("\033[%dC", x);
+	    printf("\033[?25h");
+	    prev_len = len;
+	    redraw = 0;
+	}
+
+	key = mygetkey_timeout(&kbd_to, &tto);
+
+	switch (key) {
+	case KEY_NONE:
+	    /* We timed out. */
+	    *timedout = true;
+	    return NULL;
+
+	case KEY_CTRL('L'):
+	    redraw = 2;
+	    break;
+
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    ret = cmdline;
+	    done = true;
+	    break;
+
+	case KEY_BACKSPACE:
+	case KEY_DEL:
+	    if (cursor) {
+		memmove(cmdline + cursor - 1, cmdline + cursor,
+			len - cursor + 1);
+		len--;
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('D'):
+	case KEY_DELETE:
+	    if (cursor < len) {
+		memmove(cmdline + cursor, cmdline + cursor + 1, len - cursor);
+		len--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('U'):
+	    if (len) {
+		len = cursor = 0;
+		cmdline[len] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('W'):
+	    if (cursor) {
+		int prevcursor = cursor;
+
+		while (cursor && my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+		while (cursor && !my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+#if 0
+		memmove(cmdline + cursor, cmdline + prevcursor,
+			len - prevcursor + 1);
+#else
+		{
+		    int i;
+		    char *q = cmdline + cursor;
+		    char *p = cmdline + prevcursor;
+		    for (i = 0; i < len - prevcursor + 1; i++)
+			*q++ = *p++;
+		}
+#endif
+		len -= (prevcursor - cursor);
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_LEFT:
+	case KEY_CTRL('B'):
+	    if (cursor) {
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	case KEY_CTRL('F'):
+	    if (cursor < len) {
+		putchar(cmdline[cursor]);
+		cursor++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    y++;
+		    x = 0;
+		}
+	    }
+	    break;
+
+	case KEY_CTRL('K'):
+	    if (cursor < len) {
+		cmdline[len = cursor] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_HOME:
+	case KEY_CTRL('A'):
+	    if (cursor) {
+		cursor = 0;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_END:
+	case KEY_CTRL('E'):
+	    if (cursor != len) {
+		cursor = len;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_F1:
+	case KEY_F2:
+	case KEY_F3:
+	case KEY_F4:
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+	    if (show_fkey != NULL) {
+		(*show_fkey) (key);
+		redraw = 1;
+	    }
+	    break;
+	case KEY_CTRL('P'):
+	case KEY_UP:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    struct list_head *next;
+
+		    if (!comm_counter)
+			next = cli_history_head.next;
+		    else
+			next = comm_counter->list.next;
+
+		    comm_counter =
+			list_entry(next, typeof(*comm_counter), list);
+
+		    if (&comm_counter->list != &cli_history_head)
+			strcpy(cmdline, comm_counter->command);
+
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	case KEY_CTRL('N'):
+	case KEY_DOWN:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    struct list_head *prev;
+
+		    if (!comm_counter)
+			prev = cli_history_head.prev;
+		    else
+			prev = comm_counter->list.prev;
+
+		    comm_counter =
+			list_entry(prev, typeof(*comm_counter), list);
+
+		    if (&comm_counter->list != &cli_history_head)
+			strcpy(cmdline, comm_counter->command);
+
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	case KEY_CTRL('R'):
+	    {
+	         /* 
+	          * Handle this case in another function, since it's 
+	          * a kind of special.
+	          */
+	        const char *p = cmd_reverse_search(&cursor, &kbd_to, &tto);
+	        if (p) {
+	            strcpy(cmdline, p);
+		    len = strlen(cmdline);
+	        } else {
+	            cmdline[0] = '\0';
+		    cursor = len = 0;
+	        }
+	        redraw = 1;
+	    }
+	    break;
+	case KEY_TAB:
+	    {
+		const char *p;
+		size_t len;
+
+		/* Label completion enabled? */
+		if (nocomplete)
+	            break;
+
+		p = cmdline;
+		len = 0;
+		while(*p && !my_isspace(*p)) {
+		    p++;
+		    len++;
+		}
+
+		print_labels(cmdline, len);
+		redraw = 1;
+		break;
+	    }
+	case KEY_CTRL('V'):
+	    if (BIOSName)
+		printf("%s%s%s", syslinux_banner,
+		       (char *)MK_PTR(0, BIOSName), copyright_str);
+	    else
+		printf("%s%s", syslinux_banner, copyright_str);
+
+	    redraw = 1;
+	    break;
+
+	default:
+	    if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
+		if (cursor == len) {
+		    cmdline[len++] = key;
+		    cmdline[len] = '\0';
+		    putchar(key);
+		    cursor++;
+		    x++;
+		    if (x >= width) {
+			printf("\r\n\033[K");
+			y++;
+			x = 0;
+		    }
+		    prev_len++;
+		} else {
+		    if (cursor > len)
+			return NULL;
+
+		    memmove(cmdline + cursor + 1, cmdline + cursor,
+			    len - cursor + 1);
+		    cmdline[cursor++] = key;
+		    len++;
+		    redraw = 1;
+		}
+	    }
+	    break;
+	}
+    }
+
+    printf("\033[?7h");
+
+    /* Add the command to the history if its length is larger than 0 */
+    len = strlen(ret);
+    if (len > 0) {
+	comm_counter = malloc(sizeof(struct cli_command));
+	comm_counter->command = malloc(sizeof(char) * (len + 1));
+	strcpy(comm_counter->command, ret);
+	list_add(&(comm_counter->list), &cli_history_head);
+    }
+
+    return len ? ret : NULL;
+}
+
+static int __constructor cli_init(void)
+{
+	INIT_LIST_HEAD(&cli_history_head);
+
+	return 0;
+}
+
+static void __destructor cli_exit(void)
+{
+	/* Nothing to do */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <colortbl.h>
+#include "menu.h"
+
+/*
+ * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows
+ *
+ * 00 - screen		Rest of the screen
+ * 01 - border		Border area
+ * 02 - title		Title bar
+ * 03 - unsel		Unselected menu item
+ * 04 - hotkey		Unselected hotkey
+ * 05 - sel		Selection bar
+ * 06 - hotsel		Selected hotkey
+ * 07 - scrollbar	Scroll bar
+ * 08 - tabmsg		Press [Tab] message
+ * 09 - cmdmark		Command line marker
+ * 10 - cmdline		Command line
+ * 11 - pwdborder	Password box border
+ * 12 - pwdheader	Password box header
+ * 13 - pwdentry	Password box contents
+ * 14 - timeout_msg	Timeout message
+ * 15 - timeout		Timeout counter
+ * 16 - help		Current entry help text
+ * 17 - disabled        Disabled menu item
+ */
+
+static const struct color_table default_colors[] = {
+    {"screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL},
+    {"unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL},
+    {"hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL},
+    {"sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL},
+    {"hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL},
+    {"scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL},
+    {"cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL},
+    {"cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL},
+};
+
+#define NCOLORS (sizeof default_colors/sizeof default_colors[0])
+const int message_base_color = NCOLORS;
+const int menu_color_table_size = NCOLORS + 256;
+
+/* Algorithmically generate the msgXX colors */
+void set_msg_colors_global(struct color_table *tbl,
+			   unsigned int fg, unsigned int bg,
+			   enum color_table_shadow shadow)
+{
+    struct color_table *cp = tbl + message_base_color;
+    unsigned int i;
+    unsigned int fga, bga;
+    unsigned int fgh, bgh;
+    unsigned int fg_idx, bg_idx;
+    unsigned int fg_rgb, bg_rgb;
+
+    static const unsigned int pc2rgb[8] =
+	{ 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00,
+	0xffffff
+    };
+
+    /* Converting PC RGBI to sensible RGBA values is an "interesting"
+       proposition.  This algorithm may need plenty of tweaking. */
+
+    fga = fg & 0xff000000;
+    fgh = ((fg >> 1) & 0xff000000) | 0x80000000;
+
+    bga = bg & 0xff000000;
+    bgh = ((bg >> 1) & 0xff000000) | 0x80000000;
+
+    for (i = 0; i < 256; i++) {
+	fg_idx = i & 15;
+	bg_idx = i >> 4;
+
+	fg_rgb = pc2rgb[fg_idx & 7] & fg;
+	bg_rgb = pc2rgb[bg_idx & 7] & bg;
+
+	if (fg_idx & 8) {
+	    /* High intensity foreground */
+	    fg_rgb |= fgh;
+	} else {
+	    fg_rgb |= fga;
+	}
+
+	if (bg_idx == 0) {
+	    /* Default black background, assume transparent */
+	    bg_rgb = 0;
+	} else if (bg_idx & 8) {
+	    bg_rgb |= bgh;
+	} else {
+	    bg_rgb |= bga;
+	}
+
+	cp->argb_fg = fg_rgb;
+	cp->argb_bg = bg_rgb;
+	cp->shadow = shadow;
+	cp++;
+    }
+}
+
+struct color_table *default_color_table(void)
+{
+    unsigned int i;
+    const struct color_table *dp;
+    struct color_table *cp;
+    struct color_table *color_table;
+    static const int pc2ansi[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+    static char msg_names[6 * 256];
+    char *mp;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = default_colors;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS; i++) {
+	*cp = *dp;
+	cp->ansi = refstrdup(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    mp = msg_names;
+    for (i = 0; i < 256; i++) {
+	cp->name = mp;
+	mp += sprintf(mp, "msg%02x", i) + 1;
+
+	rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "",
+		 pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]);
+	cp++;
+    }
+
+  /*** XXX: This needs to move to run_menu() ***/
+    console_color_table = color_table;
+    console_color_table_size = NCOLORS + 256;
+
+    set_msg_colors_global(color_table, MSG_COLORS_DEF_FG,
+			  MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW);
+
+    return color_table;
+}
+
+struct color_table *copy_color_table(const struct color_table *master)
+{
+    const struct color_table *dp;
+    struct color_table *color_table, *cp;
+    unsigned int i;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = master;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS + 256; i++) {
+	*cp = *dp;
+	cp->ansi = refstr_get(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    return color_table;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/*
+ *   Copyright 2011 Intel Corporation - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * These values correspond to the "default" and "ui" commands
+ * respectively. "ui" takes precendence over "default".
+ */
+#define LEVEL_DEFAULT	1
+#define LEVEL_UI	2
+
+extern short uappendlen;	//bytes in append= command
+extern short ontimeoutlen;	//bytes in ontimeout command
+extern short onerrorlen;	//bytes in onerror command
+extern short forceprompt;	//force prompt
+extern short noescape;		//no escape
+extern short nocomplete;	//no label completion on TAB key
+extern short allowimplicit;	//allow implicit kernels
+extern short allowoptions;	//user-specified options allowed
+extern short includelevel;	//nesting level
+extern short defaultlevel;	//the current level of default
+extern short vkernel;		//have we seen any "label" statements?
+extern short displaycon;	//conio.inc
+extern short nohalt;		//idle.inc
+
+extern const char *default_cmd;	//"default" command line
+extern const char *onerror;	//"onerror" command line
+extern const char *ontimeout;	//"ontimeout" command line
+
+extern void cat_help_file(int key);
+extern struct menu_entry *find_label(const char *str);
+extern void print_labels(const char *prefix, size_t len);
+
+extern int new_linux_kernel(char *okernel, char *ocmdline);
+
+extern void pm_load_high(com32sys_t *regs);
+
+extern void ldlinux_enter_command(void);
+extern void ldlinux_console_init(void);
+extern const char *apply_extension(const char *kernel, const char *ext);
+
+#endif /* __CONFIG_H__ */
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <dprintf.h>
+
+#include <com32.h>
+#include <sys/exec.h>
+#include <sys/io.h>
+#include <sys/module.h>
+#include "core.h"
+#include "menu.h"
+#include "fs.h"
+#include "config.h"
+#include "localboot.h"
+#include "bios.h"
+
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+#include <syslinux/config.h>
+#include <syslinux/boot.h>
+
+const struct image_types image_boot_types[] = {
+    { "localboot", IMAGE_TYPE_LOCALBOOT },
+    { "kernel", IMAGE_TYPE_KERNEL },
+    { "linux", IMAGE_TYPE_LINUX },
+    { "boot", IMAGE_TYPE_BOOT },
+    { "bss", IMAGE_TYPE_BSS },
+    { "pxe", IMAGE_TYPE_PXE },
+    { "fdimage", IMAGE_TYPE_FDIMAGE },
+    { "com32", IMAGE_TYPE_COM32 },
+    { "config", IMAGE_TYPE_CONFIG },
+    { NULL, 0 },
+};
+
+extern int create_args_and_load(char *);
+
+__export void execute(const char *cmdline, uint32_t type, bool sysappend)
+{
+	const char *kernel, *args;
+	const char *p;
+	com32sys_t ireg;
+	char *q, ch;
+
+	memset(&ireg, 0, sizeof ireg);
+
+	if (strlen(cmdline) >= MAX_CMDLINE_LEN) {
+		printf("cmdline too long\n");
+		return;
+	}
+
+	q = malloc(MAX_CMDLINE_LEN);
+	if (!q) {
+		printf("%s(): Fail to malloc a buffer to exec %s\n",
+			__func__, cmdline);
+		return;
+	}
+
+	kernel = q;
+	p = cmdline;
+	while (*p && !my_isspace(*p))
+		*q++ = *p++;
+	*q++ = '\0';
+
+	args = q;
+	while (*p && my_isspace(*p))
+		p++;
+
+	do {
+		*q++ = ch = *p++;
+	} while (ch);
+
+	if (sysappend) {
+		/* If we've seen some args, insert a space */
+		if (--q != args)
+			*q++ = ' ';
+
+		do_sysappend(q);
+	}
+
+	dprintf("kernel is %s, args = %s  type = %d \n", kernel, args, type);
+
+	if (kernel[0] == '.') {
+		/* It might be a type specifier */
+		const struct image_types *t;
+		for (t = image_boot_types; t->name; t++) {
+			if (!strcmp(kernel + 1, t->name)) {
+				/*
+				 * Strip the type specifier, apply the
+				 * filename extension if COM32 and
+				 * retry.
+				 */
+				p = args;
+				if (t->type == IMAGE_TYPE_COM32) {
+					p = apply_extension(p, ".c32");
+					if (!p)
+						return;
+				}
+
+				execute(p, t->type, sysappend);
+				return;
+			}
+		}
+	}
+
+	if (type == IMAGE_TYPE_COM32) {
+		/*
+		 * We may be called with the console in an unknown
+		 * state, so initialise it.
+		 */
+		ldlinux_console_init();
+
+		/* new entry for elf format c32 */
+		if (create_args_and_load((char *)cmdline))
+			printf("Failed to load COM32 file %s\n", kernel);
+
+		/*
+		 * The old COM32 module code would run the module then
+		 * drop the user back at the command prompt,
+		 * irrespective of how the COM32 module was loaded,
+		 * e.g. from vesamenu.c32.
+		 */
+		unload_modules_since(LDLINUX);
+
+		/* Restore the console */
+		ldlinux_console_init();
+
+		ldlinux_enter_command();
+	} else if (type == IMAGE_TYPE_CONFIG) {
+		char *argv[] = { LDLINUX, NULL, NULL };
+		char *config;
+		int rv;
+
+		/* kernel contains the config file name */
+		config = malloc(FILENAME_MAX);
+		if (!config)
+			goto out;
+
+		realpath(config, kernel, FILENAME_MAX);
+
+		/* If we got anything on the command line, do a chdir */
+		if (*args)
+			mangle_name(config_cwd, args);
+
+		argv[1] = config;
+		rv = start_ldlinux(2, argv);
+		printf("Failed to exec %s: %s\n", LDLINUX, strerror(rv));
+	} else if (type == IMAGE_TYPE_LOCALBOOT) {
+		local_boot(strtoul(kernel, NULL, 0));
+	} else if (type == IMAGE_TYPE_PXE || type == IMAGE_TYPE_BSS ||
+		   type == IMAGE_TYPE_BOOT) {
+		chainboot_file(kernel, type);
+	} else {
+		/* Need add one item for kernel load, as we don't use
+		* the assembly runkernel.inc any more */
+		new_linux_kernel((char *)kernel, (char *)args);
+	}
+
+out:
+	free((void *)kernel);
+
+	/* If this returns, something went bad; return to menu */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,243 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * get_key.c
+ *
+ * Get a single key, and try to pick apart function key codes.
+ * This doesn't decode anywhere close to all possiblities, but
+ * hopefully is enough to be useful.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/times.h>
+#include <getkey.h>
+#include <libutil.h>
+#include <sys/file.h>
+
+struct keycode {
+    int code;
+    int seqlen;
+    const unsigned char *seq;
+};
+
+#define CODE(x,y) { x, (sizeof y)-1, (const unsigned char *)(y) }
+
+static const struct keycode keycodes[] = {
+    /* First, the BIOS combined codes */
+    CODE(KEY_F1, "\0\x3B"),
+    CODE(KEY_F2, "\0\x3C"),
+    CODE(KEY_F3, "\0\x3D"),
+    CODE(KEY_F4, "\0\x3E"),
+    CODE(KEY_F5, "\0\x3F"),
+    CODE(KEY_F6, "\0\x40"),
+    CODE(KEY_F7, "\0\x41"),
+    CODE(KEY_F8, "\0\x42"),
+    CODE(KEY_F9, "\0\x43"),
+    CODE(KEY_F10, "\0\x44"),
+    CODE(KEY_F11, "\0\x85"),
+    CODE(KEY_F12, "\0\x86"),
+
+    CODE(KEY_UP, "\0\x48"),
+    CODE(KEY_DOWN, "\0\x50"),
+    CODE(KEY_LEFT, "\0\x4B"),
+    CODE(KEY_RIGHT, "\0\x4D"),
+    CODE(KEY_PGUP, "\0\x49"),
+    CODE(KEY_PGDN, "\0\x51"),
+    CODE(KEY_HOME, "\0\x47"),
+    CODE(KEY_END, "\0\x4F"),
+    CODE(KEY_INSERT, "\0\x52"),
+    CODE(KEY_DELETE, "\0\x53"),
+
+    /* Now, VT/xterm/Linux codes */
+    CODE(KEY_F1, "\033[[A"),
+    CODE(KEY_F1, "\033OP"),
+    CODE(KEY_F2, "\033[[B"),
+    CODE(KEY_F2, "\033OQ"),
+    CODE(KEY_F3, "\033[[C"),
+    CODE(KEY_F3, "\033OR"),
+    CODE(KEY_F4, "\033[[D"),
+    CODE(KEY_F4, "\033OS"),
+    CODE(KEY_F5, "\033[[E"),
+    CODE(KEY_F5, "\033[15~"),
+    CODE(KEY_F6, "\033[17~"),
+    CODE(KEY_F7, "\033[18~"),
+    CODE(KEY_F8, "\033[19~"),
+    CODE(KEY_F9, "\033[20~"),
+    CODE(KEY_F10, "\033[21~"),
+    CODE(KEY_F11, "\033[23~"),
+    CODE(KEY_F12, "\033[24~"),
+
+    CODE(KEY_UP, "\033[A"),
+    CODE(KEY_DOWN, "\033[B"),
+    CODE(KEY_LEFT, "\033[D"),
+    CODE(KEY_RIGHT, "\033[C"),
+    CODE(KEY_PGUP, "\033[5~"),
+    CODE(KEY_PGUP, "\033[V"),
+    CODE(KEY_PGDN, "\033[6~"),
+    CODE(KEY_PGDN, "\033[U"),
+    CODE(KEY_HOME, "\033[1~"),
+    CODE(KEY_HOME, "\033[H"),
+    CODE(KEY_END, "\033[4~"),
+    CODE(KEY_END, "\033[F"),
+    CODE(KEY_END, "\033OF"),
+    CODE(KEY_INSERT, "\033[2~"),
+    CODE(KEY_INSERT, "\033[@"),
+    CODE(KEY_DELETE, "\033[3~"),
+
+    /* EFI scan codes */
+    CODE(KEY_UP, "\0\x01"),
+    CODE(KEY_DOWN, "\0\x02"),
+    CODE(KEY_RIGHT, "\0\x03"),
+    CODE(KEY_LEFT, "\0\x04"),
+    CODE(KEY_HOME, "\0\x05"),
+    CODE(KEY_END, "\0\x06"),
+    CODE(KEY_INSERT, "\0\x07"),
+    CODE(KEY_DELETE, "\0\x08"),
+    CODE(KEY_PGUP, "\0\x09"),
+    CODE(KEY_PGDN, "\0\x0a"),
+    CODE(KEY_F1, "\0\x0b"),
+    CODE(KEY_F2, "\0\x0c"),
+    CODE(KEY_F3, "\0\x0d"),
+    CODE(KEY_F4, "\0\x0e"),
+    CODE(KEY_F5, "\0\x0f"),
+    CODE(KEY_F6, "\0\x10"),
+    CODE(KEY_F7, "\0\x11"),
+    CODE(KEY_F8, "\0\x12"),
+    CODE(KEY_F9, "\0\x13"),
+    CODE(KEY_F10, "\0\x14"),
+    CODE(KEY_F11, "\0\x15"),
+    CODE(KEY_F12, "\0\x16"),
+    CODE(KEY_ESC, "\0\x17"),
+};
+
+#define NCODES ((int)(sizeof keycodes/sizeof(struct keycode)))
+
+#define KEY_TIMEOUT ((CLK_TCK+9)/10)
+
+/*
+ * Attempt to decode the key sequence in 'buffer'.
+ *
+ * On success (the data in 'buffer' matches a key code) put the
+ * corresponding key code in 'code' and return 0. Return 1 if 'buffer'
+ * partially matches a key code, i.e. we need more data before we can
+ * make an unambiguous match. Return -1 if the buffer does not contain
+ * a key code.
+ */
+int get_key_decode(char *buffer, int nc, int *code)
+{
+    const struct keycode *kc;
+    int i, rv;
+
+    rv = -1;
+    for (i = 0, kc = keycodes; i < NCODES; i++, kc++) {
+	if (nc == kc->seqlen && !memcmp(buffer, kc->seq, nc)) {
+	    *code = kc->code;
+	    rv = 0;
+	    break;
+	} else if (nc < kc->seqlen && !memcmp(buffer, kc->seq, nc)) {
+	    rv = 1;
+	    break;
+	}
+    }
+
+    return rv;
+}
+
+#ifdef __COM32__
+extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count);
+
+int raw_read(int fd, void *buf, size_t count)
+{
+	(void)fd;
+
+	/*
+	 * Instead of using the read(2) stdlib function use
+	 * __rawcon_read() directly since we want a single key and
+	 * don't want any processing/batching of the user input to
+	 * occur - we want the raw data.
+	 */
+	return __rawcon_read(NULL, buf, count);
+}
+#else
+extern int raw_read(int fd, void *buf, size_t count);
+#endif
+
+__export int get_key(FILE * f, clock_t timeout)
+{
+    char buffer[KEY_MAXLEN];
+    int nc, rv;
+    int another;
+    char ch;
+    clock_t start;
+    int code;
+
+    /* We typically start in the middle of a clock tick */
+    if (timeout)
+	timeout++;
+
+    nc = 0;
+    start = times(NULL);
+    do {
+	rv = raw_read(fileno(f), &ch, 1);
+	if (rv == 0 || (rv == -1 && errno == EAGAIN)) {
+	    clock_t lateness = times(NULL) - start;
+	    if (nc && lateness > 1 + KEY_TIMEOUT) {
+		if (nc == 1)
+		    return (unsigned char)buffer[0];	/* timeout */
+		else if (timeout && lateness > timeout)
+		    return KEY_NONE;
+	    } else if (!nc && timeout && lateness > timeout)
+		return KEY_NONE;	/* timeout before sequence */
+
+	    do_idle();
+
+	    another = 1;
+	    continue;
+	}
+
+	start = times(NULL);
+
+	buffer[nc++] = ch;
+
+	another = 0;
+	rv = get_key_decode(buffer, nc, &code);
+	if (!rv)
+		return code;
+	else if (rv == 1)
+		another = 1;
+
+    } while (another);
+
+    /* We got an unrecognized sequence; return the first character */
+    /* We really should remember this and return subsequent characters later */
+    return (unsigned char)buffer[0];
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/getadv.c
+ *
+ * Get a data item from the auxilliary data vector.  Returns a pointer
+ * and sets *size on success; NULL on failure.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+
+__export const void *syslinux_getadv(int tag, size_t * size)
+{
+    const uint8_t *p;
+    size_t left;
+
+    p = syslinux_adv_ptr();
+    left = syslinux_adv_size();
+
+    while (left >= 2) {
+	uint8_t ptag = *p++;
+	size_t plen = *p++;
+	left -= 2;
+
+	if (ptag == ADV_END)
+	    return NULL;	/* Not found */
+
+	if (left < plen)
+	    return NULL;	/* Item overrun */
+
+	if (ptag == tag) {
+	    *size = plen;
+	    return p;
+	}
+
+	p += plen;
+	left -= plen;
+    }
+
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,131 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <dprintf.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+#include <syslinux/pxe.h>
+#include "core.h"
+
+const char *globaldefault = NULL;
+const char *append = NULL;
+
+/* Will be called from readconfig.c */
+int new_linux_kernel(char *okernel, char *ocmdline)
+{
+	const char *kernel_name = NULL, *args = NULL;
+	struct initramfs *initramfs = NULL;
+	char *temp;
+	void *kernel_data;
+	size_t kernel_len, cmdline_len;
+	bool opt_quiet = false;
+	char *initrd_name, *cmdline;
+
+	dprintf("okernel = %s, ocmdline = %s", okernel, ocmdline);
+
+	if (okernel)
+		kernel_name = okernel;
+	else if (globaldefault)
+		kernel_name = globaldefault;
+
+	if (ocmdline)
+		args = ocmdline;
+	else if (append)
+		args = append;
+
+	cmdline_len = strlen("BOOT_IMAGE=") + strlen(kernel_name);
+	cmdline_len += 1;	/* space between BOOT_IMAGE and args */
+	cmdline_len += strlen(args);
+	cmdline_len += 1;	/* NUL-termination */
+
+	cmdline = malloc(cmdline_len);
+	if (!cmdline) {
+	    printf("Failed to alloc memory for cmdline\n");
+	    return 1;
+	}
+
+	sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args);
+
+	/* "keeppxe" handling */
+#if IS_PXELINUX
+	extern char KeepPXE;
+
+	if (strstr(cmdline, "keeppxe"))
+		KeepPXE |= 1;
+#endif
+
+	if (strstr(cmdline, "quiet"))
+		opt_quiet = true;
+
+	if (!opt_quiet)
+		printf("Loading %s... ", kernel_name);
+
+	if (loadfile(kernel_name, &kernel_data, &kernel_len)) {
+		if (opt_quiet)
+			printf("Loading %s ", kernel_name);
+		printf("failed: ");
+		goto bail;
+	}
+
+	if (!opt_quiet)
+		printf("ok\n");
+
+	/* Find and load initramfs */
+	temp = strstr(cmdline, "initrd=");
+	if (temp) {
+		/* Initialize the initramfs chain */
+		initramfs = initramfs_init();
+		if (!initramfs)
+			goto bail;
+
+		temp += 6; /* strlen("initrd") */
+		do {
+		    size_t n = 0;
+		    char *p;
+
+		    temp++;	/* Skip = or , */
+
+		    p = temp;
+		    while (*p != ' ' && *p != ',' && *p) {
+			p++;
+			n++;
+		    }
+
+		    initrd_name = malloc(n + 1);
+		    if (!initrd_name) {
+			printf("Failed to allocate space for initrd\n");
+			goto bail;
+		    }
+
+		    snprintf(initrd_name, n + 1, "%s", temp);
+		    temp += n;
+
+		    if (!opt_quiet)
+			printf("Loading %s...", initrd_name);
+
+		    if (initramfs_load_archive(initramfs, initrd_name)) {
+			if (opt_quiet)
+			    printf("Loading %s ", initrd_name);
+			free(initrd_name);
+			printf("failed: ");
+			goto bail;
+		    }
+
+		    free(initrd_name);
+
+		    if (!opt_quiet)
+			printf("ok\n");
+		} while (*temp == ',');
+	}
+
+	/* This should not return... */
+	syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, cmdline);
+	printf("Booting kernel failed: ");
+
+bail:
+	free(cmdline);
+	printf("%s\n", strerror(errno));
+	return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,348 @@
+#include <linux/list.h>
+#include <sys/times.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <core.h>
+#include <fs.h>
+#include "cli.h"
+#include "console.h"
+#include "com32.h"
+#include "menu.h"
+#include "config.h"
+#include "syslinux/adv.h"
+#include "syslinux/boot.h"
+#include "syslinux/config.h"
+
+#include <sys/module.h>
+
+struct file_ext {
+	const char *name;
+	enum kernel_type type;
+};
+
+static const struct file_ext file_extensions[] = {
+	{ ".c32", IMAGE_TYPE_COM32 },
+	{ ".img", IMAGE_TYPE_FDIMAGE },
+	{ ".bss", IMAGE_TYPE_BSS },
+	{ ".bin", IMAGE_TYPE_BOOT },
+	{ ".bs", IMAGE_TYPE_BOOT },
+	{ ".0", IMAGE_TYPE_PXE },
+	{ NULL, 0 },
+};
+
+/*
+ * Return a pointer to one byte after the last character of the
+ * command.
+ */
+static inline const char *find_command(const char *str)
+{
+	const char *p;
+
+	p = str;
+	while (*p && !my_isspace(*p))
+		p++;
+	return p;
+}
+
+__export uint32_t parse_image_type(const char *kernel)
+{
+	const struct file_ext *ext;
+	const char *p;
+	int len;
+
+	/* Find the end of the command */
+	p = find_command(kernel);
+	len = p - kernel;
+
+	for (ext = file_extensions; ext->name; ext++) {
+		int elen = strlen(ext->name);
+
+		if (!strncmp(kernel + len - elen, ext->name, elen))
+			return ext->type;
+	}
+
+	/* use IMAGE_TYPE_KERNEL as default */
+	return IMAGE_TYPE_KERNEL;
+}
+
+/*
+ * Returns the kernel name with file extension if one wasn't present.
+ */
+static const char *get_extension(const char *kernel)
+{
+	const struct file_ext *ext;
+	const char *p;
+	int len;
+
+	/* Find the end of the command */
+	p = find_command(kernel);
+	len = p - kernel;
+
+	for (ext = file_extensions; ext->name; ext++) {
+		char *str;
+		int elen = strlen(ext->name);
+		FILE *f;
+
+		str = malloc(len + elen + 1);
+
+		strncpy(str, kernel, len);
+		strncpy(str + len, ext->name, elen);
+		str[len + elen] = '\0';
+		f = findpath(str);
+		free(str);
+
+		if (f) {
+			fclose(f);
+			return ext->name;
+		}
+	}
+
+	return NULL;
+}
+
+const char *apply_extension(const char *kernel, const char *ext)
+{
+	const char *p;
+	char *k;
+	int len = strlen(kernel);
+	int elen = strlen(ext);
+
+	k = malloc(len + elen + 1);
+	if (!k)
+		return NULL;
+
+	p = find_command(kernel);
+
+	len = p - kernel;
+
+	/* Copy just the kernel name */
+	memcpy(k, kernel, len);
+
+	/* Append the extension */
+	if (strncmp(p - elen, ext, elen)) {
+		memcpy(k + len, ext, elen);
+		len += elen;
+	}
+
+	/* Copy the rest of the command line */
+	strcpy(k + len, p);
+
+	k[len + strlen(p)] = '\0';
+
+	return k;
+}
+
+/*
+ * Attempt to load a kernel after deciding what type of image it is.
+ *
+ * We only return from this function if something went wrong loading
+ * the the kernel. If we return the caller should call enter_cmdline()
+ * so that the user can help us out.
+ */
+__export void load_kernel(const char *command_line)
+{
+	struct menu_entry *me;
+	const char *cmdline;
+	const char *kernel;
+	uint32_t type;
+
+	kernel = strdup(command_line);
+	if (!kernel)
+		goto bad_kernel;
+
+	/* Virtual kernel? */
+	me = find_label(kernel);
+	if (me) {
+		const char *args;
+		char *cmd;
+		size_t len = strlen(me->cmdline) + 1;
+
+		/* Find the end of the command */
+		args = find_command(kernel);
+		while(*args && my_isspace(*args))
+			args++;
+
+		if (strlen(args))
+			len += strlen(args) + 1; /* +1 for space (' ') */
+
+		cmd = malloc(len);
+		if (!cmd)
+			goto bad_kernel;
+
+		if (strlen(args))
+			snprintf(cmd, len, "%s %s", me->cmdline, args);
+		else
+			strncpy(cmd, me->cmdline, len);
+
+		type = parse_image_type(cmd);
+		execute(cmd, type, false);
+		/* We shouldn't return */
+		goto bad_kernel;
+	}
+
+	if (!allowimplicit)
+		goto bad_implicit;
+
+	/* Insert a null character to ignore any user-specified options */
+	if (!allowoptions) {
+		char *p = (char *)find_command(kernel);
+		*p = '\0';
+	}
+
+	type = parse_image_type(kernel);
+	if (type == IMAGE_TYPE_KERNEL) {
+		const char *ext;
+
+		/*
+		 * Automatically lookup the extension if one wasn't
+		 * supplied by the user.
+		 */
+		ext = get_extension(kernel);
+		if (ext) {
+			const char *k;
+
+			k = apply_extension(kernel, ext);
+			if (!k)
+				goto bad_kernel;
+
+			free((void *)kernel);
+			kernel = k;
+
+			type = parse_image_type(kernel);
+		}
+	}
+
+	execute(kernel, type, true);
+	free((void *)kernel);
+
+bad_implicit:
+bad_kernel:
+	/*
+	 * If we fail to boot the kernel execute the "onerror" command
+	 * line.
+	 */
+	if (onerrorlen) {
+		me = find_label(onerror);
+		if (me)
+			rsprintf(&cmdline, "%s %s", me->cmdline, default_cmd);
+		else
+			rsprintf(&cmdline, "%s %s", onerror, default_cmd);
+
+		type = parse_image_type(cmdline);
+		execute(cmdline, type, true);
+	}
+}
+
+/*
+ * If this function returns you must call ldinux_enter_command() to
+ * preserve the 4.0x behaviour.
+ */
+void ldlinux_auto_boot(void)
+{
+	if (!defaultlevel) {
+		if (strlen(ConfigName))
+			printf("No DEFAULT or UI configuration directive found!\n");
+		if (noescape)
+			kaboom();
+	} else
+		load_kernel(default_cmd);
+}
+
+static void enter_cmdline(void)
+{
+	const char *cmdline;
+
+	/* Enter endless command line prompt, should support "exit" */
+	while (1) {
+		bool to = false;
+
+		if (noescape) {
+			ldlinux_auto_boot();
+			continue;
+		}
+
+		cmdline = edit_cmdline("boot:", 1, NULL, cat_help_file, &to);
+		printf("\n");
+
+		/* return if user only press enter or we timed out */
+		if (!cmdline || cmdline[0] == '\0') {
+			if (to && ontimeoutlen)
+				load_kernel(ontimeout);
+			else
+				ldlinux_auto_boot();
+		} else
+			load_kernel(cmdline);
+	}
+}
+
+void ldlinux_enter_command(void)
+{
+	enter_cmdline();
+}
+
+/*
+ * Undo the work we did in openconsole().
+ */
+static void __destructor close_console(void)
+{
+	int i;
+
+	for (i = 0; i <= 2; i++)
+		close(i);
+}
+
+void ldlinux_console_init(void)
+{
+	openconsole(&dev_stdcon_r, &dev_ansiserial_w);
+}
+
+__export int main(int argc __unused, char **argv)
+{
+	const void *adv;
+	const char *cmdline;
+	size_t count = 0;
+
+	ldlinux_console_init();
+
+	parse_configs(&argv[1]);
+
+	__syslinux_set_serial_console_info();
+
+	adv = syslinux_getadv(ADV_BOOTONCE, &count);
+	if (adv && count) {
+		/*
+		 * We apparently have a boot-once set; clear it and
+		 * then execute the boot-once.
+		 */
+		char *src, *dst;
+		size_t i;
+
+		src = (char *)adv;
+		cmdline = dst = malloc(count + 1);
+		if (!dst) {
+			printf("Failed to allocate memory for ADV\n");
+			ldlinux_enter_command();
+		}
+
+		for (i = 0; i < count; i++)
+			*dst++ = *src++;
+		*dst = '\0';	/* Null-terminate */
+
+		/* Clear the boot-once data from the ADV */
+		if (!syslinux_setadv(ADV_BOOTONCE, 0, NULL))
+			syslinux_adv_write();
+
+		load_kernel(cmdline); /* Shouldn't return */
+		ldlinux_enter_command();
+	}
+
+	if (!forceprompt && !shift_is_held())
+		ldlinux_auto_boot();
+
+	if (defaultlevel > 1)
+		ldlinux_auto_boot();
+
+	ldlinux_enter_command();
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,112 @@
+/*
+ * -----------------------------------------------------------------------
+ *
+ *   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * loadhigh.c
+ *
+ * An alternate interface to getfssec.
+ *
+ * Inputs:	SI  = file handle/cluster pointer
+ *		EDI = target address in high memory
+ *		EAX = maximum number of bytes to load
+ *		DX  = zero-padding mask (e.g. 0003h for pad to dword)
+ *		BX  = 16-bit subroutine to call at the top of each loop
+ *                    (to print status and check for abort)
+ *		EBP = maximum load address
+ *
+ * Outputs:	SI  = file handle/cluster pointer
+ *		EBX = first untouched address (not including padding)
+ *		EDI = first untouched address (including padding)
+ *		CF  = reached EOF
+ *		OF  = ran out of high memory
+ */
+
+#include <com32.h>
+#include <minmax.h>
+#include "core.h"
+#include "fs.h"
+
+#define MAX_CHUNK	(1UL << 20) /* 1 MB */
+
+void pm_load_high(com32sys_t *regs)
+{
+    struct fs_info *fs;
+    uint32_t bytes;
+    uint32_t zero_mask;
+    bool have_more;
+    uint32_t bytes_read;
+    char *buf, *limit;
+    struct file *file;
+    uint32_t sector_mask;
+    size_t pad;
+    uint32_t retflags = 0;
+
+    bytes     = regs->eax.l;
+    zero_mask = regs->edx.w[0];
+    buf       = (char *)regs->edi.l;
+    limit     = (char *)(regs->ebp.l & ~zero_mask);
+    file      = handle_to_file(regs->esi.w[0]);
+    fs        = file->fs;
+
+    sector_mask = SECTOR_SIZE(fs) - 1;
+
+    while (bytes) {
+	uint32_t sectors;
+	uint32_t chunk;
+
+	if (buf + SECTOR_SIZE(fs) > limit) {
+	    /* Can't fit even one more sector in... */
+	    retflags = EFLAGS_OF;
+	    break;
+	}
+
+	chunk = bytes;
+
+	if (regs->ebx.w[0]) {
+	    call16((void (*)(void))(size_t)regs->ebx.w[0], &zero_regs, NULL);
+	    chunk = min(chunk, MAX_CHUNK);
+	}
+
+	if (chunk > (((char *)limit - buf) & ~sector_mask))
+	    chunk = ((char *)limit - buf) & ~sector_mask;
+
+	sectors = (chunk + sector_mask) >> SECTOR_SHIFT(fs);
+	bytes_read = fs->fs_ops->getfssec(file, buf, sectors, &have_more);
+
+	if (bytes_read > chunk)
+	    bytes_read = chunk;
+
+	buf += bytes_read;
+	bytes -= bytes_read;
+
+	if (!have_more) {
+	    /*
+	     * If we reach EOF, the filesystem driver will have already closed
+	     * the underlying file... this really should be cleaner.
+	     */
+	    _close_file(file);
+	    regs->esi.w[0] = 0;
+	    retflags = EFLAGS_CF;
+	    break;
+	}
+    }
+
+    pad = (size_t)buf & zero_mask;
+    if (pad)
+	memset(buf, 0, pad);
+
+    regs->ebx.l = (size_t)buf;
+    regs->edi.l = (size_t)buf + pad;
+    set_flags(regs, retflags);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdio.h>
+#include <bios.h>
+#include <graphics.h>
+
+static uint8_t TextAttribute;	/* Text attribute for message file */
+extern uint8_t DisplayMask;	/* Display modes mask */
+
+/* Routine to interpret next print char */
+static void (*NextCharJump)(uint8_t);
+
+void msg_initvars(void);
+static void msg_setfg(uint8_t data);
+static void msg_putchar(uint8_t ch);
+
+/*
+ *
+ * get_msg_file: Load a text file and write its contents to the screen,
+ *               interpreting color codes.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int get_msg_file(char *filename)
+{
+	FILE *f;
+	char ch;
+
+	f = fopen(filename, "r");
+	if (!f)
+		return -1;
+
+	TextAttribute = 0x7;	/* Default grey on white */
+	DisplayMask = 0x7;	/* Display text in all modes */
+	msg_initvars();
+
+	/*
+	 * Read the text file a byte at a time and interpret that
+	 * byte.
+	 */
+	while ((ch = getc(f)) != EOF) {
+		/* DOS EOF? */
+		if (ch == 0x1A)
+			break;
+
+		NextCharJump(ch);	/* Do what shall be done */
+	}
+
+	DisplayMask = 0x07;
+
+	fclose(f);
+	return 0;
+}
+
+static inline int display_mask_vga(void)
+{
+	uint8_t mask = UsingVGA & 0x1;
+	return (DisplayMask & ++mask);
+}
+
+static void msg_setbg(uint8_t data)
+{
+	if (unhexchar(&data) == 0) {
+		data <<= 4;
+		if (display_mask_vga())
+			TextAttribute = data;
+
+		NextCharJump = msg_setfg;
+	} else {
+		TextAttribute = 0x7;	/* Default attribute */
+		NextCharJump = msg_putchar;
+	}
+}
+
+static void msg_setfg(uint8_t data)
+{
+	if (unhexchar(&data) == 0) {
+		if (display_mask_vga()) {
+			/* setbg set foreground to 0 */
+			TextAttribute |= data;
+		}
+	} else
+		TextAttribute = 0x7;	/* Default attribute */
+
+	NextCharJump = msg_putchar;
+}
+
+static inline void msg_ctrl_o(void)
+{
+	NextCharJump = msg_setbg;
+}
+
+/* Convert ANSI colors to PC display attributes */
+static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+static void set_fgbg(void)
+{
+	uint8_t bg, fg;
+
+	fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
+	bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
+
+	printf("\033[");
+	if (TextAttribute & 0x8)
+		printf("1;"); /* Foreground bright */
+
+	printf("3%dm\033[", fg);
+
+	if (TextAttribute & 0x80)
+		printf("5;"); /* Foreground blink */
+
+	printf("4%dm", bg);
+}
+
+static void msg_formfeed(void)
+{
+	set_fgbg();
+	printf("\033[2J\033[H\033[0m");
+}
+
+static void msg_novga(void)
+{
+	syslinux_force_text_mode();
+	msg_initvars();
+}
+
+static void msg_viewimage(void)
+{
+	FILE *f;
+
+	*VGAFilePtr = '\0';	/* Zero-terminate filename */
+
+	mangle_name(VGAFileMBuf, VGAFileBuf);
+	f = fopen(VGAFileMBuf, "r");
+	if (!f) {
+		/* Not there */
+		NextCharJump = msg_putchar;
+		return;
+	}
+
+	vgadisplayfile(f);
+	fclose(f);
+	msg_initvars();
+}
+
+/*
+ * Getting VGA filename
+ */
+static void msg_filename(uint8_t data)
+{
+	/* <LF> = end of filename */
+	if (data == 0x0A) {
+		msg_viewimage();
+		return;
+	}
+
+	/* Ignore space/control char */
+	if (data > ' ') {
+		if ((char *)VGAFilePtr < (VGAFileBuf + sizeof(VGAFileBuf)))
+			*VGAFilePtr++ = data;
+	}
+}
+
+static void msg_vga(void)
+{
+	NextCharJump = msg_filename;
+	VGAFilePtr = (uint16_t *)VGAFileBuf;
+}
+
+static void msg_normal(uint8_t data)
+{
+	/* 0x1 = text mode, 0x2 = graphics mode */
+	if (!display_mask_vga() || !(DisplayCon & 0x01)) {
+		/* Write to serial port */
+		if (DisplayMask & 0x4)
+			write_serial(data);
+
+		return;		/* Not screen */
+	}
+
+	set_fgbg();
+	printf("%c\033[0m", data);
+}
+
+static void msg_modectl(uint8_t data)
+{
+	data &= 0x07;
+	DisplayMask = data;
+	NextCharJump = msg_putchar;
+}
+
+static void msg_putchar(uint8_t ch)
+{
+	/* 10h to 17h are mode controls */
+	if (ch >= 0x10 && ch < 0x18) {
+		msg_modectl(ch);
+		return;
+	}
+
+	switch (ch) {
+	case 0x0F:		/* ^O = color code follows */
+		msg_ctrl_o();
+		break;
+	case 0x0D:		/* Ignore <CR> */
+		break;
+	case 0x0C:		/* <FF> = clear screen */
+		msg_formfeed();
+		break;
+	case 0x19:		/* <EM> = return to text mode */
+		msg_novga();
+		break;
+	case 0x18:		/* <CAN> = VGA filename follows */
+		msg_vga();
+		break;
+	default:
+		msg_normal(ch);
+		break;
+	}
+}
+
+/*
+ * Subroutine to initialize variables, also needed after loading
+ * graphics file.
+ */
+void msg_initvars(void)
+{
+	/* Initialize state machine */
+	NextCharJump = msg_putchar;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1571 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2013 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <sys/io.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <minmax.h>
+#include <alloca.h>
+#include <inttypes.h>
+#include <colortbl.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <dprintf.h>
+#include <ctype.h>
+#include <bios.h>
+#include <core.h>
+#include <fs.h>
+#include <syslinux/pxe_api.h>
+
+#include "menu.h"
+#include "config.h"
+#include "getkey.h"
+#include "core.h"
+#include "fs.h"
+
+const struct menu_parameter mparm[NPARAMS] = {
+    [P_WIDTH] = {"width", 0},
+    [P_MARGIN] = {"margin", 10},
+    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
+    [P_MENU_ROWS] = {"rows", 12},
+    [P_TABMSG_ROW] = {"tabmsgrow", 18},
+    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
+    [P_END_ROW] = {"endrow", -1},
+    [P_PASSWD_ROW] = {"passwordrow", 11},
+    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
+    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
+    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
+    [P_HSHIFT] = {"hshift", 0},
+    [P_VSHIFT] = {"vshift", 0},
+    [P_HIDDEN_ROW] = {"hiddenrow", -2},
+};
+
+/* Must match enum kernel_type */
+static const char *const kernel_types[] = {
+    "none",
+    "localboot",
+    "kernel",
+    "linux",
+    "boot",
+    "bss",
+    "pxe",
+    "fdimage",
+    "comboot",
+    "com32",
+    "config",
+    NULL
+};
+
+short uappendlen = 0;		//bytes in append= command
+short ontimeoutlen = 0;		//bytes in ontimeout command
+short onerrorlen = 0;		//bytes in onerror command
+short forceprompt = 0;		//force prompt
+short noescape = 0;		//no escape
+short nocomplete = 0;		//no label completion on TAB key
+short allowimplicit = 1;	//allow implicit kernels
+short allowoptions = 1;		//user-specified options allowed
+short includelevel = 1;		//nesting level
+short defaultlevel = 0;		//the current level of default
+short vkernel = 0;		//have we seen any "label" statements?
+extern short NoHalt;		//idle.c
+
+const char *onerror = NULL;	//"onerror" command line
+const char *ontimeout = NULL;	//"ontimeout" command line
+
+__export const char *default_cmd = NULL;	//"default" command line
+
+/* Empty refstring */
+const char *empty_string;
+
+/* Root menu, starting menu, hidden menu, and list of all menus */
+struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
+
+/* These are global parameters regardless of which menu we're displaying */
+int shiftkey = 0;		/* Only display menu if shift key pressed */
+int hiddenmenu = 0;
+long long totaltimeout = 0;
+unsigned int kbdtimeout = 0;
+
+/* Keep track of global default */
+static int has_ui = 0;		/* DEFAULT only counts if UI is found */
+extern const char *globaldefault;
+static bool menusave = false;	/* True if there is any "menu save" */
+
+/* Linked list of all entires, hidden or not; used by unlabel() */
+static struct menu_entry *all_entries;
+static struct menu_entry **all_entries_end = &all_entries;
+
+static const struct messages messages[MSG_COUNT] = {
+    [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."},
+    [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"},
+    [MSG_NOTAB] = {"notabmsg", ""},
+    [MSG_PASSPROMPT] = {"passprompt", "Password required"},
+};
+
+#define astrdup(x) ({ char *__x = (x); \
+                      size_t __n = strlen(__x) + 1; \
+                      char *__p = alloca(__n); \
+                      if ( __p ) memcpy(__p, __x, __n); \
+                      __p; })
+
+/*
+ * Search the list of all menus for a specific label
+ */
+static struct menu *find_menu(const char *label)
+{
+    struct menu *m;
+
+    for (m = menu_list; m; m = m->next) {
+	if (!strcmp(label, m->label))
+	    return m;
+    }
+
+    return NULL;
+}
+
+#define MAX_LINE 4096
+
+/* Strip ^ from a string, returning a new reference to the same refstring
+   if none present */
+static const char *strip_caret(const char *str)
+{
+    const char *p, *r;
+    char *q;
+    int carets = 0;
+
+    p = str;
+    for (;;) {
+	p = strchr(p, '^');
+	if (!p)
+	    break;
+	carets++;
+	p++;
+    }
+
+    if (!carets)
+	return refstr_get(str);
+
+    r = q = refstr_alloc(strlen(str) - carets);
+    for (p = str; *p; p++)
+	if (*p != '^')
+	    *q++ = *p;
+
+    *q = '\0';			/* refstr_alloc() already did this... */
+
+    return r;
+}
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+/* Returns a pointer to the first character past the keyword */
+static char *looking_at(char *line, const char *kwd)
+{
+    char *p = line;
+    const char *q = kwd;
+
+    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
+	p++;
+	q++;
+    }
+
+    if (*q)
+	return NULL;		/* Didn't see the keyword */
+
+    return my_isspace(*p) ? p : NULL;	/* Must be EOL or whitespace */
+}
+
+static struct menu *new_menu(struct menu *parent,
+			     struct menu_entry *parent_entry, const char *label)
+{
+    struct menu *m = calloc(1, sizeof(struct menu));
+    int i;
+	
+	//dprintf("enter: menu_label = %s", label);
+
+    m->label = label;
+    m->title = refstr_get(empty_string);
+
+    if (parent) {
+	/* Submenu */
+	m->parent = parent;
+	m->parent_entry = parent_entry;
+	parent_entry->action = MA_SUBMENU;
+	parent_entry->submenu = m;
+
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstr_get(parent->messages[i]);
+
+	memcpy(m->mparm, parent->mparm, sizeof m->mparm);
+
+	m->allowedit = parent->allowedit;
+	m->timeout = parent->timeout;
+	m->save = parent->save;
+
+	m->ontimeout = refstr_get(parent->ontimeout);
+	m->onerror = refstr_get(parent->onerror);
+	m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
+	m->menu_background = refstr_get(parent->menu_background);
+
+	m->color_table = copy_color_table(parent->color_table);
+
+	for (i = 0; i < 12; i++) {
+	    m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname);
+	    m->fkeyhelp[i].background =
+		refstr_get(parent->fkeyhelp[i].background);
+	}
+    } else {
+	/* Root menu */
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstrdup(messages[i].defmsg);
+	for (i = 0; i < NPARAMS; i++)
+	    m->mparm[i] = mparm[i].value;
+
+	m->allowedit = true;	/* Allow edits of the command line */
+	m->color_table = default_color_table();
+    }
+
+    m->next = menu_list;
+    menu_list = m;
+
+    return m;
+}
+
+struct labeldata {
+    const char *label;
+    const char *kernel;
+    enum kernel_type type;
+    const char *append;
+    const char *initrd;
+    const char *menulabel;
+    const char *passwd;
+    char *helptext;
+    unsigned int ipappend;
+    unsigned int menuhide;
+    unsigned int menudefault;
+    unsigned int menuseparator;
+    unsigned int menudisabled;
+    unsigned int menuindent;
+    enum menu_action action;
+    int save;
+    struct menu *submenu;
+};
+
+/* Menu currently being parsed */
+static struct menu *current_menu;
+
+static void clear_label_data(struct labeldata *ld)
+{
+    refstr_put(ld->label);
+    refstr_put(ld->kernel);
+    refstr_put(ld->append);
+    refstr_put(ld->initrd);
+    refstr_put(ld->menulabel);
+    refstr_put(ld->passwd);
+
+    memset(ld, 0, sizeof *ld);
+}
+
+static struct menu_entry *new_entry(struct menu *m)
+{
+    struct menu_entry *me;
+
+    //dprintf("enter, call from menu %s", m->label);
+
+    if (m->nentries >= m->nentries_space) {
+	if (!m->nentries_space)
+	    m->nentries_space = 1;
+	else
+	    m->nentries_space <<= 1;
+
+	m->menu_entries = realloc(m->menu_entries, m->nentries_space *
+				  sizeof(struct menu_entry *));
+    }
+
+    me = calloc(1, sizeof(struct menu_entry));
+    me->menu = m;
+    me->entry = m->nentries;
+    m->menu_entries[m->nentries++] = me;
+    *all_entries_end = me;
+    all_entries_end = &me->next;
+
+    return me;
+}
+
+static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
+{
+    const char *p = strchr(me->displayname, '^');
+
+    if (me->action != MA_DISABLED) {
+	if (p && p[1]) {
+	    unsigned char hotkey = p[1] & ~0x20;
+	    if (!m->menu_hotkeys[hotkey]) {
+		me->hotkey = hotkey;
+		m->menu_hotkeys[hotkey] = me;
+	    }
+	}
+    }
+}
+
+/*
+ * Copy a string, converting whitespace characters to underscores
+ * and compacting them.  Return a pointer to the final null.
+ */
+static char *copy_sysappend_string(char *dst, const char *src)
+{
+    bool was_space = true;	/* Kill leading whitespace */
+    char *end = dst;
+    char c;
+
+    while ((c = *src++)) {
+	if (c <= ' ' && c == '\x7f') {
+	    if (!was_space)
+		*dst++ = '_';
+	    was_space = true;
+	} else {
+	    *dst++ = c;
+	    end = dst;
+	    was_space = false;
+	}
+    }
+    *end = '\0';
+    return end;
+}
+
+static void record(struct menu *m, struct labeldata *ld, const char *append)
+{
+	int i;
+	struct menu_entry *me;
+	const struct syslinux_ipappend_strings *ipappend;
+
+	if (!ld->label)
+		return;			/* Nothing defined */
+
+	/* Hidden entries are recorded on a special "hidden menu" */
+	if (ld->menuhide)
+		m = hide_menu;
+
+	char ipoptions[4096], *ipp;
+	const char *a;
+	char *s;
+
+	me = new_entry(m);
+
+	me->displayname = ld->menulabel
+	    ? refstr_get(ld->menulabel) : refstr_get(ld->label);
+	me->label = refstr_get(ld->label);
+	me->passwd = refstr_get(ld->passwd);
+	me->helptext = ld->helptext;
+	me->hotkey = 0;
+	me->action = ld->action ? ld->action : MA_CMD;
+	me->save = ld->save ? (ld->save > 0) : m->save;
+
+	if (ld->menuindent) {
+	    const char *dn;
+
+	    rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname);
+	    refstr_put(me->displayname);
+	    me->displayname = dn;
+	}
+
+	if (ld->menuseparator) {
+	    refstr_put(me->displayname);
+	    me->displayname = refstr_get(empty_string);
+	}
+
+	if (ld->menuseparator || ld->menudisabled) {
+	    me->action = MA_DISABLED;
+	    refstr_put(me->label);
+	    me->label = NULL;
+	    refstr_put(me->passwd);
+	    me->passwd = NULL;
+	}
+
+	if (ld->menulabel)
+	    consider_for_hotkey(m, me);
+
+	switch (me->action) {
+	case MA_CMD:
+	    ipp = ipoptions;
+	    *ipp = '\0';
+
+	    if (ld->initrd)
+		ipp += sprintf(ipp, " initrd=%s", ld->initrd);
+
+	    if (ld->ipappend) {
+		ipappend = syslinux_ipappend_strings();
+		for (i = 0; i < ipappend->count; i++) {
+		    if ((ld->ipappend & (1U << i)) &&
+			ipappend->ptr[i] && ipappend->ptr[i][0]) {
+			*ipp++ = ' ';
+			ipp = copy_sysappend_string(ipp, ipappend->ptr[i]);
+		    }
+		}
+	    }
+
+	    a = ld->append;
+	    if (!a)
+		a = append;
+	    if (!a || (a[0] == '-' && !a[1]))
+		a = "";
+	    s = a[0] ? " " : "";
+
+	    if (ld->type == KT_KERNEL)
+		rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
+	    else
+		rsprintf(&me->cmdline, ".%s %s%s%s%s",
+			 kernel_types[ld->type], ld->kernel, s, a, ipoptions);
+		dprintf("type = %s, cmd = %s", kernel_types[ld->type], me->cmdline);
+	    break;
+
+	case MA_GOTO_UNRES:
+	case MA_EXIT_UNRES:
+	    me->cmdline = refstr_get(ld->kernel);
+	    break;
+
+	case MA_GOTO:
+	case MA_EXIT:
+	    me->submenu = ld->submenu;
+	    break;
+
+	default:
+	    break;
+	}
+
+	if (ld->menudefault && me->action == MA_CMD)
+	    m->defentry = m->nentries - 1;
+
+    clear_label_data(ld);
+}
+
+static struct menu *begin_submenu(const char *tag)
+{
+    struct menu_entry *me;
+
+    if (!tag[0])
+	tag = NULL;
+
+    me = new_entry(current_menu);
+    me->displayname = refstrdup(tag);
+    return new_menu(current_menu, me, refstr_get(me->displayname));
+}
+
+static struct menu *end_submenu(void)
+{
+    return current_menu->parent ? current_menu->parent : current_menu;
+}
+
+void print_labels(const char *prefix, size_t len)
+{
+    struct menu_entry *me;
+
+    printf("\n");
+    for (me = all_entries; me; me = me->next ) {
+	if (!me->label)
+	    continue;
+
+	if (!strncmp(prefix, me->label, len))
+	    printf(" %s", me->label);
+    }
+    printf("\n");
+}
+
+struct menu_entry *find_label(const char *str)
+{
+    const char *p;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos])
+	    return me;
+    }
+
+    return NULL;
+}
+
+static const char *unlabel(const char *str)
+{
+    /* Convert a CLI-style command line to an executable command line */
+    const char *p;
+    const char *q;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos]) {
+	    /* Found matching label */
+	    rsprintf(&q, "%s%s", me->cmdline, p);
+	    refstr_put(str);
+	    return q;
+	}
+    }
+
+    return str;
+}
+
+static const char *__refdup_word(char *p, char **ref)
+{
+    char *sp = p;
+    char *ep = sp;
+
+    while (*ep && !my_isspace(*ep))
+	ep++;
+
+    if (ref)
+	*ref = ep;
+    return refstrndup(sp, ep - sp);
+}
+
+static const char *refdup_word(char **p)
+{
+    return __refdup_word(*p, p);
+}
+
+int my_isxdigit(char c)
+{
+    unsigned int uc = c;
+
+    return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6;
+}
+
+unsigned int hexval(char c)
+{
+    unsigned char uc = c | 0x20;
+    unsigned int v;
+
+    v = uc - '0';
+    if (v < 10)
+	return v;
+
+    return uc - 'a' + 10;
+}
+
+unsigned int hexval2(const char *p)
+{
+    return (hexval(p[0]) << 4) + hexval(p[1]);
+}
+
+uint32_t parse_argb(char **p)
+{
+    char *sp = *p;
+    char *ep;
+    uint32_t argb;
+    size_t len, dl;
+
+    if (*sp == '#')
+	sp++;
+
+    ep = sp;
+
+    while (my_isxdigit(*ep))
+	ep++;
+
+    *p = ep;
+    len = ep - sp;
+
+    switch (len) {
+    case 3:			/* #rgb */
+	argb =
+	    0xff000000 +
+	    (hexval(sp[0]) * 0x11 << 16) +
+	    (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11);
+	break;
+    case 4:			/* #argb */
+	argb =
+	    (hexval(sp[0]) * 0x11 << 24) +
+	    (hexval(sp[1]) * 0x11 << 16) +
+	    (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11);
+	break;
+    case 6:			/* #rrggbb */
+    case 9:			/* #rrrgggbbb */
+    case 12:			/* #rrrrggggbbbb */
+	dl = len / 3;
+	argb =
+	    0xff000000 +
+	    (hexval2(sp + 0) << 16) +
+	    (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2);
+	break;
+    case 8:			/* #aarrggbb */
+	/* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb,
+	   assume the latter is a more common format */
+    case 16:			/* #aaaarrrrggggbbbb */
+	dl = len / 4;
+	argb =
+	    (hexval2(sp + 0) << 24) +
+	    (hexval2(sp + dl) << 16) +
+	    (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3);
+	break;
+    default:
+	argb = 0xffff0000;	/* Bright red (error indication) */
+	break;
+    }
+
+    return argb;
+}
+
+/*
+ * Parser state.  This is global so that including multiple
+ * files work as expected, which is that everything works the
+ * same way as if the files had been concatenated together.
+ */
+//static const char *append = NULL;
+extern const char *append;
+extern uint16_t PXERetry;
+static struct labeldata ld;
+
+static int parse_main_config(const char *filename);
+
+static char *is_kernel_type(char *cmdstr, enum kernel_type *type)
+{
+    const char *const *p;
+    char *q;
+    enum kernel_type t = KT_NONE;
+
+    for (p = kernel_types; *p; p++, t++) {
+	if ((q = looking_at(cmdstr, *p))) {
+	    *type = t;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+static char *is_message_name(char *cmdstr, enum message_number *msgnr)
+{
+    char *q;
+    enum message_number i;
+
+    for (i = 0; i < MSG_COUNT; i++) {
+	if ((q = looking_at(cmdstr, messages[i].name))) {
+	    *msgnr = i;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+extern void get_msg_file(char *);
+
+void cat_help_file(int key)
+{
+	struct menu *cm = current_menu;
+	int fkey;
+
+	switch (key) {
+	case KEY_F1:
+		fkey = 0;
+		break;
+	case KEY_F2:
+		fkey = 1;
+		break;
+	case KEY_F3:
+		fkey = 2;
+		break;
+	case KEY_F4:
+		fkey = 3;
+		break;
+	case KEY_F5:
+		fkey = 4;
+		break;
+	case KEY_F6:
+		fkey = 5;
+		break;
+	case KEY_F7:
+		fkey = 6;
+		break;
+	case KEY_F8:
+		fkey = 7;
+		break;
+	case KEY_F9:
+		fkey = 8;
+		break;
+	case KEY_F10:
+		fkey = 9;
+		break;
+	case KEY_F11:
+		fkey = 10;
+		break;
+	case KEY_F12:
+		fkey = 11;
+		break;
+	default:
+		fkey = -1;
+		break;
+	}
+
+	if (fkey == -1)
+		return;
+
+	if (cm->fkeyhelp[fkey].textname) {
+		printf("\n");
+		get_msg_file((char *)cm->fkeyhelp[fkey].textname);
+	}
+}
+
+static char *is_fkey(char *cmdstr, int *fkeyno)
+{
+    char *q;
+    int no;
+
+    if ((cmdstr[0] | 0x20) != 'f')
+	return NULL;
+
+    no = strtoul(cmdstr + 1, &q, 10);
+    if (!my_isspace(*q))
+	return NULL;
+
+    if (no < 0 || no > 12)
+	return NULL;
+
+    *fkeyno = (no == 0) ? 10 : no - 1;
+    return q;
+}
+
+extern uint8_t FlowIgnore;
+extern uint8_t FlowInput;
+extern uint8_t FlowOutput;
+extern uint16_t SerialPort;
+extern uint16_t BaudDivisor;
+static uint8_t SerialNotice = 1;
+
+#define DEFAULT_BAUD	9600
+#define BAUD_DIVISOR	115200
+
+extern void sirq_cleanup_nowipe(void);
+extern void sirq_install(void);
+extern void write_serial_str(char *);
+
+extern void loadfont(const char *);
+extern void loadkeys(const char *);
+
+extern char syslinux_banner[];
+extern char copyright_str[];
+
+/*
+ * PATH-based lookup
+ *
+ * Each entry in the PATH directive is separated by a colon, e.g.
+ *
+ *     PATH /bar:/bin/foo:/baz/bar/bin
+ */
+static int parse_path(char *p)
+{
+    struct path_entry *entry;
+    const char *str;
+
+    while (*p) {
+	char *c = p;
+
+	/* Find the next directory */
+	while (*c && *c != ':')
+	    c++;
+
+	str = refstrndup(p, c - p);
+	if (!str)
+	    goto bail;
+
+	entry = path_add(str);
+	refstr_put(str);
+
+	if (!entry)
+	    goto bail;
+
+	if (!*c++)
+	    break;
+	p = c;
+    }
+
+    return 0;
+
+bail:
+    return -1;
+}
+
+static void parse_config_file(FILE * f);
+
+static void do_include_menu(char *str, struct menu *m)
+{
+    const char *file;
+    char *p;
+    FILE *f;
+    int fd;
+
+    p = skipspace(str);
+    file = refdup_word(&p);
+    p = skipspace(p);
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+	goto put;
+
+    f = fdopen(fd, "r");
+    if (!f)
+	goto bail;
+
+    if (*p) {
+	record(m, &ld, append);
+	m = current_menu = begin_submenu(p);
+    }
+
+    parse_config_file(f);
+
+    if (*p) {
+	record(m, &ld, append);
+	m = current_menu = end_submenu();
+    }
+
+bail:
+    close(fd);
+put:
+    refstr_put(file);
+
+}
+
+static void do_include(char *str)
+{
+    const char *file;
+    char *p;
+    FILE *f;
+    int fd;
+
+    p = skipspace(str);
+    file = refdup_word(&p);
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+	goto put;
+
+    f = fdopen(fd, "r");
+    if (f)
+	parse_config_file(f);
+
+    close(fd);
+put:
+    refstr_put(file);
+}
+
+static void parse_config_file(FILE * f)
+{
+    char line[MAX_LINE], *p, *ep, ch;
+    enum kernel_type type;
+    enum message_number msgnr;
+    int fkeyno;
+    struct menu *m = current_menu;
+
+    while (fgets(line, sizeof line, f)) {
+	p = strchr(line, '\r');
+	if (p)
+	    *p = '\0';
+	p = strchr(line, '\n');
+	if (p)
+	    *p = '\0';
+
+	p = skipspace(line);
+
+	if (looking_at(p, "menu")) {
+
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "label")) {
+			if (ld.label) {
+				refstr_put(ld.menulabel);
+				ld.menulabel = refstrdup(skipspace(p + 5));
+			} else if (m->parent_entry) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstrdup(skipspace(p + 5));
+				consider_for_hotkey(m->parent, m->parent_entry);
+				if (!m->title[0]) {
+				/* MENU LABEL -> MENU TITLE on submenu */
+				refstr_put(m->title);
+				m->title = strip_caret(m->parent_entry->displayname);
+				}
+			}
+			} else if (looking_at(p, "title")) {
+			refstr_put(m->title);
+			m->title = refstrdup(skipspace(p + 5));
+			if (m->parent_entry) {
+				/* MENU TITLE -> MENU LABEL on submenu */
+				if (m->parent_entry->displayname == m->label) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstr_get(m->title);
+				}
+			}
+	    } else if (looking_at(p, "default")) {
+		if (ld.label) {
+		    ld.menudefault = 1;
+		} else if (m->parent_entry) {
+		    m->parent->defentry = m->parent_entry->entry;
+		}
+	    } else if (looking_at(p, "hide")) {
+		ld.menuhide = 1;
+	    } else if (looking_at(p, "passwd")) {
+		if (ld.label) {
+		    refstr_put(ld.passwd);
+		    ld.passwd = refstrdup(skipspace(p + 6));
+		} else if (m->parent_entry) {
+		    refstr_put(m->parent_entry->passwd);
+		    m->parent_entry->passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if (looking_at(p, "shiftkey")) {
+		shiftkey = 1;
+	    } else if (looking_at(p, "save")) {
+		menusave = true;
+		if (ld.label)
+		    ld.save = 1;
+		else
+		    m->save = true;
+	    } else if (looking_at(p, "nosave")) {
+		if (ld.label)
+		    ld.save = -1;
+		else
+		    m->save = false;
+	    } else if (looking_at(p, "onerror")) {
+		refstr_put(m->onerror);
+		m->onerror = refstrdup(skipspace(p + 7));
+		onerrorlen = strlen(m->onerror);
+		refstr_put(onerror);
+		onerror = refstrdup(m->onerror);
+	    } else if (looking_at(p, "master")) {
+		p = skipspace(p + 6);
+		if (looking_at(p, "passwd")) {
+		    refstr_put(m->menu_master_passwd);
+		    m->menu_master_passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if ((ep = looking_at(p, "include"))) {
+		do_include_menu(ep, m);
+	    } else if ((ep = looking_at(p, "background"))) {
+		p = skipspace(ep);
+		refstr_put(m->menu_background);
+		m->menu_background = refdup_word(&p);
+	    } else if ((ep = looking_at(p, "hidden"))) {
+		hiddenmenu = 1;
+	    } else if ((ep = is_message_name(p, &msgnr))) {
+		refstr_put(m->messages[msgnr]);
+		m->messages[msgnr] = refstrdup(skipspace(ep));
+	    } else if ((ep = looking_at(p, "color")) ||
+		       (ep = looking_at(p, "colour"))) {
+		int i;
+		struct color_table *cptr;
+		p = skipspace(ep);
+		cptr = m->color_table;
+		for (i = 0; i < menu_color_table_size; i++) {
+		    if ((ep = looking_at(p, cptr->name))) {
+			p = skipspace(ep);
+			if (*p) {
+			    if (looking_at(p, "*")) {
+				p++;
+			    } else {
+				refstr_put(cptr->ansi);
+				cptr->ansi = refdup_word(&p);
+			    }
+
+			    p = skipspace(p);
+			    if (*p) {
+				if (looking_at(p, "*"))
+				    p++;
+				else
+				    cptr->argb_fg = parse_argb(&p);
+
+				p = skipspace(p);
+				if (*p) {
+				    if (looking_at(p, "*"))
+					p++;
+				    else
+					cptr->argb_bg = parse_argb(&p);
+
+				    /* Parse a shadow mode */
+				    p = skipspace(p);
+				    ch = *p | 0x20;
+				    if (ch == 'n')	/* none */
+					cptr->shadow = SHADOW_NONE;
+				    else if (ch == 's')	/* std, standard */
+					cptr->shadow = SHADOW_NORMAL;
+				    else if (ch == 'a')	/* all */
+					cptr->shadow = SHADOW_ALL;
+				    else if (ch == 'r')	/* rev, reverse */
+					cptr->shadow = SHADOW_REVERSE;
+				}
+			    }
+			}
+			break;
+		    }
+		    cptr++;
+		}
+	    } else if ((ep = looking_at(p, "msgcolor")) ||
+		       (ep = looking_at(p, "msgcolour"))) {
+		unsigned int fg_mask = MSG_COLORS_DEF_FG;
+		unsigned int bg_mask = MSG_COLORS_DEF_BG;
+		enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW;
+
+		p = skipspace(ep);
+		if (*p) {
+		    if (!looking_at(p, "*"))
+			fg_mask = parse_argb(&p);
+
+		    p = skipspace(p);
+		    if (*p) {
+			if (!looking_at(p, "*"))
+			    bg_mask = parse_argb(&p);
+
+			p = skipspace(p);
+			switch (*p | 0x20) {
+			case 'n':
+			    shadow = SHADOW_NONE;
+			    break;
+			case 's':
+			    shadow = SHADOW_NORMAL;
+			    break;
+			case 'a':
+			    shadow = SHADOW_ALL;
+			    break;
+			case 'r':
+			    shadow = SHADOW_REVERSE;
+			    break;
+			default:
+			    /* go with default */
+			    break;
+			}
+		    }
+		}
+		set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow);
+	    } else if (looking_at(p, "separator")) {
+		record(m, &ld, append);
+		ld.label = refstr_get(empty_string);
+		ld.menuseparator = 1;
+		record(m, &ld, append);
+	    } else if (looking_at(p, "disable") || looking_at(p, "disabled")) {
+		ld.menudisabled = 1;
+	    } else if (looking_at(p, "indent")) {
+		ld.menuindent = atoi(skipspace(p + 6));
+	    } else if (looking_at(p, "begin")) {
+		record(m, &ld, append);
+		m = current_menu = begin_submenu(skipspace(p + 5));
+	    } else if (looking_at(p, "end")) {
+		record(m, &ld, append);
+		m = current_menu = end_submenu();
+	    } else if (looking_at(p, "quit")) {
+		if (ld.label)
+		    ld.action = MA_QUIT;
+	    } else if (looking_at(p, "goto")) {
+		if (ld.label) {
+		    ld.action = MA_GOTO_UNRES;
+		    refstr_put(ld.kernel);
+		    ld.kernel = refstrdup(skipspace(p + 4));
+		}
+	    } else if (looking_at(p, "exit")) {
+		p = skipspace(p + 4);
+		if (ld.label && m->parent) {
+		    if (*p) {
+			/* This is really just a goto, except for the marker */
+			ld.action = MA_EXIT_UNRES;
+			refstr_put(ld.kernel);
+			ld.kernel = refstrdup(p);
+		    } else {
+			ld.action = MA_EXIT;
+			ld.submenu = m->parent;
+		    }
+		}
+	    } else if (looking_at(p, "start")) {
+		start_menu = m;
+	    } else {
+		/* Unknown, check for layout parameters */
+		enum parameter_number mp;
+		for (mp = 0; mp < NPARAMS; mp++) {
+		    if ((ep = looking_at(p, mparm[mp].name))) {
+			m->mparm[mp] = atoi(skipspace(ep));
+			break;
+		    }
+		}
+	    }
+	}
+	/* feng: menu handling end */	
+	else if (looking_at(p, "text")) {
+
+		/* loop till we fined the "endtext" */
+	    enum text_cmd {
+		TEXT_UNKNOWN,
+		TEXT_HELP
+	    } cmd = TEXT_UNKNOWN;
+	    int len = ld.helptext ? strlen(ld.helptext) : 0;
+	    int xlen;
+
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "help"))
+		cmd = TEXT_HELP;
+
+	    while (fgets(line, sizeof line, f)) {
+		p = skipspace(line);
+		if (looking_at(p, "endtext"))
+		    break;
+
+		xlen = strlen(line);
+
+		switch (cmd) {
+		case TEXT_UNKNOWN:
+		    break;
+		case TEXT_HELP:
+		    ld.helptext = realloc(ld.helptext, len + xlen + 1);
+		    memcpy(ld.helptext + len, line, xlen + 1);
+		    len += xlen;
+		    break;
+		}
+	    }
+	} else if ((ep = is_fkey(p, &fkeyno))) {
+	    p = skipspace(ep);
+	    if (m->fkeyhelp[fkeyno].textname) {
+		refstr_put(m->fkeyhelp[fkeyno].textname);
+		m->fkeyhelp[fkeyno].textname = NULL;
+	    }
+	    if (m->fkeyhelp[fkeyno].background) {
+		refstr_put(m->fkeyhelp[fkeyno].background);
+		m->fkeyhelp[fkeyno].background = NULL;
+	    }
+
+	    refstr_put(m->fkeyhelp[fkeyno].textname);
+	    m->fkeyhelp[fkeyno].textname = refdup_word(&p);
+	    if (*p) {
+		p = skipspace(p);
+		m->fkeyhelp[fkeyno].background = refdup_word(&p);
+	    }
+	} else if ((ep = looking_at(p, "include"))) {
+	    do_include(ep);
+	} else if (looking_at(p, "append")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.append);
+		ld.append = a;
+	    } else {
+		refstr_put(append);
+		append = a;
+	    }
+	    //dprintf("we got a append: %s", a);
+	} else if (looking_at(p, "initrd")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.initrd);
+		ld.initrd = a;
+	    } else {
+		/* Ignore */
+	    }
+	} else if (looking_at(p, "label")) {
+	    p = skipspace(p + 5);
+	    /* when first time see "label", it will not really record anything */
+	    record(m, &ld, append);
+	    ld.label = __refdup_word(p, NULL);
+	    ld.kernel = __refdup_word(p, NULL);
+	    /* feng: this is the default type for all */
+	    ld.type = KT_KERNEL;
+	    ld.passwd = NULL;
+	    ld.append = NULL;
+	    ld.initrd = NULL;
+	    ld.menulabel = NULL;
+	    ld.helptext = NULL;
+	    ld.ipappend = SysAppends;
+	    ld.menudefault = ld.menuhide = ld.menuseparator =
+		ld.menudisabled = ld.menuindent = 0;
+	} else if ((ep = is_kernel_type(p, &type))) {
+	    if (ld.label) {
+		refstr_put(ld.kernel);
+		ld.kernel = refstrdup(skipspace(ep));
+		ld.type = type;
+		//dprintf("got a kernel: %s, type = %d", ld.kernel, ld.type);
+	    }
+	} else if (looking_at(p, "timeout")) {
+	    kbdtimeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "totaltimeout")) {
+	    totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "ontimeout")) {
+	    ontimeout = refstrdup(skipspace(p + 9));
+	    ontimeoutlen = strlen(ontimeout);
+	} else if (looking_at(p, "allowoptions")) {
+	    allowoptions = !!atoi(skipspace(p + 12));
+	} else if ((ep = looking_at(p, "ipappend")) ||
+		   (ep = looking_at(p, "sysappend"))) {
+	    uint32_t s = strtoul(skipspace(ep), NULL, 0);
+	    if (ld.label)
+		ld.ipappend = s;
+	    else
+		SysAppends = s;
+	} else if (looking_at(p, "default")) {
+	    /* default could be a kernel image or another label */
+	    refstr_put(globaldefault);
+	    globaldefault = refstrdup(skipspace(p + 7));
+
+	    /*
+	     * On the chance that "default" is actually a kernel image
+	     * and not a label, store a copy of it, but only if we
+	     * haven't seen a "ui" command. "ui" commands take
+	     * precendence over "default" commands.
+	     */
+	    if (defaultlevel < LEVEL_UI) {
+		defaultlevel = LEVEL_DEFAULT;
+		refstr_put(default_cmd);
+		default_cmd = refstrdup(globaldefault);
+	    }
+	} else if (looking_at(p, "ui")) {
+	    has_ui = 1;
+	    defaultlevel = LEVEL_UI;
+	    refstr_put(default_cmd);
+	    default_cmd = refstrdup(skipspace(p + 2));
+	}
+	
+	/*
+	 * subset 1:  pc_opencmd 
+	 * display/font/kbdmap are rather similar, open a file then do sth
+	 */
+	else if (looking_at(p, "display")) {
+		const char *filename;
+		char *dst = KernelName;
+		size_t len = FILENAME_MAX - 1;
+
+		filename = refstrdup(skipspace(p + 7));
+
+		while (len-- && not_whitespace(*filename))
+			*dst++ = *filename++;
+		*dst = '\0';
+
+		get_msg_file(KernelName);
+		refstr_put(filename);
+	} else if (looking_at(p, "font")) {
+		const char *filename;
+		char *dst = KernelName;
+		size_t len = FILENAME_MAX - 1;
+
+		filename = refstrdup(skipspace(p + 4));
+
+		while (len-- && not_whitespace(*filename))
+			*dst++ = *filename++;
+		*dst = '\0';
+
+		loadfont(KernelName);
+		refstr_put(filename);
+	} else if (looking_at(p, "kbdmap")) {
+		const char *filename;
+
+		filename = refstrdup(skipspace(p + 6));
+		loadkeys(filename);
+		refstr_put(filename);
+	}
+	/*
+	 * subset 2:  pc_setint16
+	 * set a global flag
+	 */
+	else if (looking_at(p, "implicit")) {
+		allowimplicit = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "prompt")) {
+		forceprompt = atoi(skipspace(p + 6));
+	} else if (looking_at(p, "console")) {
+		DisplayCon = atoi(skipspace(p + 7));
+	} else if (looking_at(p, "allowoptions")) {
+		allowoptions = atoi(skipspace(p + 12));
+	} else if (looking_at(p, "noescape")) {
+		noescape = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "nocomplete")) {
+		nocomplete = atoi(skipspace(p + 10));
+	} else if (looking_at(p, "nohalt")) {
+		NoHalt = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "onerror")) {
+		refstr_put(m->onerror);
+		m->onerror = refstrdup(skipspace(p + 7));
+		onerrorlen = strlen(m->onerror);
+		refstr_put(onerror);
+		onerror = refstrdup(m->onerror);
+	}
+
+	else if (looking_at(p, "pxeretry"))
+		PXERetry = atoi(skipspace(p + 8));
+
+	/* serial setting, bps, flow control */
+	else if (looking_at(p, "serial")) {
+		uint16_t port, flow;
+		uint32_t baud;
+
+		p = skipspace(p + 6);
+		port = atoi(p);
+
+		while (isalnum(*p))
+			p++;
+		p = skipspace(p);
+
+		/* Default to no flow control */
+		FlowOutput = 0;
+		FlowInput = 0;
+
+		baud = DEFAULT_BAUD;
+		if (isalnum(*p)) {
+			uint8_t ignore;
+
+			/* setup baud */
+			baud = atoi(p);
+			while (isalnum(*p))
+				p++;
+			p = skipspace(p);
+
+			ignore = 0;
+			flow = 0;
+			if (isalnum(*p)) {
+				/* flow control */
+				flow = atoi(p);
+				ignore = ((flow & 0x0F00) >> 4);
+			}
+
+			FlowIgnore = ignore;
+			flow = ((flow & 0xff) << 8) | (flow & 0xff);
+			flow &= 0xF00B;
+			FlowOutput = (flow & 0xff);
+			FlowInput = ((flow & 0xff00) >> 8);
+		}
+
+		/*
+		 * Parse baud
+		 */
+		if (baud < 75) {
+			/* < 75 baud == bogus */
+			SerialPort = 0;
+			continue;
+		}
+
+		baud = BAUD_DIVISOR / baud;
+		baud &= 0xffff;
+		BaudDivisor = baud;
+
+		port = get_serial_port(port);
+		SerialPort = port;
+
+		/*
+		 * Begin code to actually set up the serial port
+		 */
+		sirq_cleanup_nowipe();
+
+		outb(0x83, port + 3); /* Enable DLAB */
+		io_delay();
+
+		outb((baud & 0xff), port); /* write divisor to LS */
+		io_delay();
+
+		outb(((baud & 0xff00) >> 8), port + 1); /* write to MS */
+		io_delay();
+
+		outb(0x03, port + 3); /* Disable DLAB */
+		io_delay();
+
+		/*
+		 * Read back LCR (detect missing hw). If nothing here
+		 * we'll read 00 or FF.
+		 */
+		if (inb(port + 3) != 0x03) {
+			/* Assume serial port busted */
+			SerialPort = 0;
+			continue;
+		}
+
+		outb(0x01, port + 2); /* Enable FIFOs if present */
+		io_delay();
+
+		/* Disable FIFO if unusable */
+		if (inb(port + 2) < 0x0C0) {
+			outb(0, port + 2);
+			io_delay();
+		}
+
+		/* Assert bits in MCR */
+		outb(FlowOutput, port + 4);
+		io_delay();
+
+		/* Enable interrupts if requested */
+		if (FlowOutput & 0x8)
+			sirq_install();
+
+		/* Show some life */
+		if (SerialNotice != 0) {
+			SerialNotice = 0;
+
+			write_serial_str(syslinux_banner);
+			write_serial_str(copyright_str);
+		}
+
+	} else if (looking_at(p, "say")) {
+		printf("%s\n", p+4);
+	} else if (looking_at(p, "path")) {
+		if (parse_path(skipspace(p + 4)))
+			printf("Failed to parse PATH\n");
+	} else if (looking_at(p, "sendcookies")) {
+		const union syslinux_derivative_info *sdi;
+
+		p += strlen("sendcookies");
+		sdi = syslinux_derivative_info();
+
+		if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+			SendCookies = strtoul(skipspace(p), NULL, 10);
+			http_bake_cookies();
+		}
+	}
+    }
+}
+
+static int parse_main_config(const char *filename)
+{
+	const char *mode = "r";
+	FILE *f;
+	int fd;
+
+	if (!filename)
+		fd = open_config();
+	else
+		fd = open(filename, O_RDONLY);
+
+	if (fd < 0)
+		return fd;
+
+	if (config_cwd[0]) {
+		if (chdir(config_cwd) < 0)
+			printf("Failed to chdir to %s\n", config_cwd);
+		config_cwd[0] = '\0';
+	}
+
+	f = fdopen(fd, mode);
+	parse_config_file(f);
+
+	/*
+	 * Update ConfigName so that syslinux_config_file() returns
+	 * the filename we just opened. filesystem-specific
+	 * open_config() implementations are expected to update
+	 * ConfigName themselves.
+	 */
+	if (filename)
+	    strcpy(ConfigName, filename);
+
+	return 0;
+}
+
+static void resolve_gotos(void)
+{
+    struct menu_entry *me;
+    struct menu *m;
+
+    for (me = all_entries; me; me = me->next) {
+	if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) {
+	    m = find_menu(me->cmdline);
+	    refstr_put(me->cmdline);
+	    me->cmdline = NULL;
+	    if (m) {
+		me->submenu = m;
+		me->action--;	/* Drop the _UNRES */
+	    } else {
+		me->action = MA_DISABLED;
+	    }
+	}
+    }
+}
+
+void parse_configs(char **argv)
+{
+    const char *filename;
+    struct menu *m;
+    struct menu_entry *me;
+    dprintf("enter");
+
+    empty_string = refstrdup("");
+
+    /* feng: reset current menu_list and entry list */
+    menu_list = NULL;
+    all_entries = NULL;
+
+    /* Initialize defaults for the root and hidden menus */
+    hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
+    root_menu = new_menu(NULL, NULL, refstrdup(".top"));
+    start_menu = root_menu;
+
+    /* Other initialization */
+    memset(&ld, 0, sizeof(struct labeldata));
+
+    /* Actually process the files */
+    current_menu = root_menu;
+
+    if (!argv || !*argv) {
+	if (parse_main_config(NULL) < 0) {
+	    printf("WARNING: No configuration file found\n");
+	    return;
+	}
+    } else {
+	while ((filename = *argv++)) {
+		dprintf("Parsing config: %s", filename);
+	    parse_main_config(filename);
+	}
+    }
+
+    /* On final EOF process the last label statement */
+    record(current_menu, &ld, append);
+
+    /* Common postprocessing */
+    resolve_gotos();
+
+    /* Handle global default */
+    //if (has_ui && globaldefault) {
+    if (globaldefault) {
+	dprintf("gloabldefault = %s", globaldefault);
+	me = find_label(globaldefault);
+	if (me && me->menu != hide_menu) {
+	    me->menu->defentry = me->entry;
+	    start_menu = me->menu;
+	    default_menu = me->menu;
+	}
+    }
+
+    /* If "menu save" is active, let the ADV override the global default */
+    if (menusave) {
+	size_t len;
+	const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
+	char *lstr;
+	if (lbl && len) {
+	    lstr = refstr_alloc(len);
+	    memcpy(lstr, lbl, len);	/* refstr_alloc() adds the final null */
+	    me = find_label(lstr);
+	    if (me && me->menu != hide_menu) {
+		me->menu->defentry = me->entry;
+		start_menu = me->menu;
+	    }
+	    refstr_put(lstr);
+	}
+    }
+
+    /* Final per-menu initialization, with all labels known */
+    for (m = menu_list; m; m = m->next) {
+	m->curentry = m->defentry;	/* All menus start at their defaults */
+
+	if (m->ontimeout)
+	    m->ontimeout = unlabel(m->ontimeout);
+	if (m->onerror)
+	    m->onerror = unlabel(m->onerror);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,106 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * refstr.c
+ *
+ * Simple reference-counted strings
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/module.h>
+#include "refstr.h"
+
+/* Allocate space for a refstring of len bytes, plus final null */
+/* The final null is inserted in the string; the rest is uninitialized. */
+char *refstr_alloc(size_t len)
+{
+    char *r = malloc(sizeof(unsigned int) + len + 1);
+    if (!r)
+	return NULL;
+    *(unsigned int *)r = 1;
+    r += sizeof(unsigned int);
+    r[len] = '\0';
+    return r;
+}
+
+const char *refstrndup(const char *str, size_t len)
+{
+    char *r;
+
+    if (!str)
+	return NULL;
+
+    len = strnlen(str, len);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+const char *refstrdup(const char *str)
+{
+    char *r;
+    size_t len;
+
+    if (!str)
+	return NULL;
+
+    len = strlen(str);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+int vrsprintf(const char **bufp, const char *fmt, va_list ap)
+{
+    va_list ap1;
+    int len;
+    char *p;
+
+    va_copy(ap1, ap);
+    len = vsnprintf(NULL, 0, fmt, ap1);
+    va_end(ap1);
+
+    *bufp = p = refstr_alloc(len);
+    if (!p)
+	return -1;
+
+    return vsnprintf(p, len + 1, fmt, ap);
+}
+
+int rsprintf(const char **bufp, const char *fmt, ...)
+{
+    int rv;
+    va_list ap;
+
+    va_start(ap, fmt);
+    rv = vrsprintf(bufp, fmt, ap);
+    va_end(ap);
+
+    return rv;
+}
+
+void refstr_put(const char *r)
+{
+    unsigned int *ref;
+
+    if (r) {
+	ref = (unsigned int *)r - 1;
+
+	if (!--*ref)
+	    free(ref);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/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.
+ *
+ * NOTE: Data is not written to disk unless
+ * syslinux_adv_write() is called.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <alloca.h>
+
+__export int syslinux_setadv(int tag, size_t size, const void *data)
+{
+    uint8_t *p, *advtmp;
+    size_t rleft, left;
+
+    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;
+    }
+
+    rleft = left = syslinux_adv_size();
+    p = advtmp = alloca(left);
+    memcpy(p, syslinux_adv_ptr(), left);	/* Make working copy */
+
+    while (rleft >= 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 >= rleft) {
+		/* Entire remainder is our tag */
+		break;
+	    }
+	    memmove(p, p + plen, rleft - plen);
+	    rleft -= plen;	/* Fewer bytes to read, but not to write */
+	} else {
+	    /* Not our tag */
+	    if (plen > rleft)
+		break;		/* Corrupt tag (overrun) - overwrite it */
+
+	    left -= plen;
+	    rleft -= 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 to low memory */
+    memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size());
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include <string.h>
+
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#define INFO_PRINT(fmt, args...)	printf("[COM32] " fmt, ##args)
+
+#define MAX_COMMAND_SIZE 	80	// Maximum size of the cmd line
+#define COMMAND_DELIM		" \t\n"	// Whitespace delimiters
+#define MAX_COMMAND_ARGS	(MAX_COMMAND_SIZE/2)	// Maximum argument count for
+												 // program execution
+
+/**
+ * print_help - Display usage instructions on the screen.
+ */
+static void print_help(void)
+{
+    printf("List of available commands:\n");
+    printf("exit - exits the program\n");
+    printf("help - shows this message\n");
+    printf("load <library>... - loads the libraries into the environment\n");
+    printf("spawn <executable> <args> - launches an executable module\n");
+    printf
+	("unload <library>... - unloads the libraries from the environment\n");
+    printf("list - prints the currently loaded modules\n");
+}
+
+/**
+ * print_prompt - Display the command prompt.
+ */
+static void print_prompt(void)
+{
+    printf("\nelflink> ");
+}
+
+/**
+ * read_command - Read a new command from the standard input.
+ * @cmd: the buffer to store the command
+ * @size: the maximum size of the string that can be stored in the buffer
+ *
+ * If the command is larger than the specified size, it is truncated.
+ */
+static void read_command(char *cmd, int size)
+{
+    char *nl = NULL;
+    fgets(cmd, size, stdin);
+
+    // Strip the newline
+    nl = strchr(cmd, '\n');
+
+    if (nl != NULL)
+	*nl = '\0';
+}
+
+/**
+ * process_spawn - Handles the execution of a 'spawn' command.
+ *
+ * The command line is in the internal buffer of strtok.
+ */
+static void process_spawn(void)
+{
+    // Compose the command line
+    char **cmd_line = malloc((MAX_COMMAND_ARGS + 1) * sizeof(char *));
+    int argc = 0, result;
+    char *crt_arg;
+
+    do {
+	crt_arg = strtok(NULL, COMMAND_DELIM);
+	if (crt_arg != NULL && strlen(crt_arg) > 0) {
+	    cmd_line[argc] = crt_arg;
+	    argc++;
+	} else {
+	    break;
+	}
+    } while (argc < MAX_COMMAND_ARGS);
+
+    cmd_line[argc] = NULL;
+
+    if (cmd_line[0] == NULL) {
+	printf("You must specify an executable module.\n");
+    } else {
+	result = spawnv(cmd_line[0], cmd_line);
+
+	printf("Spawn returned %d\n", result);
+    }
+
+    free(cmd_line);
+}
+
+/**
+ * process_library - Handles the execution of the 'load' and 'unload' commands.
+ * @load: contains 1 if the libraries are to be loaded, 0 for unloading.
+ *
+ * The command line is in the internal buffer of strtok.
+ */
+static void process_library(int load)
+{
+    char *crt_lib;
+    int result;
+
+    while ((crt_lib = strtok(NULL, COMMAND_DELIM)) != NULL) {
+	if (strlen(crt_lib) > 0) {
+	    if (load)
+		result = load_library(crt_lib);
+	    else
+		result = unload_library(crt_lib);
+
+	    if (result == 0) {
+		printf("Library '%s' %sloaded successfully.\n", crt_lib,
+		       load ? "" : "un");
+	    } else {
+		printf("Could not %sload library '%s': error %d\n",
+		       load ? "" : "un", crt_lib, result);
+	    }
+	}
+    }
+}
+
+/**
+ * process_list - Handles the execution of the 'list' command.
+ *
+ */
+static void process_list(void)
+{
+    struct elf_module *module;
+    struct module_dep *crt_dep;
+
+    for_each_module(module) {
+	printf("%s (%dK, %s, %s) : ", module->name, module->module_size >> 10,
+	       module->shallow ? "shallow" : "regular",
+	       module->main_func == NULL ? "library" : "program");
+
+	list_for_each_entry(crt_dep, &module->required, list) {
+	    printf("%s ", crt_dep->module->name);
+	}
+
+	printf("\n");
+    }
+}
+
+/**
+ * process_command - Recognizes the requested command and executes it.
+ * @cmd: the command to be executed.
+ *
+ * Returns 1 if the command was 'exit', 0 otherwise.
+ */
+static int process_command(char *cmd)
+{
+    char *cmd_name;
+
+    cmd_name = strtok(cmd, COMMAND_DELIM);
+
+    if (strcmp(cmd_name, "exit") == 0) {
+	printf("Goodbye!\n");
+	return 1;
+    } else if (strcmp(cmd_name, "help") == 0) {
+	print_help();
+    } else if (strcmp(cmd_name, "load") == 0) {
+	process_library(1);
+    } else if (strcmp(cmd_name, "spawn") == 0) {
+	process_spawn();
+    } else if (strcmp(cmd_name, "unload") == 0) {
+	process_library(0);
+    } else if (strcmp(cmd_name, "list") == 0) {
+	process_list();
+    } else {
+	printf("Unknown command. Type 'help' for a list of valid commands.\n");
+    }
+
+    return 0;
+}
+
+/**
+ * The entry point of 'test_com32' COM module.
+ */
+int main(int argc, char **argv)
+{
+    int done = 0;
+    int res;
+    char command[MAX_COMMAND_SIZE] = { 0 };
+
+    // Open a standard r/w console
+    openconsole(&dev_stdcon_r, &dev_stdcon_w);
+
+    res = exec_init();
+    if (res != 0) {
+	printf("Failed to initialize the execution environment.\n");
+	return res;
+    } else {
+	printf("Execution environment initialized successfully.\n");
+    }
+
+    printf("\nFor a list of available commands, type 'help'.\n");
+
+    do {
+	print_prompt();
+	read_command(command, MAX_COMMAND_SIZE);
+	done = process_command(command);
+
+    } while (!done);
+
+    exec_term();
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## GDB remote debugging
+##
+
+topdir = ../..
+MAKEDIR = $(topdir)/mk
+include $(MAKEDIR)/com32.mk
+
+CFLAGS += -fPIE
+
+LIBS	   = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC)
+LNXLIBS	   = ../libutil/libutil_lnx.a
+
+MODULES	  = gdbstub.c32
+TESTFILES =
+
+OBJS = main.o int.o serial.o gdbstub.o
+
+all: $(MODULES) $(TESTFILES)
+
+gdbstub.elf : $(OBJS) $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist clean:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+	mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)
+	install -m 644 $(MODULES) $(INSTALLROOT)$(AUXDIR)
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/gdbstub.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/gdbstub.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/gdbstub.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2008 Stefan Hajnoczi <stefanha@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; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/**
+ * @file
+ *
+ * GDB stub for remote debugging
+ *
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "serial.h"
+
+typedef uint32_t gdbreg_t;
+
+enum {
+    POSIX_EINVAL = 0x1c,	/* used to report bad arguments to GDB */
+    SIZEOF_PAYLOAD = 256,	/* buffer size of GDB payload data */
+    DR7_CLEAR = 0x00000400,	/* disable hardware breakpoints */
+    DR6_CLEAR = 0xffff0ff0,	/* clear breakpoint status */
+};
+
+/* The register snapshot, this must be in sync with interrupt handler and the
+ * GDB protocol. */
+enum {
+    GDBMACH_EAX,
+    GDBMACH_ECX,
+    GDBMACH_EDX,
+    GDBMACH_EBX,
+    GDBMACH_ESP,
+    GDBMACH_EBP,
+    GDBMACH_ESI,
+    GDBMACH_EDI,
+    GDBMACH_EIP,
+    GDBMACH_EFLAGS,
+    GDBMACH_CS,
+    GDBMACH_SS,
+    GDBMACH_DS,
+    GDBMACH_ES,
+    GDBMACH_FS,
+    GDBMACH_GS,
+    GDBMACH_NREGS,
+    GDBMACH_SIZEOF_REGS = GDBMACH_NREGS * sizeof(gdbreg_t)
+};
+
+/* Breakpoint types */
+enum {
+    GDBMACH_BPMEM,
+    GDBMACH_BPHW,
+    GDBMACH_WATCH,
+    GDBMACH_RWATCH,
+    GDBMACH_AWATCH,
+};
+
+struct gdbstub {
+    int exit_handler;		/* leave interrupt handler */
+
+    int signo;
+    gdbreg_t *regs;
+
+    void (*parse) (struct gdbstub * stub, char ch);
+    uint8_t cksum1;
+
+    /* Buffer for payload data when parsing a packet.  Once the
+     * packet has been received, this buffer is used to hold
+     * the reply payload. */
+    char buf[SIZEOF_PAYLOAD + 4];	/* $...PAYLOAD...#XX */
+    char *payload;		/* start of payload */
+    int len;			/* length of payload */
+};
+
+/** Hardware breakpoint, fields stored in x86 bit pattern form */
+struct hwbp {
+    int type;			/* type (1=write watchpoint, 3=access watchpoint) */
+    unsigned long addr;		/* linear address */
+    size_t len;			/* length (0=1-byte, 1=2-byte, 3=4-byte) */
+    int enabled;
+};
+
+static struct hwbp hwbps[4];
+static gdbreg_t dr7 = DR7_CLEAR;
+
+static inline void gdbmach_set_pc(gdbreg_t * regs, gdbreg_t pc)
+{
+    regs[GDBMACH_EIP] = pc;
+}
+
+static inline void gdbmach_set_single_step(gdbreg_t * regs, int step)
+{
+    regs[GDBMACH_EFLAGS] &= ~(1 << 8);	/* Trace Flag (TF) */
+    regs[GDBMACH_EFLAGS] |= (step << 8);
+}
+
+static inline void gdbmach_breakpoint(void)
+{
+    __asm__ __volatile__("int $3\n");
+}
+
+static struct hwbp *gdbmach_find_hwbp(int type, unsigned long addr, size_t len)
+{
+    struct hwbp *available = NULL;
+    unsigned int i;
+    for (i = 0; i < sizeof hwbps / sizeof hwbps[0]; i++) {
+	if (hwbps[i].type == type && hwbps[i].addr == addr
+	    && hwbps[i].len == len) {
+	    return &hwbps[i];
+	}
+	if (!hwbps[i].enabled) {
+	    available = &hwbps[i];
+	}
+    }
+    return available;
+}
+
+static void gdbmach_commit_hwbp(struct hwbp *bp)
+{
+    int regnum = bp - hwbps;
+
+    /* Set breakpoint address */
+    switch (regnum) {
+    case 0:
+__asm__ __volatile__("movl %0, %%dr0\n": :"r"(bp->addr));
+	break;
+    case 1:
+__asm__ __volatile__("movl %0, %%dr1\n": :"r"(bp->addr));
+	break;
+    case 2:
+__asm__ __volatile__("movl %0, %%dr2\n": :"r"(bp->addr));
+	break;
+    case 3:
+__asm__ __volatile__("movl %0, %%dr3\n": :"r"(bp->addr));
+	break;
+    }
+
+    /* Set type */
+    dr7 &= ~(0x3 << (16 + 4 * regnum));
+    dr7 |= bp->type << (16 + 4 * regnum);
+
+    /* Set length */
+    dr7 &= ~(0x3 << (18 + 4 * regnum));
+    dr7 |= bp->len << (18 + 4 * regnum);
+
+    /* Set/clear local enable bit */
+    dr7 &= ~(0x3 << 2 * regnum);
+    dr7 |= bp->enabled << 2 * regnum;
+}
+
+int gdbmach_set_breakpoint(int type, unsigned long addr, size_t len, int enable)
+{
+    struct hwbp *bp;
+
+    /* Check and convert breakpoint type to x86 type */
+    switch (type) {
+    case GDBMACH_WATCH:
+	type = 0x1;
+	break;
+    case GDBMACH_AWATCH:
+	type = 0x3;
+	break;
+    default:
+	return 0;		/* unsupported breakpoint type */
+    }
+
+    /* Only lengths 1, 2, and 4 are supported */
+    if (len != 2 && len != 4) {
+	len = 1;
+    }
+    len--;			/* convert to x86 breakpoint length bit pattern */
+
+    /* Set up the breakpoint */
+    bp = gdbmach_find_hwbp(type, addr, len);
+    if (!bp) {
+	return 0;		/* ran out of hardware breakpoints */
+    }
+    bp->type = type;
+    bp->addr = addr;
+    bp->len = len;
+    bp->enabled = enable;
+    gdbmach_commit_hwbp(bp);
+    return 1;
+}
+
+static void gdbmach_disable_hwbps(void)
+{
+    /* Store and clear hardware breakpoints */
+    __asm__ __volatile__("movl %0, %%dr7\n"::"r"(DR7_CLEAR));
+}
+
+static void gdbmach_enable_hwbps(void)
+{
+    /* Clear breakpoint status register */
+    __asm__ __volatile__("movl %0, %%dr6\n"::"r"(DR6_CLEAR));
+
+    /* Restore hardware breakpoints */
+    __asm__ __volatile__("movl %0, %%dr7\n"::"r"(dr7));
+}
+
+/* Packet parser states */
+static void gdbstub_state_new(struct gdbstub *stub, char ch);
+static void gdbstub_state_data(struct gdbstub *stub, char ch);
+static void gdbstub_state_cksum1(struct gdbstub *stub, char ch);
+static void gdbstub_state_cksum2(struct gdbstub *stub, char ch);
+static void gdbstub_state_wait_ack(struct gdbstub *stub, char ch);
+
+static void serial_write(void *buf, size_t len)
+{
+    char *p = buf;
+    while (len-- > 0)
+	serial_putc(*p++);
+}
+
+static uint8_t gdbstub_from_hex_digit(char ch)
+{
+    if (ch >= '0' && ch <= '9')
+	return ch - '0';
+    else if (ch >= 'A' && ch <= 'F')
+	return ch - 'A' + 0xa;
+    else
+	return (ch - 'a' + 0xa) & 0xf;
+}
+
+static uint8_t gdbstub_to_hex_digit(uint8_t b)
+{
+    b &= 0xf;
+    return (b < 0xa ? '0' : 'a' - 0xa) + b;
+}
+
+/*
+ * To make reading/writing device memory atomic, we check for
+ * 2- or 4-byte aligned operations and handle them specially.
+ */
+
+static void gdbstub_from_hex_buf(char *dst, char *src, int lenbytes)
+{
+    if (lenbytes == 2 && ((unsigned long)dst & 0x1) == 0) {
+	uint16_t i = gdbstub_from_hex_digit(src[2]) << 12 |
+	    gdbstub_from_hex_digit(src[3]) << 8 |
+	    gdbstub_from_hex_digit(src[0]) << 4 |
+	    gdbstub_from_hex_digit(src[1]);
+	*(uint16_t *) dst = i;
+    } else if (lenbytes == 4 && ((unsigned long)dst & 0x3) == 0) {
+	uint32_t i = gdbstub_from_hex_digit(src[6]) << 28 |
+	    gdbstub_from_hex_digit(src[7]) << 24 |
+	    gdbstub_from_hex_digit(src[4]) << 20 |
+	    gdbstub_from_hex_digit(src[5]) << 16 |
+	    gdbstub_from_hex_digit(src[2]) << 12 |
+	    gdbstub_from_hex_digit(src[3]) << 8 |
+	    gdbstub_from_hex_digit(src[0]) << 4 |
+	    gdbstub_from_hex_digit(src[1]);
+	*(uint32_t *) dst = i;
+    } else {
+	while (lenbytes-- > 0) {
+	    *dst++ = gdbstub_from_hex_digit(src[0]) << 4 |
+		gdbstub_from_hex_digit(src[1]);
+	    src += 2;
+	}
+    }
+}
+
+static void gdbstub_to_hex_buf(char *dst, char *src, int lenbytes)
+{
+    if (lenbytes == 2 && ((unsigned long)src & 0x1) == 0) {
+	uint16_t i = *(uint16_t *) src;
+	dst[0] = gdbstub_to_hex_digit(i >> 4);
+	dst[1] = gdbstub_to_hex_digit(i);
+	dst[2] = gdbstub_to_hex_digit(i >> 12);
+	dst[3] = gdbstub_to_hex_digit(i >> 8);
+    } else if (lenbytes == 4 && ((unsigned long)src & 0x3) == 0) {
+	uint32_t i = *(uint32_t *) src;
+	dst[0] = gdbstub_to_hex_digit(i >> 4);
+	dst[1] = gdbstub_to_hex_digit(i);
+	dst[2] = gdbstub_to_hex_digit(i >> 12);
+	dst[3] = gdbstub_to_hex_digit(i >> 8);
+	dst[4] = gdbstub_to_hex_digit(i >> 20);
+	dst[5] = gdbstub_to_hex_digit(i >> 16);
+	dst[6] = gdbstub_to_hex_digit(i >> 28);
+	dst[7] = gdbstub_to_hex_digit(i >> 24);
+    } else {
+	while (lenbytes-- > 0) {
+	    *dst++ = gdbstub_to_hex_digit(*src >> 4);
+	    *dst++ = gdbstub_to_hex_digit(*src);
+	    src++;
+	}
+    }
+}
+
+static uint8_t gdbstub_cksum(char *data, int len)
+{
+    uint8_t cksum = 0;
+    while (len-- > 0) {
+	cksum += (uint8_t) * data++;
+    }
+    return cksum;
+}
+
+static void gdbstub_tx_packet(struct gdbstub *stub)
+{
+    uint8_t cksum = gdbstub_cksum(stub->payload, stub->len);
+    stub->buf[0] = '$';
+    stub->buf[stub->len + 1] = '#';
+    stub->buf[stub->len + 2] = gdbstub_to_hex_digit(cksum >> 4);
+    stub->buf[stub->len + 3] = gdbstub_to_hex_digit(cksum);
+    serial_write(stub->buf, stub->len + 4);
+    stub->parse = gdbstub_state_wait_ack;
+}
+
+/* GDB commands */
+static void gdbstub_send_ok(struct gdbstub *stub)
+{
+    stub->payload[0] = 'O';
+    stub->payload[1] = 'K';
+    stub->len = 2;
+    gdbstub_tx_packet(stub);
+}
+
+static void gdbstub_send_num_packet(struct gdbstub *stub, char reply, int num)
+{
+    stub->payload[0] = reply;
+    stub->payload[1] = gdbstub_to_hex_digit((char)num >> 4);
+    stub->payload[2] = gdbstub_to_hex_digit((char)num);
+    stub->len = 3;
+    gdbstub_tx_packet(stub);
+}
+
+/* Format is arg1,arg2,...,argn:data where argn are hex integers and data is not an argument */
+static int gdbstub_get_packet_args(struct gdbstub *stub, unsigned long *args,
+				   int nargs, int *stop_idx)
+{
+    int i;
+    char ch = 0;
+    int argc = 0;
+    unsigned long val = 0;
+    for (i = 1; i < stub->len && argc < nargs; i++) {
+	ch = stub->payload[i];
+	if (ch == ':') {
+	    break;
+	} else if (ch == ',') {
+	    args[argc++] = val;
+	    val = 0;
+	} else {
+	    val = (val << 4) | gdbstub_from_hex_digit(ch);
+	}
+    }
+    if (stop_idx) {
+	*stop_idx = i;
+    }
+    if (argc < nargs) {
+	args[argc++] = val;
+    }
+    return ((i == stub->len || ch == ':') && argc == nargs);
+}
+
+static void gdbstub_send_errno(struct gdbstub *stub, int errno)
+{
+    gdbstub_send_num_packet(stub, 'E', errno);
+}
+
+static void gdbstub_report_signal(struct gdbstub *stub)
+{
+    gdbstub_send_num_packet(stub, 'S', stub->signo);
+}
+
+static void gdbstub_read_regs(struct gdbstub *stub)
+{
+    gdbstub_to_hex_buf(stub->payload, (char *)stub->regs, GDBMACH_SIZEOF_REGS);
+    stub->len = GDBMACH_SIZEOF_REGS * 2;
+    gdbstub_tx_packet(stub);
+}
+
+static void gdbstub_write_regs(struct gdbstub *stub)
+{
+    if (stub->len != 1 + GDBMACH_SIZEOF_REGS * 2) {
+	gdbstub_send_errno(stub, POSIX_EINVAL);
+	return;
+    }
+    gdbstub_from_hex_buf((char *)stub->regs, &stub->payload[1],
+			 GDBMACH_SIZEOF_REGS);
+    gdbstub_send_ok(stub);
+}
+
+static void gdbstub_read_mem(struct gdbstub *stub)
+{
+    unsigned long args[2];
+    if (!gdbstub_get_packet_args
+	(stub, args, sizeof args / sizeof args[0], NULL)) {
+	gdbstub_send_errno(stub, POSIX_EINVAL);
+	return;
+    }
+    args[1] = (args[1] < SIZEOF_PAYLOAD / 2) ? args[1] : SIZEOF_PAYLOAD / 2;
+    gdbstub_to_hex_buf(stub->payload, (char *)args[0], args[1]);
+    stub->len = args[1] * 2;
+    gdbstub_tx_packet(stub);
+}
+
+static void gdbstub_write_mem(struct gdbstub *stub)
+{
+    unsigned long args[2];
+    int colon;
+    if (!gdbstub_get_packet_args
+	(stub, args, sizeof args / sizeof args[0], &colon) || colon >= stub->len
+	|| stub->payload[colon] != ':' || (stub->len - colon - 1) % 2 != 0) {
+	gdbstub_send_errno(stub, POSIX_EINVAL);
+	return;
+    }
+    gdbstub_from_hex_buf((char *)args[0], &stub->payload[colon + 1],
+			 (stub->len - colon - 1) / 2);
+    gdbstub_send_ok(stub);
+}
+
+static void gdbstub_continue(struct gdbstub *stub, int single_step)
+{
+    gdbreg_t pc;
+    if (stub->len > 1
+	&& gdbstub_get_packet_args(stub, (unsigned long *)&pc, 1, NULL)) {
+	gdbmach_set_pc(stub->regs, pc);
+    }
+    gdbmach_set_single_step(stub->regs, single_step);
+    stub->exit_handler = 1;
+    /* Reply will be sent when we hit the next breakpoint or interrupt */
+}
+
+static void gdbstub_breakpoint(struct gdbstub *stub)
+{
+    unsigned long args[3];
+    int enable = stub->payload[0] == 'Z' ? 1 : 0;
+    if (!gdbstub_get_packet_args
+	(stub, args, sizeof args / sizeof args[0], NULL)) {
+	gdbstub_send_errno(stub, POSIX_EINVAL);
+	return;
+    }
+    if (gdbmach_set_breakpoint(args[0], args[1], args[2], enable)) {
+	gdbstub_send_ok(stub);
+    } else {
+	/* Not supported */
+	stub->len = 0;
+	gdbstub_tx_packet(stub);
+    }
+}
+
+static void gdbstub_rx_packet(struct gdbstub *stub)
+{
+    switch (stub->payload[0]) {
+    case '?':
+	gdbstub_report_signal(stub);
+	break;
+    case 'g':
+	gdbstub_read_regs(stub);
+	break;
+    case 'G':
+	gdbstub_write_regs(stub);
+	break;
+    case 'm':
+	gdbstub_read_mem(stub);
+	break;
+    case 'M':
+	gdbstub_write_mem(stub);
+	break;
+    case 'c':			/* Continue */
+    case 'k':			/* Kill */
+    case 's':			/* Step */
+    case 'D':			/* Detach */
+	gdbstub_continue(stub, stub->payload[0] == 's');
+	if (stub->payload[0] == 'D') {
+	    gdbstub_send_ok(stub);
+	}
+	break;
+    case 'Z':			/* Insert breakpoint */
+    case 'z':			/* Remove breakpoint */
+	gdbstub_breakpoint(stub);
+	break;
+    default:
+	stub->len = 0;
+	gdbstub_tx_packet(stub);
+	break;
+    }
+}
+
+/* GDB packet parser */
+static void gdbstub_state_new(struct gdbstub *stub, char ch)
+{
+    if (ch == '$') {
+	stub->len = 0;
+	stub->parse = gdbstub_state_data;
+    }
+}
+
+static void gdbstub_state_data(struct gdbstub *stub, char ch)
+{
+    if (ch == '#') {
+	stub->parse = gdbstub_state_cksum1;
+    } else if (ch == '$') {
+	stub->len = 0;		/* retry new packet */
+    } else {
+	/* If the length exceeds our buffer, let the checksum fail */
+	if (stub->len < SIZEOF_PAYLOAD) {
+	    stub->payload[stub->len++] = ch;
+	}
+    }
+}
+
+static void gdbstub_state_cksum1(struct gdbstub *stub, char ch)
+{
+    stub->cksum1 = gdbstub_from_hex_digit(ch) << 4;
+    stub->parse = gdbstub_state_cksum2;
+}
+
+static void gdbstub_state_cksum2(struct gdbstub *stub, char ch)
+{
+    uint8_t their_cksum;
+    uint8_t our_cksum;
+
+    stub->parse = gdbstub_state_new;
+    their_cksum = stub->cksum1 + gdbstub_from_hex_digit(ch);
+    our_cksum = gdbstub_cksum(stub->payload, stub->len);
+
+    if (their_cksum == our_cksum) {
+	serial_write("+", 1);
+	if (stub->len > 0) {
+	    gdbstub_rx_packet(stub);
+	}
+    } else {
+	serial_write("-", 1);
+    }
+}
+
+static void gdbstub_state_wait_ack(struct gdbstub *stub, char ch)
+{
+    if (ch == '+') {
+	stub->parse = gdbstub_state_new;
+    } else {
+	/* This retransmit is very aggressive but necessary to keep
+	 * in sync with GDB. */
+	gdbstub_tx_packet(stub);
+    }
+}
+
+void gdbstub_handler(int signo, gdbreg_t * regs)
+{
+    struct gdbstub stub;
+
+    gdbmach_disable_hwbps();
+
+    stub.parse = gdbstub_state_new;
+    stub.payload = &stub.buf[1];
+    stub.signo = signo;
+    stub.regs = regs;
+    stub.exit_handler = 0;
+    gdbstub_report_signal(&stub);
+    while (!stub.exit_handler)
+	stub.parse(&stub, serial_getc());
+
+    gdbmach_enable_hwbps();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/int.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/int.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/int.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,77 @@
+    .section ".text","ax"
+
+#define SIGTRAP 5
+
+#define SIZEOF_I386_REGS    32
+#define SIZEOF_I386_FLAGS   4
+
+/* When invoked, the stack contains: eflags, cs, eip, signo. */
+#define IH_OFFSET_GDB_REGS ( 0 )
+#define IH_OFFSET_GDB_EIP ( IH_OFFSET_GDB_REGS + SIZEOF_I386_REGS )
+#define IH_OFFSET_GDB_EFLAGS ( IH_OFFSET_GDB_EIP + 4 )
+#define IH_OFFSET_GDB_SEG_REGS ( IH_OFFSET_GDB_EFLAGS + SIZEOF_I386_FLAGS )
+#define IH_OFFSET_GDB_END ( IH_OFFSET_GDB_SEG_REGS + 6 * 4 )
+#define IH_OFFSET_OLD_EIP ( IH_OFFSET_GDB_END )
+#define IH_OFFSET_OLD_CS ( IH_OFFSET_OLD_EIP + 4 )
+#define IH_OFFSET_OLD_EFLAGS ( IH_OFFSET_OLD_CS + 4 )
+#define IH_OFFSET_END ( IH_OFFSET_OLD_EFLAGS + 4 )
+
+/* We also access the stack whilst still storing or restoring
+ * the register snapshot.  Since ESP is in flux, we need
+ * special offsets.
+ */
+#define IH_OFFSET_FLUX_OLD_CS ( IH_OFFSET_OLD_CS - 44 )
+#define IH_OFFSET_FLUX_OLD_EFLAGS ( IH_OFFSET_OLD_EFLAGS - 40 )
+#define IH_OFFSET_FLUX_OLD_EIP ( IH_OFFSET_OLD_EIP - 36 )
+#define IH_OFFSET_FLUX_END ( IH_OFFSET_END - 20 )
+
+    .global int_handler
+int_handler:
+	/* Store CPU state in GDB register snapshot */
+	pushw	$0
+	pushw	%gs
+	pushw	$0
+	pushw	%fs
+	pushw	$0
+	pushw	%es
+	pushw	$0
+	pushw	%ds
+	pushw	$0
+	pushw	%ss
+	pushw	$0
+	pushw	IH_OFFSET_FLUX_OLD_CS + 2(%esp)
+	pushl	IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
+	pushl	IH_OFFSET_FLUX_OLD_EIP(%esp)
+	pushl	%edi
+	pushl	%esi
+	pushl	%ebp
+	leal	IH_OFFSET_FLUX_END(%esp), %edi
+	pushl	%edi /* old ESP */
+	pushl	%ebx
+	pushl	%edx
+	pushl	%ecx
+	pushl	%eax
+
+	/* Call GDB stub exception handler */
+    movl    $SIGTRAP, %eax
+	movl	%esp, %edx
+	call	gdbstub_handler
+
+	/* Restore CPU state from GDB register snapshot */
+	popl	%eax
+	popl	%ecx
+	popl	%edx
+	popl	%ebx
+	addl	$4, %esp /* Changing ESP currently not supported */
+	popl	%ebp
+	popl	%esi
+	popl	%edi
+	popl	IH_OFFSET_FLUX_OLD_EIP(%esp)
+	popl	IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
+	popl	IH_OFFSET_FLUX_OLD_CS(%esp)
+	popl	%ss
+	popl	%ds
+	popl	%es
+	popl	%fs
+	popl	%gs
+	iret
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/main.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <syslinux/loadfile.h>
+#include "serial.h"
+
+#define X86_INT_DB      1
+#define X86_INT_BP      3
+#define COM32_IDT       ((void*)0x100000)
+#define COM32_LOAD_ADDR ((void*)0x101000)
+#define STACK_SIZE      0x1000
+
+extern char _start[], _end[];
+
+struct reloc_info {
+    void *data;
+    size_t len;
+    uint32_t old_esp;
+    uint32_t reloc_base;
+};
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+static inline uint32_t reloc_ptr(struct reloc_info *ri, void *ptr)
+{
+    return ri->reloc_base + (uint32_t) ((char *)ptr - _start);
+}
+
+static void hijack_interrupt(int intn, uint32_t handler)
+{
+    struct {
+	uint32_t lo;
+	uint32_t hi;
+    } *idt = COM32_IDT;
+
+    idt[intn].lo = (idt[intn].lo & 0xffff0000) | (handler & 0x0000ffff);
+    idt[intn].hi = (idt[intn].hi & 0x0000ffff) | (handler & 0xffff0000);
+}
+
+static void shift_cmdline(struct com32_sys_args *com32)
+{
+    char *p;
+
+    /* Skip leading whitespace */
+    for (p = com32->cs_cmdline; *p != '\0' && *p == ' '; p++) ;
+
+    /* Skip first word */
+    for (; *p != '\0' && *p != ' '; p++) ;
+
+    /* Skip whitespace after first word */
+    for (; *p != '\0' && *p == ' '; p++) ;
+
+    com32->cs_cmdline = p;
+}
+
+static __noreturn reloc_entry(struct reloc_info *ri)
+{
+    extern char int_handler[];
+    size_t stack_frame_size = sizeof(struct com32_sys_args) + 4;
+    struct com32_sys_args *com32;
+    uint32_t module_esp;
+
+    hijack_interrupt(X86_INT_DB, reloc_ptr(ri, int_handler));
+    hijack_interrupt(X86_INT_BP, reloc_ptr(ri, int_handler));
+
+    /* Copy module to load address */
+    memcpy(COM32_LOAD_ADDR, ri->data, ri->len);
+
+    /* Copy stack frame onto module stack */
+    module_esp = (ri->reloc_base - stack_frame_size) & ~15;
+    memcpy((void *)module_esp, (void *)ri->old_esp, stack_frame_size);
+
+    /* Fix up command line */
+    com32 = (struct com32_sys_args *)(module_esp + 4);
+    shift_cmdline(com32);
+
+    /* Set up CPU state to run module and enter GDB */
+    asm volatile ("movl %0, %%esp\n\t"
+		  "pushf\n\t"
+		  "pushl %%cs\n\t"
+		  "pushl %1\n\t"
+		  "jmp *%2\n\t"::"r" (module_esp),
+		  "c"(COM32_LOAD_ADDR), "r"(reloc_ptr(ri, int_handler))
+	);
+    for (;;) ;			/* shut the compiler up */
+}
+
+static inline __noreturn reloc(void *ptr, size_t len)
+{
+    extern uint32_t __entry_esp;
+    size_t total_size = _end - _start;
+    __noreturn(*entry_fn) (struct reloc_info *);
+    struct reloc_info ri;
+    uint32_t esp;
+    char *dest;
+
+    /* Calculate relocation address, preserve current stack */
+    asm volatile ("movl %%esp, %0\n\t":"=m" (esp));
+    dest = (char *)((esp - STACK_SIZE - total_size) & ~3);
+
+    /* Calculate entry point in relocated code */
+    entry_fn = (void *)(dest + ((char *)reloc_entry - _start));
+
+    /* Copy all sections to relocation address */
+    printf("Relocating %d bytes from %p to %p\n", total_size, _start, dest);
+    memcpy(dest, _start, total_size);
+
+    /* Call into relocated code */
+    ri.data = ptr;
+    ri.len = len;
+    ri.old_esp = __entry_esp;
+    ri.reloc_base = (uint32_t) dest;
+    entry_fn(&ri);
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    if (argc < 2) {
+	error("Usage: gdbstub.c32 com32_file arguments...\n");
+	return 1;
+    }
+
+    if (loadfile(argv[1], &data, &data_len)) {
+	error("Unable to load file\n");
+	return 1;
+    }
+
+    serial_init();
+
+    /* No more lib calls after this point */
+    reloc(data, data_len);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,193 @@
+/*
+ * The serial port interface routines implement a simple polled i/o
+ * interface to a standard serial port.  Due to the space restrictions
+ * for the boot blocks, no BIOS support is used (since BIOS requires
+ * expensive real/protected mode switches), instead the rudimentary
+ * BIOS support is duplicated here.
+ *
+ * The base address and speed for the i/o port are passed from the
+ * Makefile in the COMCONSOLE and CONSPEED preprocessor macros.  The
+ * line control parameters are currently hard-coded to 8 bits, no
+ * parity, 1 stop bit (8N1).  This can be changed in init_serial().
+ */
+
+#include <stddef.h>
+#include <sys/io.h>
+#include "serial.h"
+
+/* Set default values if none specified */
+
+#ifndef COMCONSOLE
+#define COMCONSOLE	0x3f8
+#endif
+
+#ifndef COMSPEED
+#define COMSPEED	9600
+#endif
+
+#ifndef COMDATA
+#define COMDATA		8
+#endif
+
+#ifndef COMPARITY
+#define COMPARITY	0
+#endif
+
+#ifndef COMSTOP
+#define COMSTOP		1
+#endif
+
+#undef UART_BASE
+#define UART_BASE ( COMCONSOLE )
+
+#undef UART_BAUD
+#define UART_BAUD ( COMSPEED )
+
+#if ((115200%UART_BAUD) != 0)
+#error Bad ttys0 baud rate
+#endif
+
+#define COMBRD (115200/UART_BAUD)
+
+/* Line Control Settings */
+#define UART_LCS ( ( ( (COMDATA) - 5 )	<< 0 ) | \
+		   ( ( (COMPARITY) )	<< 3 ) | \
+		   ( ( (COMSTOP) - 1 )	<< 2 ) )
+
+/* Data */
+#define UART_RBR 0x00
+#define UART_TBR 0x00
+
+/* Control */
+#define UART_IER 0x01
+#define UART_IIR 0x02
+#define UART_FCR 0x02
+#define UART_LCR 0x03
+#define UART_MCR 0x04
+#define UART_DLL 0x00
+#define UART_DLM 0x01
+
+/* Status */
+#define UART_LSR 0x05
+#define  UART_LSR_TEMPT 0x40	/* Transmitter empty */
+#define  UART_LSR_THRE  0x20	/* Transmit-hold-register empty */
+#define  UART_LSR_BI	0x10	/* Break interrupt indicator */
+#define  UART_LSR_FE	0x08	/* Frame error indicator */
+#define  UART_LSR_PE	0x04	/* Parity error indicator */
+#define  UART_LSR_OE	0x02	/* Overrun error indicator */
+#define  UART_LSR_DR	0x01	/* Receiver data ready */
+
+#define UART_MSR 0x06
+#define UART_SCR 0x07
+
+#define uart_readb(addr) inb(addr)
+#define uart_writeb(val,addr) outb((val),(addr))
+
+/*
+ * void serial_putc(int ch);
+ *	Write character `ch' to port UART_BASE.
+ */
+void serial_putc(int ch)
+{
+    int status;
+    for (;;) {
+	status = uart_readb(UART_BASE + UART_LSR);
+	if (status & UART_LSR_THRE) {
+	    /* TX buffer emtpy */
+	    uart_writeb(ch, UART_BASE + UART_TBR);
+	    break;
+	}
+    }
+}
+
+/*
+ * int serial_getc(void);
+ *	Read a character from port UART_BASE.
+ */
+int serial_getc(void)
+{
+    int status;
+    int ch;
+    do {
+	status = uart_readb(UART_BASE + UART_LSR);
+    } while ((status & 1) == 0);
+    ch = uart_readb(UART_BASE + UART_RBR);	/* fetch (first) character */
+    ch &= 0x7f;			/* remove any parity bits we get */
+    if (ch == 0x7f) {		/* Make DEL... look like BS */
+	ch = 0x08;
+    }
+    return ch;
+}
+
+/*
+ * int serial_init(void);
+ *	Initialize port UART_BASE to speed COMSPEED, line settings 8N1.
+ */
+void serial_init(void)
+{
+    int status;
+    int divisor, lcs;
+
+    divisor = COMBRD;
+    lcs = UART_LCS;
+
+#ifdef COMPRESERVE
+    lcs = uart_readb(UART_BASE + UART_LCR) & 0x7f;
+    uart_writeb(0x80 | lcs, UART_BASE + UART_LCR);
+    divisor =
+	(uart_readb(UART_BASE + UART_DLM) << 8) | uart_readb(UART_BASE +
+							     UART_DLL);
+    uart_writeb(lcs, UART_BASE + UART_LCR);
+#endif
+
+    /* Set Baud Rate Divisor to COMSPEED, and test to see if the
+     * serial port appears to be present.
+     */
+    uart_writeb(0x80 | lcs, UART_BASE + UART_LCR);
+    uart_writeb(0xaa, UART_BASE + UART_DLL);
+    if (uart_readb(UART_BASE + UART_DLL) != 0xaa) {
+	goto out;
+    }
+    uart_writeb(0x55, UART_BASE + UART_DLL);
+    if (uart_readb(UART_BASE + UART_DLL) != 0x55) {
+	goto out;
+    }
+    uart_writeb(divisor & 0xff, UART_BASE + UART_DLL);
+    if (uart_readb(UART_BASE + UART_DLL) != (divisor & 0xff)) {
+	goto out;
+    }
+    uart_writeb(0xaa, UART_BASE + UART_DLM);
+    if (uart_readb(UART_BASE + UART_DLM) != 0xaa) {
+	goto out;
+    }
+    uart_writeb(0x55, UART_BASE + UART_DLM);
+    if (uart_readb(UART_BASE + UART_DLM) != 0x55) {
+	goto out;
+    }
+    uart_writeb((divisor >> 8) & 0xff, UART_BASE + UART_DLM);
+    if (uart_readb(UART_BASE + UART_DLM) != ((divisor >> 8) & 0xff)) {
+	goto out;
+    }
+    uart_writeb(lcs, UART_BASE + UART_LCR);
+
+    /* disable interrupts */
+    uart_writeb(0x0, UART_BASE + UART_IER);
+
+    /* disable fifo's */
+    uart_writeb(0x00, UART_BASE + UART_FCR);
+
+    /* Set clear to send, so flow control works... */
+    uart_writeb((1 << 1), UART_BASE + UART_MCR);
+
+    /* Flush the input buffer. */
+    do {
+	/* rx buffer reg
+	 * throw away (unconditionally the first time)
+	 */
+	(void)uart_readb(UART_BASE + UART_RBR);
+	/* line status reg */
+	status = uart_readb(UART_BASE + UART_LSR);
+    } while (status & UART_LSR_DR);
+out:
+    return;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gdbstub/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+#ifndef _GPXE_SERIAL_H
+#define _GPXE_SERIAL_H
+
+/** @file
+ *
+ * Serial driver functions
+ *
+ */
+
+extern void serial_putc(int ch);
+extern int serial_getc(void);
+extern void serial_init(void);
+
+#endif /* _GPXE_SERIAL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gfxboot/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gfxboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gfxboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,56 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 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.
+##
+## -----------------------------------------------------------------------
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+MODULES	  = gfxboot.c32
+
+all: $(MODULES)
+
+OBJS = gfxboot.o realmode_callback.o
+
+gfxboot.elf : $(OBJS) $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+realmode_callback.o: realmode_callback.asm
+ifeq ($(ARCH),i386)
+	$(NASM) -f bin -O99 -o $*.tmp -l $*.lst $<
+	$(OBJCOPY) -B i386 -I binary -O elf32-i386 \
+	  --redefine-sym _binary_$*_tmp_start=$*_start \
+	  --redefine-sym _binary_$*_tmp_end=$*_end \
+	  --strip-symbol _binary_$*_tmp_size \
+	  $*.tmp $@
+endif
+ifeq ($(ARCH),x86_64)
+	$(NASM) -f bin -O99 -o $*.tmp -l $*.lst $<
+	$(OBJCOPY) -B i386:x86-64 -I binary -O elf64-x86-64 \
+	  --redefine-sym _binary_$*_tmp_start=$*_start \
+	  --redefine-sym _binary_$*_tmp_end=$*_end \
+	  --strip-symbol _binary_$*_tmp_size \
+	  $*.tmp $@
+endif
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/gfxboot/gfxboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gfxboot/gfxboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gfxboot/gfxboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,976 @@
+/*
+ *
+ * gfxboot.c
+ *
+ * A com32 module to load gfxboot graphics.
+ *
+ * Copyright (c) 2009 Steffen Winterfeldt.
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <minmax.h>
+#include <ctype.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/config.h>
+#include <syslinux/linux.h>
+#include <syslinux/boot.h>
+#include <console.h>
+#include <com32.h>
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#define MAX_CONFIG_LINE_LEN	2048
+#define MAX_CMDLINE_LEN		2048
+
+// buffer for realmode callback
+// must be at least block size; can in theory be larger than 4k, but there's
+// not enough space left
+#define REALMODE_BUF_SIZE	4096
+#define LOWMEM_BUF_SIZE		65536
+
+// gfxboot working memory in MB
+#define	GFX_MEMORY_SIZE		7
+
+// read chunk size for progress bar
+#define CHUNK_SIZE	(64 << 10)
+
+// callback function numbers
+#define GFX_CB_INIT		0
+#define GFX_CB_DONE		1
+#define GFX_CB_INPUT		2
+#define GFX_CB_MENU_INIT	3
+#define GFX_CB_INFOBOX_INIT	4
+#define GFX_CB_INFOBOX_DONE	5
+#define GFX_CB_PROGRESS_INIT	6
+#define GFX_CB_PROGRESS_DONE	7
+#define GFX_CB_PROGRESS_UPDATE	8
+#define GFX_CB_PROGRESS_LIMIT	9		// unused
+#define GFX_CB_PASSWORD_INIT	10
+#define GFX_CB_PASSWORD_DONE	11
+
+// real mode code chunk, will be placed into lowmem buffer
+extern const char realmode_callback_start[], realmode_callback_end[];
+
+// gets in the way
+#undef linux
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// gfxboot config data (64 bytes)
+typedef struct __attribute__ ((packed)) {
+  uint8_t bootloader;		//  0: boot loader type (0: lilo, 1: syslinux, 2: grub)
+  uint8_t sector_shift;		//  1: sector shift
+  uint8_t media_type;		//  2: media type (0: disk, 1: floppy, 2: cdrom)
+  uint8_t failsafe;		//  3: turn on failsafe mode (bitmask)
+				//    0: SHIFT pressed
+				//    1: skip gfxboot
+				//    2: skip monitor detection
+  uint8_t sysconfig_size;	//  4: size of sysconfig data
+  uint8_t boot_drive;		//  5: BIOS boot drive
+  uint16_t callback;		//  6: offset to callback handler
+  uint16_t bootloader_seg;	//  8: code/data segment used by bootloader; must follow gfx_callback
+  uint16_t serial_port;		// 10: syslinux initialized serial port from 'serial' option
+  uint32_t user_info_0;		// 12: data for info box
+  uint32_t user_info_1;		// 16: data for info box
+  uint32_t bios_mem_size;	// 20: BIOS memory size (in bytes)
+  uint16_t xmem_0;		// 24: extended mem area 0 (start:size in MB; 12:4 bits) - obsolete
+  uint16_t xmem_1;		// 26: extended mem area 1 - obsolete
+  uint16_t xmem_2;		// 28: extended mem area 2 - obsolete
+  uint16_t xmem_3;		// 30: extended mem area 3 - obsolete
+  uint32_t file;		// 32: start of gfx file
+  uint32_t archive_start;	// 36: start of cpio archive
+  uint32_t archive_end;		// 40: end of cpio archive
+  uint32_t mem0_start;		// 44: low free memory start
+  uint32_t mem0_end;		// 48: low free memory end
+  uint32_t xmem_start;		// 52: extended mem start
+  uint32_t xmem_end;		// 56: extended mem end
+  uint16_t features;		// 60: feature flags returned by GFX_CB_INIT
+  				//    0: GFX_CB_MENU_INIT accepts 32 bit addresses
+  				//    1: knows about xmem_start, xmem_end
+  uint16_t reserved_1;		// 62:
+  uint32_t gfxboot_cwd;		// 64: if set, points to current gfxboot working directory relative
+				//     to syslinux working directory
+} gfx_config_t;
+
+
+// gfxboot menu description (18 bytes)
+typedef struct __attribute__ ((packed)) {
+  uint16_t entries;
+  char *default_entry;
+  char *label_list;
+  uint16_t label_size;
+  char *arg_list;
+  uint16_t arg_size;
+} gfx_menu_t;
+
+
+// menu description
+typedef struct menu_s {
+  struct menu_s *next;
+  char *label;		// config entry name
+  char *menu_label;	// text to show in boot menu
+  char *kernel;		// name of program to load
+  char *alt_kernel;	// alternative name in case user has replaced it
+  char *linux;		// de facto an alias for 'kernel'
+  char *localboot;	// boot from local disk
+  char *initrd;		// initrd as separate line (instead of as part of 'append')
+  char *append;		// kernel args
+  char *ipappend;	// append special pxelinux args (see doc)
+} menu_t;
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+gfx_config_t gfx_config;
+gfx_menu_t gfx_menu;
+
+menu_t *menu;
+menu_t *menu_default;
+static menu_t *menu_ptr, **menu_next;
+
+struct {
+  uint32_t jmp_table[12];
+  uint16_t code_seg;
+  char fname_buf[64];
+} gfx;
+
+void *lowmem_buf;
+
+int timeout;
+
+char cmdline[MAX_CMDLINE_LEN];
+
+// progress bar is visible
+unsigned progress_active;
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void show_message(char *file);
+char *get_config_file_name(void);
+char *skip_nonspaces(char *s);
+void chop_line(char *s);
+int read_config_file(const char *filename);
+unsigned magic_ok(unsigned char *buf, unsigned *code_size);
+unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len, unsigned *code_size);
+int gfx_init(char *file);
+int gfx_menu_init(void);
+void gfx_done(void);
+int gfx_input(void);
+void gfx_infobox(int type, char *str1, char *str2);
+void gfx_progress_init(ssize_t kernel_size, char *label);
+void gfx_progress_update(ssize_t size);
+void gfx_progress_done(void);
+void *load_one(char *file, ssize_t *file_size);
+void boot(int index);
+void boot_entry(menu_t *menu_ptr, char *arg);
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int main(int argc, char **argv)
+{
+  int menu_index;
+  const union syslinux_derivative_info *sdi;
+  char working_dir[256];
+
+  openconsole(&dev_stdcon_r, &dev_stdcon_w);
+
+  lowmem_buf = lmalloc(LOWMEM_BUF_SIZE);
+  if (!lowmem_buf) {
+    printf("Could not allocate memory.\n");
+    return 1;
+  }
+
+  sdi = syslinux_derivative_info();
+
+  gfx_config.sector_shift = sdi->disk.sector_shift;
+  gfx_config.boot_drive = sdi->disk.drive_number;
+
+  if(sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+    gfx_config.sector_shift = 11;
+    gfx_config.boot_drive = 0;
+  }
+
+  gfx_config.media_type = gfx_config.boot_drive < 0x80 ? 1 : 0;
+
+  if(sdi->c.filesystem == SYSLINUX_FS_ISOLINUX) {
+    gfx_config.media_type = sdi->iso.cd_mode ? 0 : 2;
+  }
+
+  gfx_config.bootloader = 1;
+  gfx_config.sysconfig_size = sizeof gfx_config;
+  gfx_config.bootloader_seg = 0;	// apparently not needed
+
+  if(argc < 2) {
+    printf("Usage: gfxboot.c32 bootlogo_file [message_file]\n");
+    if(argc > 2) show_message(argv[2]);
+
+    return 0;
+  }
+
+  if(read_config_file("~")) {
+    printf("Error reading config file\n");
+    if(argc > 2) show_message(argv[2]);
+
+    return 0;
+  }
+
+  if(getcwd(working_dir, sizeof working_dir)) {
+    gfx_config.gfxboot_cwd = (uint32_t) working_dir;
+  }
+
+  if(gfx_init(argv[1])) {
+    printf("Error setting up gfxboot\n");
+    if(argc > 2) show_message(argv[2]);
+
+    return 0;
+  }
+
+  gfx_menu_init();
+
+  for(;;) {
+    menu_index = gfx_input();
+
+    // abort gfx, return to text mode prompt
+    if(menu_index == -1) {
+      gfx_done();
+      break;
+    }
+
+    // does not return if it succeeds
+    boot(menu_index);
+  }
+
+  if(argc > 2) show_message(argv[2]);
+
+  return 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void show_message(char *file)
+{
+  int c;
+  FILE *f;
+
+  if(!(f = fopen(file, "r"))) return;
+
+  while((c = getc(f)) != EOF) {
+    if(c < ' ' && c != '\n' && c != '\t') continue;
+    printf("%c", c);
+  }
+
+  fclose(f);
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+char *skip_nonspaces(char *s)
+{
+  while(*s && *s != ' ' && *s != '\t') s++;
+
+  return s;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void chop_line(char *s)
+{
+  int i = strlen(s);
+
+  if(!i) return;
+
+  while(--i >= 0) {
+    if(s[i] == ' ' || s[i] == '\t' || s[i] == '\n') {
+      s[i] = 0;
+    }
+    else {
+      break;
+    }
+  }
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Read and parse syslinux config file.
+//
+// return:
+//   0: ok, 1: error
+//
+int read_config_file(const char *filename)
+{
+  FILE *f;
+  char *s, *t, buf[MAX_CONFIG_LINE_LEN];
+  unsigned u, top_level = 0, text = 0;
+
+  if(!strcmp(filename, "~")) {
+    top_level = 1;
+    filename = syslinux_config_file();
+    gfx_menu.entries = 0;
+    gfx_menu.label_size = 0;
+    gfx_menu.arg_size = 0;
+    menu_ptr = NULL;
+    menu_next = &menu;
+    menu_default = calloc(1, sizeof *menu_default);
+  }
+
+  if(!(f = fopen(filename, "r"))) return 1;
+
+  while((s = fgets(buf, sizeof buf, f))) {
+    chop_line(s);
+    s = skipspace(s);
+    if(!*s || *s == '#') continue;
+    t = skip_nonspaces(s);
+    if(*t) *t++ = 0;
+    t = skipspace(t);
+
+    if(!strcasecmp(s, "endtext")) {
+      text = 0;
+      continue;
+    }
+
+    if (text)
+      continue;
+
+    if(!strcasecmp(s, "timeout")) {
+      timeout = atoi(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "default")) {
+      menu_default->label = strdup(t);
+      u = strlen(t);
+      if(u > gfx_menu.label_size) gfx_menu.label_size = u;
+      continue;
+    }
+
+    if(!strcasecmp(s, "label")) {
+      menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
+      menu_next = &menu_ptr->next;
+      gfx_menu.entries++;
+      menu_ptr->label = menu_ptr->menu_label = strdup(t);
+      u = strlen(t);
+      if(u > gfx_menu.label_size) gfx_menu.label_size = u;
+      continue;
+    }
+
+    if(!strcasecmp(s, "kernel") && menu_ptr) {
+      menu_ptr->kernel = strdup(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "linux") && menu_ptr) {
+      menu_ptr->linux = strdup(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "localboot") && menu_ptr) {
+      menu_ptr->localboot = strdup(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "initrd") && menu_ptr) {
+      menu_ptr->initrd = strdup(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "append")) {
+      (menu_ptr ?: menu_default)->append = strdup(t);
+      u = strlen(t);
+      if(u > gfx_menu.arg_size) gfx_menu.arg_size = u;
+      continue;
+    }
+
+    if(!strcasecmp(s, "ipappend") || !strcasecmp(s, "sysappend")) {
+      (menu_ptr ?: menu_default)->ipappend = strdup(t);
+      continue;
+    }
+
+    if(!strcasecmp(s, "text")) {
+      text = 1;
+      continue;
+    }
+
+    if(!strcasecmp(s, "menu") && menu_ptr) {
+      s = skipspace(t);
+      t = skip_nonspaces(s);
+      if(*t) *t++ = 0;
+      t = skipspace(t);
+
+      if(!strcasecmp(s, "label")) {
+        menu_ptr->menu_label = strdup(t);
+        u = strlen(t);
+        if(u > gfx_menu.label_size) gfx_menu.label_size = u;
+        continue;
+      }
+
+      if(!strcasecmp(s, "include")) {
+        goto do_include;
+      }
+    }
+
+    if (!strcasecmp(s, "include")) {
+do_include:
+      s = t;
+      t = skip_nonspaces(s);
+      if (*t) *t = 0;
+      read_config_file(s);
+    }
+  }
+
+  fclose(f);
+
+  if (!top_level)
+    return 0;
+
+  if (gfx_menu.entries == 0) {
+    printf("No LABEL keywords found.\n");
+    return 1;
+  }
+
+  // final '\0'
+  gfx_menu.label_size++;
+  gfx_menu.arg_size++;
+
+  // ensure we have a default entry
+  if(!menu_default->label) menu_default->label = menu->label;
+
+  if(menu_default->label) {
+    for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next) {
+      if(!strcmp(menu_default->label, menu_ptr->label)) {
+        menu_default->menu_label = menu_ptr->menu_label;
+        break;
+      }
+    }
+  }
+
+  gfx_menu.default_entry = menu_default->menu_label;
+  gfx_menu.label_list = calloc(gfx_menu.entries, gfx_menu.label_size);
+  gfx_menu.arg_list = calloc(gfx_menu.entries, gfx_menu.arg_size);
+
+  for(u = 0, menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, u++) {
+    if(!menu_ptr->append) menu_ptr->append = menu_default->append;
+    if(!menu_ptr->ipappend) menu_ptr->ipappend = menu_default->ipappend;
+
+    if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * gfx_menu.label_size, menu_ptr->menu_label);
+    if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * gfx_menu.arg_size, menu_ptr->append);
+  }
+
+  return 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Check header and return code start offset.
+//
+unsigned magic_ok(unsigned char *buf, unsigned *code_size)
+{
+  if(
+    *(unsigned *) buf == 0x0b2d97f00 &&		// magic id
+    (buf[4] == 8)				// version 8
+  ) {
+    *code_size = *(unsigned *) (buf + 12);
+    return *(unsigned *) (buf + 8);
+  }
+
+  return 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Search (cpio archive) for gfx file.
+//
+unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len, unsigned *code_size)
+{
+  unsigned i, fname_len, code_start = 0;
+
+  *gfx_file_start = 0;
+  *code_size = 0;
+
+  if((code_start = magic_ok(buf, code_size))) return code_start;
+
+  for(i = 0; i < len;) {
+    if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) {
+      fname_len = *(unsigned short *) (buf + i + 20);
+      *file_len = *(unsigned short *) (buf + i + 24) + (*(unsigned short *) (buf + i + 22) << 16);
+      i += 26 + fname_len;
+      i = ((i + 1) & ~1);
+      if((code_start = magic_ok(buf + i, code_size))) {
+        *gfx_file_start = i;
+        return code_start;
+      }
+      i += *file_len;
+      i = ((i + 1) & ~1);
+    }
+    else {
+      break;
+    }
+  }
+
+  return code_start;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Initialize gfxboot code.
+//
+// return:
+//   0: ok, 1: error
+//
+int gfx_init(char *file)
+{
+  size_t archive_size = 0;
+  void *archive;
+  unsigned code_start, code_size, file_start, file_len, u;
+  com32sys_t r;
+  void *lowmem = lowmem_buf;
+  unsigned lowmem_size = LOWMEM_BUF_SIZE;
+
+  memset(&r,0,sizeof(r));
+  progress_active = 0;
+
+  printf("Loading %s...\n", file);
+  if(loadfile(file, &archive, &archive_size)) return 1;
+
+  if(!archive_size) return 1;
+
+  // printf("%s: %d\n", file, archive_size);
+
+  gfx_config.archive_start = (uint32_t) archive;
+  gfx_config.archive_end = gfx_config.archive_start + archive_size;
+
+  // locate file inside cpio archive
+  if(!(code_start = find_file(archive, archive_size, &file_start, &file_len, &code_size))) {
+    printf("%s: invalid file format\n", file);
+    return 1;
+  }
+
+#if 0
+  printf(
+    "code_start = 0x%x, code_size = 0x%x\n"
+    "archive_start = 0x%x, archive size = 0x%x\n"
+    "file_start = 0x%x, file_len = 0x%x\n",
+    code_start, code_size,
+    gfx_config.archive_start, archive_size,
+    file_start, file_len
+  );
+#endif
+
+  gfx_config.file = gfx_config.archive_start + file_start;
+
+  u = realmode_callback_end - realmode_callback_start;
+  u = (u + REALMODE_BUF_SIZE + 0xf) & ~0xf;
+
+  if(u + code_size > lowmem_size) {
+    printf("lowmem buffer too small: size %u, needed %u\n", lowmem_size, u + code_size);
+    return 1;
+  }
+
+  memcpy(lowmem + REALMODE_BUF_SIZE, realmode_callback_start,
+	 realmode_callback_end - realmode_callback_start);
+
+  // fill in buffer size and location
+  *(uint16_t *) (lowmem + REALMODE_BUF_SIZE) = REALMODE_BUF_SIZE;
+  *(uint16_t *) (lowmem + REALMODE_BUF_SIZE + 2) = (uint32_t) lowmem >> 4;
+
+  gfx_config.bootloader_seg = ((uint32_t) lowmem + REALMODE_BUF_SIZE) >> 4;
+  gfx_config.callback = 4;	// start address
+
+  lowmem += u;
+  lowmem_size -= u;
+
+  memcpy(lowmem, archive + file_start + code_start, code_size);
+
+  gfx_config.mem0_start = (uint32_t) lowmem + code_size;
+  gfx_config.mem0_end = (uint32_t) lowmem + lowmem_size;
+  // align a bit
+  gfx_config.mem0_start = (gfx_config.mem0_start + 0xf) & ~0xf;
+
+  gfx_config.xmem_start = (uint32_t) malloc(GFX_MEMORY_SIZE << 20);
+  if(gfx_config.xmem_start) {
+    gfx_config.xmem_end = gfx_config.xmem_start + (GFX_MEMORY_SIZE << 20);
+  }
+
+  // fake; not used anyway
+  gfx_config.bios_mem_size = 256 << 20;
+
+  gfx.code_seg = (uint32_t) lowmem >> 4;
+
+  for(u = 0; u < sizeof gfx.jmp_table / sizeof *gfx.jmp_table; u++) {
+    gfx.jmp_table[u] = (gfx.code_seg << 16) + *(uint16_t *) (lowmem + 2 * u);
+  }
+
+#if 0
+  for(u = 0; u < sizeof gfx.jmp_table / sizeof *gfx.jmp_table; u++) {
+    printf("%d: 0x%08x\n", u, gfx.jmp_table[u]);
+  }
+#endif
+
+  // we are ready to start
+
+  r.esi.l = (uint32_t) &gfx_config;
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INIT], &r, &r);
+
+  if((r.eflags.l & EFLAGS_CF)) {
+    printf("graphics initialization failed\n");
+
+    return 1;
+  }
+
+  if((gfx_config.features & 3) != 3) {
+    gfx_done();
+
+    printf("%s: boot graphics code too old, please use newer version\n", file);
+
+    return 1;
+  }
+
+
+  return 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int gfx_menu_init(void)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  r.esi.l = (uint32_t) &gfx_menu;
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_MENU_INIT], &r, &r);
+
+  return 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_done(void)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  gfx_progress_done();
+
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_DONE], &r, &r);
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Run gfxboot main loop.
+//
+// return:
+//   boot menu index (-1: go to text mode prompt)
+//
+int gfx_input(void)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  r.edi.l = (uint32_t) cmdline;
+  r.ecx.l = sizeof cmdline;
+  r.eax.l = timeout * 182 / 100;
+  timeout = 0;		// use timeout only first time
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INPUT], &r, &r);
+  if((r.eflags.l & EFLAGS_CF)) r.eax.l = 1;
+
+  if(r.eax.l == 1) return -1;
+
+  return r.ebx.l;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_infobox(int type, char *str1, char *str2)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  r.eax.l = type;
+  r.esi.l = (uint32_t) str1;
+  r.edi.l = (uint32_t) str2;
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_INIT], &r, &r);
+  r.edi.l = r.eax.l = 0;
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INPUT], &r, &r);
+  __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_INFOBOX_DONE], &r, &r);
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_init(ssize_t kernel_size, char *label)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  if(!progress_active) {
+    r.eax.l = kernel_size >> gfx_config.sector_shift;		// in sectors
+    r.esi.l = (uint32_t) label;
+    __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_INIT], &r, &r);
+  }
+
+  progress_active = 1;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_update(ssize_t advance)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  if(progress_active) {
+    r.eax.l = advance >> gfx_config.sector_shift;		// in sectors
+    __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_UPDATE], &r, &r);
+  }
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void gfx_progress_done(void)
+{
+  com32sys_t r;
+
+  memset(&r,0,sizeof(r));
+  if(progress_active) {
+    __farcall(gfx.code_seg, gfx.jmp_table[GFX_CB_PROGRESS_DONE], &r, &r);
+  }
+
+  progress_active = 0;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Read file and update progress bar.
+//
+void *load_one(char *file, ssize_t *file_size)
+{
+  int fd;
+  void *buf = NULL;
+  char *str;
+  struct stat sbuf;
+  ssize_t size = 0, cur, i;
+
+  *file_size = 0;
+
+  if((fd = open(file, O_RDONLY)) == -1) {
+    asprintf(&str, "%s: file not found", file);
+    gfx_infobox(0, str, NULL);
+    free(str);
+    return buf;
+  }
+
+  if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) size = sbuf.st_size;
+
+  i = 0;
+
+  if(size) {
+    buf = malloc(size);
+    for(i = 1, cur = 0 ; cur < size && i > 0; cur += i) {
+      i = read(fd, buf + cur, min(CHUNK_SIZE, size - cur));
+      if(i == -1) break;
+      gfx_progress_update(i);
+    }
+  }
+  else {
+    do {
+      buf = realloc(buf, size + CHUNK_SIZE);
+      i = read(fd, buf + size, CHUNK_SIZE);
+      if(i == -1) break;
+      size += i;
+      gfx_progress_update(i);
+    } while(i > 0);
+  }
+
+  close(fd);
+
+  if(i == -1) {
+    asprintf(&str, "%s: read error @ %d", file, size);
+    gfx_infobox(0, str, NULL);
+    free(str);
+    free(buf);
+    buf = NULL;
+    size = 0;
+  }
+
+  *file_size = size;
+
+  return buf;
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Boot menu entry.
+//
+// cmdline can optionally start with label string.
+//
+void boot(int index)
+{
+  char *arg, *alt_kernel;
+  menu_t *menu_ptr;
+  int i, label_len;
+  unsigned ipapp;
+  const struct syslinux_ipappend_strings *ipappend;
+  char *gfxboot_cwd = (char *) gfx_config.gfxboot_cwd;
+
+  if(gfxboot_cwd) {
+    chdir(gfxboot_cwd);
+    gfx_config.gfxboot_cwd = 0;
+  }
+
+  for(menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, index--) {
+    if(!index) break;
+  }
+
+  // invalid index or menu entry
+  if(!menu_ptr || !menu_ptr->menu_label) return;
+
+  arg = skipspace(cmdline);
+  label_len = strlen(menu_ptr->menu_label);
+
+  // if it does not start with label string, assume first word is kernel name
+  if(strncmp(arg, menu_ptr->menu_label, label_len)) {
+    alt_kernel = arg;
+    arg = skip_nonspaces(arg);
+    if(*arg) *arg++ = 0;
+    if(*alt_kernel) menu_ptr->alt_kernel = alt_kernel;
+  }
+  else {
+    arg += label_len;
+  }
+
+  arg = skipspace(arg);
+
+  // handle IPAPPEND
+  if(menu_ptr->ipappend && (ipapp = atoi(menu_ptr->ipappend))) {
+    ipappend = syslinux_ipappend_strings();
+    for(i = 0; i < ipappend->count; i++) {
+      if((ipapp & (1 << i)) && ipappend->ptr[i]) {
+        sprintf(arg + strlen(arg), " %s", ipappend->ptr[i]);
+      }
+    }
+  }
+
+  boot_entry(menu_ptr, arg);
+
+  gfx_progress_done();
+}
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Load & run kernel.
+//
+// Returns only on error.
+//
+void boot_entry(menu_t *menu_ptr, char *arg)
+{
+  void *kernel, *initrd_buf;
+  ssize_t kernel_size = 0, initrd_size = 0;
+  struct initramfs *initrd = NULL;
+  char *file, *cmd_buf;
+  int fd;
+  struct stat sbuf;
+  char *s, *s0, *t, *initrd_arg;
+
+  if(!menu_ptr) return;
+
+  if(menu_ptr->localboot) {
+    gfx_done();
+    syslinux_local_boot(strtol(menu_ptr->localboot, NULL, 0));
+
+    return;
+  }
+
+  file = menu_ptr->alt_kernel;
+  if(!file) file = menu_ptr->kernel;
+  if(!file) file = menu_ptr->linux;
+  if(!file) {
+    gfx_done();
+    asprintf(&cmd_buf, "%s %s", menu_ptr->label, arg);
+    syslinux_run_command(cmd_buf);
+    return;
+  }
+
+  // first, load kernel
+
+  kernel_size = 0;
+
+  if((fd = open(file, O_RDONLY)) >= 0) {
+    if(!fstat(fd, &sbuf) && S_ISREG(sbuf.st_mode)) kernel_size = sbuf.st_size;
+    close(fd);
+  }
+
+  gfx_progress_init(kernel_size, file);
+
+  kernel = load_one(file, &kernel_size);
+
+  if(!kernel) {
+    return;
+  }
+
+  if(kernel_size < 1024 || *(uint32_t *) (kernel + 0x202) != 0x53726448) {
+    // not a linux kernel
+    gfx_done();
+    asprintf(&cmd_buf, "%s %s", menu_ptr->label, arg);
+    syslinux_run_command(cmd_buf);
+    return;
+  }
+
+  // printf("kernel = %p, size = %d\n", kernel, kernel_size);
+
+  // parse cmdline for "initrd" option
+
+  initrd_arg = menu_ptr->initrd;
+
+  s = s0 = strdup(arg);
+
+  while(*s && strncmp(s, "initrd=", sizeof "initrd=" - 1)) {
+    s = skipspace(skip_nonspaces(s));
+  }
+
+  if(*s) {
+    s += sizeof "initrd=" - 1;
+    *skip_nonspaces(s) = 0;
+    initrd_arg = s;
+  }
+  else if(initrd_arg) {
+    free(s0);
+    initrd_arg = s0 = strdup(initrd_arg);
+  }
+
+  if(initrd_arg) {
+    initrd = initramfs_init();
+
+    while((t = strsep(&initrd_arg, ","))) {
+      initrd_buf = load_one(t, &initrd_size);
+
+      if(!initrd_buf) {
+        printf("%s: read error\n", t);
+        free(s0);
+        return;
+      }
+
+      initramfs_add_data(initrd, initrd_buf, initrd_size, initrd_size, 4);
+
+      // printf("initrd = %p, size = %d\n", initrd_buf, initrd_size);
+    }
+  }
+
+  free(s0);
+
+  gfx_done();
+
+  syslinux_boot_linux(kernel, kernel_size, initrd, NULL, arg);
+}
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/gfxboot/realmode_callback.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gfxboot/realmode_callback.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gfxboot/realmode_callback.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,190 @@
+		bits 16
+
+		section .text
+
+		; must be filled in
+f_buf_size	dw 0
+f_buf_seg	dw 0
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+gfx_cb:
+		push cs
+		pop ds
+
+		cmp al,cb_len
+		jae gfx_cb_80
+
+		movzx bx,al
+		add bx,bx
+		call word [bx+cb_table]
+		jmp gfx_cb_90
+
+gfx_cb_80:
+		mov al,0ffh
+gfx_cb_90:
+		retf
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Return status info.
+;
+; return:
+;  edx		filename buffer (64 bytes)
+;
+cb_status:
+		mov edx,cs
+		shl edx,4
+		add edx,f_name
+		xor al,al
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Open file.
+;
+; return:
+;    al		0: ok, 1: file not found
+;   ecx		file length (al = 0)
+;
+cb_fopen:
+		mov si,f_name
+		push ds
+		pop es
+		mov ax,6
+		int 22h
+		xchg edx,eax
+		mov al,1
+		jc cb_fopen_90
+		cmp cx,[f_buf_size]
+		ja cb_fopen_90
+		or cx,cx
+		jz cb_fopen_90
+		mov [f_block_size],cx
+		or edx,edx
+		jz cb_fopen_90
+		mov [f_handle],si
+		mov [f_size],edx
+		mov ecx,edx
+		mov ax,[f_buf_size]
+		cwd
+		div word [f_block_size]
+		mov [f_blocks],ax
+
+		xor al,al
+cb_fopen_90:
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Read next chunk.
+;
+; return:
+;   edx		buffer address (linear)
+;   ecx		data length (< 64k)
+;
+cb_fread:
+		xor ecx,ecx
+		mov si,[f_handle]
+		or si,si
+		jz cb_fread_80
+		mov cx,[f_blocks]
+		mov es,[f_buf_seg]
+		xor bx,bx
+		mov ax,7
+		int 22h
+		mov [f_handle],si
+		mov al,1
+		jc cb_fread_90
+cb_fread_80:
+		xor al,al
+cb_fread_90:
+		movzx edx,word [f_buf_seg]
+		shl edx,4
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Return current working directory.
+;
+; return:
+;  edx		filename
+;
+cb_getcwd:
+		mov ax,1fh
+		int 22h
+		mov edx,es
+		shl edx,4
+		movzx ebx,bx
+		add edx,ebx
+		xor al,al
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Set current working directory.
+;
+cb_chdir:
+		mov bx,f_name
+		push ds
+		pop es
+		mov ax,25h
+		int 22h
+		xor al,al
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; read sector
+;
+;  edx		sector
+;
+; return:
+;  edx		buffer (linear address)
+;
+;  Note: does not return on error!
+;
+cb_readsector:
+		xor edi,edi
+		xor esi,esi
+		mov cx,1
+		mov es,[f_buf_seg]
+		xor bx,bx
+		mov ax,19h
+		int 22h
+		movzx edx,word [f_buf_seg]
+		shl edx,4
+		xor al,al
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+; Re-read fs structures.
+;
+cb_mount:
+		mov ax,26h
+		int 22h
+		setc al
+		ret
+
+
+; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+;
+		align 2, db 0
+
+cb_table	dw cb_status
+		dw cb_fopen
+		dw cb_fread
+		dw cb_getcwd
+		dw cb_chdir
+		dw cb_readsector
+		dw cb_mount
+cb_len		equ ($-cb_table)/2
+
+f_handle	dw 0
+f_block_size	dw 0
+f_blocks	dw 0
+f_size		dd 0
+f_name		times 64 db 0
+f_name_len	equ $ - f_name
+
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1 @@
+Put header files for LGPL or GPL library functions in this directory.
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/acpi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/acpi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/acpi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,99 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 ACPI_H
+#define ACPI_H
+
+#define DEBUG_ACPI 0
+
+void dbg_printf(const char *fmt, ...);
+#define DEBUG_PRINT(x) do { if (DEBUG_ACPI) dbg_printf x; } while (0)
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <acpi/structs.h>
+#include <acpi/rsdp.h>
+#include <acpi/rsdt.h>
+#include <acpi/xsdt.h>
+#include <acpi/fadt.h>
+#include <acpi/madt.h>
+#include <acpi/dsdt.h>
+#include <acpi/ssdt.h>
+#include <acpi/sbst.h>
+#include <acpi/ecdt.h>
+#include <acpi/facs.h>
+#include <acpi/hpet.h>
+#include <acpi/tcpa.h>
+#include <acpi/mcfg.h>
+#include <acpi/slic.h>
+#include <acpi/boot.h>
+
+enum { ACPI_FOUND = 1, ENO_ACPI = 2 , MADT_FOUND = 3 , ENO_MADT = 4 };
+
+#define MAX_SSDT 128
+
+/* Some other description HEADERS : ACPI doc: 5.2.6*/
+#define OEMX "OEMx"
+#define SRAR "SRAT"
+#define BERT "BERT"
+#define BOOT "BOOT"
+#define CPEP "CPEP"
+#define DBGP "DGBP"
+#define DMAR "DMAR"
+#define ERST "ERST"
+#define ETDT "ETDT"
+#define HEST "HEST"
+#define HPET "HPET"
+#define IBFT "IBFT"
+#define MCFG "MCFG"
+#define SPCR "SPCR"
+#define SPMI "SPMI"
+#define TCPA "TCPA"
+#define UEFI "UEFI"
+#define WAET "WAET"
+#define WDAT "WDAT"
+#define WDRT "WDRT"
+#define WSPT "WSPT"
+#define SLIC "SLIC"
+
+/* This macro are used to extract ACPI structures 
+ * please be careful about the q (interator) naming */
+#define cp_struct(dest) memcpy(dest,q,sizeof(*dest)); q+=sizeof(*dest)
+#define cp_str_struct(dest) memcpy(dest,q,sizeof(dest)-1); dest[sizeof(dest)-1]=0;q+=sizeof(dest)-1
+
+typedef struct {
+    s_rsdp rsdp;
+    s_rsdt rsdt;
+    s_xsdt xsdt;
+    s_fadt fadt;
+    s_madt madt;
+    s_dsdt dsdt;
+    s_ssdt *ssdt[MAX_SSDT];
+    uint8_t ssdt_count;
+    s_sbst sbst;
+    s_ecdt ecdt;
+    s_facs facs;
+    s_hpet hpet;
+    s_tcpa tcpa;
+    s_mcfg mcfg;
+    s_slic slic;
+    s_boot boot;
+} s_acpi;
+
+int parse_acpi(s_acpi * acpi);
+int parse_xsdt(s_acpi * acpi);
+void parse_madt(s_acpi * acpi);
+int search_rsdp(s_acpi *acpi);
+void get_acpi_description_header(uint8_t *q, s_acpi_description_header * adh);
+bool parse_header(uint64_t *address, s_acpi *acpi);
+char *flags_to_string(char *buffer, uint16_t flags);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/boot.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/boot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/boot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 BOOT_H
+#define BOOT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define BOOT "BOOT"
+
+enum { BOOT_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    /* What's inside ? */
+    bool valid;
+} s_boot;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/dsdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/dsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/dsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,28 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 DSDT_H
+#define DSDT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define DSDT "DSDT"
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    uint8_t *definition_block;
+    bool valid;
+} s_dsdt;
+
+void parse_dsdt(s_dsdt *dsdt);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ecdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ecdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ecdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 ECDT_H
+#define ECDT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define ECDT "ECDT"
+
+/* Offset of the EC_ID in the structure */
+#define EC_ID_OFFSET 65
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    bool valid;
+    uint32_t warning_energy_level;
+    uint32_t low_energy_level;
+    uint32_t critical_energy_level;
+    s_gas ec_control;
+    s_gas ec_data;
+    uint32_t uid;
+    uint8_t gpe_bit;
+    char *ec_id;
+} s_ecdt;
+
+void parse_ecdt(s_ecdt * ecdt);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/facs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/facs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/facs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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 FACS_H
+#define FACS_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define FACS "FACS"
+
+/* Features Flags for "flags" */
+#define S4BIOS_F 1
+
+/* Features flags for global_lock */
+#define PENDING 1
+#define OWNED 1<<1
+
+typedef struct {
+    uint64_t *address;
+    uint8_t signature[4+1];
+    uint8_t length;
+    uint32_t hardware_signature;
+    uint32_t firmware_waking_vector;
+    uint32_t global_lock;
+    uint32_t flags;
+    uint64_t x_firmware_waking_vector;
+    uint8_t version;
+    bool valid;
+} s_facs;
+
+void parse_facs(s_facs *facs);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/fadt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/fadt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/fadt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,121 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 FADT_H
+#define FADT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+enum { FADT_TABLE_FOUND = 1};
+
+#define FACP "FACP"
+#define FADT "FADT"
+
+/* prefered pm profiles */
+enum { PM_UNSPECIFIED = 0,
+    PM_DESKTOP = 1,
+    PM_MOBILE = 2,
+    PM_WORKSTATION = 3,
+    PM_ENTERPRISE_SERVER = 4,
+    PM_SOHO_SERVER = 5,
+    PM_APPLIANCE_PC = 6,
+    PM_PERFORMANCE_SERVER = 7
+};
+
+/* iapc_boot_arch flags*/
+#define IAPC_LEGAGY_DEVICE 1
+#define IAPC_8042 1<<1
+#define IAPC_VGA_NOT_PRESENT 1<<2
+#define IAPC_MSI_NOT_SUPPORTED 1<<3
+#define IAPC_PCIE_ASPM_CONTROLS 1<<4
+
+/* feature flags for "flags" */
+#define WBINVD 1
+#define WBINVD_FLUSH 1<<1
+#define PROC_C1 1<<2
+#define P_LVL2_UP 1<<3
+#define PWR_BUTTON 1<<4
+#define SLP_BUTTON 1<<5
+#define FIX_RTC 1<<6
+#define RTC_S4 1<<7
+#define TMR_VAL_EXT 1<<8
+#define DCK_CAP 1<<9
+#define RESET_REG_SUP 1<<10
+#define SEALED_CASE 1<<11
+#define HEADLESS 1<<12
+#define CPU_SW_SLP 1<<13
+#define PCI_EXP_WAK 1<<14
+#define USE_PLATEFORM_CLOCK 1<<15
+#define S4_RTC_STS_VALID 1<<16
+#define REMOTE_POWER_ON_CAPABLE 1<<17
+#define FORCE_APIC_CLUSTER_MODEL 1<<18
+#define FORCE_APIC_PHYSICAL_DESTINATION_MODE 1<<19
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    bool valid;
+    uint32_t *firmware_ctrl;
+    uint32_t *dsdt_address;
+    uint8_t reserved;
+    uint8_t prefered_pm_profile;
+    uint16_t sci_int;
+    uint32_t smi_cmd;
+    uint8_t acpi_enable;
+    uint8_t acpi_disable;
+    uint8_t s4bios_req;
+    uint8_t pstate_cnt;
+    uint32_t pm1a_evt_blk;
+    uint32_t pm1b_evt_blk;
+    uint32_t pm1a_cnt_blk;
+    uint32_t pm1b_cnt_blk;
+    uint32_t pm2_cnt_blk;
+    uint32_t pm_tmr_blk;
+    uint32_t gpe0_blk;
+    uint32_t gpe1_blk;
+    uint8_t pm1_evt_len;
+    uint8_t pm1_cnt_len;
+    uint8_t pm2_cnt_len;
+    uint8_t pm_tmr_len;
+    uint8_t gpe0_blk_len;
+    uint8_t gpe1_blk_len;
+    uint8_t gpe1_base;
+    uint8_t cst_cnt;
+    uint16_t p_lvl2_lat;
+    uint16_t p_lvl3_lat;
+    uint16_t flush_size;
+    uint16_t flush_stride;
+    uint8_t duty_offset;
+    uint8_t duty_width;
+    uint8_t day_alarm;
+    uint8_t mon_alarm;
+    uint8_t century;
+    uint16_t iapc_boot_arch;
+    uint8_t reserved_2;
+    uint32_t flags;
+    s_gas reset_reg;
+    uint8_t reset_value;
+    uint8_t reserved_3[3];
+    uint64_t *x_firmware_ctrl;
+    uint64_t *x_dsdt;
+    s_gas x_pm1a_evt_blk;
+    s_gas x_pm1b_evt_blk;
+    s_gas x_pm1a_cnt_blk;
+    s_gas x_pm1b_cnt_blk;
+    s_gas x_pm2_cnt_blk;
+    s_gas x_pm_tmr_blk;
+    s_gas x_gpe0_blk;
+    s_gas x_gpe1_blk;
+} s_fadt;
+
+void parse_fadt(s_fadt * fadt);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/hpet.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/hpet.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/hpet.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 HPET_H
+#define HPET_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define HPET "HPET"
+
+enum { HPET_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    /* What's inside ? */
+    bool valid;
+} s_hpet;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/madt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/madt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/madt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 MADT_H
+#define MADT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define MADT "MADT"
+#define APIC "APIC"
+
+enum {
+    PROCESSOR_LOCAL_APIC = 0,
+    IO_APIC = 1,
+    INTERRUPT_SOURCE_OVERRIDE = 2,
+    NMI = 3,
+    LOCAL_APIC_NMI_STRUCTURE = 4,
+    LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE = 5,
+    IO_SAPIC = 6,
+    LOCAL_SAPIC = 7,
+    PLATEFORM_INTERRUPT_SOURCES = 8
+};
+
+/* Features flags for 
+ * - processor_local_apic flags
+ * - local sapic flags
+ */
+#define PROCESSOR_LOCAL_APIC_ENABLE 1
+
+#define MAX_S_L_P 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t acpi_id;
+    uint8_t apic_id;
+    uint32_t flags;
+} __attribute__ ((packed)) s_processor_local_apic;
+
+#define MAX_IO_APIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t io_apic_id;
+    uint8_t reserved;
+    uint32_t io_apic_address;
+    uint32_t global_system_interrupt_base;
+} __attribute__ ((packed)) s_io_apic;
+
+/* Features flags for
+ * - interrupt_source_override
+ * - nmi
+ */
+/* Bits 1&2 must be set to 0 */
+#define POLARITY_CONFORM_MASK 0x0
+#define POLARITY_ACTIVE_HIGH 0x1
+#define POLARITY_RESERVED 0x2
+#define POLARITY_ACTIVE_LOW 0x3
+/* Bits 3&4 must be set to 0 */
+#define TRIGGER_CONFORM_MASK 0x3
+#define TRIGGER_EDGE 0x4
+#define TRIGGER_RESERVED 0x8
+#define TRIGGER_LEVEL 0xA
+
+#define MAX_I_S_O 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t bus;
+    uint8_t source;
+    uint32_t global_system_interrupt;
+    uint16_t flags;
+} __attribute__ ((packed)) s_interrupt_source_override;
+
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t flags;
+    uint32_t global_system_interrupt;
+} __attribute__ ((packed)) s_nmi;
+
+#define MAX_LOCAL_APIC_NMI 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t acpi_processor_id;
+    uint16_t flags;
+    uint8_t local_apic_lint;
+} __attribute__ ((packed)) s_local_apic_nmi;
+
+#define MAX_L_A_A_O 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint16_t reserved;
+    uint64_t local_apic_address;
+} __attribute__ ((packed)) s_local_apic_address_override;
+
+#define MAX_IO_SAPIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t io_apic_id;
+    uint8_t reserved;
+    uint32_t global_system_interrupt_base;
+    uint64_t io_sapic_address;
+} __attribute__ ((packed)) s_io_sapic;
+
+#define ACPI_PROCESSOR_UID_STRING_OFFSET 16
+#define MAX_LOCAL_SAPIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t acpi_processor_id;
+    uint8_t local_sapic_id;
+    uint8_t local_sapic_eid;
+    uint8_t reserved[3];
+    uint32_t flags;
+    uint32_t acpi_processor_uid_value;
+    char *acpi_processor_uid_string;
+} __attribute__ ((packed)) s_local_sapic;
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    uint32_t local_apic_address;
+    uint32_t flags;
+    s_processor_local_apic processor_local_apic[MAX_S_L_P];
+    uint8_t processor_local_apic_count;
+    s_io_apic io_apic[MAX_IO_APIC];
+    uint8_t io_apic_count;
+    s_interrupt_source_override interrupt_source_override[MAX_I_S_O];
+    uint8_t interrupt_source_override_count;
+    s_nmi nmi[MAX_I_S_O];
+    uint8_t nmi_count;
+    s_local_apic_nmi local_apic_nmi[MAX_LOCAL_APIC_NMI];
+    uint8_t local_apic_nmi_count;
+    s_local_apic_address_override local_apic_address_override[MAX_L_A_A_O];
+    uint8_t local_apic_address_override_count;
+    s_io_sapic io_sapic[MAX_IO_SAPIC];
+    uint8_t io_sapic_count;
+    s_local_sapic local_sapic[MAX_LOCAL_SAPIC];
+    uint8_t local_sapic_count;
+    bool valid;
+} s_madt;
+
+void print_madt(s_madt * madt);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/mcfg.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/mcfg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/mcfg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 MCFG_H
+#define MCFG_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define MCFG "MCFG"
+
+enum { MCFG_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    /* What's inside ? */
+    bool valid;
+} s_mcfg;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 RSDP_H
+#define RSDP_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define RSDP_MIN_ADDRESS 0x0E0000
+#define RSDP_MAX_ADDRESS 0x0FFFFF
+
+#define RSDP "RSD PTR"
+
+enum { RSDP_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint8_t *address;
+    uint8_t signature[8 + 1];
+    uint8_t checksum;
+    uint8_t oem_id[6 + 1];
+    uint8_t revision;
+    uint8_t *rsdt_address;
+    uint32_t length;
+    uint8_t *xsdt_address;
+    uint8_t extended_checksum;
+    bool valid;
+} s_rsdp;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/rsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 RSDT_H
+#define RSDT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+enum { RSDT_TABLE_FOUND = 1};
+
+#define RSDT "RSDT"
+
+typedef struct {
+    uint8_t *address;
+    s_acpi_description_header header;
+    uint8_t *entry[255];
+    uint8_t entry_count;
+    bool valid;
+} s_rsdt;
+
+int parse_rsdt(s_rsdt * rsdt);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/sbst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/sbst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/sbst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 SBST_H
+#define SBST_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define SBST "SBST"
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    bool valid;
+    uint32_t warning_energy_level;
+    uint32_t low_energy_level;
+    uint32_t critical_energy_level;
+} s_sbst;
+
+void parse_sbst(s_sbst * sbst);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/slic.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/slic.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/slic.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 SLIC_H
+#define SLIC_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define SLIC "SLIC"
+
+enum { SLIC_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    /* What's inside ? */
+    bool valid;
+} s_slic;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ssdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ssdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/ssdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,28 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 SSDT_H
+#define SSDT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define SSDT "SSDT"
+#define PSDT "PSDT"
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    uint8_t *definition_block;
+    bool valid;
+} s_ssdt;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/structs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/structs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/structs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 ACPI_STRUCTS_H
+#define ACPI_STRUCTS_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+/* This value define the real size of the acpi structure 
+ * Our is bigger as we manage the \0 of strings
+ * */
+#define ACPI_HEADER_SIZE 36
+
+enum { GAS_SYSTEM_MEMORY=0, GAS_SYSTEM_IO=1 };
+
+/* Generic Address Structure (GAS) Format */
+typedef struct {
+    /* address_space_id could be {GAS_SYSTEM_MEMORY | GAS_SYSTEM_IO} */
+    uint8_t address_space_id;
+    uint8_t register_bit_width;
+    uint8_t register_bit_offset;
+    uint8_t reserved;
+    uint64_t address;
+} __attribute__ ((packed)) s_gas;
+
+typedef struct {
+    uint8_t signature[4 + 1];
+    uint32_t length;
+    uint8_t revision;
+    uint8_t checksum;
+    uint8_t oem_id[6 + 1];
+    uint8_t oem_table_id[8 + 1];
+    uint32_t oem_revision;
+    uint8_t creator_id[4 + 1];
+    uint32_t creator_revision;
+} s_acpi_description_header;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/tcpa.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/tcpa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/tcpa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 TCPA_H
+#define TCPA_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define TCPA "TCPA"
+
+enum { TCPA_TABLE_FOUND = 1 };
+
+typedef struct {
+    uint64_t *address;
+    s_acpi_description_header header;
+    /* What's inside ? */
+    bool valid;
+} s_tcpa;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/xsdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/xsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/acpi/xsdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - 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 XSDT_H
+#define XSDT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+enum { XSDT_TABLE_FOUND = 1 };
+
+#define XSDT "XSDT"
+
+typedef struct {
+    uint8_t *address;
+    s_acpi_description_header header;
+    uint64_t *entry[255];
+    uint8_t entry_count;
+    bool valid;
+} s_xsdt;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/cpuid.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/cpuid.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/cpuid.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,317 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2009 Erwan Velu - All Rights Reserved
+ *
+ *   Portions of this file taken from the Linux kernel,
+ *   Copyright 1991-2009 Linus Torvalds and contributors
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2
+ *   as published by the Free Software Foundation, Inc.,
+ *   51 Franklin St, Fifth Floor, Boston MA 02110-1301;
+ *   incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _CPUID_H
+#define _CPUID_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <cpufeature.h>
+#include <sys/bitops.h>
+#include <sys/cpu.h>
+#include <sys/io.h>
+#include <klibc/compiler.h>
+
+#define PAGE_SIZE 4096
+
+#define CPU_MODEL_SIZE  48
+#define CPU_VENDOR_SIZE 48
+
+#define CPU_FLAGS(m_) \
+m_(bool,  fpu, 			/* Onboard FPU */) \
+m_(bool,  vme, 			/* Virtual Mode Extensions */) \
+m_(bool,  de, 			/* Debugging Extensions */) \
+m_(bool,  pse,			/* Page Size Extensions */) \
+m_(bool,  tsc,			/* Time Stamp Counter */) \
+m_(bool,  msr,			/* Model-Specific Registers, RDMSR, WRMSR */) \
+m_(bool,  pae,			/* Physical Address Extensions */) \
+m_(bool,  mce,			/* Machine Check Architecture */) \
+m_(bool,  cx8,			/* CMPXCHG8 instruction */) \
+m_(bool,  apic,			/* Onboard APIC */) \
+m_(bool,  sep,			/* SYSENTER/SYSEXIT */) \
+m_(bool,  mtrr,			/* Memory Type Range Registers */) \
+m_(bool,  pge,			/* Page Global Enable */) \
+m_(bool,  mca,			/* Machine Check Architecture */) \
+m_(bool,  cmov,			/* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */) \
+m_(bool,  pat,			/* Page Attribute Table */) \
+m_(bool,  pse_36,		/* 36-bit PSEs */) \
+m_(bool,  psn,			/* Processor serial number */) \
+m_(bool,  clflsh,		/* Supports the CLFLUSH instruction */) \
+m_(bool,  dts,			/* Debug Trace Store */) \
+m_(bool,  acpi,			/* ACPI via MSR */) \
+m_(bool,  pbe,			/* Pending Break Enable */) \
+m_(bool,  mmx,			/* Multimedia Extensions */) \
+m_(bool,  fxsr,			/* FXSAVE and FXRSTOR instructions (fast save and restore of FPU context), and CR4.OSFXSR available */) \
+m_(bool,  sse,			/* Streaming SIMD Extensions */) \
+m_(bool,  sse2,			/* Streaming SIMD Extensions 2 */) \
+m_(bool,  ss,			/* CPU self snoop */) \
+m_(bool,  htt,			/* Hyper-Threading */) \
+m_(bool,  acc,			/* Automatic clock control */) \
+m_(bool,  syscall,		/* SYSCALL/SYSRET */) \
+m_(bool,  mp,			/* MP Capable. */) \
+m_(bool,  nx,			/* Execute Disable */) \
+m_(bool,  mmxext,		/* AMD MMX extensions */) \
+m_(bool,  fxsr_opt,		/* FXSAVE/FXRSTOR optimizations */) \
+m_(bool,  gbpages,		/* "pdpe1gb" GB pages */) \
+m_(bool,  rdtscp,		/* RDTSCP */) \
+m_(bool,  lm,			/* Long Mode (x86-64) */) \
+m_(bool,  nowext,		/* AMD 3DNow! extensions */) \
+m_(bool,  now,			/* 3DNow! */) \
+m_(bool,  smp,			/* A smp configuration has been found */) \
+m_(bool,  pni,			/* Streaming SIMD Extensions-3 */) \
+m_(bool,  pclmulqd,		/* PCLMULQDQ instruction */) \
+m_(bool,  dtes64,		/* 64-bit Debug Store */) \
+m_(bool,  vmx,			/* Hardware virtualization */) \
+m_(bool,  smx,			/* Safer Mode */) \
+m_(bool,  est,			/* Enhanced SpeedStep */) \
+m_(bool,  tm2,			/* Thermal Monitor 2  */) \
+m_(bool,  sse3,			/* Supplemental SSE-3 */) \
+m_(bool,  cid,			/* Context ID */) \
+m_(bool,  fma,			/* Fused multiply-add  */) \
+m_(bool,  cx16,			/* CMPXCHG16B */) \
+m_(bool,  xtpr,			/* Send Task Priority Messages */) \
+m_(bool,  pdcm,			/* Performance Capabilities  */) \
+m_(bool,  dca,			/* Direct Cache Access */) \
+m_(bool,  xmm4_1,		/* "sse4_1" SSE-4.1 */) \
+m_(bool,  xmm4_2,		/* "sse4_2" SSE-4.2 */) \
+m_(bool,  x2apic,		/* x2APIC */) \
+m_(bool,  movbe,			/* MOVBE instruction */) \
+m_(bool,  popcnt,		/* POPCNT instruction */) \
+m_(bool,  aes,			/* AES Instruction */) \
+m_(bool,  xsave,			/* XSAVE/XRSTOR/XSETBV/XGETBV */) \
+m_(bool,  osxsave,		/* XSAVE enabled in the OS */) \
+m_(bool,  avx,			/* Advanced Vector Extensions */) \
+m_(bool,  hypervisor,		/* Running on a hypervisor */) \
+m_(bool,  ace2,			/* Advanced Cryptography Engine v2 */) \
+m_(bool,  ace2_en,		/* ACE v2 enabled */) \
+m_(bool,  phe,			/* PadLock Hash Engine */) \
+m_(bool,  phe_en,		/* PadLock Hash Engine Enabled */) \
+m_(bool,  pmm,			/* PadLock Montgomery Multiplier */) \
+m_(bool,  pmm_en,		/* PadLock Montgomery Multiplier enabled */) \
+m_(bool,  svm,			/* Secure virtual machine */) \
+m_(bool,  extapic,		/* Extended APIC space */) \
+m_(bool,  cr8_legacy,		/* CR8 in 32-bit mode */) \
+m_(bool,  abm,			/* Advanced bit manipulation */) \
+m_(bool,  sse4a,			/* SSE4-A */) \
+m_(bool,  misalignsse,		/* Misaligned SSE mode */) \
+m_(bool,  nowprefetch,		/* 3DNow prefetch instructions */) \
+m_(bool,  osvw,			/* OS Visible Workaround */) \
+m_(bool,  ibs,			/*  Instruction Based Sampling */) \
+m_(bool,  sse5,			/* SSE5 */) \
+m_(bool,  skinit,		/* SKINIT/STGI instructions */) \
+m_(bool,  wdt,			/* Watchdog Timer */) \
+m_(bool,  ida,			/* Intel Dynamic Acceleration */) \
+m_(bool,  arat,			/* Always Running APIC Timer */) \
+m_(bool,  tpr_shadow,		/* Intel TPR Shadow */) \
+m_(bool,  vnmi,			/* Intel Virtual NMI */) \
+m_(bool,  flexpriority,		/* Intel FlexPriority */) \
+m_(bool,  ept,			/* Intel Extended Page Table */) \
+m_(bool,  vpid,			/* Intel Virtual Processor ID */)
+
+#define STRUCT_MEMBERS(type_, name_, comment_) type_ name_;
+
+#define STRUCT_MEMBER_NAMES(type_, name_, comment_) #name_ , 
+
+#define STRUCTURE_MEMBER_OFFSETS(type_, name_, comment_) \
+	  offsetof(s_cpu_flags, name_),
+
+typedef struct {
+    CPU_FLAGS(STRUCT_MEMBERS)
+} s_cpu_flags;
+
+extern size_t cpu_flags_offset[];
+extern const char *cpu_flags_names[];
+extern size_t cpu_flags_count;
+
+typedef struct {
+    char vendor[CPU_VENDOR_SIZE];
+    uint8_t vendor_id;
+    uint8_t family;
+    char model[CPU_MODEL_SIZE];
+    uint8_t model_id;
+    uint8_t stepping;
+    uint8_t num_cores;
+    uint16_t l1_data_cache_size;
+    uint16_t l1_instruction_cache_size;
+    uint16_t l2_cache_size;
+    s_cpu_flags flags;
+} s_cpu;
+
+extern bool get_cpu_flag_value_from_name(s_cpu *cpu, const char * flag);
+/**********************************************************************************/
+/**********************************************************************************/
+/* From this point this is some internal stuff mainly taken from the linux kernel */
+/**********************************************************************************/
+/**********************************************************************************/
+
+/*
+ * EFLAGS bits
+ */
+#define X86_EFLAGS_CF   0x00000001	/* Carry Flag */
+#define X86_EFLAGS_PF   0x00000004	/* Parity Flag */
+#define X86_EFLAGS_AF   0x00000010	/* Auxillary carry Flag */
+#define X86_EFLAGS_ZF   0x00000040	/* Zero Flag */
+#define X86_EFLAGS_SF   0x00000080	/* Sign Flag */
+#define X86_EFLAGS_TF   0x00000100	/* Trap Flag */
+#define X86_EFLAGS_IF   0x00000200	/* Interrupt Flag */
+#define X86_EFLAGS_DF   0x00000400	/* Direction Flag */
+#define X86_EFLAGS_OF   0x00000800	/* Overflow Flag */
+#define X86_EFLAGS_IOPL 0x00003000	/* IOPL mask */
+#define X86_EFLAGS_NT   0x00004000	/* Nested Task */
+#define X86_EFLAGS_RF   0x00010000	/* Resume Flag */
+#define X86_EFLAGS_VM   0x00020000	/* Virtual Mode */
+#define X86_EFLAGS_AC   0x00040000	/* Alignment Check */
+#define X86_EFLAGS_VIF  0x00080000	/* Virtual Interrupt Flag */
+#define X86_EFLAGS_VIP  0x00100000	/* Virtual Interrupt Pending */
+#define X86_EFLAGS_ID   0x00200000	/* CPUID detection flag */
+
+#define X86_VENDOR_INTEL 0
+#define X86_VENDOR_CYRIX 1
+#define X86_VENDOR_AMD 2
+#define X86_VENDOR_UMC 3
+#define X86_VENDOR_NEXGEN 4
+#define X86_VENDOR_CENTAUR 5
+#define X86_VENDOR_RISE 6
+#define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_NSC 8
+#define X86_VENDOR_UNKNOWN 9 
+#define X86_VENDOR_NUM 10 
+
+#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
+
+// Taken from asm/processor-flags.h
+// NSC/Cyrix CPU configuration register indexes
+#define CX86_CCR2       0xc2
+#define CX86_CCR3	0xc3
+#define CX86_DIR0       0xfe
+#define CX86_DIR1       0xff
+
+static const char Cx86_model[][9] = {
+	"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
+	"M II ", "Unknown"
+};
+
+static const char Cx486_name[][5] = {
+	"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
+	"SRx2", "DRx2"
+};
+
+static const char Cx486S_name[][4] = {
+	"S", "S2", "Se", "S2e"
+};
+
+static const char Cx486D_name[][4] = {
+	"DX", "DX2", "?", "?", "?", "DX4"
+};
+
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ *  Members of this structure are referenced in head.S, so think twice
+ *  before touching them. [mj]
+ */
+
+struct cpuinfo_x86 {
+    uint8_t x86;		/* CPU family */
+    uint8_t x86_vendor;		/* CPU vendor */
+    uint8_t x86_model;
+    uint8_t x86_mask;
+    char wp_works_ok;		/* It doesn't on 386's */
+    char hlt_works_ok;		/* Problems on some 486Dx4's and old 386's */
+    char hard_math;
+    char rfu;
+    int cpuid_level;		/* Maximum supported CPUID level, -1=no CPUID */
+    uint32_t x86_capability[NCAPINTS];
+    char x86_vendor_id[16];
+    char x86_model_id[64];
+    uint16_t x86_l1_data_cache_size;	/* in KB, if available */
+    uint16_t x86_l1_instruction_cache_size;	/* in KB, if available */
+    uint16_t x86_l2_cache_size;	/* in KB, if available */
+    int x86_cache_alignment;	/* in bytes */
+    char fdiv_bug;
+    char f00f_bug;
+    char coma_bug;
+    char pad0;
+    int x86_power;
+    unsigned long loops_per_jiffy;
+#ifdef CONFIG_SMP
+    cpumask_t llc_shared_map;	/* cpus sharing the last level cache */
+#endif
+    unsigned char x86_num_cores;	/* cpuid returned the number of cores */
+    unsigned char booted_cores;	/* number of cores as seen by OS */
+    unsigned char apicid;
+    unsigned char x86_clflush_size;
+
+} __attribute__ ((__packed__));
+
+struct cpu_model_info {
+    int vendor;
+    int family;
+    char *model_names[16];
+};
+
+/* attempt to consolidate cpu attributes */
+struct cpu_dev {
+    const char *c_vendor;
+
+    /* some have two possibilities for cpuid string */
+    const char *c_ident[2];
+
+    struct cpu_model_info c_models[4];
+
+    void (*c_init) (struct cpuinfo_x86 * c);
+    void (*c_identify) (struct cpuinfo_x86 * c);
+    unsigned int (*c_size_cache) (struct cpuinfo_x86 * c, unsigned int size);
+};
+
+/*
+ * Structure definitions for SMP machines following the
+ * Intel Multiprocessing Specification 1.1 and 1.4.
+ */
+
+/*
+ * This tag identifies where the SMP configuration
+ * information is.
+ */
+
+#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
+
+struct intel_mp_floating {
+    char mpf_signature[4];	/* "_MP_"                       */
+    uint32_t mpf_physptr;	/* Configuration table address  */
+    uint8_t mpf_length;		/* Our length (paragraphs)      */
+    uint8_t mpf_specification;	/* Specification version        */
+    uint8_t mpf_checksum;	/* Checksum (makes sum 0)       */
+    uint8_t mpf_feature1;	/* Standard or configuration ?  */
+    uint8_t mpf_feature2;	/* Bit7 set for IMCR|PIC        */
+    uint8_t mpf_feature3;	/* Unused (0)                   */
+    uint8_t mpf_feature4;	/* Unused (0)                   */
+    uint8_t mpf_feature5;	/* Unused (0)                   */
+};
+
+static inline uint8_t getCx86(uint8_t reg) {
+	outb(reg, 0x22);
+	return inb(0x23);
+}
+
+static inline void setCx86(uint8_t reg, uint8_t data) {
+	outb(reg, 0x22);
+	outb(data, 0x23);
+}
+
+extern void get_cpu_vendor(struct cpuinfo_x86 *c);
+extern void detect_cpu(s_cpu * cpu);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/bootloaders.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/bootloaders.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/bootloaders.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __BOOTLOADERS_H_
+#define __BOOTLOADERS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+#include <disk/partition.h>
+
+int get_bootloader_string(struct driveinfo *, const struct part_entry *,
+			  char *, const int);
+#endif /* __BOOTLOADERS_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/common.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdint.h>
+
+/* For PAGE_SIZE */
+#include <cpuid.h>
+
+#define SECTOR 512		/* bytes/sector */
+
+struct ebios_dapa {
+    uint16_t len;
+    uint16_t count;
+    uint16_t off;
+    uint16_t seg;
+    uint64_t lba;
+};
+
+#endif /* _COMMON_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/errno_disk.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/errno_disk.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/errno_disk.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _ERRNO_DISK_H
+#define _ERRNO_DISK_H
+
+extern int errno_disk;
+
+/* Prefix with ED to avoid confusion with errno */
+#define	EDINV	0x01		/* Invalid function in AH or invalid parameter */
+#define	EDADDR	0x02		/* Address mark not found */
+#define	EDRO	0x03		/* Disk write-protected */
+#define	EDNOFND	0x04		/* Sector not found/read error */
+#define	EDRFAIL	0x05		/* Reset failed (hard disk) */
+#define	EDCHANG	0x06		/* Disk changed (floppy) */
+#define	EDFAIL	0x07		/* Drive parameter activity failed (hard disk) */
+#define	EDDMA	0x08		/* DMA overrun */
+#define	EDBOUND	0x09		/* Data boundary error (attempted DMA across 64K boundary or >80h sectors) */
+#define	EDBADS	0x0A		/* Bad sector detected (hard disk) */
+#define	EDBADT	0x0B		/* Bad track detected (hard disk) */
+#define	EDINVM	0x0C		/* Unsupported track or invalid media */
+#define	EDINVS	0x0D		/* Invalid number of sectors on format (PS/2 hard disk) */
+#define	EDADDRM	0x0E		/* Control data address mark detected (hard disk) */
+#define	EDDMARG	0x0F		/* DMA arbitration level out of range (hard disk) */
+#define	EDCRCF	0x10		/* Uncorrectable CRC or ECC error on read */
+#define	EDCRCV	0x11		/* Data ECC corrected (hard disk) */
+#define	EDCTRL	0x20		/* Controller failure */
+#define	EDMEDIA	0x31		/* No media in drive (IBM/MS INT 13 extensions) */
+#define	EDCMOS	0x32		/* Incorrect drive type stored in CMOS (Compaq) */
+#define	EDSEEKF	0x40		/* Seek failed */
+#define	EDTIME	0x80		/* Timeout (not ready) */
+#define	EDREADY	0xAA		/* Drive not ready (hard disk) */
+#define	EDNLOCK	0xB0		/* Volume not locked in drive (INT 13 extensions) */
+#define	EDLOCK	0xB1		/* Volume locked in drive (INT 13 extensions) */
+#define	EDREMOV	0xB2		/* Volume not removable (INT 13 extensions) */
+#define	EDUSED	0xB3		/* Volume in use (INT 13 extensions) */
+#define	EDCOUNT	0xB4		/* Lock count exceeded (INT 13 extensions) */
+#define	EDEJF	0xB5		/* Valid eject request failed (INT 13 extensions) */
+#define	EDUNKOWN	0xBB	/* Undefined error (hard disk) */
+#define	EDWF	0xCC		/* Write fault (hard disk) */
+#define	EDRF	0xE0		/* Status register error (hard disk) */
+#define	EDSF	0xFF		/* Sense operation failed (hard disk) */
+
+#endif /* _ERRNO_DISK_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/error.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/error.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/error.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _ERROR_H_
+#define _ERROR_H_
+void get_error(const char *);
+#endif /* _ERROR_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/geom.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/geom.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/geom.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,326 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Some parts borrowed from Linux:
+ *
+ *   Copyright (C) 2002, 2003, 2004 Dell Inc.
+ *   by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _GEOM_H_
+#define _GEOM_H_
+
+#include <stdint.h>
+
+/**
+ * INT 13 Extensions
+ *
+ * Note: if the size is less than 30 on call, the final DWORD will not be
+ *       returned by a v2.x implementation; similarly for the Device Path info
+ **/
+struct edd_device_parameters {
+    uint16_t len;		/* size of returned data */
+	/**
+	 * Bitfields for IBM/MS INT 13 Extensions information flags:
+	 * Bit(s)    Description    (Table 00274)
+	 * 0    DMA boundary errors handled transparently
+	 * 1    cylinder/head/sectors-per-track information is valid
+	 * 2    removable drive
+	 * 3    write with verify supported
+	 * 4    drive has change-line support (required if drive >= 80h is removable)
+	 * 5    drive can be locked (required if drive >= 80h is removable)
+	 * 6    CHS information set to maximum supported values, not current media
+	 * 15-7    reserved (0)
+	 **/
+    uint16_t info;		/* information flags */
+    uint32_t cylinders;		/* number of physical cylinders on drive */
+    uint32_t heads;		/* number of physical heads on drive */
+    uint32_t sectors_per_track;	/* number of physical sectors per track */
+    uint64_t sectors;		/* total number of sectors on drive */
+    uint16_t bytes_per_sector;	/* bytes per sector */
+    /* --- v2.0+ --- */
+    uint32_t dpte_pointer;	/* EDD configuration parameters, FFFFh:FFFFh if not available */
+    /* --- v3.0 --- */
+    uint16_t device_path_information;	/* signature BEDDh to indicate presence of Device Path info */
+    uint8_t device_path_length;	/* length of Device Path information, including signature and this byte (24h for v3.0) */
+    uint8_t device_path_reserved;	/* reserved (0) */
+    uint16_t device_path_reserved_2;	/* reserved (0) */
+    uint8_t host_bus_type[4];	/* ASCIZ name of host bus ("ISA" or "PCI") */
+    uint8_t interface_type[8];	/* ASCIZ name of interface type
+				 *         "ATA"
+				 *         "ATAPI"
+				 *         "SCSI"
+				 *         "USB"
+				 *         "1394" IEEE 1394 (FireWire)
+				 *         "FIBRE" Fibre Channel
+				 */
+	/**
+	 * Format of EDD v3.0 Interface Path:
+	 * Offset    Size    Description    (Table 00275)
+	 * ---ISA---
+	 * 00h    WORD    16-bit base address
+	 * 02h 6 BYTEs    reserved (0)
+	 * ---PCI---
+	 * 00h    BYTE    PCI bus number
+	 * 01h    BYTE    PCI device number
+	 * 02h    BYTE    PCI function number
+	 * 03h 5 BYTEs    reserved (0)
+	 **/
+    union {
+	struct {
+	    uint16_t base_address;
+	    uint16_t reserved1;
+	    uint32_t reserved2;
+	} __attribute__ ((packed)) isa;
+	struct {
+	    uint8_t bus;
+	    uint8_t slot;
+	    uint8_t function;
+	    uint8_t channel;
+	    uint32_t reserved;
+	} __attribute__ ((packed)) pci;
+	/* pcix is same as pci */
+	struct {
+	    uint64_t reserved;
+	} __attribute__ ((packed)) ibnd;
+	struct {
+	    uint64_t reserved;
+	} __attribute__ ((packed)) xprs;
+	struct {
+	    uint64_t reserved;
+	} __attribute__ ((packed)) htpt;
+	struct {
+	    uint64_t reserved;
+	} __attribute__ ((packed)) unknown;
+    } interface_path;
+	/**
+	 * Format of EDD v3.0 Device Path:
+	 * Offset    Size    Description    (Table 00276)
+	 * ---ATA---
+	 * 00h    BYTE    flag: 00h = master, 01h = slave
+	 * 01h 7 BYTEs    reserved (0)
+	 * ---ATAPI---
+	 * 00h    BYTE    flag: 00h = master, 01h = slave
+	 * 01h    BYTE    logical unit number
+	 * 02h 6 BYTEs    reserved (0)
+	 * ---SCSI---
+	 * 00h    BYTE    logical unit number
+	 * 01h 7 BYTEs    reserved (0)
+	 * ---USB---
+	 * 00h    BYTE    to be determined
+	 * 01h 7 BYTEs    reserved (0)
+	 * ---IEEE1394---
+	 * 00h    QWORD    64-bit FireWire General Unique Identifier (GUID)
+	 * ---FibreChannel---
+	 * 00h    QWORD    Word Wide Number (WWN)
+	 **/
+    union {
+	struct {
+	    uint8_t device;
+	    uint8_t reserved1;
+	    uint16_t reserved2;
+	    uint32_t reserved3;
+	    uint64_t reserved4;
+	} __attribute__ ((packed)) ata;
+	struct {
+	    uint8_t device;
+	    uint8_t lun;
+	    uint8_t reserved1;
+	    uint8_t reserved2;
+	    uint32_t reserved3;
+	    uint64_t reserved4;
+	} __attribute__ ((packed)) atapi;
+	struct {
+	    uint16_t id;
+	    uint64_t lun;
+	    uint16_t reserved1;
+	    uint32_t reserved2;
+	} __attribute__ ((packed)) scsi;
+	struct {
+	    uint64_t serial_number;
+	    uint64_t reserved;
+	} __attribute__ ((packed)) usb;
+	struct {
+	    uint64_t eui;
+	    uint64_t reserved;
+	} __attribute__ ((packed)) i1394;
+	struct {
+	    uint64_t wwid;
+	    uint64_t lun;
+	} __attribute__ ((packed)) fibre;
+	struct {
+	    uint64_t identity_tag;
+	    uint64_t reserved;
+	} __attribute__ ((packed)) i2o;
+	struct {
+	    uint32_t array_number;
+	    uint32_t reserved1;
+	    uint64_t reserved2;
+	} __attribute__ ((packed)) raid;
+	struct {
+	    uint8_t device;
+	    uint8_t reserved1;
+	    uint16_t reserved2;
+	    uint32_t reserved3;
+	    uint64_t reserved4;
+	} __attribute__ ((packed)) sata;
+	struct {
+	    uint64_t reserved1;
+	    uint64_t reserved2;
+	} __attribute__ ((packed)) unknown;
+    } device_path;
+    uint8_t reserved;		/* reserved (0) */
+    uint8_t checksum;		/* checksum of bytes 1Eh-40h (two's complement of sum, which makes
+				 * the 8-bit sum of bytes 1Eh-41h equal 00h) */
+} __attribute__ ((packed));
+
+/*
+ * Disk parameters
+ */
+struct driveinfo {
+    int disk;			/* Disk port (0x80 - 0xff) */
+    /* Legacy C/H/S */
+    int cbios;			/* CHS geometry is valid */
+    int legacy_max_head;
+    int legacy_max_cylinder;
+    int legacy_sectors_per_track;
+    int legacy_max_drive;
+    int legacy_type;		/* Drive type (AT/PS2 floppies only) */
+    /* EDD support */
+    int ebios;			/* EBIOS supported on this disk */
+    int edd_version;		/* EBIOS major version */
+    int edd_functionality_subset;
+    struct edd_device_parameters edd_params;	/* EDD parameters */
+};
+
+/**
+ * Format of Phoenix Enhanced Disk Drive Spec translated drive parameter table:
+ * Offset    Size    Description    (Table 00277)
+ * 00h    WORD    number of cylinders
+ * 02h    BYTE    number of heads
+ * 03h    BYTE    A0h (signature indicating translated table)
+ * 04h    BYTE    number of physical sectors per track
+ * 05h    WORD    starting write precompensation cylinder number
+ * 07h    BYTE    reserved
+ * 08h    BYTE    control byte (see #03198 at INT 41"DISK 0")
+ * 09h    WORD    number of physical cylinders
+ * 0Bh    BYTE    number of physical heads
+ * 0Ch    WORD    cylinder number of landing zone
+ * 0Eh    BYTE    number of logical sectors per track
+ * 0Fh    BYTE    checksum
+ * Program: the Phoenix Enhanced Disk Drive Specification is an addition to the
+ *     IBM/MS INT 13 extensions
+ *
+ * Format of Phoenix Enhanced Disk Drive Spec Fixed Disk Parameter Table:
+ * Offset    Size    Description    (Table 00278)
+ * 00h    WORD    physical I/O port base address
+ * 02h    WORD    disk-drive control port address
+ * 04h    BYTE    drive flags (see #00279)
+ * 05h    BYTE    proprietary information
+ *         bits 7-4 reserved (0)
+ *         bits 3-0: Phoenix proprietary (used by BIOS)
+ * 06h    BYTE    IRQ for drive (bits 3-0; bits 7-4 reserved and must be 0)
+ * 07h    BYTE    sector count for multi-sector transfers
+ * 08h    BYTE    DMA control
+ *         bits 7-4: DMA type (0-2) as per ATA-2 specification
+ *         bits 3-0: DMA channel
+ * 09h    BYTE    programmed I/O control
+ *         bits 7-4: reserved (0)
+ *         bits 3-0: PIO type (1-4) as per ATA-2 specification
+ * 0Ah    WORD    drive options (see #00280)
+ * 0Ch 2 BYTEs    reserved (0)
+ * 0Eh    BYTE    extension revision level (high nybble=major, low nybble=minor)
+ *         (currently 10h for v1.0 and 11h for v1.1-3.0)
+ * 0Fh    BYTE    2's complement checksum of bytes 00h-0Eh
+ *         8-bit sum of all bytes 00h-0Fh should equal 00h
+ * SeeAlso: #00277
+ *
+ * Bitfields for Phoenix Enhanced Disk Drive Spec drive flags:
+ * Bit(s)    Description    (Table 00279)
+ * 7    reserved (1)
+ * 6    LBA enabled
+ * 5    reserved (1)
+ * 4    drive is slave
+ * 3-0    reserved (0)
+ * SeeAlso: #00278,#00280
+ *
+ * Bitfields for Phoenix Enhanced Disk Drive Spec drive options:
+ * Bit(s)    Description    (Table 00280)
+ * 0    fast PIO enabled
+ * 1    fast DMA access enabled
+ * 2    block PIO (multi-sector transfers) enabled
+ * 3    CHS translation enabled
+ * 4    LBA translation enabled
+ * 5    removable media
+ * 6    ATAPI device (CD-ROM)
+ * 7    32-bit transfer mode
+ * ---v1.1+ ---
+ * 8    ATAPI device uses DRQ to signal readiness for packet command
+ *     (must be 0 if bit 6 is 0)
+ * 10-9    translation type (must be 00 if bit 3 is 0)
+ *     00 Phoenix bit-shifting translation
+ *     01 LBA-assisted translation
+ *     10 reserved
+ *     11 proprietary translation
+ * ---v3.0---
+ * 11    Ultra DMA access enabled
+ * 15-12    reserved
+ **/
+
+/*
+ * Values for diskette drive type:
+ *     01h    360K
+ *     02h    1.2M
+ *     03h    720K
+ *     04h    1.44M
+ *     05h    ???
+ *            reportedly an obscure drive type shipped on some IBM machines,
+ *            2.88M on some machines (at least AMI 486 BIOS)
+ *     06h    2.88M
+ *     10h    ATAPI Removable Media Device
+ */
+enum diskette_drive_types {
+    DISKETTE_360K = 1,
+    DISKETTE_1_2M = 2,
+    DISKETTE_720K = 3,
+    DISKETTE_1_44M = 4,
+    DISKETTE_2_88M = 6,
+    DISKETTE_ATAPI = 10,
+};
+
+/**
+ * chs_to_lba - compute lba value from cylinder, head and sector number
+ **/
+static inline int chs_to_lba(const struct driveinfo *drive_info,
+			     const unsigned int cylinder,
+			     const unsigned int head, const unsigned int sector)
+{
+    /* Use EDD, if valid */
+    if (drive_info->edd_params.sectors_per_track > 0 &&
+	drive_info->edd_params.heads > 0)
+	return (sector - 1) +
+	    (head * drive_info->edd_params.sectors_per_track) +
+	    (cylinder * (drive_info->edd_params.heads) *
+	     drive_info->edd_params.sectors_per_track);
+    else if (drive_info->cbios)
+	return (sector - 1) + (head * drive_info->legacy_sectors_per_track) +
+	    (cylinder * (drive_info->legacy_max_head + 1) *
+	     drive_info->legacy_sectors_per_track);
+}
+
+void lba_to_chs(const struct driveinfo *drive_info, const int lba,
+		unsigned int *cylinder, unsigned int *head,
+		unsigned int *sector);
+int get_drive_parameters(struct driveinfo *drive_info);
+
+#endif /* _GEOM_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/mbrs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/mbrs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/mbrs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __MBRS_H_
+#define __MBRS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+
+void get_mbr_string(const uint32_t, void *, const int);
+uint32_t get_mbr_id(const struct driveinfo *);
+#endif /* __MBRS_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/msdos.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/msdos.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/msdos.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _MSDOS_H_
+#define _MSDOS_H_
+
+#include <disk/geom.h>
+#include <disk/partition.h>
+
+typedef void (*p_callback) (struct driveinfo *, struct part_entry *, int, int);
+int parse_partition_table(struct driveinfo *, p_callback);
+
+#endif /* _MSDOS_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/partition.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/partition.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/partition.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _PARTITION_H_
+#define _PARTITION_H_
+
+#include <stdint.h>
+
+#define PARTITION_TABLES_OFFSET	0x1be
+
+/* A DOS partition table entry */
+struct part_entry {
+    uint8_t active_flag;	/* 0x80 if "active" */
+    uint8_t start_head;
+    uint8_t start_sect;
+    uint8_t start_cyl;
+    uint8_t ostype;
+    uint8_t end_head;
+    uint8_t end_sect;
+    uint8_t end_cyl;
+    uint32_t start_lba;
+    uint32_t length;
+} __attribute__ ((packed));
+
+void get_label(int label, char **buffer_label);
+#endif /* _PARTITION_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/read.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/read.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/read.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _READ_H_
+#define _READ_H_
+
+#include <disk/geom.h>
+
+int read_mbr(int, void *);
+int dev_read(int, void *, unsigned int, int);
+int read_sectors(struct driveinfo *, void *, const unsigned int, const int);
+#endif /* _READ_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/swsusp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/swsusp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/swsusp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+#ifndef _SWSUSP_H_
+#define _SWSUSP_H_
+
+#include <disk/geom.h>
+#include <disk/common.h>
+#include <disk/partition.h>
+
+#define SWSUSP_SIG	"S1SUSPEND"
+
+struct swsusp_header {
+    char reserved[PAGE_SIZE - 20 - sizeof(unsigned long) - sizeof(int)];
+    unsigned long image;
+    unsigned int flags;		/* Flags to pass to the "boot" kernel */
+    char orig_sig[10];
+    char sig[10];
+} __attribute__ ((packed));
+
+int swsusp_check(struct driveinfo *, struct part_entry *);
+#endif /* _SWSUSP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/util.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include <com32.h>
+
+int int13_retry(const com32sys_t * inreg, com32sys_t * outreg);
+#endif /* _UTIL_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/write.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/write.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/disk/write.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _WRITE_H_
+#define _WRITE_H_
+
+#include <disk/geom.h>
+
+int write_sectors(const struct driveinfo *, const unsigned int,
+		  const void *, const int);
+int write_verify_sector(struct driveinfo *drive_info,
+			const unsigned int, const void *);
+int write_verify_sectors(struct driveinfo *,
+			 const unsigned int, const void *, const int);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_H
+#define DMI_H
+#include <inttypes.h>
+#define MAX_DMI_MEMORY_ITEMS 32
+#define MAX_DMI_CACHE_ITEMS 32
+#define OEM_STRINGS_SIZE 512
+#define HARDWARE_SECURITY_SIZE 16
+
+#define PAGE_SIZE 4096
+
+extern const char *out_of_spec;
+extern const char *bad_index;
+
+#define WORD(x) (uint16_t)(*(const uint16_t *)(x))
+#define DWORD(x) (uint32_t)(*(const uint32_t *)(x))
+#define QWORD(x) (*(const uint64_t *)(x))
+
+enum { DMI_TABLE_PRESENT = 100, ENODMITABLE };
+
+#include "dmi_bios.h"
+#include "dmi_system.h"
+#include "dmi_base_board.h"
+#include "dmi_chassis.h"
+#include "dmi_processor.h"
+#include "dmi_memory.h"
+#include "dmi_battery.h"
+#include "dmi_ipmi.h"
+#include "dmi_cache.h"
+
+extern char display_line;
+#define moreprintf(...) do { display_line++; if (display_line == 24) { char tempbuf[10]; display_line=0; printf("Press enter to continue"); fgets(tempbuf, sizeof tempbuf, stdin);}  printf ( __VA_ARGS__); } while (0);
+
+typedef struct {
+    uint16_t num;
+    uint16_t len;
+    uint16_t ver;
+    uint32_t base;
+    uint16_t major_version;
+    uint16_t minor_version;
+} dmi_table;
+
+struct dmi_header {
+    uint8_t type;
+    uint8_t length;
+    uint16_t handle;
+    uint8_t *data;
+};
+
+typedef struct {
+    s_bios bios;
+    s_system system;
+    s_base_board base_board;
+    s_chassis chassis;
+    s_processor processor;
+    s_battery battery;
+    s_memory_module memory_module[MAX_DMI_MEMORY_ITEMS];
+    s_memory memory[MAX_DMI_MEMORY_ITEMS];
+    s_ipmi ipmi;
+    s_cache cache[MAX_DMI_CACHE_ITEMS];
+    int memory_module_count;
+    int memory_count;
+    int cache_count;
+    dmi_table dmitable;
+    char oem_strings[OEM_STRINGS_SIZE];
+    struct {
+	char power_on_passwd_status[HARDWARE_SECURITY_SIZE];
+	char keyboard_passwd_status[HARDWARE_SECURITY_SIZE];
+	char administrator_passwd_status[HARDWARE_SECURITY_SIZE];
+	char front_panel_reset_status[HARDWARE_SECURITY_SIZE];
+	bool filled;
+    } hardware_security;
+} s_dmi;
+
+void to_dmi_header(struct dmi_header *h, uint8_t * data);
+void dmi_bios_runtime_size(uint32_t code, s_dmi * dmi);
+const char *dmi_string(struct dmi_header *dm, uint8_t s);
+int dmi_checksum(uint8_t * buf, int len);
+void parse_dmitable(s_dmi * dmi);
+void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi);
+int dmi_iterate(s_dmi * dmi);
+
+/* dmi_utils.c */
+void display_bios_characteristics(s_dmi * dmi);
+void display_base_board_features(s_dmi * dmi);
+void display_processor_flags(s_dmi * dmi);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_base_board.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_base_board.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_base_board.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_BASE_BOARD_H
+#define DMI_BASE_BOARD_H
+
+#include "stdbool.h"
+#define BASE_BOARD_MANUFACTURER_SIZE		65
+#define BASE_BOARD_PRODUCT_NAME_SIZE		65
+#define BASE_BOARD_VERSION_SIZE			65
+#define BASE_BOARD_SERIAL_SIZE			65
+#define BASE_BOARD_ASSET_TAG_SIZE		65
+#define BASE_BOARD_LOCATION_SIZE		65
+#define BASE_BOARD_FEATURES_SIZE		32
+#define BASE_BOARD_TYPE_SIZE			32
+
+#define BASE_BOARD_NB_ELEMENTS			5
+
+#define BASE_BOARD_DEVICE_DESCRIPTION		65
+
+extern const char *base_board_features_strings[];
+
+/* this struct have BASE_BOARD_NB_ELEMENTS */
+/* each bool is associated to the relevant message above */
+typedef struct {
+    bool hosting;
+    bool board_needs_daughter;
+    bool removable;
+    bool replaceable;
+    bool hot_swappable;
+} __attribute__ ((__packed__)) s_base_board_features;
+
+typedef struct {
+    char manufacturer[BASE_BOARD_MANUFACTURER_SIZE];
+    char product_name[BASE_BOARD_PRODUCT_NAME_SIZE];
+    char version[BASE_BOARD_VERSION_SIZE];
+    char serial[BASE_BOARD_SERIAL_SIZE];
+    char asset_tag[BASE_BOARD_ASSET_TAG_SIZE];
+    char location[BASE_BOARD_LOCATION_SIZE];
+    char type[BASE_BOARD_TYPE_SIZE];
+    s_base_board_features features;
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+    struct {
+	char type[16];
+	uint8_t status;
+	char description[BASE_BOARD_DEVICE_DESCRIPTION];
+    } devices_information[10];
+} s_base_board;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_battery.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_battery.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_battery.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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 DMI_BATTERY_H
+#define DMI_BATTERY_H
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+#define BATTERY_LOCATION_SIZE		65
+#define BATTERY_MANUFACTURER_SIZE	65
+#define BATTERY_MANUFACTURE_DATE_SIZE	65
+#define BATTERY_SERIAL_SIZE		65
+#define BATTERY_DEVICE_NAME_SIZE	65
+#define BATTERY_CHEMISTRY_SIZE		32
+#define BATTERY_CAPACITY_SIZE		16
+#define BATTERY_DESIGN_VOLTAGE_SIZE	16
+#define BATTERY_SBDS_SIZE		255
+#define BATTERY_MAXIMUM_ERROR_SIZE	32
+#define BATTERY_SBDS_SERIAL_SIZE	32
+#define BATTERY_SBDS_MANUFACTURE_DATE_SIZE	255
+#define BATTERY_SBDS_CHEMISTRY_SIZE	65
+#define BATTERY_OEM_INFO_SIZE		255
+
+typedef struct {
+    char location[BATTERY_LOCATION_SIZE];
+    char manufacturer[BATTERY_MANUFACTURER_SIZE];
+    char manufacture_date[BATTERY_MANUFACTURE_DATE_SIZE];
+    char serial[BATTERY_SERIAL_SIZE];
+    char name[BATTERY_DEVICE_NAME_SIZE];
+    char chemistry[BATTERY_CHEMISTRY_SIZE];
+    char design_capacity[BATTERY_CAPACITY_SIZE];
+    char design_voltage[BATTERY_DESIGN_VOLTAGE_SIZE];
+    char sbds[BATTERY_SBDS_SIZE];
+    char sbds_serial[BATTERY_SBDS_SERIAL_SIZE];
+    char maximum_error[BATTERY_MAXIMUM_ERROR_SIZE];
+    char sbds_manufacture_date[BATTERY_SBDS_MANUFACTURE_DATE_SIZE];
+    char sbds_chemistry[BATTERY_SBDS_CHEMISTRY_SIZE];
+    char oem_info[BATTERY_OEM_INFO_SIZE];
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+} s_battery;
+
+const char *dmi_battery_chemistry(uint8_t code);
+void dmi_battery_capacity(uint16_t code, uint8_t multiplier, char *capacity);
+void dmi_battery_voltage(uint16_t code, char *voltage);
+void dmi_battery_maximum_error(uint8_t code, char *error);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_bios.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_bios.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_bios.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,108 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_BIOS_H
+#define DMI_BIOS_H
+
+#include "stdbool.h"
+#define BIOS_VENDOR_SIZE		65
+#define BIOS_VERSION_SIZE		65
+#define BIOS_RELEASE_SIZE		65
+#define BIOS_RUNTIME_SIZE_UNIT_SIZE	16
+#define BIOS_ROM_UNIT_SIZE		16
+#define BIOS_BIOS_REVISION_SIZE		16
+#define BIOS_FIRMWARE_REVISION_SIZE	16
+
+#define BIOS_CHAR_NB_ELEMENTS		29
+#define BIOS_CHAR_X1_NB_ELEMENTS	8
+#define BIOS_CHAR_X2_NB_ELEMENTS	3
+
+extern const char *bios_charac_strings[];
+
+/* this struct has BIOS_CHAR_NB_ELEMENTS */
+/* each bool is associated with the relevant message above */
+typedef struct {
+    bool bios_characteristics_not_supported;
+    bool isa;
+    bool mca;
+    bool eisa;
+    bool pci;
+    bool pc_card;
+    bool pnp;
+    bool apm;
+    bool bios_upgreadable;
+    bool bios_shadowing;
+    bool vlb;
+    bool escd;
+    bool boot_from_cd;
+    bool selectable_boot;
+    bool bios_rom_socketed;
+    bool boot_from_pcmcia;
+    bool edd;
+    bool japanese_floppy_nec_9800_1_2MB;
+    bool japanese_floppy_toshiba_1_2MB;
+    bool floppy_5_25_360KB;
+    bool floppy_5_25_1_2MB;
+    bool floppy_3_5_720KB;
+    bool floppy_3_5_2_88MB;
+    bool print_screen;
+    bool keyboard_8042_support;
+    bool serial_support;
+    bool printer_support;
+    bool cga_mono_support;
+    bool nec_pc_98;
+} __attribute__ ((__packed__)) s_characteristics;
+
+extern const char *bios_charac_x1_strings[];
+
+/* this struct has BIOS_CHAR_X1_NB_ELEMENTS */
+/* each bool is associated with the relevant message above */
+typedef struct {
+    bool acpi;
+    bool usb_legacy;
+    bool agp;
+    bool i2o_boot;
+    bool ls_120_boot;
+    bool zip_drive_boot;
+    bool ieee_1394_boot;
+    bool smart_battery;
+} __attribute__ ((__packed__)) s_characteristics_x1;
+
+extern const char *bios_charac_x2_strings[];
+
+/* this struct has BIOS_CHAR_X2_NB_ELEMENTS */
+/* each bool is associated with the relevant message above */
+typedef struct {
+    bool bios_boot_specification;
+    bool bios_network_boot_by_keypress;
+    bool target_content_distribution;
+} __attribute__ ((__packed__)) s_characteristics_x2;
+
+typedef struct {
+    char vendor[BIOS_VENDOR_SIZE];
+    char version[BIOS_VERSION_SIZE];
+    char release_date[BIOS_RELEASE_SIZE];
+    uint16_t address;
+    uint16_t runtime_size;
+    char runtime_size_unit[BIOS_RUNTIME_SIZE_UNIT_SIZE];
+    uint16_t rom_size;
+    char rom_size_unit[BIOS_ROM_UNIT_SIZE];
+    s_characteristics characteristics;
+    s_characteristics_x1 characteristics_x1;
+    s_characteristics_x2 characteristics_x2;
+    char bios_revision[BIOS_BIOS_REVISION_SIZE];
+    char firmware_revision[BIOS_FIRMWARE_REVISION_SIZE];
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+} s_bios;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_cache.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_cache.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_cache.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Some part borrowed from DMI Decode:
+ *
+ *   (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   (C) 2002-2007 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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 DMI_CACHE_H
+#define DMI_CACHE_H
+
+#include <stdint.h>
+
+#include "stdbool.h"
+
+#define CACHE_SOCKET_DESIGNATION_SIZE  65
+
+typedef struct {
+    char socket_designation[CACHE_SOCKET_DESIGNATION_SIZE];
+    char configuration[32];
+    char mode[32];
+    char location[8];
+    uint16_t installed_size;
+    uint16_t max_size;
+    char supported_sram_types[32];
+    char installed_sram_types[32];
+    uint16_t speed;
+    char error_correction_type[32];
+    char system_type[16];
+    char associativity[32];
+} __attribute__ ((__packed__)) s_cache;
+
+const char *dmi_cache_mode(uint8_t code);
+const char *dmi_cache_location(uint8_t code);
+uint16_t dmi_cache_size(uint16_t code);
+void dmi_cache_types(uint16_t code, const char *sep, char *array);
+const char *dmi_cache_ec_type(uint8_t code);
+const char *dmi_cache_type(uint8_t code);
+const char *dmi_cache_associativity(uint8_t code);
+#endif /* DMI_CACHE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_chassis.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_chassis.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_chassis.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_CHASSIS_H
+#define DMI_CHASSIS_H
+
+#define CHASSIS_MANUFACTURER_SIZE	65
+#define CHASSIS_TYPE_SIZE		16
+#define CHASSIS_LOCK_SIZE		16
+#define CHASSIS_VERSION_SIZE		65
+#define CHASSIS_SERIAL_SIZE		65
+#define CHASSIS_ASSET_TAG_SIZE		65
+#define CHASSIS_BOOT_UP_STATE_SIZE	32
+#define CHASSIS_POWER_SUPPLY_STATE_SIZE		32
+#define CHASSIS_THERMAL_STATE_SIZE	32
+#define CHASSIS_SECURITY_STATUS_SIZE	32
+#define CHASSIS_OEM_INFORMATION_SIZE	32
+
+typedef struct {
+    char manufacturer[CHASSIS_MANUFACTURER_SIZE];
+    char type[CHASSIS_TYPE_SIZE];
+    char lock[CHASSIS_LOCK_SIZE];
+    char version[CHASSIS_VERSION_SIZE];
+    char serial[CHASSIS_SERIAL_SIZE];
+    char asset_tag[CHASSIS_ASSET_TAG_SIZE];
+    char boot_up_state[CHASSIS_BOOT_UP_STATE_SIZE];
+    char power_supply_state[CHASSIS_POWER_SUPPLY_STATE_SIZE];
+    char thermal_state[CHASSIS_THERMAL_STATE_SIZE];
+    char security_status[CHASSIS_SECURITY_STATUS_SIZE];
+    char oem_information[CHASSIS_OEM_INFORMATION_SIZE];
+    uint16_t height;
+    uint16_t nb_power_cords;
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+} s_chassis;
+
+const char *dmi_chassis_type(uint8_t code);
+const char *dmi_chassis_lock(uint8_t code);
+const char *dmi_chassis_state(uint8_t code);
+const char *dmi_chassis_security_status(uint8_t code);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_ipmi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_ipmi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_ipmi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2009 Erwan Velu - 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 DMI_IPMI_H
+#define DMI_IPMI_H
+
+#define IPMI_INTERFACE_TYPE_SIZE	32
+#define IPMI_MEMORY_MODEL_SIZE		16
+
+typedef struct {
+    char interface_type[IPMI_INTERFACE_TYPE_SIZE];
+    uint8_t major_specification_version;
+    uint8_t minor_specification_version;
+    uint8_t I2C_slave_address;
+    uint16_t nv_address;
+    uint64_t base_address;
+
+    uint8_t irq;
+    bool filled;
+} s_ipmi;
+
+void dmi_ipmi_base_address(uint8_t type, const uint8_t * p, s_ipmi * ipmi);
+const char *dmi_ipmi_interface_type(uint8_t code);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_memory.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_memory.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_memory.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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 DMI_MEMORY_H
+#define DMI_MEMORY_H
+
+#define MEMORY_MANUFACTURER_SIZE	65
+#define MEMORY_ERROR_SIZE		16
+#define MEMORY_TOTAL_WIDTH_SIZE		16
+#define MEMORY_DATA_WIDTH_SIZE		16
+#define MEMORY_SIZE_SIZE		32
+#define MEMORY_FORM_FACTOR_SIZE		32
+#define MEMORY_DEVICE_SET_SIZE		32
+#define MEMORY_DEVICE_LOCATOR_SIZE	65
+#define MEMORY_BANK_LOCATOR_SIZE	65
+#define MEMORY_TYPE_SIZE		32
+#define MEMORY_TYPE_DETAIL_SIZE		16
+#define MEMORY_SPEED_SIZE		16
+#define MEMORY_SERIAL_SIZE		65
+#define MEMORY_ASSET_TAG_SIZE		65
+#define MEMORY_PART_NUMBER_SIZE		65
+#define MEMORY_SOCKET_DESIGNATION_SIZE	65
+
+typedef struct {
+    char manufacturer[MEMORY_MANUFACTURER_SIZE];
+    char error[MEMORY_ERROR_SIZE];
+    char total_width[MEMORY_TOTAL_WIDTH_SIZE];
+    char data_width[MEMORY_DATA_WIDTH_SIZE];
+    char size[MEMORY_SIZE_SIZE];
+    char form_factor[MEMORY_FORM_FACTOR_SIZE];
+    char device_set[MEMORY_DEVICE_SET_SIZE];
+    char device_locator[MEMORY_DEVICE_LOCATOR_SIZE];
+    char bank_locator[MEMORY_BANK_LOCATOR_SIZE];
+    char type[MEMORY_TYPE_SIZE];
+    char type_detail[MEMORY_TYPE_DETAIL_SIZE];
+    char speed[MEMORY_SPEED_SIZE];
+    char serial[MEMORY_SERIAL_SIZE];
+    char asset_tag[MEMORY_ASSET_TAG_SIZE];
+    char part_number[MEMORY_PART_NUMBER_SIZE];
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+} s_memory;
+
+typedef struct {
+    char socket_designation[MEMORY_SOCKET_DESIGNATION_SIZE];
+    char bank_connections[8];
+    char speed[8];
+    char type[48];
+    char installed_size[48];
+    char enabled_size[48];
+    char error_status[8];
+    bool filled;
+} s_memory_module;
+
+void dmi_memory_array_error_handle(uint16_t code, char *array);
+void dmi_memory_device_width(uint16_t code, char *width);
+void dmi_memory_device_size(uint16_t code, char *size);
+const char *dmi_memory_device_form_factor(uint8_t code);
+void dmi_memory_device_set(uint8_t code, char *set);
+const char *dmi_memory_device_type(uint8_t code);
+void dmi_memory_device_type_detail(uint16_t code, char *type_detail, int sizeof_type_detail);
+void dmi_memory_device_speed(uint16_t code, char *speed);
+
+void dmi_memory_module_connections(uint8_t, char *, int);
+void dmi_memory_module_speed(uint8_t, char *);
+void dmi_memory_module_types(uint16_t, const char *, char *, int);
+void dmi_memory_module_size(uint8_t, char *, int);
+void dmi_memory_module_error(uint8_t, const char *, char *);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_processor.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_processor.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_processor.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,115 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_PROCESSOR_H
+#define DMI_PROCESSOR_H
+
+#include "stdbool.h"
+#include "string.h"
+#define PROCESSOR_SOCKET_DESIGNATION_SIZE		65
+#define PROCESSOR_TYPE_SIZE		32
+#define PROCESSOR_FAMILY_SIZE		32
+#define PROCESSOR_MANUFACTURER_SIZE     65
+#define PROCESSOR_VERSION_SIZE		65	
+#define PROCESSOR_VOLTAGE_SIZE		16
+#define PROCESSOR_STATUS_SIZE		16
+#define PROCESSOR_UPGRADE_SIZE		16
+#define PROCESSOR_CACHE_SIZE		16
+#define PROCESSOR_SERIAL_SIZE		65
+#define PROCESSOR_ASSET_TAG_SIZE	65
+#define PROCESSOR_PART_NUMBER_SIZE	65
+#define PROCESSOR_ID_SIZE		32
+
+#define PROCESSOR_FLAGS_ELEMENTS	32
+/* Intel AP-485 revision 28, table 5 */
+extern const char *cpu_flags_strings[PROCESSOR_FLAGS_ELEMENTS];
+
+/* this struct have PROCESSOR_FLAGS_ELEMENTS */
+/* each bool is associated to the relevant message above */
+typedef struct {
+    bool fpu;
+    bool vme;
+    bool de;
+    bool pse;
+    bool tsc;
+    bool msr;
+    bool pae;
+    bool mce;
+    bool cx8;
+    bool apic;
+    bool null_10;
+    bool sep;
+    bool mtrr;
+    bool pge;
+    bool mca;
+    bool cmov;
+    bool pat;
+    bool pse_36;
+    bool psn;
+    bool clfsh;
+    bool null_20;
+    bool ds;
+    bool acpi;
+    bool mmx;
+    bool fxsr;
+    bool sse;
+    bool sse2;
+    bool ss;
+    bool htt;
+    bool tm;
+    bool null_30;
+    bool pbe;
+} __attribute__ ((__packed__)) s_dmi_cpu_flags;
+
+typedef struct {
+    uint8_t type;
+    uint8_t family;
+    uint8_t model;
+    uint8_t stepping;
+    uint8_t minor_stepping;
+} __attribute__ ((__packed__)) s_signature;
+
+typedef struct {
+    char socket_designation[PROCESSOR_SOCKET_DESIGNATION_SIZE];
+    char type[PROCESSOR_TYPE_SIZE];
+    char family[PROCESSOR_FAMILY_SIZE];
+    char manufacturer[PROCESSOR_MANUFACTURER_SIZE];
+    char version[PROCESSOR_VERSION_SIZE];
+    uint16_t voltage_mv;
+    uint16_t external_clock;
+    uint16_t max_speed;
+    uint16_t current_speed;
+    char status[PROCESSOR_STATUS_SIZE];
+    char upgrade[PROCESSOR_UPGRADE_SIZE];
+    char cache1[PROCESSOR_CACHE_SIZE];
+    char cache2[PROCESSOR_CACHE_SIZE];
+    char cache3[PROCESSOR_CACHE_SIZE];
+    char serial[PROCESSOR_SERIAL_SIZE];
+    char asset_tag[PROCESSOR_ASSET_TAG_SIZE];
+    char part_number[PROCESSOR_PART_NUMBER_SIZE];
+    char id[PROCESSOR_ID_SIZE];
+    uint16_t core_count;
+    uint16_t core_enabled;
+    uint16_t thread_count;
+    s_dmi_cpu_flags cpu_flags;
+    s_signature signature;
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+} s_processor;
+
+const char *dmi_processor_type(uint8_t code);
+const char *dmi_processor_family(uint8_t code, char *manufacturer);
+const char *dmi_processor_status(uint8_t code);
+const char *dmi_processor_upgrade(uint8_t code);
+void dmi_processor_cache(uint16_t code, const char *level, uint16_t ver,
+			 char *cache);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_system.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_system.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/dmi/dmi_system.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 DMI_SYSTEM_H
+#define DMI_SYSTEM_H
+
+#define SYSTEM_MANUFACTURER_SIZE	65
+#define SYSTEM_PRODUCT_NAME_SIZE	65
+#define SYSTEM_VERSION_SIZE		65
+#define SYSTEM_SERIAL_SIZE		65
+#define SYSTEM_UUID_SIZE		40
+#define SYSTEM_WAKEUP_TYPE_SIZE		32
+#define SYSTEM_SKU_NUMBER_SIZE		65
+#define SYSTEM_FAMILY_SIZE		65
+
+#define SYSTEM_BOOT_STATUS_SIZE		50
+#define SYSTEM_CONFIGURATION_OPTIONS_SIZE	50
+
+typedef struct {
+    char manufacturer[SYSTEM_MANUFACTURER_SIZE];
+    char product_name[SYSTEM_PRODUCT_NAME_SIZE];
+    char version[SYSTEM_VERSION_SIZE];
+    char serial[SYSTEM_SERIAL_SIZE];
+    char uuid[SYSTEM_UUID_SIZE];
+    char wakeup_type[SYSTEM_WAKEUP_TYPE_SIZE];
+    char sku_number[SYSTEM_SKU_NUMBER_SIZE];
+    char family[SYSTEM_FAMILY_SIZE];
+/* The filled field have to be set to true when the dmitable implement that item */
+    bool filled;
+    char system_boot_status[SYSTEM_BOOT_STATUS_SIZE];
+    char configuration_options[SYSTEM_CONFIGURATION_OPTIONS_SIZE];
+    struct {
+	bool filled;
+	uint8_t status;
+	uint8_t watchdog;
+	char boot_option[17];
+	char boot_option_on_limit[17];
+	char reset_count[8];
+	char reset_limit[8];
+	char timer_interval[8];
+	char timeout[8];
+    } system_reset;
+} s_system;
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/memory.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/memory.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/memory.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from meminfo.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Some parts borrowed from Linux:
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _MEMORY_H_
+#define _MEMORY_H_
+#include <stdint.h>
+
+#define E820MAX 128
+#define E820_RAM        1
+#define E820_RESERVED   2
+#define E820_ACPI       3	/* usable as RAM once ACPI tables have been read */
+#define E820_NVS        4
+
+#define RES_START       0xa0000
+#define RES_END         0x100000
+
+struct e820entry {
+    uint64_t addr;		/* start of memory segment */
+    uint64_t size;		/* size of memory segment */
+    uint64_t type;		/* type of memory segment */
+} __attribute__ ((packed));
+
+const char *const e820_types[5];
+
+void get_type(int, char *, int);
+void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found);
+int detect_memory_e801(int *, int *);
+int detect_memory_88(int *);
+
+/* The following stuff could be merge once the addr_t will be set to 64bits.
+ * syslinux_scan_memory can be used for that purpose */
+unsigned long memsize_e820(struct e820entry *e820, int e820_nr);
+int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios,
+		      short old_nr);
+unsigned long detect_memsize(void);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/vpd/vpd.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/vpd/vpd.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/vpd/vpd.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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 VPD_H
+#define VPD_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+enum { VPD_TABLE_PRESENT = 100, ENOVPDTABLE };
+
+typedef struct {
+    char bios_build_id[10];
+    char box_serial_number[8];
+    char motherboard_serial_number[12];
+    char machine_type_model[8];
+    char bios_release_date[9];
+    char default_flash_filename[13];
+    char bios_version[255];
+    char base_address[16];
+    bool filled;
+} s_vpd;
+
+int vpd_decode(s_vpd * vpd);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gplinclude/zzjson/zzjson.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gplinclude/zzjson/zzjson.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gplinclude/zzjson/zzjson.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+/* ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+#ifndef ZZJSON_H
+#define ZZJSON_H
+
+#include <stdlib.h>
+
+/* Version: */
+
+#define ZZJSON_VERSION_MAJOR    1
+#define ZZJSON_VERSION_MINOR    1
+#define ZZJSON_VERSION_MICRO    0
+#define ZZJSON_VERSION_INT      ( 1<<16 | 1<<8 | 0 )
+#define ZZJSON_IDENT            "zzjson 1.1.0"
+
+/* Defines: */
+
+#define ZZJSON_ALLOW_EXTRA_COMMA        1
+#define ZZJSON_ALLOW_ILLEGAL_ESCAPE     2
+#define ZZJSON_ALLOW_CONTROL_CHARS      4
+#define ZZJSON_ALLOW_GARBAGE_AT_END     8
+#define ZZJSON_ALLOW_COMMENTS           16
+
+#define ZZJSON_VERY_LOOSE               (-1)
+#define ZZJSON_VERY_STRICT              0
+
+/* Types: */
+
+/* needed by: pa = parser, pr = printer, f = free, q = query, c = create */
+typedef struct ZZJSON_CONFIG {
+    int strictness;                                        // pa
+    void *ihandle;                                         // pa
+    int (*getchar)(void *ihandle);                         // pa
+    int (*ungetchar)(int c, void *ihandle);                // pa
+    void *(*malloc)(size_t size);                          // pa      c
+    void *(*calloc)(size_t nmemb, size_t size);            // pa      c
+    void (*free)(void *ptr);                               // pa    f c
+    void *(*realloc)(void *ptr, size_t size);              // pa
+    void *ehandle;                                         // pa pr   c
+    void (*error)(void *ehandle, const char *format, ...); // pa pr   c
+    void *ohandle;                                         //    pr
+    int (*print)(void *ohandle, const char *format, ...);  //    pr
+    int (*putchar)(int c, void *handle);                   //    pr
+} ZZJSON_CONFIG;
+
+typedef enum ZZJSON_TYPE {
+    ZZJSON_NONE = 0,
+    ZZJSON_OBJECT,
+    ZZJSON_ARRAY,
+    ZZJSON_STRING,
+    ZZJSON_NUMBER_NEGINT,
+    ZZJSON_NUMBER_POSINT,
+    ZZJSON_NUMBER_DOUBLE,
+    ZZJSON_NULL,
+    ZZJSON_TRUE,
+    ZZJSON_FALSE
+} ZZJSON_TYPE;
+
+typedef struct ZZJSON {
+    ZZJSON_TYPE type;
+    union {
+        struct {
+            char *label;
+            struct ZZJSON *val;
+        } object;
+        struct {
+            struct ZZJSON *val;
+        } array;
+        struct {
+            char *string;
+        } string;
+        struct {
+            union {
+                unsigned long long ival;
+                double             dval;
+            } val;
+        } number;
+    } value;
+    struct ZZJSON *next;
+} ZZJSON;
+
+/* Functions: */
+
+ZZJSON *zzjson_parse(ZZJSON_CONFIG *config);
+void zzjson_free(ZZJSON_CONFIG *config, ZZJSON *zzjson);
+int zzjson_print(ZZJSON_CONFIG *config, ZZJSON *zzjson);
+
+ZZJSON *zzjson_object_find_label(ZZJSON *zzjson, char *label);
+ZZJSON *zzjson_object_find_labels(ZZJSON *zzjson, ...); // end with , NULL
+unsigned int zzjson_object_count(ZZJSON *zzjson);
+unsigned int zzjson_array_count(ZZJSON *zzjson);
+
+ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config);
+ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d);
+ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i);
+ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s);
+
+/* list of ZZJSON *'s and end with , NULL */
+ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...);
+
+/* list of char*,ZZJSON* pairs, end with , NULL */
+ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...);
+
+ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
+                                                    ZZJSON *val);
+ZZJSON *zzjson_array_append (ZZJSON_CONFIG *config, ZZJSON *array,
+                                                    ZZJSON *val);
+
+ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
+                                        char *label, ZZJSON *val);
+ZZJSON *zzjson_object_append (ZZJSON_CONFIG *config, ZZJSON *object,
+                                        char *label, ZZJSON *val);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+#
+# LGPL/GPL code library
+#
+
+# Include configuration rules
+include $(MAKEDIR)/lib.mk
+
+REQFLAGS += -I$(SRC)/../gplinclude -I$(SRC)/../gplinclude/zzjson
+
+GPLDIRS := $(SRC) $(addprefix $(SRC)/,disk dmi vpd acpi zzjson)
+LIBOBJS := $(subst $(SRC)/,,$(foreach dir,$(GPLDIRS),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c))))
+
+BINDIR   = /usr/bin
+LIBDIR   = /usr/lib
+DATADIR  = /usr/share
+AUXDIR   = $(DATADIR)/syslinux
+INCDIR   = /usr/include
+COM32DIR = $(AUXDIR)/com32
+
+all: makeoutputdirs libgpl.c32
+
+makeoutputdirs:
+	@mkdir -p $(foreach b, \
+		$(addprefix $(OBJ),$(sort $(dir $(LIBOBJS)))),$(b))
+
+libgpl.elf : $(LIBOBJS)
+	$(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
+
+tidy dist clean:
+	find . \( -name \*.o -o -name .\*.d -o -name \*.tmp \) -print0 | \
+		xargs -0r rm -f
+
+spotless: clean
+	rm -f *.c32
+	rm -f *~ \#* */*~ */\#*
+
+# Mixing in the GPL include files is suboptimal, but I'm not sure
+# there is a better way to do it.
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+	install -m 644 libgpl.c32 $(INSTALLROOT)$(COM32DIR)
+	mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
+	cp -r $(SRC)/../gplinclude $(INSTALLROOT)$(COM32DIR)/include/
+
+-include .*.d */.*.d */*/.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,259 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include "acpi/acpi.h"
+
+/* M1PS flags have to be interpreted as strings */
+char *flags_to_string(char *buffer, uint16_t flags)
+{
+    strcpy(buffer, "default");
+    if ((flags & POLARITY_ACTIVE_HIGH) == POLARITY_ACTIVE_HIGH)
+	strcpy(buffer, "high");
+    else if ((flags & POLARITY_ACTIVE_LOW) == POLARITY_ACTIVE_LOW)
+	strcpy(buffer, "low");
+    if ((flags & TRIGGER_EDGE) == TRIGGER_EDGE)
+	strncat(buffer, " edge", 5);
+    else if ((flags & TRIGGER_LEVEL) == TRIGGER_LEVEL)
+	strncat(buffer, " level", 6);
+    else
+	strncat(buffer, " default", 8);
+
+    return buffer;
+}
+
+void dbg_printf(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+}
+
+void init_acpi(s_acpi * acpi)
+{
+    memset(acpi, 0, sizeof(s_acpi));
+}
+
+int parse_acpi(s_acpi * acpi)
+{
+    int ret_val;
+    init_acpi(acpi);
+
+    /* Let's seach for RSDP table */
+    if ((ret_val = search_rsdp(acpi)) != RSDP_TABLE_FOUND)
+	return ret_val;
+
+    /* Let's seach for RSDT table
+     * That's not a big deal not having it, XSDT is far more relevant */
+    parse_rsdt(&acpi->rsdt);
+    if (parse_xsdt(acpi) != XSDT_TABLE_FOUND) {
+	    DEBUG_PRINT(("XSDT Detection failed\n"));
+	    for (int table=0; table <acpi->rsdt.entry_count; table++) {
+		parse_header((uint64_t *)acpi->rsdt.entry[table],acpi);
+	    }
+    }
+    return ACPI_FOUND;
+}
+
+void get_acpi_description_header(uint8_t * q, s_acpi_description_header * adh)
+{
+    cp_str_struct(adh->signature);
+    cp_struct(&adh->length);
+    cp_struct(&adh->revision);
+    cp_struct(&adh->checksum);
+    cp_str_struct(adh->oem_id);
+    cp_str_struct(adh->oem_table_id);
+    cp_struct(&adh->oem_revision);
+    cp_str_struct(adh->creator_id);
+    cp_struct(&adh->creator_revision);
+    DEBUG_PRINT(("acpi_header at %p = %s | %s | %s\n", q, adh->signature,adh->oem_id, adh->creator_id ));
+}
+
+bool parse_header(uint64_t *address, s_acpi *acpi) {
+	    s_acpi_description_header adh;
+	    memset(&adh, 0, sizeof(adh));
+
+	    get_acpi_description_header((uint8_t *)address, &adh);
+
+	    /* Trying to determine the pointed table */
+	    /* Looking for FADT */
+	    if (memcmp(adh.signature, FACP, sizeof(FACP) - 1) == 0) {
+		DEBUG_PRINT(("FACP table found\n"));
+		s_fadt *f = &acpi->fadt;
+		s_facs *fa = &acpi->facs;
+		s_dsdt *d = &acpi->dsdt;
+		/* This structure is valid, let's fill it */
+		f->valid = true;
+		f->address = address;
+		memcpy(&f->header, &adh, sizeof(adh));
+		parse_fadt(f);
+
+		/* FACS wasn't already detected
+		 * FADT points to it, let's try to detect it */
+		if (fa->valid == false) {
+		    fa->address = (uint64_t *)f->x_firmware_ctrl;
+		    parse_facs(fa);
+		    if (fa->valid == false) {
+			/* Let's try again */
+			fa->address = (uint64_t *)f->firmware_ctrl;
+			parse_facs(fa);
+		    }
+		}
+
+		/* DSDT wasn't already detected
+		 * FADT points to it, let's try to detect it */
+		if (d->valid == false) {
+		    s_acpi_description_header new_adh;
+		    get_acpi_description_header((uint8_t *)f->x_dsdt,
+						&new_adh);
+		    if (memcmp(new_adh.signature, DSDT, sizeof(DSDT) - 1) == 0) {
+			DEBUG_PRINT(("DSDT table found via x_dsdt\n"));
+			d->valid = true;
+			d->address = (uint64_t *)f->x_dsdt;
+			memcpy(&d->header, &new_adh, sizeof(new_adh));
+			parse_dsdt(d);
+		    } else {
+			/* Let's try again */
+			get_acpi_description_header((uint8_t *)f->dsdt_address,
+						    &new_adh);
+			if (memcmp(new_adh.signature, DSDT, sizeof(DSDT) - 1) ==
+			    0) {
+			    DEBUG_PRINT(("DSDT table found via dsdt_address\n"));
+			    d->valid = true;
+			    d->address = (uint64_t *)f->dsdt_address;
+			    memcpy(&d->header, &new_adh, sizeof(new_adh));
+			    parse_dsdt(d);
+			}
+		    }
+		}
+	    } /* Looking for MADT */
+	    else if (memcmp(adh.signature, APIC, sizeof(APIC) - 1) == 0) {
+		DEBUG_PRINT(("MADT table found\n"));
+		s_madt *m = &acpi->madt;
+		/* This structure is valid, let's fill it */
+		m->valid = true;
+		m->address =address;
+		memcpy(&m->header, &adh, sizeof(adh));
+		parse_madt(acpi);
+	    } else if (memcmp(adh.signature, DSDT, sizeof(DSDT) - 1) == 0) {
+		DEBUG_PRINT(("DSDT table found\n"));
+		s_dsdt *d = &acpi->dsdt;
+		/* This structure is valid, let's fill it */
+		d->valid = true;
+		d->address = address;
+		memcpy(&d->header, &adh, sizeof(adh));
+		parse_dsdt(d);
+		/* PSDT have to be considered as SSDT. Intel ACPI Spec @ 5.2.11.3 */
+	    } else if ((memcmp(adh.signature, SSDT, sizeof(SSDT) - 1) == 0)
+		       || (memcmp(adh.signature, PSDT, sizeof(PSDT) - 1) == 0)) {
+		
+		DEBUG_PRINT(("SSDT table found with %s \n",adh.signature));
+
+		if ((acpi->ssdt_count >= MAX_SSDT - 1))
+		    return false;
+
+		/* We can have many SSDT, so let's allocate a new one */
+		if ((acpi->ssdt[acpi->ssdt_count] =
+		     malloc(sizeof(s_ssdt))) == NULL)
+		    return false;
+		s_ssdt *s = acpi->ssdt[acpi->ssdt_count];
+
+		/* This structure is valid, let's fill it */
+		s->valid = true;
+		s->address = address;
+		memcpy(&s->header, &adh, sizeof(adh));
+
+		/* Searching how much definition blocks we must copy */
+		uint32_t definition_block_size = adh.length - ACPI_HEADER_SIZE;
+		if ((s->definition_block =
+		     malloc(definition_block_size)) != NULL) {
+		    memcpy(s->definition_block,
+			   (s->address + ACPI_HEADER_SIZE),
+			   definition_block_size);
+		}
+		/* Increment the number of ssdt we have */
+		acpi->ssdt_count++;
+	    } else if (memcmp(adh.signature, SBST, sizeof(SBST) - 1) == 0) {
+		DEBUG_PRINT(("SBST table found\n"));
+		s_sbst *s = &acpi->sbst;
+		/* This structure is valid, let's fill it */
+		s->valid = true;
+		s->address = address;
+		memcpy(&s->header, &adh, sizeof(adh));
+		parse_sbst(s);
+	    } else if (memcmp(adh.signature, ECDT, sizeof(ECDT) - 1) == 0) {
+		DEBUG_PRINT(("ECDT table found\n"));
+		s_ecdt *e = &acpi->ecdt;
+		/* This structure is valid, let's fill it */
+		e->valid = true;
+		e->address = address;
+		memcpy(&e->header, &adh, sizeof(adh));
+		parse_ecdt(e);
+	    }  else if (memcmp(adh.signature, HPET, sizeof(HPET) - 1) == 0) {
+		DEBUG_PRINT(("HPET table found\n"));
+		s_hpet *h = &acpi->hpet;
+		/* This structure is valid, let's fill it */
+		h->valid = true;
+		h->address = address;
+		memcpy(&h->header, &adh, sizeof(adh));
+	    } else if (memcmp(adh.signature, TCPA, sizeof(TCPA) - 1) == 0) {
+		DEBUG_PRINT(("TCPA table found\n"));
+		s_tcpa *t = &acpi->tcpa;
+		/* This structure is valid, let's fill it */
+		t->valid = true;
+		t->address = address;
+		memcpy(&t->header, &adh, sizeof(adh));
+	    } else if (memcmp(adh.signature, MCFG, sizeof(MCFG) - 1) == 0) {
+		DEBUG_PRINT(("MCFG table found\n"));
+		s_mcfg *m = &acpi->mcfg;
+		/* This structure is valid, let's fill it */
+		m->valid = true;
+		m->address = address;
+		memcpy(&m->header, &adh, sizeof(adh));
+	    } else if (memcmp(adh.signature, SLIC, sizeof(SLIC) - 1) == 0) {
+		DEBUG_PRINT(("SLIC table found\n"));
+		s_slic *s = &acpi->slic;
+		/* This structure is valid, let's fill it */
+		s->valid = true;
+		s->address = address;
+		memcpy(&s->header, &adh, sizeof(adh));
+	    } else if (memcmp(adh.signature, BOOT, sizeof(BOOT) - 1) == 0) {
+		DEBUG_PRINT(("BOOT table found\n"));
+		s_boot *b = &acpi->boot;
+		/* This structure is valid, let's fill it */
+		b->valid = true;
+		b->address = address;
+		memcpy(&b->header, &adh, sizeof(adh));
+	    }
+	    
+	    return true;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/dsdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/dsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/dsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+void parse_dsdt(s_dsdt * d)
+{
+    uint8_t *q;
+    q = (uint8_t *)d->address;
+    q += ACPI_HEADER_SIZE;
+
+    /* Searching how much definition blocks we must copy */
+    uint32_t definition_block_size=d->header.length-ACPI_HEADER_SIZE;
+    if ((d->definition_block=malloc(definition_block_size)) != NULL) {
+	memcpy(d->definition_block,q,definition_block_size);
+    }
+
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/ecdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/ecdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/ecdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+void parse_ecdt(s_ecdt * e)
+{
+    uint8_t *q;
+    q = (uint8_t *)e->address;
+    q += ACPI_HEADER_SIZE;
+
+    /* Copying remaining structs */
+    cp_struct(&e->ec_control);
+    cp_struct(&e->ec_data);
+    cp_struct(&e->uid);
+    cp_struct(&e->gpe_bit);
+
+    /* Searching ec_id size we must copy */
+    uint32_t ec_id_size = e->header.length - EC_ID_OFFSET;
+    if ((e->ec_id = malloc(ec_id_size)) != NULL) {
+	memcpy(e->ec_id, (uint64_t *) (e->address + EC_ID_OFFSET), ec_id_size);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/facs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/facs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/facs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+void parse_facs(s_facs * f)
+{
+    uint8_t *q;
+    q = (uint8_t *) f->address;
+
+    DEBUG_PRINT(("Searching FACS at %p\n",q));
+    if (memcmp(q, FACS, sizeof(FACS) - 1) == 0) {
+	f->valid = true;
+	cp_str_struct(f->signature);
+	cp_struct(&f->length);
+	cp_struct(&f->hardware_signature);
+	cp_struct(&f->firmware_waking_vector);
+	cp_struct(&f->global_lock);
+	cp_struct(&f->flags);
+	cp_struct(&f->x_firmware_waking_vector);
+	cp_struct(&f->version);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/fadt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/fadt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/fadt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,99 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+void parse_fadt(s_fadt * f)
+{
+    /* Let's seach for FADT table */
+    uint8_t *q;
+
+    /* Fixing table name */
+    memcpy(f->header.signature,FADT,sizeof(FADT));
+    
+    /* Copying remaining structs */
+    q = (uint8_t *)f->address;
+    q += ACPI_HEADER_SIZE;
+    DEBUG_PRINT(("- Parsing FADT at %p\n",q));
+
+    cp_struct(&f->firmware_ctrl);
+    cp_struct(&f->dsdt_address);
+    cp_struct(&f->reserved);
+    cp_struct(&f->prefered_pm_profile);
+    cp_struct(&f->sci_int);
+    cp_struct(&f->smi_cmd);
+    cp_struct(&f->acpi_enable);
+    cp_struct(&f->acpi_disable);
+    cp_struct(&f->s4bios_req);
+    cp_struct(&f->pstate_cnt);
+    cp_struct(&f->pm1a_evt_blk);
+    cp_struct(&f->pm1b_evt_blk);
+    cp_struct(&f->pm1a_cnt_blk);
+    cp_struct(&f->pm1b_cnt_blk);
+    cp_struct(&f->pm2_cnt_blk);
+    cp_struct(&f->pm_tmr_blk);
+    cp_struct(&f->gpe0_blk);
+    cp_struct(&f->gpe1_blk);
+    cp_struct(&f->pm1_evt_len);
+    cp_struct(&f->pm1_cnt_len);
+    cp_struct(&f->pm2_cnt_len);
+    cp_struct(&f->pm_tmr_len);
+    cp_struct(&f->gpe0_blk_len);
+    cp_struct(&f->gpe1_blk_len);
+    cp_struct(&f->gpe1_base);
+    cp_struct(&f->cst_cnt);
+    cp_struct(&f->p_lvl2_lat);
+    cp_struct(&f->p_lvl3_lat);
+    cp_struct(&f->flush_size);
+    cp_struct(&f->flush_stride);
+    cp_struct(&f->duty_offset);
+    cp_struct(&f->duty_width);
+    cp_struct(&f->day_alarm);
+    cp_struct(&f->mon_alarm);
+    cp_struct(&f->century);
+    cp_struct(&f->iapc_boot_arch);
+    cp_struct(&f->reserved_2);
+    cp_struct(&f->flags);
+    cp_struct(&f->reset_reg);
+    cp_struct(&f->reset_value);
+    cp_struct(f->reserved_3);
+    cp_struct(&f->x_firmware_ctrl);
+    cp_struct(&f->x_dsdt);
+    cp_struct(&f->x_pm1a_evt_blk);
+    cp_struct(&f->x_pm1b_evt_blk);
+    cp_struct(&f->x_pm1a_cnt_blk);
+    cp_struct(&f->x_pm1b_cnt_blk);
+    cp_struct(&f->x_pm2_cnt_blk);
+    cp_struct(&f->x_pm_tmr_blk);
+    cp_struct(&f->x_gpe0_blk);
+    cp_struct(&f->x_gpe1_blk);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/madt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/madt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/madt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,172 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include <stdlib.h>
+#include "acpi/acpi.h"
+
+/* Parse the apic structures */
+static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
+{
+    uint8_t type = *q;
+    q++;
+    uint8_t length = *q;
+    q++;
+    s_processor_local_apic *sla;
+    s_io_apic *sio;
+    s_interrupt_source_override *siso;
+    s_nmi *snmi;
+    s_local_apic_nmi *slan;
+    s_local_apic_address_override *slaao;
+    s_io_sapic *siosapic;
+    s_local_sapic *sls;
+    s_madt *madt = &acpi->madt;
+
+    switch (type) {
+    case PROCESSOR_LOCAL_APIC:
+	sla = &madt->processor_local_apic[madt->processor_local_apic_count];
+	sla->type = type;
+	sla->length = length;
+	cp_struct(&sla->acpi_id);
+	cp_struct(&sla->apic_id);
+	cp_struct(&sla->flags);
+	madt->processor_local_apic_count++;
+	break;
+    case IO_APIC:
+	sio = &madt->io_apic[madt->io_apic_count];
+	sio->type = type;
+	sio->length = length;
+	cp_struct(&sio->io_apic_id);
+	cp_struct(&sio->reserved);
+	cp_struct(&sio->io_apic_address);
+	cp_struct(&sio->global_system_interrupt_base);
+	madt->io_apic_count++;
+	break;
+    case INTERRUPT_SOURCE_OVERRIDE:
+	siso =
+	    &madt->interrupt_source_override[madt->
+					     interrupt_source_override_count];
+	siso->type = type;
+	siso->length = length;
+	siso->bus = *q;
+	q++;
+	siso->source = *q;
+	q++;
+	cp_struct(&siso->global_system_interrupt);
+	cp_struct(&siso->flags);
+	madt->interrupt_source_override_count++;
+	break;
+    case NMI:
+	snmi = &madt->nmi[madt->nmi_count];
+	snmi->type = type;
+	snmi->length = length;
+	cp_struct(&snmi->flags);
+	cp_struct(&snmi->global_system_interrupt);
+	madt->nmi_count++;
+	break;
+    case LOCAL_APIC_NMI_STRUCTURE:
+	slan = &madt->local_apic_nmi[madt->local_apic_nmi_count];
+	slan->type = type;
+	slan->length = length;
+	cp_struct(&slan->acpi_processor_id);
+	cp_struct(&slan->flags);
+	cp_struct(&slan->local_apic_lint);
+	madt->local_apic_nmi_count++;
+	break;
+    case LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE:
+	slaao =
+	    &madt->local_apic_address_override[madt->
+					       local_apic_address_override_count];
+	slaao->type = type;
+	slaao->length = length;
+	cp_struct(&slaao->reserved);
+	cp_struct(&slaao->local_apic_address);
+	madt->local_apic_address_override_count++;
+	break;
+    case IO_SAPIC:
+	siosapic = &madt->io_sapic[madt->io_sapic_count];
+	siosapic->type = type;
+	siosapic->length = length;
+	cp_struct(&siosapic->io_apic_id);
+	cp_struct(&siosapic->reserved);
+	cp_struct(&siosapic->global_system_interrupt_base);
+	cp_struct(&siosapic->io_sapic_address);
+	madt->io_sapic_count++;
+	break;
+    case LOCAL_SAPIC:
+	sls = &madt->local_sapic[madt->local_sapic_count];
+	sls->type = type;
+	sls->length = length;
+	cp_struct(&sls->acpi_processor_id);
+	cp_struct(&sls->local_sapic_id);
+	cp_struct(&sls->local_sapic_eid);
+	cp_struct(sls->reserved);
+	cp_struct(&sls->flags);
+	cp_struct(&sls->acpi_processor_uid_value);
+	if ((sls->acpi_processor_uid_string =
+	     malloc(length - ACPI_PROCESSOR_UID_STRING_OFFSET)) != NULL) {
+	    memcpy(sls->acpi_processor_uid_string, q,
+		   length - ACPI_PROCESSOR_UID_STRING_OFFSET);
+	    q += length - ACPI_PROCESSOR_UID_STRING_OFFSET;
+	}
+	madt->local_sapic_count++;
+	break;
+    default:
+	printf("Unkown APIC structure type %u, size=%u \n", type, length);
+	q += length - 2;
+	break;
+    }
+    return q;
+}
+
+void parse_madt(s_acpi * acpi)
+{
+    /* Let's seach for FADT table */
+    uint8_t *q, *max_address;
+    s_madt *m = &acpi->madt;
+
+    /* Fixing table name */
+    memcpy(m->header.signature, APIC, sizeof(APIC));
+
+    /* Copying remaining structs */
+    q = (uint8_t *)m->address;
+    q += ACPI_HEADER_SIZE;
+    
+    max_address = (uint8_t *)m->address;
+    max_address += m->header.length;
+
+    cp_struct(&m->local_apic_address);
+    cp_struct(&m->flags);
+
+    while (q <  max_address) {
+	q = add_apic_structure(acpi, q);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+int search_rsdp(s_acpi * acpi)
+{
+    /* Let's seach for RSDT table */
+    uint8_t *q;
+
+    /* Let's start for the base address */
+    for (q = (uint8_t *)RSDP_MIN_ADDRESS; q < (uint8_t *)RSDP_MAX_ADDRESS; q+=16 ) {
+	/* Searching for RSDP with "RSD PTR" signature */
+	if (memcmp(q, RSDP, sizeof(RSDP)-1) == 0) {
+	    s_rsdp *r = &acpi->rsdp;
+	    r->valid = true;
+	    r->address = q;
+	    cp_str_struct(r->signature);
+	    cp_struct(&r->checksum);
+	    cp_str_struct(r->oem_id);
+	    cp_struct(&r->revision);
+	    cp_struct(&r->rsdt_address);
+	    cp_struct(&r->length);
+	    cp_struct(&r->xsdt_address);
+	    cp_struct(&r->extended_checksum);
+	    q += 3;		/* reserved field */
+	    acpi->rsdt.address = r->rsdt_address;
+	    acpi->xsdt.address = r->xsdt_address;
+	    DEBUG_PRINT(("RSDT should be at %p\n",r->rsdt_address));
+	    DEBUG_PRINT(("XSDT should be at %p\n",r->xsdt_address));
+	    return RSDP_TABLE_FOUND;
+	}
+    }
+    return -RSDP_TABLE_FOUND;
+}
+
+void print_rsdp(s_acpi * acpi)
+{
+    s_rsdp *r = &acpi->rsdp;
+
+    if (!r->valid)
+	return;
+    printf("RSDP Table @ 0x%p\n", r->address);
+    printf(" signature         : %s\n", r->signature);
+    printf(" checksum          : %u\n", r->checksum);
+    printf(" oem id            : %s\n", r->oem_id);
+    printf(" revision          : %u\n", r->revision);
+    printf(" RDST address      : %p\n", r->rsdt_address);
+    printf(" length            : %u\n", r->length);
+    printf(" XSDT address      : %p\n", r->xsdt_address);
+    printf(" extended checksum : %u\n", r->extended_checksum);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/rsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+int parse_rsdt(s_rsdt *r)
+{
+    /* Let's seach for RSDT table */
+    uint8_t *q;
+
+    /* Let's start for the base address */
+    q = r->address;
+
+    DEBUG_PRINT(("Searching for RSDT at %p\n",q));
+    /* Searching for MADT with APIC signature */
+    if (memcmp(q, RSDT, sizeof(RSDT)-1) == 0) {
+//        DEBUG_PRINT(("RSDT : %c %c %c %c\n",q[0], q[1], q[2], q[3]));
+	r->valid = true;
+	DEBUG_PRINT(("Before \n"));
+	get_acpi_description_header(q, &r->header);
+	DEBUG_PRINT(("RSDT table at %p found with %d bytes long with %d items\n",r->address, r->header.length,(r->header.length-ACPI_HEADER_SIZE)/4));
+
+	uint32_t *start = (uint32_t *)r->address;
+	start += (ACPI_HEADER_SIZE / 4);
+	uint32_t *max = (uint32_t *)r->address;
+	max += (r->header.length / 4);
+	DEBUG_PRINT(("Searching starting at %p till %p\n",start,max));
+	uint32_t *p;
+	for (p = start ; p < max; p++) {
+            /* Let's grab the pointed table header */
+            char address[16] = { 0 };
+            sprintf(address, "%x", *p);
+            uint32_t *pointed_address = (uint32_t *)strtoul(address, NULL, 16);
+	    r->entry[r->entry_count] = (uint8_t *)pointed_address;
+	    DEBUG_PRINT(("%d : %p\n",r->entry_count, r->entry[r->entry_count]));
+	    r->entry_count++;
+	}
+	return RSDT_TABLE_FOUND;
+    }
+
+    return -RSDT_TABLE_FOUND;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/sbst.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/sbst.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/sbst.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+void parse_sbst(s_sbst * s)
+{
+    uint8_t *q;
+    q = (uint8_t *)s->address;
+    q += ACPI_HEADER_SIZE;
+
+    /* Copying remaining structs */
+    cp_struct(&s->warning_energy_level);
+    cp_struct(&s->low_energy_level);
+    cp_struct(&s->critical_energy_level);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/xsdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/xsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/xsdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+#include "acpi/acpi.h"
+
+int parse_xsdt(s_acpi * acpi)
+{
+    /* Let's seach for XSDT table */
+    uint8_t *q;
+
+    /* Let's start for the base address */
+    q = acpi->xsdt.address;
+
+    /* If address is null return an error */
+    if (q == 0 ) {
+	DEBUG_PRINT(("XSDT is null, exiting\n"));
+    	return -XSDT_TABLE_FOUND;
+    }
+
+    DEBUG_PRINT(("Searching XSDT at %p",q));
+    /* Searching for MADT with APIC signature */
+    if (memcmp(q, XSDT, sizeof(XSDT) - 1) == 0) {
+	s_xsdt *x = &acpi->xsdt;
+	x->valid = true;
+	get_acpi_description_header(q, &x->header);
+	DEBUG_PRINT(("XSDT table found at %p : length=%d\n",x->address,x->header.length));
+	DEBUG_PRINT(("Expected Tables = %d\n",(x->header.length-ACPI_HEADER_SIZE)/8));
+
+	/* We now have a set of pointers to some tables */
+	uint64_t *p = NULL;
+	for (p = ((uint64_t *)(x->address + ACPI_HEADER_SIZE));
+	     p < ((uint64_t *)(x->address + x->header.length)); p++) {
+	    DEBUG_PRINT((" Looking for HEADER at %p = %x\n",p,*p));
+
+	    /* Let's grab the pointed table header */
+	    char address[16] = { 0 };
+	    sprintf(address, "%llx", *p);
+	    uint64_t *pointed_address = (uint64_t *)strtoul(address, NULL, 16);
+
+	    x->entry[x->entry_count] = pointed_address;
+	    if (parse_header(pointed_address, acpi)) {
+		x->entry_count++;
+	    }
+	}
+	return XSDT_TABLE_FOUND;
+    }
+    return -XSDT_TABLE_FOUND;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/cpuid.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,615 @@
+/*
+ * Portions of this file taken from the Linux kernel,
+ * Copyright 1991-2009 Linus Torvalds and contributors
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "cpuid.h"
+
+const char *cpu_flags_names[] = {
+    CPU_FLAGS(STRUCT_MEMBER_NAMES)
+};
+
+size_t cpu_flags_offset[] = {
+    CPU_FLAGS(STRUCTURE_MEMBER_OFFSETS)
+};
+
+size_t cpu_flags_count = sizeof cpu_flags_names / sizeof *cpu_flags_names;
+
+struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = { };
+
+bool get_cpu_flag_value_from_name(s_cpu *cpu, const char * flag_name) {
+    size_t i;
+    bool cpu_flag_present=false, *flag_value = &cpu_flag_present;
+
+    for (i = 0; i < cpu_flags_count; i++) {
+	if (strcmp(cpu_flags_names[i],flag_name) == 0) {
+        	flag_value = (bool *)((char *)&cpu->flags + cpu_flags_offset[i]);
+	}
+    }
+    return *flag_value;
+}
+
+
+/*
+* CPUID functions returning a single datum
+*/
+
+/* Probe for the CPUID instruction */
+static int have_cpuid_p(void)
+{
+    return cpu_has_eflag(X86_EFLAGS_ID);
+}
+
+static struct cpu_dev amd_cpu_dev = {
+    .c_vendor = "AMD",
+    .c_ident = {"AuthenticAMD"}
+};
+
+static struct cpu_dev intel_cpu_dev = {
+    .c_vendor = "Intel",
+    .c_ident = {"GenuineIntel"}
+};
+
+static struct cpu_dev cyrix_cpu_dev = {
+    .c_vendor = "Cyrix",
+    .c_ident = {"CyrixInstead"}
+};
+
+static struct cpu_dev umc_cpu_dev = {
+    .c_vendor = "UMC",
+    .c_ident = {"UMC UMC UMC"}
+
+};
+
+static struct cpu_dev nexgen_cpu_dev = {
+    .c_vendor = "Nexgen",
+    .c_ident = {"NexGenDriven"}
+};
+
+static struct cpu_dev centaur_cpu_dev = {
+    .c_vendor = "Centaur",
+    .c_ident = {"CentaurHauls"}
+};
+
+static struct cpu_dev rise_cpu_dev = {
+    .c_vendor = "Rise",
+    .c_ident = {"RiseRiseRise"}
+};
+
+static struct cpu_dev transmeta_cpu_dev = {
+    .c_vendor = "Transmeta",
+    .c_ident = {"GenuineTMx86", "TransmetaCPU"}
+};
+
+static struct cpu_dev nsc_cpu_dev = {
+    .c_vendor = "National Semiconductor",
+    .c_ident = {"Geode by NSC"}
+};
+
+static struct cpu_dev unknown_cpu_dev = {
+    .c_vendor = "Unknown Vendor",
+    .c_ident = {"Unknown CPU"}
+};
+
+/*
+ * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
+ */
+void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+{
+	unsigned char ccr2, ccr3;
+
+	/* we test for DEVID by checking whether CCR3 is writable */
+	ccr3 = getCx86(CX86_CCR3);
+	setCx86(CX86_CCR3, ccr3 ^ 0x80);
+	getCx86(0xc0);   /* dummy to change bus */
+
+	if (getCx86(CX86_CCR3) == ccr3) {       /* no DEVID regs. */
+		ccr2 = getCx86(CX86_CCR2);
+		setCx86(CX86_CCR2, ccr2 ^ 0x04);
+		getCx86(0xc0);  /* dummy */
+
+		if (getCx86(CX86_CCR2) == ccr2) /* old Cx486SLC/DLC */
+			*dir0 = 0xfd;
+		else {                          /* Cx486S A step */
+			setCx86(CX86_CCR2, ccr2);
+			*dir0 = 0xfe;
+		}
+	} else {
+		setCx86(CX86_CCR3, ccr3);  /* restore CCR3 */
+
+		/* read DIR0 and DIR1 CPU registers */
+		*dir0 = getCx86(CX86_DIR0);
+		*dir1 = getCx86(CX86_DIR1);
+	}
+}
+
+void init_cpu_devs(void)
+{
+    cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev;
+    cpu_devs[X86_VENDOR_CYRIX] = &cyrix_cpu_dev;
+    cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev;
+    cpu_devs[X86_VENDOR_UMC] = &umc_cpu_dev;
+    cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev;
+    cpu_devs[X86_VENDOR_CENTAUR] = &centaur_cpu_dev;
+    cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev;
+    cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev;
+    cpu_devs[X86_VENDOR_NSC] = &nsc_cpu_dev;
+    cpu_devs[X86_VENDOR_UNKNOWN] = &unknown_cpu_dev;
+}
+
+void get_cpu_vendor(struct cpuinfo_x86 *c)
+{
+    char *v = c->x86_vendor_id;
+    int i;
+    init_cpu_devs();
+    for (i = 0; i < X86_VENDOR_NUM-1; i++) {
+	if (cpu_devs[i]) {
+	    if (!strcmp(v, cpu_devs[i]->c_ident[0]) ||
+		(cpu_devs[i]->c_ident[1] &&
+		 !strcmp(v, cpu_devs[i]->c_ident[1]))) {
+		c->x86_vendor = i;
+		return;
+	    }
+	}
+    }
+
+    c->x86_vendor = X86_VENDOR_UNKNOWN;
+}
+
+int get_model_name(struct cpuinfo_x86 *c)
+{
+    unsigned int *v;
+    char *p, *q;
+
+    if (cpuid_eax(0x80000000) < 0x80000004)
+	return 0;
+
+    v = (unsigned int *)c->x86_model_id;
+    cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
+    cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
+    cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
+    c->x86_model_id[48] = 0;
+
+    /* Intel chips right-justify this string for some dumb reason;
+       undo that brain damage */
+    p = q = &c->x86_model_id[0];
+    while (*p == ' ')
+	p++;
+    if (p != q) {
+	while (*p)
+	    *q++ = *p++;
+	while (q <= &c->x86_model_id[48])
+	    *q++ = '\0';	/* Zero-pad the rest */
+    }
+
+    return 1;
+}
+
+void detect_cache(uint32_t xlvl, struct cpuinfo_x86 *c)
+{
+    uint32_t eax, ebx, ecx, edx, l2size;
+    /* Detecting L1 cache */
+    if (xlvl >= 0x80000005) {
+	cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
+	c->x86_l1_data_cache_size = ecx >> 24;
+	c->x86_l1_instruction_cache_size = edx >> 24;
+    }
+
+    /* Detecting L2 cache */
+    c->x86_l2_cache_size = 0;
+
+    if (xlvl < 0x80000006)	/* Some chips just has a large L1. */
+	return;
+
+    cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
+    l2size = ecx >> 16;
+
+    /* Vendor based fixes */
+    switch (c->x86_vendor) {
+    case X86_VENDOR_INTEL:
+	/*
+	 * Intel PIII Tualatin. This comes in two flavours.
+	 * One has 256kb of cache, the other 512. We have no way
+	 * to determine which, so we use a boottime override
+	 * for the 512kb model, and assume 256 otherwise.
+	 */
+	if ((c->x86 == 6) && (c->x86_model == 11) && (l2size == 0))
+	    l2size = 256;
+	break;
+    case X86_VENDOR_AMD:
+	/* AMD errata T13 (order #21922) */
+	if ((c->x86 == 6)) {
+	    if (c->x86_model == 3 && c->x86_mask == 0)	/* Duron Rev A0 */
+		l2size = 64;
+	    if (c->x86_model == 4 && (c->x86_mask == 0 || c->x86_mask == 1))	/* Tbird rev A1/A2 */
+		l2size = 256;
+	}
+	break;
+    }
+    c->x86_l2_cache_size = l2size;
+}
+
+void detect_cyrix(struct cpuinfo_x86 *c) {
+	unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
+        char *buf = c->x86_model_id;
+	char Cx86_cb[] = "?.5x Core/Bus Clock";
+	const char cyrix_model_mult1[] = "12??43";
+	const char cyrix_model_mult2[] = "12233445";
+        const char *p = NULL;
+
+	do_cyrix_devid(&dir0, &dir1);
+	dir0_msn = dir0 >> 4; /* identifies CPU "family"   */
+	dir0_lsn = dir0 & 0xf;                /* model or clock multiplier */
+	c->x86_model = (dir1 >> 4) + 1;
+        c->x86_mask = dir1 & 0xf;
+	switch (dir0_msn) {
+		unsigned char tmp;
+
+	        case 0: /* Cx486SLC/DLC/SRx/DRx */
+                	 p = Cx486_name[dir0_lsn & 7];
+			 break;
+	
+		case 1: /* Cx486S/DX/DX2/DX4 */
+	                 p = (dir0_lsn & 8) ? Cx486D_name[dir0_lsn & 5] : Cx486S_name[dir0_lsn & 3];
+			 break;
+
+	         case 2: /* 5x86 */
+	                 Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];
+			 p = Cx86_cb+2;
+			 break;
+
+		case 3: /* 6x86/6x86L */
+			   Cx86_cb[1] = ' ';
+			   Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];
+			   if (dir1 > 0x21) { /* 686L */
+				   Cx86_cb[0] = 'L';
+				   p = Cx86_cb;
+				   (c->x86_model)++;
+			   } else             /* 686 */
+				   p = Cx86_cb+1;
+			   
+			   c->coma_bug = 1;
+			   break;
+		case 4:
+	                   c->x86_l1_data_cache_size = 16; /* Yep 16K integrated cache thats it */
+			   if (c->cpuid_level != 2) { /* Media GX */
+				   Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
+				   p = Cx86_cb+2;
+			   }
+			   break;
+		
+		case 5: /* 6x86MX/M II */
+			   if (dir1 > 7) {
+				   dir0_msn++;  /* M II */
+			   } else {
+	                           c->coma_bug = 1;      /* 6x86MX, it has the bug. */
+			   }
+
+			   tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;
+			   Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];
+			   p = Cx86_cb+tmp;
+			   if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))
+				   (c->x86_model)++;
+			   break;
+		
+		case 0xf:  /* Cyrix 486 without DEVID registers */
+			   switch (dir0_lsn) {
+				   case 0xd:  /* either a 486SLC or DLC w/o DEVID */
+					   dir0_msn = 0; 
+					   p = Cx486_name[(c->hard_math) ? 1 : 0];
+					   break;
+				   
+				   case 0xe:  /* a 486S A step */
+					   dir0_msn = 0;
+					   p = Cx486S_name[0];
+					   break;
+			   }
+			   break;
+			   
+		default:
+			   dir0_msn = 7;
+			   break;
+	}
+
+	/* If the processor is unknown, we keep the model name we got
+	 * from the generic call */
+	if (dir0_msn < 7) {	
+		strcpy(buf, Cx86_model[dir0_msn & 7]);
+		if (p) strcat(buf, p);
+	}
+}
+
+void generic_identify(struct cpuinfo_x86 *c)
+{
+    uint32_t tfms, xlvl;
+    uint32_t eax, ebx, ecx, edx;
+
+    /* Get vendor name */
+    cpuid(0x00000000,
+	  (uint32_t *) & c->cpuid_level,
+	  (uint32_t *) & c->x86_vendor_id[0],
+	  (uint32_t *) & c->x86_vendor_id[8],
+	  (uint32_t *) & c->x86_vendor_id[4]);
+
+    get_cpu_vendor(c);
+
+    /* Intel-defined flags: level 0x00000001 */
+    if (c->cpuid_level >= 0x00000001) {
+	uint32_t capability, excap;
+	cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
+	c->x86_capability[0] = capability;
+	c->x86_capability[4] = excap;
+	c->x86 = (tfms >> 8) & 15;
+	c->x86_model = (tfms >> 4) & 15;
+	if (c->x86 == 0xf)
+	    c->x86 += (tfms >> 20) & 0xff;
+	if (c->x86 >= 0x6)
+	    c->x86_model += ((tfms >> 16) & 0xF) << 4;
+	c->x86_mask = tfms & 15;
+	if (cpu_has(c, X86_FEATURE_CLFLSH))
+	    c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8;
+    } else {
+	/* Have CPUID level 0 only - unheard of */
+	c->x86 = 4;
+    }
+
+    /* AMD-defined flags: level 0x80000001 */
+    xlvl = cpuid_eax(0x80000000);
+    if ((xlvl & 0xffff0000) == 0x80000000) {
+	if (xlvl >= 0x80000001) {
+	    c->x86_capability[1] = cpuid_edx(0x80000001);
+	    c->x86_capability[6] = cpuid_ecx(0x80000001);
+	}
+	if (xlvl >= 0x80000004)
+	    get_model_name(c);	/* Default name */
+    }
+
+    /* Specific detection code */
+    switch (c->x86_vendor) {
+	    case X86_VENDOR_CYRIX:
+	    case X86_VENDOR_NSC: detect_cyrix(c); break;
+	    default: break;
+    }
+
+    /* Detecting the number of cores */
+    switch (c->x86_vendor) {
+    case X86_VENDOR_AMD:
+	if (xlvl >= 0x80000008) {
+	    c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+	    if (c->x86_num_cores & (c->x86_num_cores - 1))
+		c->x86_num_cores = 1;
+	}
+	break;
+    case X86_VENDOR_INTEL:
+	if (c->cpuid_level >= 0x00000004) {
+	    cpuid(0x4, &eax, &ebx, &ecx, &edx);
+	    c->x86_num_cores = ((eax & 0xfc000000) >> 26) + 1;
+	}
+	break;
+    default:
+	c->x86_num_cores = 1;
+	break;
+    }
+
+    detect_cache(xlvl, c);
+}
+
+/*
+ * Checksum an MP configuration block.
+ */
+
+static int mpf_checksum(unsigned char *mp, int len)
+{
+    int sum = 0;
+
+    while (len--)
+	sum += *mp++;
+
+    return sum & 0xFF;
+}
+
+static int smp_scan_config(unsigned long base, unsigned long length)
+{
+    unsigned long *bp = (unsigned long *)base;
+    struct intel_mp_floating *mpf;
+
+//        printf("Scan SMP from %p for %ld bytes.\n", bp,length);
+    if (sizeof(*mpf) != 16) {
+	printf("Error: MPF size\n");
+	return 0;
+    }
+
+    while (length > 0) {
+	mpf = (struct intel_mp_floating *)bp;
+	if ((*bp == SMP_MAGIC_IDENT) &&
+	    (mpf->mpf_length == 1) &&
+	    !mpf_checksum((unsigned char *)bp, 16) &&
+	    ((mpf->mpf_specification == 1)
+	     || (mpf->mpf_specification == 4))) {
+	    return 1;
+	}
+	bp += 4;
+	length -= 16;
+    }
+    return 0;
+}
+
+int find_smp_config(void)
+{
+//        unsigned int address;
+
+    /*
+     * FIXME: Linux assumes you have 640K of base ram..
+     * this continues the error...
+     *
+     * 1) Scan the bottom 1K for a signature
+     * 2) Scan the top 1K of base RAM
+     * 3) Scan the 64K of bios
+     */
+    if (smp_scan_config(0x0, 0x400) ||
+	smp_scan_config(639 * 0x400, 0x400) ||
+	smp_scan_config(0xF0000, 0x10000))
+	return 1;
+    /*
+     * If it is an SMP machine we should know now, unless the
+     * configuration is in an EISA/MCA bus machine with an
+     * extended bios data area.
+     *
+     * there is a real-mode segmented pointer pointing to the
+     * 4K EBDA area at 0x40E, calculate and scan it here.
+     *
+     * NOTE! There are Linux loaders that will corrupt the EBDA
+     * area, and as such this kind of SMP config may be less
+     * trustworthy, simply because the SMP table may have been
+     * stomped on during early boot. These loaders are buggy and
+     * should be fixed.
+     *
+     * MP1.4 SPEC states to only scan first 1K of 4K EBDA.
+     */
+
+//        address = get_bios_ebda();
+//        if (address)
+//                smp_scan_config(address, 0x400);
+    return 0;
+}
+
+void set_cpu_flags(struct cpuinfo_x86 *c, s_cpu * cpu)
+{
+    cpu->flags.fpu = cpu_has(c, X86_FEATURE_FPU);
+    cpu->flags.vme = cpu_has(c, X86_FEATURE_VME);
+    cpu->flags.de = cpu_has(c, X86_FEATURE_DE);
+    cpu->flags.pse = cpu_has(c, X86_FEATURE_PSE);
+    cpu->flags.tsc = cpu_has(c, X86_FEATURE_TSC);
+    cpu->flags.msr = cpu_has(c, X86_FEATURE_MSR);
+    cpu->flags.pae = cpu_has(c, X86_FEATURE_PAE);
+    cpu->flags.mce = cpu_has(c, X86_FEATURE_MCE);
+    cpu->flags.cx8 = cpu_has(c, X86_FEATURE_CX8);
+    cpu->flags.apic = cpu_has(c, X86_FEATURE_APIC);
+    cpu->flags.sep = cpu_has(c, X86_FEATURE_SEP);
+    cpu->flags.mtrr = cpu_has(c, X86_FEATURE_MTRR);
+    cpu->flags.pge = cpu_has(c, X86_FEATURE_PGE);
+    cpu->flags.mca = cpu_has(c, X86_FEATURE_MCA);
+    cpu->flags.cmov = cpu_has(c, X86_FEATURE_CMOV);
+    cpu->flags.pat = cpu_has(c, X86_FEATURE_PAT);
+    cpu->flags.pse_36 = cpu_has(c, X86_FEATURE_PSE36);
+    cpu->flags.psn = cpu_has(c, X86_FEATURE_PN);
+    cpu->flags.clflsh = cpu_has(c, X86_FEATURE_CLFLSH);
+    cpu->flags.dts = cpu_has(c, X86_FEATURE_DTES);
+    cpu->flags.acpi = cpu_has(c, X86_FEATURE_ACPI);
+    cpu->flags.pbe = cpu_has(c, X86_FEATURE_PBE);
+    cpu->flags.mmx = cpu_has(c, X86_FEATURE_MMX);
+    cpu->flags.fxsr = cpu_has(c, X86_FEATURE_FXSR);
+    cpu->flags.sse = cpu_has(c, X86_FEATURE_XMM);
+    cpu->flags.sse2 = cpu_has(c, X86_FEATURE_XMM2);
+    cpu->flags.ss = cpu_has(c, X86_FEATURE_SELFSNOOP);
+    cpu->flags.htt = cpu_has(c, X86_FEATURE_HT);
+    cpu->flags.acc = cpu_has(c, X86_FEATURE_ACC);
+    cpu->flags.syscall = cpu_has(c, X86_FEATURE_SYSCALL);
+    cpu->flags.mp = cpu_has(c, X86_FEATURE_MP);
+    cpu->flags.nx = cpu_has(c, X86_FEATURE_NX);
+    cpu->flags.mmxext = cpu_has(c, X86_FEATURE_MMXEXT);
+    cpu->flags.fxsr_opt = cpu_has(c, X86_FEATURE_FXSR_OPT);
+    cpu->flags.gbpages = cpu_has(c, X86_FEATURE_GBPAGES);
+    cpu->flags.rdtscp = cpu_has(c, X86_FEATURE_RDTSCP);
+    cpu->flags.lm = cpu_has(c, X86_FEATURE_LM);
+    cpu->flags.nowext = cpu_has(c, X86_FEATURE_3DNOWEXT);
+    cpu->flags.now = cpu_has(c, X86_FEATURE_3DNOW);
+    cpu->flags.smp = find_smp_config();
+    cpu->flags.pni = cpu_has(c, X86_FEATURE_XMM3);
+    cpu->flags.pclmulqd = cpu_has(c, X86_FEATURE_PCLMULQDQ);
+    cpu->flags.dtes64 = cpu_has(c, X86_FEATURE_DTES64);
+    cpu->flags.vmx = cpu_has(c, X86_FEATURE_VMX);
+    cpu->flags.smx = cpu_has(c, X86_FEATURE_SMX);
+    cpu->flags.est = cpu_has(c, X86_FEATURE_EST);
+    cpu->flags.tm2 = cpu_has(c, X86_FEATURE_TM2);
+    cpu->flags.sse3 = cpu_has(c, X86_FEATURE_SSE3);
+    cpu->flags.cid = cpu_has(c, X86_FEATURE_CID);
+    cpu->flags.fma = cpu_has(c, X86_FEATURE_FMA);
+    cpu->flags.cx16 = cpu_has(c, X86_FEATURE_CX16);
+    cpu->flags.xtpr = cpu_has(c, X86_FEATURE_XTPR);
+    cpu->flags.pdcm = cpu_has(c, X86_FEATURE_PDCM);
+    cpu->flags.dca = cpu_has(c, X86_FEATURE_DCA);
+    cpu->flags.xmm4_1 = cpu_has(c, X86_FEATURE_XMM4_1);
+    cpu->flags.xmm4_2 = cpu_has(c, X86_FEATURE_XMM4_2);
+    cpu->flags.x2apic = cpu_has(c, X86_FEATURE_X2APIC);
+    cpu->flags.movbe = cpu_has(c, X86_FEATURE_MOVBE);
+    cpu->flags.popcnt = cpu_has(c, X86_FEATURE_POPCNT);
+    cpu->flags.aes = cpu_has(c, X86_FEATURE_AES);
+    cpu->flags.xsave = cpu_has(c, X86_FEATURE_XSAVE);
+    cpu->flags.osxsave = cpu_has(c, X86_FEATURE_OSXSAVE);
+    cpu->flags.avx = cpu_has(c, X86_FEATURE_AVX);
+    cpu->flags.hypervisor = cpu_has(c, X86_FEATURE_HYPERVISOR);
+    cpu->flags.ace2 = cpu_has(c, X86_FEATURE_ACE2);
+    cpu->flags.ace2_en = cpu_has(c, X86_FEATURE_ACE2_EN);
+    cpu->flags.phe = cpu_has(c, X86_FEATURE_PHE);
+    cpu->flags.phe_en = cpu_has(c, X86_FEATURE_PHE_EN);
+    cpu->flags.pmm = cpu_has(c, X86_FEATURE_PMM);
+    cpu->flags.pmm_en = cpu_has(c, X86_FEATURE_PMM_EN);
+    cpu->flags.extapic = cpu_has(c, X86_FEATURE_EXTAPIC);
+    cpu->flags.cr8_legacy = cpu_has(c, X86_FEATURE_CR8_LEGACY);
+    cpu->flags.abm = cpu_has(c, X86_FEATURE_ABM);
+    cpu->flags.sse4a = cpu_has(c, X86_FEATURE_SSE4A);
+    cpu->flags.misalignsse = cpu_has(c, X86_FEATURE_MISALIGNSSE);
+    cpu->flags.nowprefetch = cpu_has(c, X86_FEATURE_3DNOWPREFETCH);
+    cpu->flags.osvw = cpu_has(c, X86_FEATURE_OSVW);
+    cpu->flags.ibs = cpu_has(c, X86_FEATURE_IBS);
+    cpu->flags.sse5 = cpu_has(c, X86_FEATURE_SSE5);
+    cpu->flags.skinit = cpu_has(c, X86_FEATURE_SKINIT);
+    cpu->flags.wdt = cpu_has(c, X86_FEATURE_WDT);
+    cpu->flags.ida = cpu_has(c, X86_FEATURE_IDA);
+    cpu->flags.arat = cpu_has(c, X86_FEATURE_ARAT);
+    cpu->flags.tpr_shadow = cpu_has(c, X86_FEATURE_TPR_SHADOW);
+    cpu->flags.vnmi = cpu_has(c, X86_FEATURE_VNMI);
+    cpu->flags.flexpriority = cpu_has(c, X86_FEATURE_FLEXPRIORITY);
+    cpu->flags.ept = cpu_has(c, X86_FEATURE_EPT);
+    cpu->flags.vpid = cpu_has(c, X86_FEATURE_VPID);
+    cpu->flags.svm = cpu_has(c, X86_FEATURE_SVM);
+}
+
+void set_generic_info(struct cpuinfo_x86 *c, s_cpu * cpu)
+{
+    cpu->family = c->x86;
+    cpu->vendor_id = c->x86_vendor;
+    cpu->model_id = c->x86_model;
+    cpu->stepping = c->x86_mask;
+    strlcpy(cpu->vendor, cpu_devs[c->x86_vendor]->c_vendor,
+	    sizeof(cpu->vendor));
+    strlcpy(cpu->model, c->x86_model_id, sizeof(cpu->model));
+    cpu->num_cores = c->x86_num_cores;
+    cpu->l1_data_cache_size = c->x86_l1_data_cache_size;
+    cpu->l1_instruction_cache_size = c->x86_l1_instruction_cache_size;
+    cpu->l2_cache_size = c->x86_l2_cache_size;
+}
+
+void detect_cpu(s_cpu * cpu)
+{
+    struct cpuinfo_x86 c;
+    memset(&c,0,sizeof(c));
+    c.x86_clflush_size = 32;
+    c.x86_vendor = X86_VENDOR_UNKNOWN;
+    c.cpuid_level = -1;		/* CPUID not detected */
+    c.x86_num_cores = 1;
+    memset(&cpu->flags, 0, sizeof(s_cpu_flags));
+
+    if (!have_cpuid_p())
+	return;
+
+    generic_identify(&c);
+    set_generic_info(&c, cpu);
+    set_cpu_flags(&c, cpu);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/ata.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+#include <inttypes.h>
+#include <string.h>
+
+/**
+ *      ata_id_string - Convert IDENTIFY DEVICE page into string
+ *      @id: IDENTIFY DEVICE results we will examine
+ *      @s: string into which data is output
+ *      @ofs: offset into identify device page
+ *      @len: length of string to return. must be an even number.
+ *
+ *      The strings in the IDENTIFY DEVICE page are broken up into
+ *      16-bit chunks.  Run through the string, and output each
+ *      8-bit chunk linearly, regardless of platform.
+ *
+ *      LOCKING:
+ *      caller.
+ */
+void ata_id_string(const uint16_t * id, unsigned char *s,
+		   unsigned int ofs, unsigned int len)
+{
+    unsigned int c;
+
+    while (len > 0) {
+	c = id[ofs] >> 8;
+	*s = c;
+	s++;
+
+	c = id[ofs] & 0xff;
+	*s = c;
+	s++;
+
+	ofs++;
+	len -= 2;
+    }
+}
+
+/**
+ *      ata_id_c_string - Convert IDENTIFY DEVICE page into C string
+ *      @id: IDENTIFY DEVICE results we will examine
+ *      @s: string into which data is output
+ *      @ofs: offset into identify device page
+ *      @len: length of string to return. must be an odd number.
+ *
+ *      This function is identical to ata_id_string except that it
+ *      trims trailing spaces and terminates the resulting string with
+ *      null.  @len must be actual maximum length (even number) + 1.
+ *
+ *      LOCKING:
+ *      caller.
+ */
+void ata_id_c_string(const uint16_t * id, unsigned char *s,
+		     unsigned int ofs, unsigned int len)
+{
+    unsigned char *p;
+
+    ata_id_string(id, s, ofs, len - 1);
+
+    p = s + strnlen((const char *)s, len - 1);
+    while (p > s && p[-1] == ' ')
+	p--;
+    *p = '\0';
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/bootloaders.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/bootloaders.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/bootloaders.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/bootloaders.h>
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * get_bootloader_string - return a string describing the boot code in a
+ *			   bootsector
+ * @d:			driveinfo struct describing the drive
+ * @p:	partition to scan (usually the active one)
+ * @buffer:		pre-allocated buffer
+ * @buffer_size:	@buffer size
+ **/
+int get_bootloader_string(struct driveinfo *d, const struct part_entry *p,
+			  char *buffer, const int buffer_size)
+{
+    char boot_sector[SECTOR * sizeof(char)];
+
+    if (read_sectors(d, &boot_sector, p->start_lba, 1) == -1)
+	return -1;
+    else {
+	if (!strncmp(boot_sector + 3, "SYSLINUX", 8))
+	    strlcpy(buffer, "SYSLINUX", buffer_size - 1);
+	else if (!strncmp(boot_sector + 3, "EXTLINUX", 8))
+	    strlcpy(buffer, "EXTLINUX", buffer_size - 1);
+	else if (!strncmp(boot_sector + 3, "MSWIN4.1", 8))
+	    strlcpy(buffer, "MSWIN4.1", buffer_size - 1);
+	else
+	    return -1;
+	/* Add more... */
+
+	buffer[buffer_size - 1] = '\0';
+	return 0;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/errno_disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/errno_disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/errno_disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,12 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/errno_disk.h>
+
+int errno_disk;
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/error.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/error.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/error.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <disk/errno_disk.h>
+
+/**
+ * get_error - decode a disk error status
+ * @s:	Preallocated buffer
+ *
+ * Fill @buffer_ptr with the last errno_disk
+ **/
+void get_error(const char *s)
+{
+    fprintf(stderr, "%s: error %d\n", s, errno_disk);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/geom.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/geom.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/geom.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,278 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <string.h>
+#include <stdio.h>
+#include <disk/geom.h>
+
+#include <stdio.h>
+
+/**
+ * lba_to_chs - split given lba into cylinders/heads/sectors
+ **/
+void lba_to_chs(const struct driveinfo *drive_info, const int lba,
+		unsigned int *cylinder, unsigned int *head,
+		unsigned int *sector)
+{
+    unsigned int track;
+
+    /* Use EDD, if valid */
+    if (drive_info->edd_params.sectors_per_track > 0 &&
+	drive_info->edd_params.heads > 0) {
+	*cylinder = (lba % drive_info->edd_params.sectors_per_track) + 1;
+	track = lba / drive_info->edd_params.sectors_per_track;
+	*head = track % drive_info->edd_params.heads;
+	*sector = track / drive_info->edd_params.heads;
+    } else if (drive_info->cbios) {
+	*cylinder = (lba % drive_info->legacy_sectors_per_track) + 1;
+	track = lba / drive_info->legacy_sectors_per_track;
+	*head = track % (drive_info->legacy_max_head + 1);
+	*sector = track / (drive_info->legacy_max_head + 1);
+    }
+}
+
+/**
+ * detect_extensions - detect if we can use extensions
+ *
+ * INT 13 - IBM/MS INT 13 Extensions - INSTALLATION CHECK
+ *    AH = 41h
+ *    BX = 55AAh
+ *    DL = drive (80h-FFh)
+ *
+ * Return: CF set on error (extensions not supported)
+ *    AH = 01h (invalid function)
+ *    CF clear if successful
+ *    BX = AA55h if installed
+ *    AH = major version of extensions
+ *        01h = 1.x
+ *        20h = 2.0 / EDD-1.0
+ *        21h = 2.1 / EDD-1.1
+ *        30h = EDD-3.0
+ *    AL = internal use
+ *    CX = API subset support bitmap (see #00271)
+ *    DH = extension version (v2.0+ ??? -- not present in 1.x)
+ *
+ * Note: the Phoenix Enhanced Disk Drive Specification v1.0 uses version 2.0 of
+ *       the INT 13 Extensions API
+ *
+ * Bitfields for IBM/MS INT 13 Extensions API support bitmap:
+ * Bit(s)    Description    (Table 00271)
+ *     0 extended disk access functions (AH=42h-44h,47h,48h) supported
+ *     1 removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h)
+ *       supported
+ *     2 enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
+ *       extended drive parameter table is valid (see #00273,#00278)
+ *     3-15    reserved (0)
+ **/
+static int detect_extensions(struct driveinfo *drive_info)
+{
+    com32sys_t getebios, ebios;
+
+    memset(&getebios, 0, sizeof getebios);
+    memset(&ebios, 0, sizeof ebios);
+
+    getebios.eflags.b[0] = 0x3;	/* CF set */
+    getebios.ebx.w[0] = 0x55aa;
+    getebios.edx.b[0] = drive_info->disk;
+    getebios.eax.b[1] = 0x41;
+
+    __intcall(0x13, &getebios, &ebios);
+
+    if (!(ebios.eflags.l & EFLAGS_CF) && ebios.ebx.w[0] == 0xaa55) {
+	drive_info->ebios = 1;
+	drive_info->edd_version = ebios.eax.b[1];
+	drive_info->edd_functionality_subset = ebios.ecx.w[0];
+	return 0;
+    } else
+	return -1;		/* Drive does not exist? */
+}
+
+/**
+ * get_drive_parameters_with_extensions - retrieve disk parameters via AH=48h
+ *
+ * INT 13 - IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS
+ *     AH = 48h
+ *     DL = drive (80h-FFh)
+ *     DS:SI -> buffer for drive parameters
+ * Return: CF clear if successful
+ *     AH = 00h
+ *     DS:SI buffer filled
+ *     CF set on error
+ *     AH = error code (see #00234)
+ * BUG: several different Compaq BIOSes incorrectly report high-numbered
+ *     drives (such as 90h, B0h, D0h, and F0h) as present, giving them the
+ *     same geometry as drive 80h; as a workaround, scan through disk
+ *     numbers, stopping as soon as the number of valid drives encountered
+ *     equals the value in 0040h:0075h
+ **/
+static int get_drive_parameters_with_extensions(struct driveinfo *drive_info)
+{
+    com32sys_t inreg, outreg;
+    struct edd_device_parameters *dp;
+
+    memset(&inreg, 0, sizeof inreg);
+
+    /*
+     * The caller shall set this value to the maximum Result Buffer
+     * length, in bytes. If the length of this buffer is less than 30
+     * bytes, this function shall not return the pointer to Drive Parameter
+     * Table (DPT) extension. If the buffer length is 30 or greater on
+     * entry, it shall be set to 30 on exit. If the buffer length is
+     * between 26 and 29, it shall be set to 26 on exit.
+     * If the buffer length is less than 26 on entry an error shall be
+     * returned.
+     */
+    dp = lmalloc(sizeof *dp);
+    if (!dp)
+	return -1;
+
+    dp->len = sizeof(struct edd_device_parameters);
+
+    inreg.esi.w[0] = OFFS(dp);
+    inreg.ds = SEG(dp);
+    inreg.edx.b[0] = drive_info->disk;
+    inreg.eax.b[1] = 0x48;
+
+    __intcall(0x13, &inreg, &outreg);
+
+    /* CF set on error */
+    if (outreg.eflags.l & EFLAGS_CF) {
+	lfree(dp);
+	return outreg.eax.b[1];
+    }
+
+    memcpy(&drive_info->edd_params, dp, sizeof drive_info->edd_params);
+    lfree(dp);
+
+    return 0;
+}
+
+/**
+ * get_drive_parameters_without_extensions - retrieve drive parameters via AH=08h
+ *
+ * INT 13 - DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI)
+ *     AH = 08h
+ *     DL = drive (bit 7 set for hard disk)
+ *
+ * Return: CF set on error
+ *     AH = status (07h) (see #00234)
+ *     CF clear if successful
+ *     AH = 00h
+ *     AL = 00h on at least some BIOSes
+ *     BL = drive type (AT/PS2 floppies only) (see #00242)
+ *     CH = low eight bits of maximum cylinder number
+ *     CL = maximum sector number (bits 5-0)
+ *          high two bits of maximum cylinder number (bits 7-6)
+ *     DH = maximum head number
+ *     DL = number of drives
+ *     ES:DI -> drive parameter table (floppies only)
+ *
+ * Notes:
+ *   - may return successful even though specified drive is greater than the
+ *     number of attached drives of that type (floppy/hard); check DL to
+ *     ensure validity
+ *   - for systems predating the IBM AT, this call is only valid for hard
+ *     disks, as it is implemented by the hard disk BIOS rather than the
+ *     ROM BIOS
+ *   - Toshiba laptops with HardRAM return DL=02h when called with DL=80h,
+ *     but fail on DL=81h. The BIOS data at 40h:75h correctly reports 01h.
+ *     may indicate only two drives present even if more are attached; to
+ *     ensure a correct count, one can use AH=15h to scan through possible
+ *     drives
+ *   - for BIOSes which reserve the last cylinder for testing purposes, the
+ *     cylinder count is automatically decremented
+ *     on PS/1s with IBM ROM DOS 4, nonexistent drives return CF clear,
+ *     BX=CX=0000h, and ES:DI = 0000h:0000h
+ *   - the PC-Tools PCFORMAT program requires that AL=00h before it will
+ *     proceed with the formatting
+ *
+ * BUG: several different Compaq BIOSes incorrectly report high-numbered
+ *      drives (such as 90h, B0h, D0h, and F0h) as present, giving them the
+ *      same geometry as drive 80h; as a workaround, scan through disk
+ *      numbers, stopping as soon as the number of valid drives encountered
+ *      equals the value in 0040h:0075h
+ *
+ * SeeAlso: AH=06h"Adaptec",AH=13h"SyQuest",AH=48h,AH=15h,INT 1E
+ * SeeAlso: INT 41"HARD DISK 0"
+ **/
+static int get_drive_parameters_without_extensions(struct driveinfo *drive_info)
+{
+    com32sys_t getparm, parm;
+
+    memset(&getparm, 0, sizeof getparm);
+    memset(&parm, 0, sizeof parm);
+
+    /* Ralf Brown recommends setting ES:DI to 0:0 */
+    getparm.esi.w[0] = 0;
+    getparm.ds = 0;
+    getparm.edx.b[0] = drive_info->disk;
+    getparm.eax.b[1] = 0x08;
+
+    __intcall(0x13, &getparm, &parm);
+
+    /* CF set on error */
+    if (parm.eflags.l & EFLAGS_CF)
+	return parm.eax.b[1];
+
+    /* DL contains the maximum drive number (it starts at 0) */
+    drive_info->legacy_max_drive = parm.edx.b[0];
+
+    // XXX broken
+    /* Drive specified greater than the bumber of attached drives */
+    //if (drive_info->disk > drive_info->drives)
+    //      return -1;
+
+    drive_info->legacy_type = parm.ebx.b[0];
+
+    /* DH contains the maximum head number (it starts at 0) */
+    drive_info->legacy_max_head = parm.edx.b[1];
+
+    /* Maximum sector number (bits 5-0) per track */
+    drive_info->legacy_sectors_per_track = parm.ecx.b[0] & 0x3f;
+
+    /*
+     * Maximum cylinder number:
+     *     CH = low eight bits of maximum cylinder number
+     *     CL = high two bits of maximum cylinder number (bits 7-6)
+     */
+    drive_info->legacy_max_cylinder = parm.ecx.b[1] +
+	((parm.ecx.b[0] & 0xc0) << 2);
+
+    if (drive_info->legacy_sectors_per_track > 0)
+	drive_info->cbios = 1;	/* Valid geometry */
+
+    return 0;
+}
+
+/**
+ * get_drive_parameters - retrieve drive parameters
+ * @drive_info:		driveinfo structure to fill
+ **/
+int get_drive_parameters(struct driveinfo *drive_info)
+{
+    int return_code;
+
+    if (detect_extensions(drive_info))
+	return -1;
+
+    return_code = get_drive_parameters_without_extensions(drive_info);
+
+    /* If geometry isn't valid, no need to try to get more info about the drive */
+    /* Looks like in can confuse some optical drives */
+    if (drive_info->ebios && drive_info->cbios)
+	get_drive_parameters_with_extensions(drive_info);
+
+    return return_code;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/labels.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/labels.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/labels.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,701 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+
+void get_label(int label, char **buffer_label)
+{
+    int buffer_size = (80 * sizeof(char));
+    char *buffer = malloc(buffer_size);
+    *buffer_label = buffer;
+
+    switch (label) {
+    case 0x01:
+	strlcpy(buffer, "DOS 12-bit fat", buffer_size);
+	break;
+    case 0x02:
+	strlcpy(buffer, "XENIX root", buffer_size);
+	break;
+    case 0x03:
+	strlcpy(buffer, "XENIX /usr", buffer_size);
+	break;
+    case 0x04:
+	strlcpy(buffer, "DOS 3.0+ 16-bit FAT (up to 32M)", buffer_size);
+	break;
+    case 0x05:
+	strlcpy(buffer, "DOS 3.3+ Extended Partition", buffer_size);
+	break;
+    case 0x06:
+	strlcpy(buffer, "DOS 3.31+ 16-bit FAT (over 32M)", buffer_size);
+	break;
+    case 0x07:
+	strlcpy(buffer, "NTFS/exFAT/HPFS", buffer_size);
+	//case 0x07: strlcpy(buffer, "Advanced Unix", buffer_size); break;
+	//case 0x07: strlcpy(buffer, "Windows NT NTFS", buffer_size); break;
+	//case 0x07: strlcpy(buffer, "QNX2.x (pre-1988)", buffer_size); break;
+	break;
+    case 0x08:
+	strlcpy(buffer, "AIX", buffer_size);
+	//case 0x08: strlcpy(buffer, "AIX boot partition", buffer_size); break;
+	//case 0x08: strlcpy(buffer, "SplitDrive", buffer_size); break;
+	//case 0x08: strlcpy(buffer, "DELL partition spanning multiple drives", buffer_size); break;
+	//case 0x08: strlcpy(buffer, "Commodore DOS", buffer_size); break;
+	//case 0x08: strlcpy(buffer, "QNX 1.x and 2.x ("qny")", buffer_size); break;
+	break;
+    case 0x09:
+	strlcpy(buffer, "AIX bootable partition", buffer_size);
+	//case 0x09: strlcpy(buffer, "Coherent filesystem", buffer_size); break;
+	//case 0x09: strlcpy(buffer, "QNX 1.x and 2.x ("qnz")", buffer_size); break;
+	break;
+    case 0x0a:
+	strlcpy(buffer, "OS/2 Boot Manager", buffer_size);
+	//case 0x0a: strlcpy(buffer, "Coherent swap partition", buffer_size); break;
+	//case 0x0a: strlcpy(buffer, "OPUS", buffer_size); break;
+	break;
+    case 0x0b:
+	strlcpy(buffer, "WIN95 OSR2 32-bit FAT", buffer_size);
+	break;
+    case 0x0c:
+	strlcpy(buffer, "WIN95 OSR2 32-bit FAT, LBA-mapped", buffer_size);
+	break;
+    case 0x0e:
+	strlcpy(buffer, "WIN95: DOS 16-bit FAT, LBA-mapped", buffer_size);
+	break;
+    case 0x0f:
+	strlcpy(buffer, "WIN95: Extended partition, LBA-mapped", buffer_size);
+	break;
+    case 0x10:
+	strlcpy(buffer, "OPUS", buffer_size);
+	break;
+    case 0x11:
+	strlcpy(buffer, "Hidden DOS 12-bit FAT", buffer_size);
+	break;
+    case 0x12:
+	strlcpy(buffer, "Compaq diagnostic partition", buffer_size);
+	break;
+    case 0x14:
+	strlcpy(buffer, "Hidden DOS 16-bit FAT <32M", buffer_size);
+	break;
+    case 0x16:
+	strlcpy(buffer, "Hidden DOS 16-bit FAT >=32M", buffer_size);
+	break;
+    case 0x17:
+	strlcpy(buffer, "Hidden HPFS/exFAT/NTFS", buffer_size);
+	break;
+    case 0x18:
+	strlcpy(buffer, "AST SmartSleep Partition", buffer_size);
+	break;
+    case 0x19:
+	strlcpy(buffer, "Unused (Claimed for Willowtech Photon COS)",
+		buffer_size);
+	break;
+    case 0x1b:
+	strlcpy(buffer, "Hidden WIN95 OSR2 32-bit FAT", buffer_size);
+	break;
+    case 0x1c:
+	strlcpy(buffer, "Hidden WIN95 OSR2 32-bit FAT, LBA-mapped",
+		buffer_size);
+	break;
+    case 0x1e:
+	strlcpy(buffer, "Hidden WIN95 16-bit FAT, LBA-mapped", buffer_size);
+	break;
+    case 0x20:
+	strlcpy(buffer, "Unused", buffer_size);
+	break;
+    case 0x21:
+	strlcpy(buffer, "Reserved", buffer_size);
+	//case 0x21: strlcpy(buffer, "Unused", buffer_size); break;
+	break;
+    case 0x22:
+	strlcpy(buffer, "Unused", buffer_size);
+	break;
+    case 0x23:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x24:
+	strlcpy(buffer, "NEC DOS 3.x", buffer_size);
+	break;
+    case 0x26:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x27:
+	strlcpy(buffer, "PQService (Acer laptop hidden rescue partition)", buffer_size);
+	//Windows RE hidden partition
+	//MirOS BSD partition
+	//RouterBOOT kernel partition
+	break;
+    case 0x2a:
+	strlcpy(buffer, "AtheOS File System (AFS)", buffer_size);
+	break;
+    case 0x2b:
+	strlcpy(buffer, "SyllableSecure (SylStor)", buffer_size);
+	break;
+    case 0x31:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x32:
+	strlcpy(buffer, "NOS", buffer_size);
+	break;
+    case 0x33:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x34:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x35:
+	strlcpy(buffer, "JFS on OS/2 or eCS", buffer_size);
+	break;
+    case 0x36:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x38:
+	strlcpy(buffer, "THEOS ver 3.2 2gb partition", buffer_size);
+	break;
+    case 0x39:
+	strlcpy(buffer, "Plan 9 partition", buffer_size);
+	//case 0x39: strlcpy(buffer, "THEOS ver 4 spanned partition", buffer_size); break;
+	break;
+    case 0x3a:
+	strlcpy(buffer, "THEOS ver 4 4gb partition", buffer_size);
+	break;
+    case 0x3b:
+	strlcpy(buffer, "THEOS ver 4 extended partition", buffer_size);
+	break;
+    case 0x3c:
+	strlcpy(buffer, "PartitionMagic recovery partition", buffer_size);
+	break;
+    case 0x3d:
+	strlcpy(buffer, "Hidden NetWare", buffer_size);
+	break;
+    case 0x40:
+	strlcpy(buffer, "Venix 80286", buffer_size);
+	break;
+    case 0x41:
+	strlcpy(buffer, "PPC PReP Boot", buffer_size); break;
+	//case 0x41: strlcpy(buffer, "Personal RISC Boot", buffer_size); break;
+	// strlcpy(buffer, "Linux/MINIX (sharing disk with DRDOS)", buffer_size);
+	break;
+    case 0x42:
+	strlcpy(buffer, "SFS (Secure Filesystem)", buffer_size); break;
+	// strlcpy(buffer, "Linux swap (sharing disk with DRDOS)", buffer_size);
+	//case 0x42: strlcpy(buffer, "Windows 2000 marker", buffer_size); break;
+	break;
+    case 0x43:
+	strlcpy(buffer, "Linux native (sharing disk with DRDOS)", buffer_size);
+	break;
+    case 0x44:
+	strlcpy(buffer, "GoBack partition", buffer_size);
+	break;
+    case 0x45:
+	strlcpy(buffer, "Boot-US boot manager", buffer_size);
+	//case 0x45: strlcpy(buffer, "Priam", buffer_size); break;
+	//case 0x45: strlcpy(buffer, "EUMEL/Elan", buffer_size); break;
+	break;
+    case 0x46:
+	strlcpy(buffer, "EUMEL/Elan", buffer_size);
+	break;
+    case 0x47:
+	strlcpy(buffer, "EUMEL/Elan", buffer_size);
+	break;
+    case 0x48:
+	strlcpy(buffer, "EUMEL/Elan", buffer_size);
+	break;
+    case 0x4a:
+	strlcpy(buffer, "AdaOS Aquila (Default)", buffer_size);
+	//case 0x4a: strlcpy(buffer, "ALFS/THIN lightweight filesystem for DOS", buffer_size); break;
+	break;
+    case 0x4c:
+	strlcpy(buffer, "Oberon partition", buffer_size);
+	break;
+    case 0x4d:
+	strlcpy(buffer, "QNX4.x", buffer_size);
+	break;
+    case 0x4e:
+	strlcpy(buffer, "QNX4.x 2nd part", buffer_size);
+	break;
+    case 0x4f:
+	strlcpy(buffer, "QNX4.x 3rd part", buffer_size);
+	//case 0x4f: strlcpy(buffer, "Oberon partition", buffer_size); break;
+	break;
+    case 0x50:
+	strlcpy(buffer, "OnTrack Disk Manager (older versions) RO",
+		buffer_size);
+	//case 0x50: strlcpy(buffer, "Lynx RTOS", buffer_size); break;
+	//case 0x50: strlcpy(buffer, "Native Oberon (alt)", buffer_size); break;
+	break;
+    case 0x51:
+	strlcpy(buffer, "OnTrack Disk Manager RW (DM6 Aux1)", buffer_size);
+	//case 0x51: strlcpy(buffer, "Novell", buffer_size); break;
+	break;
+    case 0x52:
+	strlcpy(buffer, "CP/M", buffer_size);
+	//case 0x52: strlcpy(buffer, "Microport SysV/AT", buffer_size); break;
+	break;
+    case 0x53:
+	strlcpy(buffer, "Disk Manager 6.0 Aux3", buffer_size);
+	break;
+    case 0x54:
+	strlcpy(buffer, "Disk Manager 6.0 Dynamic Drive Overlay", buffer_size);
+	break;
+    case 0x55:
+	strlcpy(buffer, "EZ-Drive", buffer_size);
+	break;
+    case 0x56:
+	strlcpy(buffer, "Golden Bow VFeature Partitioned Volume.", buffer_size);
+	//case 0x56: strlcpy(buffer, "DM converted to EZ-BIOS", buffer_size); break;
+	break;
+    case 0x57:
+	strlcpy(buffer, "DrivePro", buffer_size);
+	//case 0x57: strlcpy(buffer, "VNDI Partition", buffer_size); break;
+	break;
+    case 0x5c:
+	strlcpy(buffer, "Priam EDisk", buffer_size);
+	break;
+    case 0x61:
+	strlcpy(buffer, "SpeedStor", buffer_size);
+	break;
+    case 0x63:
+	strlcpy(buffer,
+		"Unix System V (SCO, ISC Unix, UnixWare, ...), Mach, GNU Hurd",
+		buffer_size);
+	break;
+    case 0x64:
+	strlcpy(buffer, "Novell Netware 286, 2.xx", buffer_size); break;
+	//strlcpy(buffer, "PC-ARMOUR protected partition", buffer_size);
+	break;
+    case 0x65:
+	strlcpy(buffer, "Novell Netware 386, 3.xx or 4.xx", buffer_size);
+	break;
+    case 0x66:
+	strlcpy(buffer, "Novell Netware SMS Partition", buffer_size);
+	break;
+    case 0x67:
+	strlcpy(buffer, "Novell", buffer_size);
+	break;
+    case 0x68:
+	strlcpy(buffer, "Novell", buffer_size);
+	break;
+    case 0x69:
+	strlcpy(buffer, "Novell Netware 5+, Novell Netware NSS Partition",
+		buffer_size);
+	break;
+    case 0x70:
+	strlcpy(buffer, "DiskSecure Multi-Boot", buffer_size);
+	break;
+    case 0x71:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x72:
+	strlcpy(buffer, "V7/x86", buffer_size);
+	break;
+    case 0x73:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x74:
+	//strlcpy(buffer, "Reserved", buffer_size);
+	strlcpy(buffer, "Scramdisk partition", buffer_size); break;
+    case 0x75:
+	strlcpy(buffer, "IBM PC/IX", buffer_size);
+	break;
+    case 0x76:
+	strlcpy(buffer, "Reserved", buffer_size);
+	break;
+    case 0x77:
+	strlcpy(buffer, "M2FS/M2CS partition", buffer_size);
+	break;
+	//case 0x77: strlcpy(buffer, "VNDI Partition", buffer_size); break;
+    case 0x78:
+	strlcpy(buffer, "XOSL FS", buffer_size);
+	break;
+    case 0x7E:
+	strlcpy(buffer, "Unused", buffer_size);
+	break;
+    case 0x80:
+	strlcpy(buffer, "MINIX until 1.4a", buffer_size);
+	break;
+    case 0x81:
+	strlcpy(buffer, "MINIX since 1.4b, early Linux", buffer_size);
+	//case 0x81: strlcpy(buffer, "Mitac disk manager", buffer_size); break;
+	break;
+    case 0x82:
+	strlcpy(buffer, "Linux swap", buffer_size);
+	//case 0x82: strlcpy(buffer, "Prime", buffer_size); break;
+	//case 0x82: strlcpy(buffer, "Solaris x86", buffer_size); break;
+	break;
+    case 0x83:
+	strlcpy(buffer, "Linux native (usually ext2fs)", buffer_size);
+	break;
+    case 0x84:
+	strlcpy(buffer, "OS/2 hidden C: drive", buffer_size);
+	//case 0x84: strlcpy(buffer, "Hibernation partition", buffer_size); break;
+	break;
+    case 0x85:
+	strlcpy(buffer, "Linux extended partition", buffer_size);
+	break;
+    case 0x86:
+	strlcpy(buffer, "NTFS volume set", buffer_size);
+	//case 0x86: strlcpy(buffer, "Old Linux RAID partition superblock", buffer_size); break;
+	break;
+    case 0x87:
+	strlcpy(buffer, "NTFS volume set", buffer_size);
+	break;
+    case 0x88:
+	strlcpy(buffer, "Linux Plaintext", buffer_size);
+	break;
+    case 0x8a:
+	strlcpy(buffer, "Linux Kernel Partition (used by AiR-BOOT)",
+		buffer_size);
+	break;
+    case 0x8b:
+	strlcpy(buffer, "Legacy Fault Tolerant FAT32 volume", buffer_size);
+	break;
+    case 0x8c:
+	strlcpy(buffer,
+		"Legacy Fault Tolerant FAT32 volume using BIOS extd INT 13h",
+		buffer_size);
+	break;
+    case 0x8d:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS FAT12 partitition",
+		buffer_size);
+	break;
+    case 0x8e:
+	strlcpy(buffer, "Linux LVM partition", buffer_size);
+	break;
+    case 0x90:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS FAT16 partitition",
+		buffer_size);
+	break;
+    case 0x91:
+	strlcpy(buffer, "Free FDISK hidden DOS extended partitition",
+		buffer_size);
+	break;
+    case 0x92:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS large FAT16 partitition",
+		buffer_size);
+	break;
+    case 0x93:
+	strlcpy(buffer, "Hidden Linux native partition", buffer_size);
+	//case 0x93: strlcpy(buffer, "Amoeba", buffer_size); break;
+	break;
+    case 0x94:
+	strlcpy(buffer, "Amoeba bad block table", buffer_size);
+	break;
+    case 0x95:
+	strlcpy(buffer, "MIT EXOPC native partitions", buffer_size);
+	break;
+    case 0x96:
+	strlcpy(buffer, "CHRP ISO-9660 filesystem", buffer_size);
+	break;
+    case 0x97:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS FAT32 partitition",
+		buffer_size);
+	break;
+    case 0x98:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS FAT32 partitition (LBA)",
+		buffer_size);
+	break;
+    case 0x99:
+	strlcpy(buffer, "DCE376 logical drive", buffer_size);
+	break;
+    case 0x9a:
+	strlcpy(buffer, "Free FDISK hidden Primary DOS FAT16 partitition (LBA)",
+		buffer_size);
+	break;
+    case 0x9b:
+	strlcpy(buffer, "Free FDISK hidden DOS extended partitition (LBA)",
+		buffer_size);
+	break;
+    case 0x9e:
+	strlcpy(buffer, "ForthOS partition", buffer_size);
+	break;
+    case 0x9f:
+	strlcpy(buffer, "BSD/OS", buffer_size);
+	break;
+    case 0xa0:
+	strlcpy(buffer, "Laptop hibernation partition", buffer_size);
+	break;
+    case 0xa1:
+	strlcpy(buffer, "Laptop hibernation partition", buffer_size);
+	//case 0xa1: strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size); break;
+	break;
+    case 0xa3:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xa4:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xa5:
+	strlcpy(buffer, "BSD/386, 386BSD, NetBSD, FreeBSD", buffer_size);
+	break;
+    case 0xa6:
+	strlcpy(buffer, "OpenBSD", buffer_size);
+	break;
+    case 0xa7:
+	strlcpy(buffer, "NeXTSTEP", buffer_size);
+	break;
+    case 0xa8:
+	strlcpy(buffer, "Mac OS-X", buffer_size);
+	break;
+    case 0xa9:
+	strlcpy(buffer, "NetBSD", buffer_size);
+	break;
+    case 0xaa:
+	strlcpy(buffer, "Olivetti Fat 12 1.44Mb Service Partition",
+		buffer_size);
+	break;
+    case 0xab:
+	strlcpy(buffer, "Mac OS-X Boot partition", buffer_size);
+	//case 0xab: strlcpy(buffer, "GO! partition", buffer_size); break;
+	break;
+    case 0xae:
+	strlcpy(buffer, "ShagOS filesystem", buffer_size);
+	break;
+    case 0xaf:
+	strlcpy(buffer, "ShagOS swap partition", buffer_size);
+	break;
+    case 0xb0:
+	strlcpy(buffer, "BootStar Dummy", buffer_size);
+	break;
+    case 0xb1:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xb2:
+	strlcpy(buffer, "QNX Neutrino Power-Safe filesystem", buffer_size);
+	break;
+    case 0xb3:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xb4:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xb6:
+	strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size);
+	break;
+    case 0xb7:
+	strlcpy(buffer, "BSDI BSD/386 filesystem", buffer_size);
+	break;
+    case 0xb8:
+	strlcpy(buffer, "BSDI BSD/386 swap partition", buffer_size);
+	break;
+    case 0xbb:
+	strlcpy(buffer, "Boot Wizard hidden", buffer_size);
+	break;
+    case 0xbc:
+	strlcpy(buffer, "Acronis backup partition", buffer_size);
+	break;
+    case 0xbe:
+	strlcpy(buffer, "Solaris 8 boot partition", buffer_size);
+	break;
+    case 0xbf:
+	strlcpy(buffer, "Solaris partition", buffer_size);
+	break;
+    case 0xc0:
+	strlcpy(buffer, "CTOS", buffer_size);
+	//case 0xc0: strlcpy(buffer, "REAL/32 secure small partition", buffer_size); break;
+	//case 0xc0: strlcpy(buffer, "NTFT Partition", buffer_size); break;
+	break;
+    case 0xc1:
+	strlcpy(buffer, "DRDOS/secured (FAT-12)", buffer_size);
+	break;
+    case 0xc2:
+	strlcpy(buffer, "Hidden Linux", buffer_size); break;
+	//strlcpy(buffer, "Reserved for DR-DOS 7+", buffer_size);
+	break;
+    case 0xc3:
+	strlcpy(buffer, "Hidden Linux swap", buffer_size);
+	break;
+    case 0xc4:
+	strlcpy(buffer, "DRDOS/secured (FAT-16, < 32M)", buffer_size);
+	break;
+    case 0xc5:
+	strlcpy(buffer, "DRDOS/secured (extended)", buffer_size);
+	break;
+    case 0xc6:
+	strlcpy(buffer, "DRDOS/secured (FAT-16, >= 32M)", buffer_size);
+	//case 0xc6: strlcpy(buffer, "Windows NT corrupted FAT16 volume/stripe set", buffer_size); break;
+	break;
+    case 0xc7:
+	strlcpy(buffer, "Windows NT corrupted NTFS volume/stripe set",
+		buffer_size);
+	//case 0xc7: strlcpy(buffer, "Syrinx boot", buffer_size); break;
+	break;
+    case 0xc8:
+	strlcpy(buffer, "Reserved for DR-DOS 8.0+", buffer_size);
+	break;
+    case 0xc9:
+	strlcpy(buffer, "Reserved for DR-DOS 8.0+", buffer_size);
+	break;
+    case 0xca:
+	strlcpy(buffer, "Reserved for DR-DOS 8.0+", buffer_size);
+	break;
+    case 0xcb:
+	strlcpy(buffer, "reserved for DRDOS/secured (FAT32)", buffer_size);
+	break;
+    case 0xcc:
+	strlcpy(buffer, "reserved for DRDOS/secured (FAT32, LBA)", buffer_size);
+	break;
+    case 0xcd:
+	strlcpy(buffer, "CTOS Memdump?", buffer_size);
+	break;
+    case 0xce:
+	strlcpy(buffer, "reserved for DRDOS/secured (FAT16, LBA)", buffer_size);
+	break;
+    case 0xcf:
+	strlcpy(buffer, "DR-DOS 7.04+ secured EXT DOS (LBA)", buffer_size);
+	break;
+    case 0xd0:
+	strlcpy(buffer, "REAL/32 secure big partition", buffer_size);
+	break;
+    case 0xd1:
+	strlcpy(buffer, "Old Multiuser DOS secured FAT12", buffer_size);
+	break;
+    case 0xd4:
+	strlcpy(buffer, "Old Multiuser DOS secured FAT16 <32M", buffer_size);
+	break;
+    case 0xd5:
+	strlcpy(buffer, "Old Multiuser DOS secured extended partition",
+		buffer_size);
+	break;
+    case 0xd6:
+	strlcpy(buffer, "Old Multiuser DOS secured FAT16 >=32M", buffer_size);
+	break;
+    case 0xd8:
+	strlcpy(buffer, "CP/M-86", buffer_size);
+	break;
+    case 0xda:
+	strlcpy(buffer, "Non-FS Data", buffer_size);
+	break;
+    case 0xdb:
+	strlcpy(buffer,
+		"Digital Research CP/M, Concurrent CP/M, Concurrent DOS",
+		buffer_size);
+	//case 0xdb: strlcpy(buffer, "CTOS (Convergent Technologies OS -Unisys)", buffer_size); break;
+	//case 0xdb: strlcpy(buffer, "KDG Telemetry SCPU boot", buffer_size); break;
+	break;
+    case 0xdd:
+	strlcpy(buffer, "Hidden CTOS Memdump?", buffer_size);
+	break;
+    case 0xde:
+	strlcpy(buffer, "Dell PowerEdge Server utilities (FAT fs)",
+		buffer_size);
+	break;
+    case 0xdf:
+	strlcpy(buffer, "DG/UX virtual disk manager partition", buffer_size);
+	break;
+	//case 0xdf: strlcpy(buffer, "BootIt EMBRM", buffer_size); break;
+    case 0xe0:
+	strlcpy(buffer,
+		"Reserved by STMicroelectronics for a filesystem called ST AVFS.",
+		buffer_size);
+	break;
+    case 0xe1:
+	strlcpy(buffer, "DOS access or SpeedStor 12-bit FAT extended partition",
+		buffer_size);
+	break;
+    case 0xe3:
+	strlcpy(buffer, "DOS R/O or SpeedStor", buffer_size);
+	break;
+    case 0xe4:
+	strlcpy(buffer, "SpeedStor 16-bit FAT extended partition < 1024 cyl.",
+		buffer_size);
+	break;
+    case 0xe5:
+	strlcpy(buffer,
+		"Tandy DOS with logical sectored FAT (According to Powerquest.)",
+		buffer_size);
+	//case 0xe5: strlcpy(buffer, "Reserved", buffer_size); break;
+	break;
+    case 0xe6:
+	strlcpy(buffer, "Storage Dimensions SpeedStor", buffer_size);
+	break;
+    case 0xe8:
+	strlcpy(buffer, "LUKS", buffer_size);
+	break;
+    case 0xeb:
+	strlcpy(buffer, "BeOS", buffer_size);
+	break;
+    case 0xec:
+	strlcpy(buffer, "SkyOS SkyFS", buffer_size);
+	break;
+    case 0xed:
+	strlcpy(buffer, "Reserved for Matthias Paul's Sprytix", buffer_size);
+	break;
+    case 0xee:
+	strlcpy(buffer,
+		"GPT",
+		buffer_size);
+	break;
+    case 0xef:
+	strlcpy(buffer, "EFI file system",
+		buffer_size);
+	break;
+    case 0xf0:
+	strlcpy(buffer, "Linux/PA-RISC boot loader", buffer_size);
+	break;
+    case 0xf1:
+	strlcpy(buffer, "SpeedStor", buffer_size);
+	break;
+    case 0xf2:
+	strlcpy(buffer,
+		"DOS 3.3+ secondary partition (Powerquest writes: Unisys DOS with logical sectored FAT.)",
+		buffer_size);
+	break;
+    case 0xf3:
+	strlcpy(buffer,
+		"Reserved (Powerquest writes: Storage Dimensions SpeedStor.)",
+		buffer_size);
+	break;
+    case 0xf4:
+	strlcpy(buffer, "SpeedStor large partition", buffer_size);
+	//case 0xf4: strlcpy(buffer, "Prologue single-volume partition", buffer_size); break;
+	break;
+    case 0xf5:
+	strlcpy(buffer, "Prologue multi-volume partition", buffer_size);
+	break;
+    case 0xf6:
+	strlcpy(buffer,
+		"Reserved (Powerquest writes: Storage Dimensions SpeedStor. )",
+		buffer_size);
+	break;
+    case 0xf7:
+	strlcpy(buffer, "DDRdrive Solid State File System", buffer_size);
+	break;
+    case 0xf9:
+	strlcpy(buffer, "pCache", buffer_size);
+	break;
+    case 0xfa:
+	strlcpy(buffer, "Bochs", buffer_size);
+	break;
+    case 0xfb:
+	strlcpy(buffer, "VMware File System partition", buffer_size);
+	break;
+    case 0xfc:
+	strlcpy(buffer, "VMware Swap partition", buffer_size);
+	break;
+    case 0xfd:
+	strlcpy(buffer,
+		"Linux raid partition with autodetect using persistent superblock (Powerquest writes: Reserved for FreeDOS. )",
+		buffer_size);
+	break;
+    case 0xfe:
+	strlcpy(buffer, "LANstep", buffer_size); break;
+	//strlcpy(buffer, "SpeedStor > 1024 cyl.", buffer_size);
+	//case 0xfe: strlcpy(buffer, "IBM PS/2 IML (Initial Microcode Load) partition, located at the end of the disk.", buffer_size); break;
+	//case 0xfe: strlcpy(buffer, "Windows NT Disk Administrator hidden partition", buffer_size); break;
+	//case 0xfe: strlcpy(buffer, "Linux Logical Volume Manager partition (old)", buffer_size); break;
+	break;
+    case 0xff:
+	strlcpy(buffer, "Xenix Bad Block Table ", buffer_size);
+	break;
+    default:
+	strlcpy(buffer, "Unknown", buffer_size);
+	break;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/mbrs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/mbrs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/mbrs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * get_mbr_string - return a string describing the boot code
+ * @label:		first four bytes of the MBR
+ * @buffer:		pre-allocated buffer
+ * @buffer_size:	@buffer size
+ **/
+void get_mbr_string(const uint32_t label, char *buffer, const int buffer_size)
+{
+    /* 2 bytes are usually enough to identify the MBR */
+    uint16_t s_label = label >> 16;
+
+    switch (s_label) {
+    case 0x0000:
+    case 0xfabe:
+	strlcpy(buffer, "No bootloader", buffer_size - 1);
+	break;
+    case 0x0ebe:
+	strlcpy(buffer, "ThinkPad", buffer_size - 1);
+	break;
+    case 0x31c0:
+	strlcpy(buffer, "Acer 3", buffer_size - 1);
+	break;
+    case 0x33c0:
+	/* We need more than 2 bytes */
+	if (((label >> 8) & 0xff) == 0x8e)
+	    strlcpy(buffer, "Windows", buffer_size - 1);
+	else if (((label >> 8) & 0xff) == 0x90)
+	    strlcpy(buffer, "DiskCryptor", buffer_size - 1);
+	else if (((label >> 8) & 0xff) == 0xfa)
+	    strlcpy(buffer, "Syslinux", buffer_size - 1);
+	else
+	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+	break;
+    case 0x33ed:
+	strlcpy(buffer, "Syslinux ISOhybrid", buffer_size - 1);
+	break;
+    case 0x33ff:
+	strlcpy(buffer, "HP/Gateway", buffer_size - 1);
+	break;
+    case 0xb800:
+	strlcpy(buffer, "PloP", buffer_size - 1);
+	break;
+    case 0xea05:
+	strlcpy(buffer, "XOSL", buffer_size - 1);
+	break;
+    case 0xea1e:
+	strlcpy(buffer, "Truecrypt Boot Loader", buffer_size - 1);
+	break;
+    case 0xeb04:
+	strlcpy(buffer, "Solaris", buffer_size - 1);
+	break;
+    case 0xeb31:
+	strlcpy(buffer, "Paragon", buffer_size - 1);
+	break;
+    case 0xeb48:
+	strlcpy(buffer, "Grub", buffer_size - 1);
+	break;
+    case 0xeb4c:
+	strlcpy(buffer, "Grub2 (v1.96)", buffer_size - 1);
+	break;
+    case 0xeb63:
+	strlcpy(buffer, "Grub2 (v1.97)", buffer_size - 1);
+	break;
+    case 0xeb5e:
+	/* We need more than 2 bytes */
+	if (((label >> 8) & 0xff) == 0x00)
+	    strlcpy(buffer, "fbinst", buffer_size - 1);
+	else if (((label >> 8) & 0xff) == 0x80)
+	    strlcpy(buffer, "Grub4Dos", buffer_size - 1);
+	else if (((label >> 8) & 0xff) == 0x90)
+	    strlcpy(buffer, "WEE", buffer_size - 1);
+	else
+	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+	break;
+    case 0xfa31:
+	/* We need more than 2 bytes */
+	if (((label >> 8) & 0xff) == 0xc0)
+	    strlcpy(buffer, "Syslinux", buffer_size - 1);
+	else if (((label >> 8) & 0xff) == 0xc9)
+	    strlcpy(buffer, "Master Boot LoaDeR", buffer_size - 1);
+	else
+	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+	break;
+    case 0xfa33:
+	strlcpy(buffer, "MS-DOS 3.30 through Windows 95 (A)", buffer_size - 1);
+	break;
+    case 0xfab8:
+	strlcpy(buffer, "FreeDOS (eXtended FDisk)", buffer_size - 1);
+	break;
+    case 0xfaeb:
+	strlcpy(buffer, "Lilo", buffer_size - 1);
+	break;
+    case 0xfc31:
+	strlcpy(buffer, "Testdisk", buffer_size - 1);
+	break;
+    case 0xfc33:
+	strlcpy(buffer, "GAG", buffer_size - 1);
+	break;
+    case 0xfceb:
+	strlcpy(buffer, "BootIT NG", buffer_size - 1);
+	break;
+    default:
+	strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+	break;
+    }
+
+    buffer[buffer_size - 1] = '\0';
+}
+
+/**
+ * get_mbr_id - return the first four bytes of the MBR
+ * @d:		driveinfo struct describing the drive
+ **/
+uint32_t get_mbr_id(const struct driveinfo *d)
+{
+    char mbr[SECTOR * sizeof(char)];
+
+    if (read_mbr(d->disk, &mbr) == -1)
+	return -1;
+    else {
+	uint32_t mbr_id;
+	/* Reverse the opcodes */
+	mbr_id = (*(uint8_t *) (mbr + 3));
+	mbr_id += (*(uint8_t *) (mbr + 2) << 8);
+	mbr_id += (*(uint8_t *) (mbr + 1) << 16);
+	mbr_id += (*(uint8_t *) mbr) << 24;
+	return mbr_id;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/msdos.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/msdos.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/msdos.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/msdos.h>
+#include <disk/partition.h>
+#include <disk/read.h>
+
+static int is_extended_partition(struct part_entry *ptab)
+{
+    return (ptab->ostype == 0x05 ||
+	    ptab->ostype == 0x0f || ptab->ostype == 0x85);
+}
+
+static int msdos_magic_present(const char *ptab)
+{
+    return (*(uint16_t *) (ptab + 0x1fe) == 0xaa55);
+}
+
+/**
+ * process_extended_partition - execute a callback for each partition contained listed in an ebr
+ * @drive_info:		driveinfo struct describing the drive
+ * @partition_offset:	Absolute start (lba) of the extended partition
+ * @ebr_offset:		Relative start (lba) of the current ebr processed within
+ *			the extended partition
+ * @callback:		Callback to execute
+ * @error:		Buffer for I/O errors
+ * @nb_part_seen:	Number of partitions found on the disk so far
+ **/
+static int process_extended_partition(struct driveinfo *drive_info,
+				      const int partition_offset,
+				      const int ebr_offset,
+				      p_callback callback, int nb_part_seen)
+{
+    int status = 0;
+    /* The ebr is located at the first sector of the extended partition */
+    char *ebr = malloc(SECTOR * sizeof(char));
+
+    if (read_sectors(drive_info, ebr, partition_offset + ebr_offset, 1) == -1)
+	goto abort;
+
+    /* Check msdos magic signature */
+    if (!msdos_magic_present(ebr))
+	goto abort;
+
+    struct part_entry *ptab =
+	(struct part_entry *)(ebr + PARTITION_TABLES_OFFSET);
+
+    for (int i = 0; i < 4; i++) {
+	if (status == -1)
+	    goto abort;
+
+	if (!is_extended_partition(&ptab[i])) {
+	    /*
+	     * This EBR partition table entry points to the
+	     * logical partition associated to that EBR
+	     */
+	    int logical_partition_start = ebr_offset + ptab[i].start_lba;
+
+	    /* Last EBR in the extended partition? */
+	    if (!logical_partition_start)
+		continue;
+
+	    /*
+	     * Check for garbage:
+	     * 3rd and 4th entries in an EBR should be zero
+	     * Some (malformed) partitioning software still add some
+	     * data partitions there.
+	     */
+	    if (ptab[i].start_lba <= 0 || ptab[i].length <= 0)
+		continue;
+
+	    nb_part_seen++;
+	    callback(drive_info,
+		     &ptab[i],
+		     partition_offset + logical_partition_start, nb_part_seen);
+	} else
+	    status = process_extended_partition(drive_info,
+						partition_offset,
+						ptab[i].start_lba,
+						callback, nb_part_seen);
+    }
+
+    free(ebr);
+    return 0;
+
+abort:
+    free(ebr);
+    return -1;
+}
+
+/**
+ * process_mbr - execute a callback for each partition contained in an {m,e}br
+ * @drive_info:	driveinfo struct describing the drive
+ * @ptab:	Pointer to the partition table
+ * @callback:	Callback to execute
+ **/
+static int process_mbr(struct driveinfo *drive_info, struct part_entry *ptab,
+		       p_callback callback)
+{
+    int status = 0;
+
+    for (int i = 0; i < 4; i++) {
+	if (status == -1)
+	    return -1;
+
+	if (ptab[i].start_sect > 0) {
+	    if (is_extended_partition(&ptab[i])) {
+		callback(drive_info, &ptab[i], ptab[i].start_lba, i + 1);
+		status =
+		    process_extended_partition(drive_info, ptab[i].start_lba, 0,
+					       callback, 4);
+	    } else
+		callback(drive_info, &ptab[i], ptab[i].start_lba, i + 1);
+	}
+    }
+
+    return 0;
+}
+
+/**
+ * parse_partition_table - execute a callback for each partition entry
+ * @d:		driveinfo struct describing the drive
+ * @callback:	Callback to execute
+ *
+ * The signature of the callback should be the following:
+ *
+ * void callback(struct driveinfo *drive_info,
+ *		 struct part_entry *ptab,
+ *		 int offset_root,
+ *		 int nb_part_seen)
+ **/
+int parse_partition_table(struct driveinfo *d, p_callback callback)
+{
+    char *mbr = malloc(SECTOR * sizeof(char));
+
+    if (read_mbr(d->disk, mbr) == -1)
+	return -1;
+    else {
+	/* Check msdos magic signature */
+	if (!msdos_magic_present(mbr))
+	    return -1;
+
+	struct part_entry *ptab =
+	    (struct part_entry *)(mbr + PARTITION_TABLES_OFFSET);
+	return process_mbr(d, ptab, callback);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,148 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/errno_disk.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <disk/util.h>
+#include <disk/common.h>
+
+/*
+ * TODO: implement file descriptors to cache metadata (geometry, ...)
+ */
+
+/**
+ * read_mbr - return a pointer to a malloced buffer containing the mbr
+ * @drive:	Drive number
+ * @buf:	Pre-allocated buffer for output
+ *
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int read_mbr(int drive, void *buf)
+{
+    struct driveinfo drive_info;
+    drive_info.disk = drive;
+
+    /* MBR: lba = 0, 1 sector */
+    return read_sectors(&drive_info, buf, 0, 1);
+}
+
+/**
+ * dev_read - read from a drive
+ * @drive:	Drive number
+ * @buf:	Pre-allocated buffer for output
+ * @lba:	Position to start reading from
+ * @sectors:	Number of sectors to read
+ *
+ * High-level routine to read from a hard drive.
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int dev_read(int drive, void *buf, unsigned int lba, int sectors)
+{
+    struct driveinfo drive_info;
+    drive_info.disk = drive;
+
+    return read_sectors(&drive_info, buf, lba, sectors);
+}
+
+/**
+ * read_sectors - read several sectors from disk
+ * @drive_info:		driveinfo struct describing the disk
+ * @data:		Pre-allocated buffer for output
+ * @lba:		Position to read
+ * @sectors:		Number of sectors to read
+ *
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int read_sectors(struct driveinfo *drive_info, void *data,
+		 const unsigned int lba, const int sectors)
+{
+    com32sys_t inreg, outreg;
+    struct ebios_dapa *dapa;
+    void *buf;
+    char *bufp = data;
+    int rv = -1;
+
+    if (get_drive_parameters(drive_info) == -1)
+	return -1;
+
+    buf = lmalloc(sectors * SECTOR);
+    if (!buf)
+	return -1;
+
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto fail;
+
+    memset(&inreg, 0, sizeof inreg);
+
+    if (drive_info->ebios) {
+	dapa->len = sizeof(*dapa);
+	dapa->count = sectors;
+	dapa->off = OFFS(buf);
+	dapa->seg = SEG(buf);
+	dapa->lba = lba;
+
+	inreg.esi.w[0] = OFFS(dapa);
+	inreg.ds = SEG(dapa);
+	inreg.edx.b[0] = drive_info->disk;
+	inreg.eax.b[1] = 0x42;	/* Extended read */
+    } else {
+	unsigned int c, h, s;
+
+	if (!drive_info->cbios) {	// XXX errno
+	    /* We failed to get the geometry */
+	    if (lba)
+		goto fail;	/* Can only read MBR */
+
+	    s = 1;
+	    h = 0;
+	    c = 0;
+	} else
+	    lba_to_chs(drive_info, lba, &s, &h, &c);
+
+	// XXX errno
+	if (s > 63 || h > 256 || c > 1023)
+	    goto fail;
+
+	inreg.eax.w[0] = 0x0201;	/* Read one sector */
+	inreg.ecx.b[1] = c & 0xff;
+	inreg.ecx.b[0] = s + (c >> 6);
+	inreg.edx.b[1] = h;
+	inreg.edx.b[0] = drive_info->disk;
+	inreg.ebx.w[0] = OFFS(buf);
+	inreg.es = SEG(buf);
+    }
+
+    /* Perform the read */
+    if (int13_retry(&inreg, &outreg)) {
+	errno_disk = outreg.eax.b[1];
+	goto fail;		/* Give up */
+    }
+
+    memcpy(bufp, buf, sectors * SECTOR);
+    rv = sectors;
+
+fail:
+    lfree(dapa);
+    lfree(buf);
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/swsusp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/swsusp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/swsusp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/swsusp.h>
+#include <disk/read.h>
+#include <disk/geom.h>
+
+/**
+ * swsusp_check - check if a (swap) partition contains the swsusp signature
+ * @drive_info:	driveinfo struct describing the disk containing the partition
+ * @ptab;	Partition table of the partition
+ **/
+int swsusp_check(struct driveinfo *drive_info, struct part_entry *ptab)
+{
+    struct swsusp_header header_p;
+    int offset;
+    int found;
+
+    /* Read first page of the swap device */
+    offset = ptab->start_lba;
+    if (read_sectors(drive_info, &header_p, offset, PAGE_SIZE / SECTOR) == -1) {
+	return -1;
+    } else {
+	found = !memcmp(SWSUSP_SIG, header_p.sig, 10);
+	return found;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/util.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <disk/geom.h>
+
+#define MAX_NB_RETRIES 6
+
+/**
+ * int13_retry - int13h with error handling
+ * @inreg:	int13h function parameters
+ * @outreg:	output registers
+ *
+ * Call int 13h, but with retry on failure.  Especially floppies need this.
+ **/
+int int13_retry(const com32sys_t * inreg, com32sys_t * outreg)
+{
+    int retry = MAX_NB_RETRIES;	/* Number of retries */
+    com32sys_t tmpregs;
+
+    if (!outreg)
+	outreg = &tmpregs;
+
+    while (retry--) {
+	__intcall(0x13, inreg, outreg);
+	if (!(outreg->eflags.l & EFLAGS_CF))
+	    return 0;		/* CF=0 => OK */
+    }
+
+    /* If we get here: error */
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/disk/write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,138 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from chain.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/common.h>
+#include <disk/errno_disk.h>
+#include <disk/read.h>
+#include <disk/util.h>
+#include <disk/write.h>
+
+/**
+ * write_sectors - write several sectors from disk
+ * @drive_info:		driveinfo struct describing the disk
+ * @lba:		Position to write
+ * @data:		Buffer to write
+ * @size:		Size of the buffer (number of sectors)
+ *
+ * Return the number of sectors write on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
+		  const void *data, const int size)
+{
+    com32sys_t inreg, outreg;
+    struct ebios_dapa *dapa;
+    void *buf;
+    int rv = -1;
+
+    buf = lmalloc(size);
+    if (!buf)
+	return -1;
+
+    dapa = lmalloc(sizeof(*dapa));
+    if (!dapa)
+	goto out;
+
+    memcpy(buf, data, size);
+    memset(&inreg, 0, sizeof inreg);
+
+    if (drive_info->ebios) {
+	dapa->len = sizeof(*dapa);
+	dapa->count = size;
+	dapa->off = OFFS(buf);
+	dapa->seg = SEG(buf);
+	dapa->lba = lba;
+
+	inreg.esi.w[0] = OFFS(dapa);
+	inreg.ds = SEG(dapa);
+	inreg.edx.b[0] = drive_info->disk;
+	inreg.eax.w[0] = 0x4300;	/* Extended write */
+    } else {
+	unsigned int c, h, s;
+
+	if (!drive_info->cbios) {	// XXX errno
+	    /* We failed to get the geometry */
+	    if (lba)
+		goto out;	/* Can only write MBR */
+
+	    s = 1;
+	    h = 0;
+	    c = 0;
+	} else
+	    lba_to_chs(drive_info, lba, &s, &h, &c);
+
+	// XXX errno
+	if (s > 63 || h > 256 || c > 1023)
+	    goto out;
+
+	inreg.eax.w[0] = 0x0301;	/* Write one sector */
+	inreg.ecx.b[1] = c & 0xff;
+	inreg.ecx.b[0] = s + (c >> 6);
+	inreg.edx.b[1] = h;
+	inreg.edx.b[0] = drive_info->disk;
+	inreg.ebx.w[0] = OFFS(buf);
+	inreg.es = SEG(buf);
+    }
+
+    /* Perform the write */
+    if (int13_retry(&inreg, &outreg)) {
+	errno_disk = outreg.eax.b[1];	/* Give up */
+    } else
+	rv = size;
+out:
+    lfree(dapa);
+    lfree(buf);
+    return rv;
+}
+
+/**
+ * write_verify_sectors - write several sectors from disk
+ * @drive_info:		driveinfo struct describing the disk
+ * @lba:		Position to write
+ * @data:		Buffer to write
+ **/
+int write_verify_sector(struct driveinfo *drive_info,
+			const unsigned int lba, const void *data)
+{
+    return write_verify_sectors(drive_info, lba, data, SECTOR);
+}
+
+/**
+ * write_verify_sectors - write several sectors from disk
+ * @drive_info:		driveinfo struct describing the disk
+ * @lba:		Position to write
+ * @data:		Buffer to write
+ * @size:		Size of the buffer (number of sectors)
+ **/
+int write_verify_sectors(struct driveinfo *drive_info,
+			 const unsigned int lba,
+			 const void *data, const int size)
+{
+    char *rb = malloc(SECTOR * size * sizeof(char));
+    int status;
+
+    if (write_sectors(drive_info, lba, data, size) == -1)
+	return -1;		/* Write failure */
+
+    if (read_sectors(drive_info, rb, lba, size) == -1)
+	return -1;		/* Readback failure */
+
+    status = memcmp(data, rb, SECTOR * size);
+    free(rb);
+    return status ? -1 : 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1040 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "dmi/dmi.h"
+
+const char *out_of_spec = "<OUT OF SPEC>";
+const char *bad_index = "<BAD INDEX>";
+
+/*
+ * Misc. util stuff
+ */
+
+/*
+ * 3.3.11 On Board Devices Information (Type 10)
+ */
+
+static const char *dmi_on_board_devices_type(uint8_t code)
+{
+    /* 3.3.11.1 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Video",
+	"SCSI Controller",
+	"Ethernet",
+	"Token Ring",
+	"Sound",
+	"PATA Controller",
+	"SATA Controller",
+	"SAS Controller"	/* 0x0A */
+    };
+
+    if (code >= 0x01 && code <= 0x0A)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+static void dmi_on_board_devices(struct dmi_header *h, s_dmi * dmi)
+{
+    uint8_t *p = h->data + 4;
+    uint8_t count = (h->length - 0x04) / 2;
+    unsigned int i;
+
+    for (i = 0;
+	 i < count
+	 && i <
+	 sizeof dmi->base_board.devices_information /
+	 sizeof *dmi->base_board.devices_information; i++) {
+	strlcpy(dmi->base_board.devices_information[i].type,
+		dmi_on_board_devices_type(p[2 * i] & 0x7F),
+		sizeof dmi->base_board.devices_information[i].type);
+	dmi->base_board.devices_information[i].status = p[2 * i] & 0x80;
+	strlcpy(dmi->base_board.devices_information[i].description,
+		dmi_string(h, p[2 * i + 1]),
+		sizeof dmi->base_board.devices_information[i].description);
+    }
+}
+
+/*
+ * 3.3.24 System Reset (Type 23)
+ */
+
+static const char *dmi_system_reset_boot_option(uint8_t code)
+{
+    static const char *option[] = {
+	"Operating System",	/* 0x1 */
+	"System Utilities",
+	"Do Not Reboot"		/* 0x3 */
+    };
+
+    if (code >= 0x1)
+	return option[code - 0x1];
+    return out_of_spec;
+}
+
+static void dmi_system_reset_count(uint16_t code, char *array)
+{
+    if (code == 0xFFFF)
+	strlcpy(array, "Unknown", sizeof array);
+    else
+	snprintf(array, sizeof array, "%u", code);
+}
+
+static void dmi_system_reset_timer(uint16_t code, char *array)
+{
+    if (code == 0xFFFF)
+	strlcpy(array, "Unknown", sizeof array);
+    else
+	snprintf(array, sizeof array, "%u min", code);
+}
+
+/*
+ * 3.3.25 Hardware Security (Type 24)
+ */
+
+static const char *dmi_hardware_security_status(uint8_t code)
+{
+    static const char *status[] = {
+	"Disabled",		/* 0x00 */
+	"Enabled",
+	"Not Implemented",
+	"Unknown"		/* 0x03 */
+    };
+
+    return status[code];
+}
+
+/*
+ * 3.3.12 OEM Strings (Type 11)
+ */
+
+static void dmi_oem_strings(struct dmi_header *h, const char *prefix,
+			    s_dmi * dmi)
+{
+    uint8_t *p = h->data + 4;
+    uint8_t count = p[0x00];
+    int i;
+
+    for (i = 1; i <= count; i++)
+	snprintf(dmi->oem_strings, OEM_STRINGS_SIZE, "%s %s %s\n",
+		 dmi->oem_strings, prefix, dmi_string(h, i));
+}
+
+/*
+ * 3.3.13 System Configuration Options (Type 12)
+ */
+static void dmi_system_configuration_options(struct dmi_header *h,
+					     const char *prefix, s_dmi * dmi)
+{
+    uint8_t *p = h->data + 4;
+    uint8_t count = p[0x00];
+    int i;
+
+    for (i = 1; i <= count; i++)
+	snprintf(dmi->system.configuration_options,
+		 SYSTEM_CONFIGURATION_OPTIONS_SIZE, "%s %s %s\n",
+		 dmi->system.configuration_options, prefix, dmi_string(h, i));
+}
+
+static void dmi_system_boot_status(uint8_t code, char *array)
+{
+    static const char *status[] = {
+	"No errors detected",	/* 0 */
+	"No bootable media",
+	"Operating system failed to load",
+	"Firmware-detected hardware failure",
+	"Operating system-detected hardware failure",
+	"User-requested boot",
+	"System security violation",
+	"Previously-requested image",
+	"System watchdog timer expired"	/* 8 */
+    };
+
+    if (code <= 8)
+	strlcpy(array, status[code], SYSTEM_BOOT_STATUS_SIZE);
+    if (code >= 128 && code <= 191)
+	strlcpy(array, "OEM-specific", SYSTEM_BOOT_STATUS_SIZE);
+    if (code >= 192)
+	strlcpy(array, "Product-specific", SYSTEM_BOOT_STATUS_SIZE);
+}
+
+void dmi_bios_runtime_size(uint32_t code, s_dmi * dmi)
+{
+    if (code & 0x000003FF) {
+	dmi->bios.runtime_size = code;
+	strlcpy(dmi->bios.runtime_size_unit, "bytes",
+		sizeof(dmi->bios.runtime_size_unit));
+    } else {
+	dmi->bios.runtime_size = code >> 10;
+	strlcpy(dmi->bios.runtime_size_unit, "KB",
+		sizeof(dmi->bios.runtime_size_unit));
+
+    }
+}
+
+void dmi_bios_characteristics(uint64_t code, s_dmi * dmi)
+{
+    int i;
+    /*
+     * This isn't very clear what this bit is supposed to mean
+     */
+    //if(code.l&(1<<3))
+    if (code && (1 << 3)) {
+	((bool *) (&dmi->bios.characteristics))[0] = true;
+	return;
+    }
+
+    for (i = 4; i <= 31; i++)
+	//if(code.l&(1<<i))
+	if (code & (1 << i))
+	    ((bool *) (&dmi->bios.characteristics))[i - 3] = true;
+}
+
+void dmi_bios_characteristics_x1(uint8_t code, s_dmi * dmi)
+{
+    int i;
+
+    for (i = 0; i <= 7; i++)
+	if (code & (1 << i))
+	    ((bool *) (&dmi->bios.characteristics_x1))[i] = true;
+}
+
+void dmi_bios_characteristics_x2(uint8_t code, s_dmi * dmi)
+{
+    int i;
+
+    for (i = 0; i <= 2; i++)
+	if (code & (1 << i))
+	    ((bool *) (&dmi->bios.characteristics_x2))[i] = true;
+}
+
+void dmi_system_uuid(uint8_t * p, s_dmi * dmi)
+{
+    int only0xFF = 1, only0x00 = 1;
+    int i;
+
+    for (i = 0; i < 16 && (only0x00 || only0xFF); i++) {
+	if (p[i] != 0x00)
+	    only0x00 = 0;
+	if (p[i] != 0xFF)
+	    only0xFF = 0;
+    }
+
+    if (only0xFF) {
+	sprintf(dmi->system.uuid, "Not Present");
+	return;
+    }
+    if (only0x00) {
+	sprintf(dmi->system.uuid, "Not Settable");
+	return;
+    }
+
+    sprintf(dmi->system.uuid,
+	    "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+	    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10],
+	    p[11], p[12], p[13], p[14], p[15]);
+}
+
+void dmi_system_wake_up_type(uint8_t code, s_dmi * dmi)
+{
+    /* 3.3.2.1 */
+    static const char *type[] = {
+	"Reserved",		/* 0x00 */
+	"Other",
+	"Unknown",
+	"APM Timer",
+	"Modem Ring",
+	"LAN Remote",
+	"Power Switch",
+	"PCI PME#",
+	"AC Power Restored"	/* 0x08 */
+    };
+
+    if (code <= 0x08) {
+	strlcpy(dmi->system.wakeup_type, type[code],
+		sizeof(dmi->system.wakeup_type));
+    } else {
+	strlcpy(dmi->system.wakeup_type, out_of_spec,
+		sizeof(dmi->system.wakeup_type));
+    }
+    return;
+}
+
+static void dmi_base_board_features(uint8_t code, s_dmi * dmi)
+{
+    if ((code & 0x1F) != 0) {
+	int i;
+
+	for (i = 0; i <= 4; i++)
+	    if (code & (1 << i))
+		((bool *) (&dmi->base_board.features))[i] = true;
+    }
+}
+
+static void dmi_base_board_type(uint8_t code, s_dmi * dmi)
+{
+    /* 3.3.3.2 */
+    static const char *type[] = {
+            "Unknown", /* 0x01 */
+            "Other",
+            "Server Blade",
+            "Connectivity Switch",
+            "System Management Module",
+            "Processor Module",
+            "I/O Module",
+            "Memory Module",
+            "Daughter Board",
+            "Motherboard",
+            "Processor+Memory Module",
+            "Processor+I/O Module",
+            "Interconnect Board" /* 0x0D */
+    };
+
+    if (code >= 0x01 && code <= 0x0D) {
+	strlcpy(dmi->base_board.type, type[code],
+		sizeof(dmi->base_board.type));
+    } else {
+	strlcpy(dmi->base_board.type, out_of_spec,
+		sizeof(dmi->base_board.type));
+    }
+    return;
+}
+
+static void dmi_processor_voltage(uint8_t code, s_dmi * dmi)
+{
+    /* 3.3.5.4 */
+    static const uint16_t voltage[] = {
+	5000,
+	3300,
+	2900
+    };
+    int i;
+
+    if (code & 0x80)
+	dmi->processor.voltage_mv = (code & 0x7f) * 100;
+    else {
+	for (i = 0; i <= 2; i++)
+	    if (code & (1 << i))
+		dmi->processor.voltage_mv = voltage[i];
+    }
+}
+
+static void dmi_processor_id(uint8_t type, uint8_t * p, const char *version,
+			     s_dmi * dmi)
+{
+    /*
+     * Extra flags are now returned in the ECX register when one calls
+     * the CPUID instruction. Their meaning is explained in table 6, but
+     * DMI doesn't support this yet.
+     */
+    uint32_t eax, edx;
+    int sig = 0;
+
+    /*
+     * This might help learn about new processors supporting the
+     * CPUID instruction or another form of identification.
+     */
+    sprintf(dmi->processor.id, "ID: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+	    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+
+    if (type == 0x05) {		/* 80386 */
+	uint16_t dx = WORD(p);
+	/*
+	 * 80386 have a different signature.
+	 */
+	dmi->processor.signature.type = (dx >> 12);
+	dmi->processor.signature.family = ((dx >> 8) & 0xF);
+	dmi->processor.signature.stepping = (dx >> 4) & 0xF;
+	dmi->processor.signature.minor_stepping = (dx & 0xF);
+	return;
+    }
+    if (type == 0x06) {		/* 80486 */
+	uint16_t dx = WORD(p);
+	/*
+	 * Not all 80486 CPU support the CPUID instruction, we have to find
+	 * wether the one we have here does or not. Note that this trick
+	 * works only because we know that 80486 must be little-endian.
+	 */
+	if ((dx & 0x0F00) == 0x0400
+	    && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070)
+	    && ((dx & 0x000F) >= 0x0003))
+	    sig = 1;
+	else {
+	    dmi->processor.signature.type = ((dx >> 12) & 0x3);
+	    dmi->processor.signature.family = ((dx >> 8) & 0xF);
+	    dmi->processor.signature.model = ((dx >> 4) & 0xF);
+	    dmi->processor.signature.stepping = (dx & 0xF);
+	    return;
+	}
+    } else if ((type >= 0x0B && type <= 0x13)	/* Intel, Cyrix */
+	       ||(type >= 0xB0 && type <= 0xB3)	/* Intel */
+	       ||type == 0xB5	/* Intel */
+	       || type == 0xB9)	/* Intel */
+	sig = 1;
+    else if ((type >= 0x18 && type <= 0x1D)	/* AMD */
+	     ||type == 0x1F	/* AMD */
+	     || (type >= 0xB6 && type <= 0xB7)	/* AMD */
+	     ||(type >= 0x83 && type <= 0x85))	/* AMD */
+	sig = 2;
+    else if (type == 0x01 || type == 0x02) {
+	/*
+	 * Some X86-class CPU have family "Other" or "Unknown". In this case,
+	 * we use the version string to determine if they are known to
+	 * support the CPUID instruction.
+	 */
+	if (strncmp(version, "Pentium III MMX", 15) == 0)
+	    sig = 1;
+	else if (strncmp(version, "AMD Athlon(TM)", 14) == 0
+		 || strncmp(version, "AMD Opteron(tm)", 15) == 0)
+	    sig = 2;
+	else
+	    return;
+    } else			/* not X86-class */
+	return;
+
+    eax = DWORD(p);
+    edx = DWORD(p + 4);
+    switch (sig) {
+    case 1:			/* Intel */
+	dmi->processor.signature.type = ((eax >> 12) & 0x3);
+	dmi->processor.signature.family =
+	    (((eax >> 16) & 0xFF0) + ((eax >> 8) & 0x00F));
+	dmi->processor.signature.model =
+	    (((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F));
+	dmi->processor.signature.stepping = (eax & 0xF);
+	break;
+    case 2:			/* AMD */
+	dmi->processor.signature.family =
+	    (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : (eax >> 8) & 0xF);
+	dmi->processor.signature.model =
+	    (((eax >> 4) & 0xF) == 0xF ? (eax >> 16) & 0xF : (eax >> 4) & 0xF);
+	dmi->processor.signature.stepping = (eax & 0xF);
+	break;
+    }
+
+    edx = DWORD(p + 4);
+    if ((edx & 0x3FF7FDFF) != 0) {
+	int i;
+	for (i = 0; i <= 31; i++)
+	    if (cpu_flags_strings[i] != NULL && edx & (1 << i))
+		((bool *) (&dmi->processor.cpu_flags))[i] = true;
+    }
+}
+
+void to_dmi_header(struct dmi_header *h, uint8_t * data)
+{
+    h->type = data[0];
+    h->length = data[1];
+    h->handle = WORD(data + 2);
+    h->data = data;
+}
+
+const char *dmi_string(struct dmi_header *dm, uint8_t s)
+{
+    char *bp = (char *)dm->data;
+    size_t i, len;
+
+    if (s == 0)
+	return "Not Specified";
+
+    bp += dm->length;
+    while (s > 1 && *bp) {
+	bp += strlen(bp);
+	bp++;
+	s--;
+    }
+
+    if (!*bp)
+	return bad_index;
+
+    /* ASCII filtering */
+    len = strlen(bp);
+    for (i = 0; i < len; i++)
+	if (bp[i] < 32 || bp[i] == 127)
+	    bp[i] = '.';
+
+    return bp;
+}
+
+int checksum(uint8_t * buf, int len)
+{
+    uint8_t sum = 0;
+    int a;
+
+    for (a = 0; a < len; a++)
+	sum += buf[a];
+    return (sum == 0);
+}
+
+static int smbios_decode(s_dmi * dmi, uint8_t * buf)
+{
+
+    dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07];
+    /* Some BIOS report weird SMBIOS version, fix that up */
+    switch (dmi->dmitable.ver) {
+    case 0x021F:
+	dmi->dmitable.ver = 0x0203;
+	break;
+    case 0x0233:
+	dmi->dmitable.ver = 0x0206;
+	break;
+    }
+    dmi->dmitable.major_version = dmi->dmitable.ver >> 8;
+    dmi->dmitable.minor_version = dmi->dmitable.ver & 0xFF;
+
+    return DMI_TABLE_PRESENT;
+}
+
+static int legacy_decode(s_dmi * dmi, uint8_t * buf)
+{
+    dmi->dmitable.num = buf[13] << 8 | buf[12];
+    dmi->dmitable.len = buf[7] << 8 | buf[6];
+    dmi->dmitable.base = buf[11] << 24 | buf[10] << 16 | buf[9] << 8 | buf[8];
+
+    /* Version already found? */
+    if (dmi->dmitable.ver > 0)
+	return DMI_TABLE_PRESENT;
+
+    dmi->dmitable.ver = (buf[0x06] << 8) + buf[0x07];
+
+    /*
+     * DMI version 0.0 means that the real version is taken from
+     * the SMBIOS version, which we don't know at this point.
+     */
+    if (buf[14] != 0) {
+	dmi->dmitable.major_version = buf[14] >> 4;
+	dmi->dmitable.minor_version = buf[14] & 0x0F;
+    } else {
+	dmi->dmitable.major_version = 0;
+	dmi->dmitable.minor_version = 0;
+    }
+    return DMI_TABLE_PRESENT;
+}
+
+int dmi_iterate(s_dmi * dmi)
+{
+    uint8_t *p, *q;
+    int found = 0;
+
+    /* Cleaning structures */
+    memset(dmi, 0, sizeof(s_dmi));
+
+    memset(&dmi->base_board, 0, sizeof(s_base_board));
+    memset(&dmi->battery, 0, sizeof(s_battery));
+    memset(&dmi->bios, 0, sizeof(s_bios));
+    memset(&dmi->chassis, 0, sizeof(s_chassis));
+    for (int i = 0; i < MAX_DMI_MEMORY_ITEMS; i++)
+	memset(&dmi->memory[i], 0, sizeof(s_memory));
+    memset(&dmi->processor, 0, sizeof(s_processor));
+    memset(&dmi->system, 0, sizeof(s_system));
+
+    /* Until we found this elements in the dmitable, we consider them as not filled */
+    dmi->base_board.filled = false;
+    dmi->battery.filled = false;
+    dmi->bios.filled = false;
+    dmi->chassis.filled = false;
+    for (int i = 0; i < MAX_DMI_MEMORY_ITEMS; i++)
+	dmi->memory[i].filled = false;
+    dmi->processor.filled = false;
+    dmi->system.filled = false;
+
+    p = (uint8_t *) 0xF0000;	/* The start address to look at the dmi table */
+    /* The anchor-string is 16-bytes aligned */
+    for (q = p; q < p + 0x10000; q += 16) {
+	/* To validate the presence of SMBIOS:
+	 * + the overall checksum must be correct
+	 * + the intermediate anchor-string must be _DMI_
+	 * + the intermediate checksum must be correct
+	 */
+	if (memcmp(q, "_SM_", 4) == 0 &&
+	    checksum(q, q[0x05]) &&
+	    memcmp(q + 0x10, "_DMI_", 5) == 0 && checksum(q + 0x10, 0x0F)) {
+	    /* Do not return, legacy_decode will need to be called
+	     * on the intermediate structure to get the table length
+	     * and address
+	     */
+	    smbios_decode(dmi, q);
+	} else if (memcmp(q, "_DMI_", 5) == 0 && checksum(q, 0x0F)) {
+	    found = 1;
+	    legacy_decode(dmi, q);
+	}
+    }
+
+    if (found)
+	return DMI_TABLE_PRESENT;
+
+    dmi->dmitable.base = 0;
+    dmi->dmitable.num = 0;
+    dmi->dmitable.ver = 0;
+    dmi->dmitable.len = 0;
+    return -ENODMITABLE;
+}
+
+void dmi_decode(struct dmi_header *h, uint16_t ver, s_dmi * dmi)
+{
+    uint8_t *data = h->data;
+
+    /*
+     * Note: DMI types 37, 38 and 39 are untested
+     */
+    switch (h->type) {
+    case 0:			/* 3.3.1 BIOS Information */
+	if (h->length < 0x12)
+	    break;
+	dmi->bios.filled = true;
+	strlcpy(dmi->bios.vendor, dmi_string(h, data[0x04]),
+		sizeof(dmi->bios.vendor));
+	strlcpy(dmi->bios.version, dmi_string(h, data[0x05]),
+		sizeof(dmi->bios.version));
+	strlcpy(dmi->bios.release_date, dmi_string(h, data[0x08]),
+		sizeof(dmi->bios.release_date));
+	dmi->bios.address = WORD(data + 0x06);
+	dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4, dmi);
+	dmi->bios.rom_size = (data[0x09] + 1) << 6;
+	strlcpy(dmi->bios.rom_size_unit, "kB", sizeof(dmi->bios.rom_size_unit));
+	dmi_bios_characteristics(QWORD(data + 0x0A), dmi);
+
+	if (h->length < 0x13)
+	    break;
+	dmi_bios_characteristics_x1(data[0x12], dmi);
+	if (h->length < 0x14)
+	    break;
+	dmi_bios_characteristics_x2(data[0x13], dmi);
+	if (h->length < 0x18)
+	    break;
+	if (data[0x14] != 0xFF && data[0x15] != 0xFF)
+	    snprintf(dmi->bios.bios_revision, sizeof(dmi->bios.bios_revision),
+		     "%u.%u", data[0x14], data[0x15]);
+	if (data[0x16] != 0xFF && data[0x17] != 0xFF)
+	    snprintf(dmi->bios.firmware_revision,
+		     sizeof(dmi->bios.firmware_revision), "%u.%u", data[0x16],
+		     data[0x17]);
+	break;
+    case 1:			/* 3.3.2 System Information */
+	if (h->length < 0x08)
+	    break;
+	dmi->system.filled = true;
+	strlcpy(dmi->system.manufacturer, dmi_string(h, data[0x04]),
+		sizeof(dmi->system.manufacturer));
+	strlcpy(dmi->system.product_name, dmi_string(h, data[0x05]),
+		sizeof(dmi->system.product_name));
+	strlcpy(dmi->system.version, dmi_string(h, data[0x06]),
+		sizeof(dmi->system.version));
+	strlcpy(dmi->system.serial, dmi_string(h, data[0x07]),
+		sizeof(dmi->system.serial));
+	if (h->length < 0x19)
+	    break;
+	dmi_system_uuid(data + 0x08, dmi);
+	dmi_system_wake_up_type(data[0x18], dmi);
+	if (h->length < 0x1B)
+	    break;
+	strlcpy(dmi->system.sku_number, dmi_string(h, data[0x19]),
+		sizeof(dmi->system.sku_number));
+	strlcpy(dmi->system.family, dmi_string(h, data[0x1A]),
+		sizeof(dmi->system.family));
+	break;
+
+    case 2:			/* 3.3.3 Base Board Information */
+	if (h->length < 0x08)
+	    break;
+	dmi->base_board.filled = true;
+	strlcpy(dmi->base_board.manufacturer, dmi_string(h, data[0x04]),
+		sizeof(dmi->base_board.manufacturer));
+	strlcpy(dmi->base_board.product_name, dmi_string(h, data[0x05]),
+		sizeof(dmi->base_board.product_name));
+	strlcpy(dmi->base_board.version, dmi_string(h, data[0x06]),
+		sizeof(dmi->base_board.version));
+	strlcpy(dmi->base_board.serial, dmi_string(h, data[0x07]),
+		sizeof(dmi->base_board.serial));
+	if (h->length < 0x0F)
+	    break;
+	strlcpy(dmi->base_board.asset_tag, dmi_string(h, data[0x08]),
+		sizeof(dmi->base_board.asset_tag));
+	dmi_base_board_features(data[0x09], dmi);
+	strlcpy(dmi->base_board.location, dmi_string(h, data[0x0A]),
+		sizeof(dmi->base_board.location));
+	dmi_base_board_type(data[0x0D], dmi);
+	if (h->length < 0x0F + data[0x0E] * sizeof(uint16_t))
+	    break;
+	break;
+    case 3:			/* 3.3.4 Chassis Information */
+	if (h->length < 0x09)
+	    break;
+	dmi->chassis.filled = true;
+	strlcpy(dmi->chassis.manufacturer, dmi_string(h, data[0x04]),
+		sizeof(dmi->chassis.manufacturer));
+	strlcpy(dmi->chassis.type, dmi_chassis_type(data[0x05] & 0x7F),
+		sizeof(dmi->chassis.type));
+	strlcpy(dmi->chassis.lock, dmi_chassis_lock(data[0x05] >> 7),
+		sizeof(dmi->chassis.lock));
+	strlcpy(dmi->chassis.version, dmi_string(h, data[0x06]),
+		sizeof(dmi->chassis.version));
+	strlcpy(dmi->chassis.serial, dmi_string(h, data[0x07]),
+		sizeof(dmi->chassis.serial));
+	strlcpy(dmi->chassis.asset_tag, dmi_string(h, data[0x08]),
+		sizeof(dmi->chassis.asset_tag));
+	if (h->length < 0x0D)
+	    break;
+	strlcpy(dmi->chassis.boot_up_state, dmi_chassis_state(data[0x09]),
+		sizeof(dmi->chassis.boot_up_state));
+	strlcpy(dmi->chassis.power_supply_state,
+		dmi_chassis_state(data[0x0A]),
+		sizeof(dmi->chassis.power_supply_state));
+	strlcpy(dmi->chassis.thermal_state,
+		dmi_chassis_state(data[0x0B]),
+		sizeof(dmi->chassis.thermal_state));
+	strlcpy(dmi->chassis.security_status,
+		dmi_chassis_security_status(data[0x0C]),
+		sizeof(dmi->chassis.security_status));
+	if (h->length < 0x11)
+	    break;
+	snprintf(dmi->chassis.oem_information,
+		 sizeof(dmi->chassis.oem_information), "0x%08X",
+		 DWORD(data + 0x0D));
+	if (h->length < 0x15)
+	    break;
+	dmi->chassis.height = data[0x11];
+	dmi->chassis.nb_power_cords = data[0x12];
+	break;
+    case 4:			/* 3.3.5 Processor Information */
+	if (h->length < 0x1A)
+	    break;
+	dmi->processor.filled = true;
+	strlcpy(dmi->processor.socket_designation,
+		dmi_string(h, data[0x04]),
+		sizeof(dmi->processor.socket_designation));
+	strlcpy(dmi->processor.type,
+		dmi_processor_type(data[0x05]), sizeof(dmi->processor.type));
+	strlcpy(dmi->processor.manufacturer,
+		dmi_string(h, data[0x07]), sizeof(dmi->processor.manufacturer));
+	strlcpy(dmi->processor.family,
+		dmi_processor_family(data[0x06],
+				     dmi->processor.manufacturer),
+		sizeof(dmi->processor.family));
+	dmi_processor_id(data[0x06], data + 8, dmi_string(h, data[0x10]), dmi);
+	strlcpy(dmi->processor.version,
+		dmi_string(h, data[0x10]), sizeof(dmi->processor.version));
+	dmi_processor_voltage(data[0x11], dmi);
+	dmi->processor.external_clock = WORD(data + 0x12);
+	dmi->processor.max_speed = WORD(data + 0x14);
+	dmi->processor.current_speed = WORD(data + 0x16);
+	if (data[0x18] & (1 << 6))
+	    strlcpy(dmi->processor.status,
+		    dmi_processor_status(data[0x18] & 0x07),
+		    sizeof(dmi->processor.status));
+	else
+	    sprintf(dmi->processor.status, "Unpopulated");
+	strlcpy(dmi->processor.upgrade,
+		dmi_processor_upgrade(data[0x19]),
+		sizeof(dmi->processor.upgrade));
+	if (h->length < 0x20)
+	    break;
+	dmi_processor_cache(WORD(data + 0x1A), "L1", ver,
+			    dmi->processor.cache1);
+	dmi_processor_cache(WORD(data + 0x1C), "L2", ver,
+			    dmi->processor.cache2);
+	dmi_processor_cache(WORD(data + 0x1E), "L3", ver,
+			    dmi->processor.cache3);
+	if (h->length < 0x23)
+	    break;
+	strlcpy(dmi->processor.serial, dmi_string(h, data[0x20]),
+		sizeof(dmi->processor.serial));
+	strlcpy(dmi->processor.asset_tag, dmi_string(h, data[0x21]),
+		sizeof(dmi->processor.asset_tag));
+	strlcpy(dmi->processor.part_number, dmi_string(h, data[0x22]),
+		sizeof(dmi->processor.part_number));
+        dmi->processor.core_count = 0;
+        dmi->processor.core_enabled = 0;
+        dmi->processor.thread_count = 0;
+	if (h->length < 0x28)
+	    break;
+        dmi->processor.core_count = data[0x23];
+        dmi->processor.core_enabled = data[0x24];
+        dmi->processor.thread_count = data[0x25];
+	break;
+    case 6:			/* 3.3.7 Memory Module Information */
+	if (h->length < 0x0C)
+	    break;
+	dmi->memory_module_count++;
+	s_memory_module *module =
+	    &dmi->memory_module[dmi->memory_module_count - 1];
+	dmi->memory_module[dmi->memory_module_count - 1].filled = true;
+	strlcpy(module->socket_designation, dmi_string(h, data[0x04]),
+		sizeof(module->socket_designation));
+	dmi_memory_module_connections(data[0x05], module->bank_connections, sizeof(module->bank_connections));
+	dmi_memory_module_speed(data[0x06], module->speed);
+	dmi_memory_module_types(WORD(data + 0x07), " ", module->type, sizeof(module->type));
+	dmi_memory_module_size(data[0x09], module->installed_size, sizeof(module->installed_size));
+	dmi_memory_module_size(data[0x0A], module->enabled_size, sizeof(module->enabled_size));
+	dmi_memory_module_error(data[0x0B], "\t\t", module->error_status);
+	break;
+    case 7:			/* 3.3.8 Cache Information */
+	if (h->length < 0x0F)
+	    break;
+	dmi->cache_count++;
+	if (dmi->cache_count > MAX_DMI_CACHE_ITEMS)
+	    break;
+	strlcpy(dmi->cache[dmi->cache_count - 1].socket_designation,
+		dmi_string(h, data[0x04]),
+		sizeof(dmi->cache[dmi->cache_count - 1].socket_designation));
+	snprintf(dmi->cache[dmi->cache_count - 1].configuration,
+		 sizeof(dmi->cache[dmi->cache_count - 1].configuration),
+		 "%s, %s, %u",
+		 WORD(data + 0x05) & 0x0080 ? "Enabled" : "Disabled",
+		 WORD(data +
+		      0x05) & 0x0008 ? "Socketed" : "Not Socketed",
+		 (WORD(data + 0x05) & 0x0007) + 1);
+	strlcpy(dmi->cache[dmi->cache_count - 1].mode,
+		dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003),
+		sizeof(dmi->cache[dmi->cache_count - 1].mode));
+	strlcpy(dmi->cache[dmi->cache_count - 1].location,
+		dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003),
+		sizeof(dmi->cache[dmi->cache_count - 1].location));
+	dmi->cache[dmi->cache_count - 1].installed_size =
+	    dmi_cache_size(WORD(data + 0x09));
+	dmi->cache[dmi->cache_count - 1].max_size =
+	    dmi_cache_size(WORD(data + 0x07));
+	dmi_cache_types(WORD(data + 0x0B), " ",
+			dmi->cache[dmi->cache_count - 1].supported_sram_types);
+	dmi_cache_types(WORD(data + 0x0D), " ",
+			dmi->cache[dmi->cache_count - 1].installed_sram_types);
+	if (h->length < 0x13)
+	    break;
+	dmi->cache[dmi->cache_count - 1].speed = data[0x0F];	/* ns */
+	strlcpy(dmi->cache[dmi->cache_count - 1].error_correction_type,
+		dmi_cache_ec_type(data[0x10]),
+		sizeof(dmi->cache[dmi->cache_count - 1].error_correction_type));
+	strlcpy(dmi->cache[dmi->cache_count - 1].system_type,
+		dmi_cache_type(data[0x11]),
+		sizeof(dmi->cache[dmi->cache_count - 1].system_type));
+	strlcpy(dmi->cache[dmi->cache_count - 1].associativity,
+		dmi_cache_associativity(data[0x12]),
+		sizeof(dmi->cache[dmi->cache_count - 1].associativity));
+	break;
+    case 10:			/* 3.3.11 On Board Devices Information */
+	dmi_on_board_devices(h, dmi);
+	break;
+    case 11:			/* 3.3.12 OEM Strings */
+	if (h->length < 0x05)
+	    break;
+	dmi_oem_strings(h, "\t", dmi);
+	break;
+    case 12:			/* 3.3.13 System Configuration Options */
+	if (h->length < 0x05)
+	    break;
+	dmi_system_configuration_options(h, "\t", dmi);
+	break;
+    case 17:			/* 3.3.18 Memory Device */
+	if (h->length < 0x15)
+	    break;
+	dmi->memory_count++;
+	if (dmi->memory_count > MAX_DMI_MEMORY_ITEMS)
+	    break;
+	s_memory *mem = &dmi->memory[dmi->memory_count - 1];
+	dmi->memory[dmi->memory_count - 1].filled = true;
+	dmi_memory_array_error_handle(WORD(data + 0x06), mem->error);
+	dmi_memory_device_width(WORD(data + 0x08), mem->total_width);
+	dmi_memory_device_width(WORD(data + 0x0A), mem->data_width);
+	dmi_memory_device_size(WORD(data + 0x0C), mem->size);
+	strlcpy(mem->form_factor,
+		dmi_memory_device_form_factor(data[0x0E]),
+		sizeof(mem->form_factor));
+	dmi_memory_device_set(data[0x0F], mem->device_set);
+	strlcpy(mem->device_locator, dmi_string(h, data[0x10]),
+		sizeof(mem->device_locator));
+	strlcpy(mem->bank_locator, dmi_string(h, data[0x11]),
+		sizeof(mem->bank_locator));
+	strlcpy(mem->type, dmi_memory_device_type(data[0x12]),
+		sizeof(mem->type));
+	dmi_memory_device_type_detail(WORD(data + 0x13), mem->type_detail, sizeof(mem->type_detail));
+	if (h->length < 0x17)
+	    break;
+	dmi_memory_device_speed(WORD(data + 0x15), mem->speed);
+	if (h->length < 0x1B)
+	    break;
+	strlcpy(mem->manufacturer, dmi_string(h, data[0x17]),
+		sizeof(mem->manufacturer));
+	strlcpy(mem->serial, dmi_string(h, data[0x18]), sizeof(mem->serial));
+	strlcpy(mem->asset_tag, dmi_string(h, data[0x19]),
+		sizeof(mem->asset_tag));
+	strlcpy(mem->part_number, dmi_string(h, data[0x1A]),
+		sizeof(mem->part_number));
+	break;
+    case 22:			/* 3.3.23 Portable Battery */
+	if (h->length < 0x10)
+	    break;
+	dmi->battery.filled = true;
+	strlcpy(dmi->battery.location, dmi_string(h, data[0x04]),
+		sizeof(dmi->battery.location));
+	strlcpy(dmi->battery.manufacturer, dmi_string(h, data[0x05]),
+		sizeof(dmi->battery.manufacturer));
+	if (data[0x06] || h->length < 0x1A)
+	    strlcpy(dmi->battery.manufacture_date,
+		    dmi_string(h, data[0x06]),
+		    sizeof(dmi->battery.manufacture_date));
+	if (data[0x07] || h->length < 0x1A)
+	    strlcpy(dmi->battery.serial, dmi_string(h, data[0x07]),
+		    sizeof(dmi->battery.serial));
+	strlcpy(dmi->battery.name, dmi_string(h, data[0x08]),
+		sizeof(dmi->battery.name));
+	if (data[0x09] != 0x02 || h->length < 0x1A)
+	    strlcpy(dmi->battery.chemistry,
+		    dmi_battery_chemistry(data[0x09]),
+		    sizeof(dmi->battery.chemistry));
+	if (h->length < 0x1A)
+	    dmi_battery_capacity(WORD(data + 0x0A), 1,
+				 dmi->battery.design_capacity);
+	else
+	    dmi_battery_capacity(WORD(data + 0x0A), data[0x15],
+				 dmi->battery.design_capacity);
+	dmi_battery_voltage(WORD(data + 0x0C), dmi->battery.design_voltage);
+	strlcpy(dmi->battery.sbds, dmi_string(h, data[0x0E]),
+		sizeof(dmi->battery.sbds));
+	dmi_battery_maximum_error(data[0x0F], dmi->battery.maximum_error);
+	if (h->length < 0x1A)
+	    break;
+	if (data[0x07] == 0)
+	    sprintf(dmi->battery.sbds_serial, "%04X", WORD(data + 0x10));
+	if (data[0x06] == 0)
+	    sprintf(dmi->battery.sbds_manufacture_date, "%u-%02u-%02u",
+		    1980 + (WORD(data + 0x12) >> 9),
+		    (WORD(data + 0x12) >> 5) & 0x0F, WORD(data + 0x12) & 0x1F);
+	if (data[0x09] == 0x02)
+	    strlcpy(dmi->battery.sbds_chemistry, dmi_string(h, data[0x14]),
+		    sizeof(dmi->battery.sbds_chemistry));
+	//      sprintf(dmi->battery.oem_info,"0x%08X",DWORD(h, data+0x16));
+	break;
+    case 23:			/* 3.3.24 System Reset */
+	if (h->length < 0x0D)
+	    break;
+	dmi->system.system_reset.filled = true;
+	dmi->system.system_reset.status = data[0x04] & (1 << 0);
+	dmi->system.system_reset.watchdog = data[0x04] & (1 << 5);
+	if (!(data[0x04] & (1 << 5)))
+	    break;
+	strlcpy(dmi->system.system_reset.boot_option,
+		dmi_system_reset_boot_option((data[0x04] >> 1) & 0x3),
+		sizeof dmi->system.system_reset.boot_option);
+	strlcpy(dmi->system.system_reset.boot_option_on_limit,
+		dmi_system_reset_boot_option((data[0x04] >> 3) & 0x3),
+		sizeof dmi->system.system_reset.boot_option_on_limit);
+	dmi_system_reset_count(WORD(data + 0x05),
+			       dmi->system.system_reset.reset_count);
+	dmi_system_reset_count(WORD(data + 0x07),
+			       dmi->system.system_reset.reset_limit);
+	dmi_system_reset_timer(WORD(data + 0x09),
+			       dmi->system.system_reset.timer_interval);
+	dmi_system_reset_timer(WORD(data + 0x0B),
+			       dmi->system.system_reset.timeout);
+	break;
+    case 24:			/* 3.3.25 Hardware Security */
+	if (h->length < 0x05)
+	    break;
+	dmi->hardware_security.filled = true;
+	strlcpy(dmi->hardware_security.power_on_passwd_status,
+		dmi_hardware_security_status(data[0x04] >> 6),
+		sizeof dmi->hardware_security.power_on_passwd_status);
+	strlcpy(dmi->hardware_security.keyboard_passwd_status,
+		dmi_hardware_security_status((data[0x04] >> 4) & 0x3),
+		sizeof dmi->hardware_security.keyboard_passwd_status);
+	strlcpy(dmi->hardware_security.administrator_passwd_status,
+		dmi_hardware_security_status((data[0x04] >> 2) & 0x3),
+		sizeof dmi->hardware_security.administrator_passwd_status);
+	strlcpy(dmi->hardware_security.front_panel_reset_status,
+		dmi_hardware_security_status(data[0x04] & 0x3),
+		sizeof dmi->hardware_security.front_panel_reset_status);
+	break;
+    case 32:			/* 3.3.33 System Boot Information */
+	if (h->length < 0x0B)
+	    break;
+	dmi_system_boot_status(data[0x0A], dmi->system.system_boot_status);
+    case 38:			/* 3.3.39 IPMI Device Information */
+	if (h->length < 0x10)
+	    break;
+	dmi->ipmi.filled = true;
+	snprintf(dmi->ipmi.interface_type,
+		 sizeof(dmi->ipmi.interface_type), "%s",
+		 dmi_ipmi_interface_type(data[0x04]));
+	dmi->ipmi.major_specification_version = data[0x05] >> 4;
+	dmi->ipmi.minor_specification_version = data[0x05] & 0x0F;
+	dmi->ipmi.I2C_slave_address = data[0x06] >> 1;
+	if (data[0x07] != 0xFF)
+	    dmi->ipmi.nv_address = data[0x07];
+	else
+	    dmi->ipmi.nv_address = 0;	/* Not Present */
+	dmi_ipmi_base_address(data[0x04], data + 0x08, &dmi->ipmi);
+	if (h->length < 0x12)
+	    break;
+	if (data[0x11] != 0x00) {
+	    dmi->ipmi.irq = data[0x11];
+	}
+	break;
+    }
+}
+
+void parse_dmitable(s_dmi * dmi)
+{
+    int i = 0;
+    uint8_t *data = NULL;
+    uint8_t buf[dmi->dmitable.len];
+    memcpy(buf, (int *)dmi->dmitable.base, sizeof(uint8_t) * dmi->dmitable.len);
+    data = buf;
+    dmi->memory_count = 0;
+    while (i < dmi->dmitable.num && data + 4 <= buf + dmi->dmitable.len) {	/* 4 is the length of an SMBIOS structure header */
+	uint8_t *next;
+	struct dmi_header h;
+	to_dmi_header(&h, data);
+	/*
+	 * If a short entry is found (less than 4 bytes), not only it
+	 * is invalid, but we cannot reliably locate the next entry.
+	 * Better stop at this point, and let the user know his/her
+	 * table is broken.
+	 */
+	if (h.length < 4) {
+	    printf
+		("Invalid entry length (%u). DMI table is broken! Stop.\n\n",
+		 (unsigned int)h.length);
+	    break;
+	}
+
+	/* loo for the next handle */
+	next = data + h.length;
+	while (next - buf + 1 < dmi->dmitable.len
+	       && (next[0] != 0 || next[1] != 0))
+	    next++;
+	next += 2;
+	if (next - buf <= dmi->dmitable.len) {
+	    dmi_decode(&h, dmi->dmitable.ver, dmi);
+	}
+	data = next;
+	i++;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_base_board.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_base_board.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_base_board.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+const char *base_board_features_strings[] = {
+    "Board is a hosting board",	/* 0 */
+    "Board requires at least one daughter board",
+    "Board is removable",
+    "Board is replaceable",
+    "Board is hot swappable"	/* 4 */
+};
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_battery.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_battery.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_battery.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+const char *dmi_battery_chemistry(uint8_t code)
+{
+    /* 3.3.23.1 */
+    static const char *chemistry[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Lead Acid",
+	"Nickel Cadmium",
+	"Nickel Metal Hydride",
+	"Lithium Ion",
+	"Zinc Air",
+	"Lithium Polymer"	/* 0x08 */
+    };
+
+    if (code >= 0x01 && code <= 0x08)
+	return chemistry[code - 0x01];
+    return out_of_spec;
+}
+
+void dmi_battery_capacity(uint16_t code, uint8_t multiplier, char *capacity)
+{
+    if (code == 0)
+	sprintf(capacity, "%s", "Unknown");
+    else
+	sprintf(capacity, "%u mWh", code * multiplier);
+}
+
+void dmi_battery_voltage(uint16_t code, char *voltage)
+{
+    if (code == 0)
+	sprintf(voltage, "%s", "Unknown");
+    else
+	sprintf(voltage, "%u mV", code);
+}
+
+void dmi_battery_maximum_error(uint8_t code, char *error)
+{
+    if (code == 0xFF)
+	sprintf(error, "%s", "Unknown");
+    else
+	sprintf(error, "%u%%", code);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_bios.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_bios.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_bios.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+
+const char *bios_charac_strings[] = {
+    "BIOS characteristics not supported",	/* 3 */
+    "ISA is supported",
+    "MCA is supported",
+    "EISA is supported",
+    "PCI is supported",
+    "PC Card (PCMCIA) is supported",
+    "PNP is supported",
+    "APM is supported",
+    "BIOS is upgradeable",
+    "BIOS shadowing is allowed",
+    "VLB is supported",
+    "ESCD support is available",
+    "Boot from CD is supported",
+    "Selectable boot is supported",
+    "BIOS ROM is socketed",
+    "Boot from PC Card (PCMCIA) is supported",
+    "EDD is supported",
+    "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
+    "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)",
+    "5.25\"/360 KB floppy services are supported (int 13h)",
+    "5.25\"/1.2 MB floppy services are supported (int 13h)",
+    "3.5\"/720 KB floppy services are supported (int 13h)",
+    "3.5\"/2.88 MB floppy services are supported (int 13h)",
+    "Print screen service is supported (int 5h)",
+    "8042 keyboard services are supported (int 9h)",
+    "Serial services are supported (int 14h)",
+    "Printer services are supported (int 17h)",
+    "CGA/mono video services are supported (int 10h)",
+    "NEC PC-98"			/* 31 */
+};
+
+const char *bios_charac_x1_strings[] = {
+    "ACPI is supported",	/* 0 */
+    "USB legacy is supported",
+    "AGP is supported",
+    "I2O boot is supported",
+    "LS-120 boot is supported",
+    "ATAPI Zip drive boot is supported",
+    "IEEE 1394 boot is supported",
+    "Smart battery is supported"	/* 7 */
+};
+
+const char *bios_charac_x2_strings[] = {
+    "BIOS boot specification is supported",	/* 0 */
+    "Function key-initiated network boot is supported",
+    "Targeted content distribution is supported"	/* 2 */
+};
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_cache.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_cache.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_cache.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,139 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Some part borrowed from DMI Decode:
+ *
+ *   (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   (C) 2002-2007 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <dmi/dmi.h>
+#include <dmi/dmi_cache.h>
+#include <stdio.h>
+
+/*
+ * 3.3.8 Cache Information (Type 7)
+ */
+
+const char *dmi_cache_mode(uint8_t code)
+{
+    static const char *mode[] = {
+	"Write Through",	/* 0x00 */
+	"Write Back",
+	"Varies With Memory Address",
+	"Unknown"		/* 0x03 */
+    };
+
+    return mode[code];
+}
+
+const char *dmi_cache_location(uint8_t code)
+{
+    static const char *location[4] = {
+	"Internal",		/* 0x00 */
+	"External",
+	"<OUT OF SPEC",		/* 0x02 */
+	"Unknown"		/* 0x03 */
+    };
+
+    if (location[code] != NULL)
+	return location[code];
+    return out_of_spec;
+}
+
+uint16_t dmi_cache_size(uint16_t code)
+{
+    if (code & 0x8000)
+	return (code & 0x7FFF) << 6;	/* KB */
+    else
+	return code;		/* KB */
+}
+
+void dmi_cache_types(uint16_t code, const char *sep, char *array)
+{
+    /* 3.3.8.2 */
+    static const char *types[] = {
+	"Other",		/* 0 */
+	"Unknown",
+	"Non-burst",
+	"Burst",
+	"Pipeline Burst",
+	"Synchronous",
+	"Asynchronous"		/* 6 */
+    };
+
+    if ((code & 0x007F) == 0)
+	strcpy(array, "None");
+    else {
+	int i;
+
+	for (i = 0; i <= 6; i++)
+	    if (code & (1 << i))
+		sprintf(array, "%s%s", sep, types[i]);
+    }
+}
+
+const char *dmi_cache_ec_type(uint8_t code)
+{
+    /* 3.3.8.3 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"None",
+	"Parity",
+	"Single-bit ECC",
+	"Multi-bit ECC"		/* 0x06 */
+    };
+
+    if (code >= 0x01 && code <= 0x06)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+const char *dmi_cache_type(uint8_t code)
+{
+    /* 3.3.8.4 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Instruction",
+	"Data",
+	"Unified"		/* 0x05 */
+    };
+
+    if (code >= 0x01 && code <= 0x05)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+const char *dmi_cache_associativity(uint8_t code)
+{
+    /* 3.3.8.5 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Direct Mapped",
+	"2-way Set-associative",
+	"4-way Set-associative",
+	"Fully Associative",
+	"8-way Set-associative",
+	"16-way Set-associative",	/* 0x08 */
+	"12-way Set-associative",
+	"24-way Set-associative",
+	"32-way Set-associative",
+	"48-way Set-associative",
+	"64-way Set-associative"	/* 0x0D */
+    };
+
+    if (code >= 0x01 && code <= 0x0D)
+	return type[code - 0x01];
+    return out_of_spec;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_chassis.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_chassis.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_chassis.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,113 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+
+const char *dmi_chassis_type(uint8_t code)
+{
+    /* 3.3.4.1 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Desktop",
+	"Low Profile Desktop",
+	"Pizza Box",
+	"Mini Tower",
+	"Tower",
+	"Portable",
+	"Laptop",
+	"Notebook",
+	"Hand Held",
+	"Docking Station",
+	"All In One",
+	"Sub Notebook",
+	"Space-saving",
+	"Lunch Box",
+	"Main Server Chassis",	/* master.mif says System */
+	"Expansion Chassis",
+	"Sub Chassis",
+	"Bus Expansion Chassis",
+	"Peripheral Chassis",
+	"RAID Chassis",
+	"Rack Mount Chassis",
+	"Sealed-case PC",
+	"Multi-system",		/* 0x19 */
+	"CompactPCI",
+	"AdvancedTCA",
+	"Blade",
+	"Blade Enclosing" /* 0x1D */
+    };
+
+    if (code >= 0x01 && code <= 0x1D)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+const char *dmi_chassis_lock(uint8_t code)
+{
+    static const char *lock[] = {
+	"Not Present",		/* 0x00 */
+	"Present"		/* 0x01 */
+    };
+
+    return lock[code];
+}
+
+const char *dmi_chassis_state(uint8_t code)
+{
+    /* 3.3.4.2 */
+    static const char *state[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Safe",			/* master.mif says OK */
+	"Warning",
+	"Critical",
+	"Non-recoverable"	/* 0x06 */
+    };
+
+    if (code >= 0x01 && code <= 0x06)
+	return (state[code - 0x01]);
+    return out_of_spec;
+}
+
+const char *dmi_chassis_security_status(uint8_t code)
+{
+    /* 3.3.4.3 */
+    static const char *status[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"None",
+	"External Interface Locked Out",
+	"External Interface Enabled"	/* 0x05 */
+    };
+
+    if (code >= 0x01 && code <= 0x05)
+	return (status[code - 0x01]);
+    return out_of_spec;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_ipmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_ipmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_ipmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Portions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+
+const char *dmi_ipmi_interface_type(uint8_t code)
+{
+    /* 3.3.39.1 and IPMI 2.0, appendix C1, table C1-2 */
+    static const char *type[] = {
+	"Unknown",		/* 0x00 */
+	"KCS (Keyboard Control Style)",
+	"SMIC (Server Management Interface Chip)",
+	"BT (Block Transfer)",
+	"SSIF (SMBus System Interface)"	/* 0x04 */
+    };
+
+    if (code <= 0x04)
+	return type[code];
+    return out_of_spec;
+}
+
+void dmi_ipmi_base_address(uint8_t type, const uint8_t * p, s_ipmi * ipmi)
+{
+    if (type == 0x04) {		/* SSIF */
+	ipmi->base_address = (*p) >> 1;
+    } else {
+	ipmi->base_address = QWORD(p);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,264 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+
+void dmi_memory_array_error_handle(uint16_t code, char *array)
+{
+    if (code == 0xFFFE)
+	sprintf(array, "%s", "Not Provided");
+    else if (code == 0xFFFF)
+	sprintf(array, "%s", "No Error");
+    else
+	sprintf(array, "0x%04X", code);
+}
+
+void dmi_memory_device_width(uint16_t code, char *width)
+{
+    /*
+     * 3.3.18 Memory Device (Type 17)
+     * If no memory module is present, width may be 0
+     */
+    if (code == 0xFFFF || code == 0)
+	sprintf(width, "%s", "Unknown");
+    else
+	sprintf(width, "%u bits", code);
+}
+
+void dmi_memory_device_size(uint16_t code, char *size)
+{
+    if (code == 0)
+	sprintf(size, "%s", "Free");
+    else if (code == 0xFFFF)
+	sprintf(size, "%s", "Unknown");
+    else {
+	if (code & 0x8000)
+	    sprintf(size, "%u kB", code & 0x7FFF);
+	else
+	    sprintf(size, "%u MB", code);
+    }
+}
+
+const char *dmi_memory_device_form_factor(uint8_t code)
+{
+    /* 3.3.18.1 */
+    static const char *form_factor[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"SIMM",
+	"SIP",
+	"Chip",
+	"DIP",
+	"ZIP",
+	"Proprietary Card",
+	"DIMM",
+	"TSOP",
+	"Row Of Chips",
+	"RIMM",
+	"SODIMM",
+	"SRIMM",
+	"FB-DIMM"		/* 0x0F */
+    };
+
+    if (code >= 0x01 && code <= 0x0F)
+	return form_factor[code - 0x01];
+    return out_of_spec;
+}
+
+void dmi_memory_device_set(uint8_t code, char *set)
+{
+    if (code == 0)
+	sprintf(set, "%s", "None");
+    else if (code == 0xFF)
+	sprintf(set, "%s", "Unknown");
+    else
+	sprintf(set, "%u", code);
+}
+
+const char *dmi_memory_device_type(uint8_t code)
+{
+    /* 3.3.18.2 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"DRAM",
+	"EDRAM",
+	"VRAM",
+	"SRAM",
+	"RAM",
+	"ROM",
+	"Flash",
+	"EEPROM",
+	"FEPROM",
+	"EPROM",
+	"CDRAM",
+	"3DRAM",
+	"SDRAM",
+	"SGRAM",
+	"RDRAM",
+	"DDR",
+	"DDR2",
+	"DDR2 FB-DIMM",		/* 0x14 */
+	NULL,
+	NULL,
+	NULL,
+	"DDR3",			/* 0x18 */
+	"FBD2"			/* 0x19 */
+    };
+
+    if (code >= 0x01 && code <= 0x19)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+void dmi_memory_device_type_detail(uint16_t code, char *type_detail, int sizeof_type_detail)
+{
+    /* 3.3.18.3 */
+    static const char *detail[] = {
+	"Other",		/* 1 */
+	"Unknown",
+	"Fast-paged",
+	"Static Column",
+	"Pseudo-static",
+	"RAMBus",
+	"Synchronous",
+	"CMOS",
+	"EDO",
+	"Window DRAM",
+	"Cache DRAM",
+	"Non-Volatile"		/* 12 */
+    };
+
+    if ((code & 0x1FFE) == 0)
+	sprintf(type_detail, "%s", "None");
+    else {
+	int i;
+
+	for (i = 1; i <= 12; i++)
+	    if (code & (1 << i))
+		snprintf(type_detail, sizeof_type_detail, "%s", detail[i - 1]);
+    }
+}
+
+void dmi_memory_device_speed(uint16_t code, char *speed)
+{
+    if (code == 0)
+	sprintf(speed, "%s", "Unknown");
+    else
+	sprintf(speed, "%u MHz", code);
+}
+
+/*
+ * 3.3.7 Memory Module Information (Type 6)
+ */
+
+void dmi_memory_module_types(uint16_t code, const char *sep, char *type, int sizeof_type)
+{
+    /* 3.3.7.1 */
+    static const char *types[] = {
+	"Other",		/* 0 */
+	"Unknown",
+	"Standard",
+	"FPM",
+	"EDO",
+	"Parity",
+	"ECC",
+	"SIMM",
+	"DIMM",
+	"Burst EDO",
+	"SDRAM"			/* 10 */
+    };
+
+    if ((code & 0x07FF) == 0)
+	sprintf(type, "%s", "None");
+    else {
+	int i;
+
+	for (i = 0; i <= 10; i++)
+	    if (code & (1 << i))
+		snprintf(type, sizeof_type, "%s%s%s", type, sep, types[i]);
+    }
+}
+
+void dmi_memory_module_connections(uint8_t code, char *connection, int sizeof_connection)
+{
+    if (code == 0xFF)
+	sprintf(connection, "%s", "None");
+    else {
+	if ((code & 0xF0) != 0xF0)
+	    sprintf(connection, "%u ", code >> 4);
+	if ((code & 0x0F) != 0x0F)
+	    snprintf(connection, sizeof_connection, "%s%u", connection, code & 0x0F);
+    }
+}
+
+void dmi_memory_module_speed(uint8_t code, char *speed)
+{
+    if (code == 0)
+	sprintf(speed, "%s", "Unknown");
+    else
+	sprintf(speed, "%u ns", code);
+}
+
+void dmi_memory_module_size(uint8_t code, char *size, int sizeof_size)
+{
+    /* 3.3.7.2 */
+    switch (code & 0x7F) {
+    case 0x7D:
+	sprintf(size, "%s", "Not Determinable");
+	break;
+    case 0x7E:
+	sprintf(size, "%s", "Disabled");
+	break;
+    case 0x7F:
+	sprintf(size, "%s", "Not Installed");
+	return;
+    default:
+	sprintf(size, "%u MB", 1 << (code & 0x7F));
+    }
+
+    if (code & 0x80)
+	snprintf(size, sizeof_size, "%s %s", size, "(Double-bank Connection)");
+    else
+	snprintf(size, sizeof_size, "%s %s", size, "(Single-bank Connection)");
+}
+
+void dmi_memory_module_error(uint8_t code, const char *prefix, char *error)
+{
+    if (code & (1 << 2))
+	sprintf(error, "%s", "See Event Log\n");
+    else {
+	if ((code & 0x03) == 0)
+	    sprintf(error, "%s", "OK\n");
+	if (code & (1 << 0))
+	    sprintf(error, "%sUncorrectable Errors\n", prefix);
+	if (code & (1 << 1))
+	    sprintf(error, "%sCorrectable Errors\n", prefix);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_processor.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/dmi/dmi_processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,431 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Pportions of this file taken from the dmidecode project
+ *
+ *   Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
+ *   Copyright (C) 2002-2008 Jean Delvare <khali@linux-fr.org>
+ *
+ *   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; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *   For the avoidance of doubt the "preferred form" of this code is one which
+ *   is in an open unpatent encumbered format. Where cryptographic key signing
+ *   forms part of the process of creating an executable the information
+ *   including keys needed to generate an equivalently functional executable
+ *   are deemed to be part of the source code.
+*/
+
+#include <dmi/dmi.h>
+#include <stdio.h>
+
+const char *dmi_processor_type(uint8_t code)
+{
+    /* 3.3.5.1 */
+    static const char *type[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Central Processor",
+	"Math Processor",
+	"DSP Processor",
+	"Video Processor"	/* 0x06 */
+    };
+
+    if (code >= 0x01 && code <= 0x06)
+	return type[code - 0x01];
+    return out_of_spec;
+}
+
+const char *dmi_processor_family(uint8_t code, char *manufacturer)
+{
+    /* 3.3.5.2 */
+    /* TODO : Need to implement code/value (see dmidecode) insteed of array to address large index */
+    static const char *family[256] = {
+	NULL,			/* 0x00 */
+	"Other",
+	"Unknown",
+	"8086",
+	"80286",
+	"80386",
+	"80486",
+	"8087",
+	"80287",
+	"80387",
+	"80487",
+	"Pentium",
+	"Pentium Pro",
+	"Pentium II",
+	"Pentium MMX",
+	"Celeron",
+	"Pentium II Xeon",
+	"Pentium III",
+	"M1",
+	"M2",
+	"Celeron M",		/* 0x14 */
+	"Pentium 4 HT",
+	NULL,
+	NULL,			/* 0x17 */
+	"Duron",
+	"K5",
+	"K6",
+	"K6-2",
+	"K6-3",
+	"Athlon",
+	"AMD2900",
+	"K6-2+",
+	"Power PC",
+	"Power PC 601",
+	"Power PC 603",
+	"Power PC 603+",
+	"Power PC 604",
+	"Power PC 620",
+	"Power PC x704",
+	"Power PC 750",
+	"Core 2 Duo",		/* 0x28 */
+	"Core 2 Duo Mobile",
+	"Core Solo Mobile",
+	"Atom",
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x2F */
+	"Alpha",
+	"Alpha 21064",
+	"Alpha 21066",
+	"Alpha 21164",
+	"Alpha 21164PC",
+	"Alpha 21164a",
+	"Alpha 21264",
+	"Alpha 21364",
+	NULL,			/* 0x38 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x3F */
+	"MIPS",
+	"MIPS R4000",
+	"MIPS R4200",
+	"MIPS R4400",
+	"MIPS R4600",
+	"MIPS R10000",
+	NULL,			/* 0x46 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x4F */
+	"SPARC",
+	"SuperSPARC",
+	"MicroSPARC II",
+	"MicroSPARC IIep",
+	"UltraSPARC",
+	"UltraSPARC II",
+	"UltraSPARC IIi",
+	"UltraSPARC III",
+	"UltraSPARC IIIi",
+	NULL,			/* 0x59 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x5F */
+	"68040",
+	"68xxx",
+	"68000",
+	"68010",
+	"68020",
+	"68030",
+	NULL,			/* 0x66 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x6F */
+	"Hobbit",
+	NULL,			/* 0x71 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x77 */
+	"Crusoe TM5000",
+	"Crusoe TM3000",
+	"Efficeon TM8000",
+	NULL,			/* 0x7B */
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x7F */
+	"Weitek",
+	NULL,			/* 0x81 */
+	"Itanium",
+	"Athlon 64",
+	"Opteron",
+	"Sempron",
+	"Turion 64",		/* 0x86 */
+	"Dual-Core Opteron",
+	"Atlhon 64 X2",
+	"Turion 64 X2",
+	"Quad-Core Opteron",
+	"Third-Generation Opteron",
+	"Phenom FX",
+	"Phenom X4",
+	"Phenom X2",
+	"Athlon X2",		/* 0x8F */
+	"PA-RISC",
+	"PA-RISC 8500",
+	"PA-RISC 8000",
+	"PA-RISC 7300LC",
+	"PA-RISC 7200",
+	"PA-RISC 7100LC",
+	"PA-RISC 7100",
+	NULL,			/* 0x97 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0x9F */
+	"V30",
+	"Quad-Core Xeon 3200",	/* 0xA1 */
+	"Dual-Core Xeon 3000",
+	"Quad-Core Xeon 5300",
+	"Dual-Core Xeon 5100",
+	"Dual-Core Xeon 5000",
+	"Dual-Core Xeon LV",
+	"Dual-Core Xeon ULV",
+	"Dual-Core Xeon 7100",
+	"Quad-Core Xeon 5400",
+	"Quad-Core Xeon",	/* 0xAA */
+	"Dual-Core Xeon 5200",
+	"Dual-Core Xeon 7200",
+	"Quad-Core Xeon 7300",
+	"Quad-Core Xeon 7400",
+	"Multi-Core Xeon 7400",			/* 0xAF */
+	"Pentium III Xeon",
+	"Pentium III Speedstep",
+	"Pentium 4",
+	"Xeon",
+	"AS400",
+	"Xeon MP",
+	"Athlon XP",
+	"Athlon MP",
+	"Itanium 2",
+	"Pentium M",
+	"Celeron D",		/* 0xBA */
+	"Pentium D",
+	"Pentium EE",
+	"Core Solo",		/* 0xBD */
+	NULL,
+	"Core 2 Duo",
+	"Core 2 Solo",
+	"Core 2 Extreme",
+	"Core 2 Quad",
+	"Core 2 Extreme Mobile",
+	"Core 2 Duo Mobile",
+	"Core 2 Solo Mobile",
+	"Core i7",
+	"Dual-Core Celeron",		/* 0xC7 */
+	"IBM390",
+	"G4",
+	"G5",
+	"ESA/390 G6",		/* 0xCB */
+	"z/Architectur",
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/*0xD0 */
+	NULL,
+	"C7-M",
+	"C7-D",
+	"C7",
+	"Eden",
+	"Multi-Core Xeon",			/*0xD6 */
+	"Dual-Core Xeon 3xxx",
+	"Quad-Core Xeon 3xxx",  /*0xD8 */
+	NULL,
+	"Dual-Core Xeon 5xxx", /*0xDA */
+	"Quad-Core Xeon 5xxx",
+	NULL,
+	"Dual-Core Xeon 7xxx", /*0xDD */
+	"Quad-Core Xeon 7xxx",
+	"Multi-Core Xeon 7xxx",
+	NULL,			/*0xE0 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"Embedded Opteron Quad-Core",	/* 0xE6 */
+	"Phenom Triple-Core",
+	"Turion Ultra Dual-Core Mobile",
+	"Turion Dual-Core Mobile",
+	"Athlon Dual-Core",
+	"Sempron SI",		/*0xEB */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,			/* 0xF9 */
+	"i860",
+	"i960",
+	NULL,			/* 0xFC */
+	NULL,
+	NULL,
+	NULL,			/* 0xFF */
+    };
+    /* Special case for ambiguous value 0xBE */
+    if (code == 0xBE) {
+	/* Best bet based on manufacturer string */
+	if (strstr(manufacturer, "Intel") != NULL
+	    || strncasecmp(manufacturer, "Intel", 5) == 0)
+	    return "Core 2";
+	if (strstr(manufacturer, "AMD") != NULL
+	    || strncasecmp(manufacturer, "AMD", 3) == 0)
+	    return "K7";
+	return "Core 2 or K7";
+    }
+
+    if (family[code] != NULL) {
+	return family[code];
+    }
+    return out_of_spec;
+}
+
+const char *dmi_processor_status(uint8_t code)
+{
+    static const char *status[] = {
+	"Unknown",		/* 0x00 */
+	"Enabled",
+	"Disabled By User",
+	"Disabled By BIOS",
+	"Idle",			/* 0x04 */
+	"<OUT OF SPEC>",
+	"<OUT OF SPEC>",
+	"Other"			/* 0x07 */
+    };
+
+    if (code <= 0x04)
+	return status[code];
+    if (code == 0x07)
+	return status[0x05];
+    return out_of_spec;
+}
+
+const char *dmi_processor_upgrade(uint8_t code)
+{
+    /* 3.3.5.5 */
+    static const char *upgrade[] = {
+	"Other",		/* 0x01 */
+	"Unknown",
+	"Daughter Board",
+	"ZIF Socket",
+	"Replaceable Piggy Back",
+	"None",
+	"LIF Socket",
+	"Slot 1",
+	"Slot 2",
+	"370-pin Socket",
+	"Slot A",
+	"Slot M",
+	"Socket 423",
+	"Socket A (Socket 462)",
+	"Socket 478",
+	"Socket 754",
+	"Socket 940",
+	"Socket 939"		/* 0x12 */
+	"Socket mPGA604",
+	"Socket LGA771",
+	"Socket LGA775",
+	"Socket S1",
+	"Socket AM2",
+	"Socket F (1207)"
+	"Socket LGA1366"	/* 0x19 */
+    };
+
+    if (code >= 0x01 && code <= 0x19)
+	return upgrade[code - 0x01];
+    return out_of_spec;
+}
+
+void dmi_processor_cache(uint16_t code, const char *level, uint16_t ver,
+			 char *cache)
+{
+    if (code == 0xFFFF) {
+	if (ver >= 0x0203)
+	    sprintf(cache, "Not Provided");
+	else
+	    sprintf(cache, "No %s Cache", level);
+    } else
+	sprintf(cache, "0x%04X", code);
+}
+
+/* Intel AP-485 revision 28, table 5 */
+const char *cpu_flags_strings[PROCESSOR_FLAGS_ELEMENTS] = {
+    "FPU (Floating-point unit on-chip)",	/* 0 */
+    "VME (Virtual mode extension)",
+    "DE (Debugging extension)",
+    "PSE (Page size extension)",
+    "TSC (Time stamp counter)",
+    "MSR (Model specific registers)",
+    "PAE (Physical address extension)",
+    "MCE (Machine check exception)",
+    "CX8 (CMPXCHG8 instruction supported)",
+    "APIC (On-chip APIC hardware supported)",
+    NULL,			/* 10 */
+    "SEP (Fast system call)",
+    "MTRR (Memory type range registers)",
+    "PGE (Page global enable)",
+    "MCA (Machine check architecture)",
+    "CMOV (Conditional move instruction supported)",
+    "PAT (Page attribute table)",
+    "PSE-36 (36-bit page size extension)",
+    "PSN (Processor serial number present and enabled)",
+    "CLFSH (CLFLUSH instruction supported)",
+    NULL,			/* 20 */
+    "DS (Debug store)",
+    "ACPI (ACPI supported)",
+    "MMX (MMX technology supported)",
+    "FXSR (Fast floating-point save and restore)",
+    "SSE (Streaming SIMD extensions)",
+    "SSE2 (Streaming SIMD extensions 2)",
+    "SS (Self-snoop)",
+    "HTT (Hyper-threading technology)",
+    "TM (Thermal monitor supported)",
+    "IA64 (IA64 capabilities)",	/* 30 */
+    "PBE (Pending break enabled)"	/* 31 */
+};
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,452 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer
+ *
+ *   Some parts borrowed from meminfo.c32:
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Some parts borrowed from Linux:
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ *   Interrupt list from Ralf Brown (http://www.cs.cmu.edu/~ralf/files.html)
+ *
+ *   This file is part of Syslinux, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdint.h>
+#include <com32.h>
+#include <string.h>
+#include <memory.h>
+
+const char *const e820_types[] = {
+    "usable",
+    "reserved",
+    "ACPI reclaim",
+    "ACPI NVS",
+    "unusable",
+};
+
+struct e820_ext_entry {
+    struct e820entry std;
+    uint32_t ext_flags;
+} __attribute__ ((packed));
+
+#define SMAP	0x534d4150	/* ASCII "SMAP" */
+
+void get_type(int type, char *type_ptr, int type_ptr_sz)
+{
+    unsigned int real_type = type - 1;
+    if (real_type < sizeof(e820_types) / sizeof(e820_types[0]))
+	strlcpy(type_ptr, e820_types[real_type], type_ptr_sz);
+}
+
+/**
+ *INT 15 - newer BIOSes - GET SYSTEM MEMORY MAP
+ *	AX = E820h
+ *	EAX = 0000E820h
+ *	EDX = 534D4150h ('SMAP')
+ *	EBX = continuation value or 00000000h to start at beginning of map
+ *	ECX = size of buffer for result, in bytes (should be >= 20 bytes)
+ *	ES:DI -> buffer for result (see #00581)
+ *
+ * Return: CF clear if successful
+ *	    EAX = 534D4150h ('SMAP')
+ *	    ES:DI buffer filled
+ *	    EBX = next offset from which to copy or 00000000h if all done
+ *	    ECX = actual length returned in bytes
+ *	CF set on error
+ *	    AH = error code (86h) (see #00496 at INT 15/AH=80h)
+ *
+ * Notes: originally introduced with the Phoenix BIOS v4.0, this function is
+ *	  now supported by most newer BIOSes, since various versions of Windows
+ *	  call it to find out about the system memory
+ *	a maximum of 20 bytes will be transferred at one time, even if ECX is
+ *	  higher; some BIOSes (e.g. Award Modular BIOS v4.50PG) ignore the
+ *	  value of ECX on entry, and always copy 20 bytes
+ *	some BIOSes expect the high word of EAX to be clear on entry, i.e.
+ *	  EAX=0000E820h
+ *	if this function is not supported, an application should fall back
+ *	  to AX=E802h, AX=E801h, and then AH=88h
+ *	the BIOS is permitted to return a nonzero continuation value in EBX
+ *	  and indicate that the end of the list has already been reached by
+ *	  returning with CF set on the next iteration
+ *	this function will return base memory and ISA/PCI memory contiguous
+ *	  with base memory as normal memory ranges; it will indicate
+ *	  chipset-defined address holes which are not in use and motherboard
+ *	  memory-mapped devices, and all occurrences of the system BIOS as
+ *	  reserved; standard PC address ranges will not be reported
+ **/
+void detect_memory_e820(struct e820entry *desc, int size_map, int *size_found)
+{
+    int count = 0;
+    static struct e820_ext_entry buf;	/* static so it is zeroed */
+    void *bounce;
+
+    com32sys_t ireg, oreg;
+    memset(&ireg, 0, sizeof ireg);
+
+    bounce = lmalloc(sizeof buf);
+    if (!bounce)
+	goto out;
+
+    ireg.eax.w[0] = 0xe820;
+    ireg.edx.l = SMAP;
+    ireg.ecx.l = sizeof(struct e820_ext_entry);
+    ireg.edi.w[0] = OFFS(bounce);
+    ireg.es = SEG(bounce);
+
+    /*
+     * Set this here so that if the BIOS doesn't change this field
+     * but still doesn't change %ecx, we're still okay...
+     */
+    memset(&buf, 0, sizeof buf);
+    buf.ext_flags = 1;
+
+    do {
+	memcpy(bounce, &buf, sizeof buf);
+
+	/* Important: %edx and %esi are clobbered by some BIOSes,
+	   so they must be either used for the error output
+	   or explicitly marked clobbered.  Given that, assume there
+	   is something out there clobbering %ebp and %edi, too. */
+	__intcall(0x15, &ireg, &oreg);
+
+	/* Some BIOSes stop returning SMAP in the middle of
+	   the search loop.  We don't know exactly how the BIOS
+	   screwed up the map at that point, we might have a
+	   partial map, the full map, or complete garbage, so
+	   just return failure. */
+	if (oreg.eax.l != SMAP) {
+	    count = 0;
+	    break;
+	}
+
+	if (oreg.eflags.l & EFLAGS_CF || oreg.ecx.l < 20)
+	    break;
+
+	memcpy(&buf, bounce, sizeof buf);
+
+	/*
+	 * ACPI 3.0 added the extended flags support.  If bit 0
+	 * in the extended flags is zero, we're supposed to simply
+	 * ignore the entry -- a backwards incompatible change!
+	 */
+	if (oreg.ecx.l > 20 && !(buf.ext_flags & 1))
+	    continue;
+
+	memcpy(&desc[count], &buf, sizeof buf);
+	count++;
+
+	/* Set continuation value */
+	ireg.ebx.l = oreg.ebx.l;
+    } while (ireg.ebx.l && count < size_map);
+
+out:
+    lfree(bounce);
+    *size_found = count;
+}
+
+/**
+ * detect_memory_e801
+ *
+ *INT 15 - Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
+ *	AX = E801h
+ *
+ * Return: CF clear if successful
+ *	    AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
+ *	    BX = extended memory above 16M, in 64K blocks
+ *	    CX = configured memory 1M to 16M, in K
+ *	    DX = configured memory above 16M, in 64K blocks
+ *	CF set on error
+ *
+ * Notes: supported by the A03 level (6/14/94) and later XPS P90 BIOSes, as well
+ *	as the Compaq Contura, 3/8/93 DESKPRO/i, and 7/26/93 LTE Lite 386 ROM
+ *	BIOS
+ *	supported by AMI BIOSes dated 8/23/94 or later
+ *	on some systems, the BIOS returns AX=BX=0000h; in this case, use CX
+ *	  and DX instead of AX and BX
+ *	this interface is used by Windows NT 3.1, OS/2 v2.11/2.20, and is
+ *	  used as a fall-back by newer versions if AX=E820h is not supported
+ *	this function is not used by MS-DOS 6.0 HIMEM.SYS when an EISA machine
+ *	  (for example with parameter /EISA) (see also MEM F000h:FFD9h), or no
+ *	  Compaq machine was detected, or parameter /NOABOVE16 was given.
+ **/
+int detect_memory_e801(int *mem_size_below_16, int *mem_size_above_16)
+{
+    com32sys_t ireg, oreg;
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0xe801;
+
+    __intcall(0x15, &ireg, &oreg);
+
+    if (oreg.eflags.l & EFLAGS_CF)
+	return -1;
+
+    if (oreg.eax.w[0] > 0x3c00)
+	return -1;		/* Bogus! */
+
+    /* Linux seems to use ecx and edx by default if they are defined */
+    if (oreg.eax.w[0] || oreg.eax.w[0]) {
+	oreg.eax.w[0] = oreg.ecx.w[0];
+	oreg.ebx.w[0] = oreg.edx.w[0];
+    }
+
+    *mem_size_below_16 = oreg.eax.w[0];	/* 1K blocks */
+    *mem_size_above_16 = oreg.ebx.w[0];	/* 64K blocks */
+
+    return 0;
+}
+
+int detect_memory_88(int *mem_size)
+{
+    com32sys_t ireg, oreg;
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0x8800;
+
+    __intcall(0x15, &ireg, &oreg);
+
+    if (oreg.eflags.l & EFLAGS_CF)
+	return -1;
+
+    *mem_size = oreg.eax.w[0];
+    return 0;
+}
+
+/*
+ * Sanitize the BIOS e820 map.
+ *
+ * This code come from the memtest86 project. It have been adjusted to match
+ * the syslinux environement.
+ * Some e820 responses include overlapping entries.  The following 
+ * replaces the original e820 map with a new one, removing overlaps.
+ * 
+ * The following stuff could be merge once the addr_t will be set to 64bits.
+ * syslinux_scan_memory can be used for that purpose 
+ */
+int sanitize_e820_map(struct e820entry *orig_map, struct e820entry *new_bios,
+		      short old_nr)
+{
+    struct change_member {
+	struct e820entry *pbios;	/* pointer to original bios entry */
+	unsigned long long addr;	/* address for this change point */
+    };
+    struct change_member change_point_list[2 * E820MAX];
+    struct change_member *change_point[2 * E820MAX];
+    struct e820entry *overlap_list[E820MAX];
+    struct e820entry biosmap[E820MAX];
+    struct change_member *change_tmp;
+    unsigned long current_type, last_type;
+    unsigned long long last_addr;
+    int chgidx, still_changing;
+    int overlap_entries;
+    int new_bios_entry;
+    int i;
+
+    /*
+       Visually we're performing the following (1,2,3,4 = memory types)...
+       Sample memory map (w/overlaps):
+       ____22__________________
+       ______________________4_
+       ____1111________________
+       _44_____________________
+       11111111________________
+       ____________________33__
+       ___________44___________
+       __________33333_________
+       ______________22________
+       ___________________2222_
+       _________111111111______
+       _____________________11_
+       _________________4______
+
+       Sanitized equivalent (no overlap):
+       1_______________________
+       _44_____________________
+       ___1____________________
+       ____22__________________
+       ______11________________
+       _________1______________
+       __________3_____________
+       ___________44___________
+       _____________33_________
+       _______________2________
+       ________________1_______
+       _________________4______
+       ___________________2____
+       ____________________33__
+       ______________________4_
+     */
+    /* First make a copy of the map */
+    for (i = 0; i < old_nr; i++) {
+	biosmap[i].addr = orig_map[i].addr;
+	biosmap[i].size = orig_map[i].size;
+	biosmap[i].type = orig_map[i].type;
+    }
+
+    /* bail out if we find any unreasonable addresses in bios map */
+    for (i = 0; i < old_nr; i++) {
+	if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+	    return 0;
+    }
+
+    /* create pointers for initial change-point information (for sorting) */
+    for (i = 0; i < 2 * old_nr; i++)
+	change_point[i] = &change_point_list[i];
+
+    /* record all known change-points (starting and ending addresses) */
+    chgidx = 0;
+    for (i = 0; i < old_nr; i++) {
+	change_point[chgidx]->addr = biosmap[i].addr;
+	change_point[chgidx++]->pbios = &biosmap[i];
+	change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
+	change_point[chgidx++]->pbios = &biosmap[i];
+    }
+
+    /* sort change-point list by memory addresses (low -> high) */
+    still_changing = 1;
+    while (still_changing) {
+	still_changing = 0;
+	for (i = 1; i < 2 * old_nr; i++) {
+	    /* if <current_addr> > <last_addr>, swap */
+	    /* or, if current=<start_addr> & last=<end_addr>, swap */
+	    if ((change_point[i]->addr < change_point[i - 1]->addr) ||
+		((change_point[i]->addr == change_point[i - 1]->addr) &&
+		 (change_point[i]->addr == change_point[i]->pbios->addr) &&
+		 (change_point[i - 1]->addr !=
+		  change_point[i - 1]->pbios->addr))
+		) {
+		change_tmp = change_point[i];
+		change_point[i] = change_point[i - 1];
+		change_point[i - 1] = change_tmp;
+		still_changing = 1;
+	    }
+	}
+    }
+
+    /* create a new bios memory map, removing overlaps */
+    overlap_entries = 0;	/* number of entries in the overlap table */
+    new_bios_entry = 0;		/* index for creating new bios map entries */
+    last_type = 0;		/* start with undefined memory type */
+    last_addr = 0;		/* start with 0 as last starting address */
+    /* loop through change-points, determining affect on the new bios map */
+    for (chgidx = 0; chgidx < 2 * old_nr; chgidx++) {
+	/* keep track of all overlapping bios entries */
+	if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) {
+	    /* add map entry to overlap list (> 1 entry implies an overlap) */
+	    overlap_list[overlap_entries++] = change_point[chgidx]->pbios;
+	} else {
+	    /* remove entry from list (order independent, so swap with last) */
+	    for (i = 0; i < overlap_entries; i++) {
+		if (overlap_list[i] == change_point[chgidx]->pbios)
+		    overlap_list[i] = overlap_list[overlap_entries - 1];
+	    }
+	    overlap_entries--;
+	}
+	/* if there are overlapping entries, decide which "type" to use */
+	/* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
+	current_type = 0;
+	for (i = 0; i < overlap_entries; i++)
+	    if (overlap_list[i]->type > current_type)
+		current_type = overlap_list[i]->type;
+	/* continue building up new bios map based on this information */
+	if (current_type != last_type) {
+	    if (last_type != 0) {
+		new_bios[new_bios_entry].size =
+		    change_point[chgidx]->addr - last_addr;
+		/* move forward only if the new size was non-zero */
+		if (new_bios[new_bios_entry].size != 0)
+		    if (++new_bios_entry >= E820MAX)
+			break;	/* no more space left for new bios entries */
+	    }
+	    if (current_type != 0) {
+		new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
+		new_bios[new_bios_entry].type = current_type;
+		last_addr = change_point[chgidx]->addr;
+	    }
+	    last_type = current_type;
+	}
+    }
+    return (new_bios_entry);
+}
+
+/* The following stuff could be merge once the addr_t will be set to 64bits.
+ * syslinux_scan_memory can be used for that purpose */
+unsigned long detect_memsize(void)
+{
+    unsigned long memory_size = 0;
+
+    /* Try to detect memory via e820 */
+    struct e820entry map[E820MAX];
+    int count = 0;
+    detect_memory_e820(map, E820MAX, &count);
+    memory_size = memsize_e820(map, count);
+    if (memory_size > 0)
+	return memory_size;
+
+    /*e820 failed, let's try e801 */
+    int mem_low, mem_high = 0;
+    if (!detect_memory_e801(&mem_low, &mem_high))
+	return mem_low + (mem_high << 6);
+
+    /*e801 failed, let's try e88 */
+    int mem_size = 0;
+    if (!detect_memory_88(&mem_size))
+	return mem_size;
+
+    /* We were enable to detect any kind of memory */
+    return 0;
+}
+
+/* The following stuff could be merge once the addr_t will be set to 64bits.
+ * syslinux_scan_memory can be used for that purpose */
+unsigned long memsize_e820(struct e820entry *e820, int e820_nr)
+{
+    int i, n, nr;
+    unsigned long memory_size = 0;
+    struct e820entry nm[E820MAX];
+
+    /* Clean up, adjust and copy the BIOS-supplied E820-map. */
+    nr = sanitize_e820_map(e820, nm, e820_nr);
+
+    /* If there is not a good 820 map returning 0 to indicate 
+       that we don't have any idea of the amount of ram we have */
+    if (nr < 1 || nr > E820MAX) {
+	return 0;
+    }
+
+    /* Build the memory map for testing */
+    n = 0;
+    for (i = 0; i < nr; i++) {
+	if (nm[i].type == E820_RAM || nm[i].type == E820_ACPI) {
+	    unsigned long long start;
+	    unsigned long long end;
+	    start = nm[i].addr;
+	    end = start + nm[i].size;
+
+	    /* Don't ever use memory between 640 and 1024k */
+	    if (start > RES_START && start < RES_END) {
+		if (end < RES_END) {
+		    continue;
+		}
+		start = RES_END;
+	    }
+	    if (end > RES_START && end < RES_END) {
+		end = RES_START;
+	    }
+	    memory_size += (end >> 12) - ((start + 4095) >> 12);
+	    n++;
+	} else if (nm[i].type == E820_NVS) {
+	    memory_size += nm[i].size >> 12;
+	}
+    }
+    return memory_size * 4;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/vpd/vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/vpd/vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/vpd/vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,103 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "vpd/vpd.h"
+
+int vpd_checksum(char *buf, int len)
+{
+    uint8_t sum = 0;
+    int a;
+
+    for (a = 0; a < len; a++)
+	sum += buf[a];
+    return (sum == 0);
+}
+
+int vpd_decode(s_vpd * vpd)
+{
+    uint8_t buf[16];
+    char *p, *q;
+
+    /* Cleaning structures */
+    memset(&vpd->base_address, 0, sizeof(vpd->base_address));
+    memset(&vpd->bios_build_id, 0, sizeof(vpd->bios_build_id));
+    memset(&vpd->box_serial_number, 0, sizeof(vpd->box_serial_number));
+    memset(&vpd->motherboard_serial_number, 0,
+	   sizeof(vpd->motherboard_serial_number));
+    memset(&vpd->machine_type_model, 0, sizeof(vpd->machine_type_model));
+    memset(&vpd->bios_release_date, 0, sizeof(vpd->bios_release_date));
+    memset(&vpd->default_flash_filename, 0,
+	   sizeof(vpd->default_flash_filename));
+    memset(&vpd->bios_version, 0, sizeof(vpd->bios_version));
+
+    /* Until we found elements in the vpdtable, we consider them as not filled */
+    vpd->filled = false;
+
+    p = (char *)0xF0000;	/* The start address to look at the dmi table */
+    for (q = p; q < p + 0x10000; q += 4) {
+	memcpy(buf, q, 5);
+	if (memcmp(buf, "\252\125VPD", 5) == 0) {
+	    snprintf(vpd->base_address, sizeof(vpd->base_address), "%p", q);
+	    if (q[5] < 0x30)
+		return -ENOVPDTABLE;
+
+	    vpd->filled = true;
+	    /* XSeries have longer records, exact length seems to vary. */
+	    if (!(q[5] >= 0x45 && vpd_checksum(q, q[5]))
+		/* Some Netvista seem to work with this. */
+		&& !(vpd_checksum(q, 0x30))
+		/* The Thinkpad/Thinkcentre checksum does *not* include the first 13 bytes. */
+		&& !(vpd_checksum(q + 0x0D, 0x30 - 0x0D))) {
+		/* A few systems have a bad checksum (xSeries 325, 330, 335
+		   and 345 with early BIOS) but the record is otherwise
+		   valid. */
+		printf("VPD: Bad checksum!\n");
+	    }
+
+	    strlcpy(vpd->bios_build_id, q + 0x0D, 9);
+	    strlcpy(vpd->box_serial_number, q + 0x16, 7);
+	    strlcpy(vpd->motherboard_serial_number, q + 0x1D, 11);
+	    strlcpy(vpd->machine_type_model, q + 0x28, 7);
+
+	    if (q[5] < 0x44)
+		return VPD_TABLE_PRESENT;
+
+	    strlcpy(vpd->bios_release_date, q + 0x30, 8);
+	    strlcpy(vpd->default_flash_filename, q + 0x38, 12);
+
+	    if (q[5] >= 0x46 && q[0x44] != 0x00) {
+		strlcpy(vpd->bios_version, q + 0x44, 255);
+	    }
+
+	    return VPD_TABLE_PRESENT;
+	}
+    }
+    return -ENOVPDTABLE;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_create.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_create.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_create.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,240 @@
+/* JSON Create ZZJSON structures
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef CONFIG_NO_ERROR_MESSAGES
+#define ERROR(x...)
+#else
+#define ERROR(x...)     config->error(config->ehandle, ##x)
+#endif
+#define MEMERROR()      ERROR("out of memory")
+
+static ZZJSON *zzjson_create_templ(ZZJSON_CONFIG *config, ZZJSON_TYPE type) {
+    ZZJSON *zzjson = config->calloc(1, sizeof(ZZJSON));
+    if (!zzjson) MEMERROR();
+    else         zzjson->type = type;
+    return zzjson;
+}
+
+ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config) {
+    return zzjson_create_templ(config, ZZJSON_TRUE);
+}
+
+ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config) {
+    return zzjson_create_templ(config, ZZJSON_FALSE);
+}
+
+ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config) {
+    return zzjson_create_templ(config, ZZJSON_NULL);
+}
+
+ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d) {
+    ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_DOUBLE);
+    if (zzjson)
+        zzjson->value.number.val.dval = d;
+    return zzjson;
+}
+
+ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i) {
+    ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_NEGINT);
+    if (zzjson) {
+        zzjson->type = i<0LL ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
+        zzjson->value.number.val.ival = llabs(i);
+    }
+    return zzjson;
+}
+
+/* sdup mimics strdup, but avoids having another function pointer in config */
+static char *sdup(ZZJSON_CONFIG *config, char *s) {
+    size_t slen = strlen(s)+1;
+    char *scopy = config->malloc(slen);
+
+    if (!scopy) MEMERROR();
+    else        memcpy(scopy, s, slen);
+    return scopy;
+}
+
+ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s) {
+    ZZJSON *zzjson = NULL;
+    char *scopy;
+        
+    if (!(scopy = sdup(config,s))) return zzjson;
+
+    if ((zzjson = zzjson_create_templ(config, ZZJSON_STRING)))
+        zzjson->value.string.string = scopy;
+    else
+        config->free(scopy);
+
+    return zzjson;
+}
+
+ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...) {
+    ZZJSON *zzjson, *retval, *val;
+    va_list ap;
+
+    if (!(zzjson = zzjson_create_templ(config, ZZJSON_ARRAY))) return zzjson;
+    retval = zzjson;
+
+    va_start(ap, config);
+    val = va_arg(ap, ZZJSON *);
+    while (val) {
+        zzjson->value.array.val = val;
+        val = va_arg(ap, ZZJSON *);
+
+        if (val) {
+            ZZJSON *next = zzjson_create_templ(config, ZZJSON_ARRAY);
+            if (!next) {
+                while (retval) {
+                    next = retval->next;
+                    config->free(retval);
+                    retval = next;
+                }
+                break;
+            }
+            zzjson->next = next;
+            zzjson = next;
+        }
+    }
+    va_end(ap);
+    return retval;
+}
+
+ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...) {
+    ZZJSON *zzjson, *retval, *val;
+    char *label, *labelcopy;
+    va_list ap;
+
+    if (!(zzjson = zzjson_create_templ(config, ZZJSON_OBJECT))) return zzjson;
+    retval = zzjson;
+
+    va_start(ap, config);
+    label = va_arg(ap, char *);
+    while (label) {
+        val = va_arg(ap, ZZJSON *);
+        labelcopy = sdup(config, label);
+
+        if (!labelcopy) {
+            zzjson_free(config, retval);
+            retval = NULL;
+            break;
+        }
+
+        zzjson->value.object.label  = labelcopy;
+        zzjson->value.object.val    = val;
+
+        label = va_arg(ap, char *);
+
+        if (label) {
+            ZZJSON *next = zzjson_create_templ(config, ZZJSON_OBJECT);
+            if (!next) {
+                while (retval) {
+                    next = retval->next;
+                    config->free(retval->value.object.label);
+                    config->free(retval);
+                    retval = next;
+                }
+                break;
+            }
+            zzjson->next = next;
+            zzjson = next;
+        }
+    }
+    va_end(ap);
+    return retval;
+}
+
+ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
+                                                    ZZJSON *val) {
+    ZZJSON *zzjson;
+
+    if (!array->value.array.val) { /* empty array */
+        array->value.array.val = val;
+        return array;
+    }
+
+    zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+    if (zzjson) {
+        zzjson->value.array.val = val;
+        zzjson->next = array;
+    }
+    return zzjson;
+}
+
+ZZJSON *zzjson_array_append(ZZJSON_CONFIG *config, ZZJSON *array,
+                                                   ZZJSON *val) {
+    ZZJSON *retval = array, *zzjson;
+
+    if (!array->value.array.val) { /* empty array */
+        array->value.array.val = val;
+        return array;
+    }
+
+    zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+    if (!zzjson) return NULL;
+
+    while (array->next) array = array->next;
+
+    zzjson->value.array.val = val;
+    array->next = zzjson;
+
+    return retval;
+}
+
+ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
+                              char *label, ZZJSON *val) {
+    ZZJSON *zzjson = NULL;
+    char *labelcopy = sdup(config, label);
+
+    if (!labelcopy) return zzjson;
+
+    if (!object->value.object.label) { /* empty object */
+        object->value.object.label  = labelcopy;
+        object->value.object.val    = val;
+        return object;
+    }
+
+    zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+    if (zzjson) {
+        zzjson->value.object.label  = labelcopy;
+        zzjson->value.object.val    = val;
+        zzjson->next = object;
+    } else {
+        config->free(labelcopy);
+    }
+    return zzjson;
+}
+
+ZZJSON *zzjson_object_append(ZZJSON_CONFIG *config, ZZJSON *object,
+                             char *label, ZZJSON *val) {
+    ZZJSON *retval = object, *zzjson = NULL;
+    char *labelcopy = sdup(config, label);
+
+    if (!labelcopy) return zzjson;
+
+    if (!object->value.object.label) { /* empty object */
+        object->value.object.label  = labelcopy;
+        object->value.object.val    = val;
+        return object;
+    }
+
+    zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+    if (!zzjson) {
+        config->free(labelcopy);
+        return NULL;
+    }
+
+    while (object->next) object = object->next;
+
+    zzjson->value.object.label  = labelcopy;
+    zzjson->value.object.val    = val;
+    object->next = zzjson;
+
+    return retval;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_free.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_free.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_free.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/* JSON free
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+
+void zzjson_free(ZZJSON_CONFIG *config, ZZJSON *zzjson) {
+    while (zzjson) {
+        ZZJSON *next;
+        switch(zzjson->type) {
+            case ZZJSON_OBJECT:
+                config->free(zzjson->value.object.label);
+                zzjson_free(config, zzjson->value.object.val);
+                break;
+            case ZZJSON_ARRAY:
+                zzjson_free(config, zzjson->value.array.val);
+                break;
+            case ZZJSON_STRING:
+                config->free(zzjson->value.string.string);
+                break;
+            default:
+                break;
+        }
+        next = zzjson->next;
+        config->free(zzjson);
+        zzjson = next;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_parse.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_parse.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_parse.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,490 @@
+/* JSON Parser
+ * ZZJSON - Copyright (C) 2008-2009 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define GETC()          config->getchar(config->ihandle)
+#define UNGETC(c)       config->ungetchar(c, config->ihandle)
+#define SKIPWS()        skipws(config)
+#ifdef CONFIG_NO_ERROR_MESSAGES
+#define ERROR(x...)
+#else
+#define ERROR(x...)     config->error(config->ehandle, ##x)
+#endif
+#define MEMERROR()      ERROR("out of memory")
+
+#define ALLOW_EXTRA_COMMA    (config->strictness & ZZJSON_ALLOW_EXTRA_COMMA)
+#define ALLOW_ILLEGAL_ESCAPE (config->strictness & ZZJSON_ALLOW_ILLEGAL_ESCAPE)
+#define ALLOW_CONTROL_CHARS  (config->strictness & ZZJSON_ALLOW_CONTROL_CHARS)
+#define ALLOW_GARBAGE_AT_END (config->strictness & ZZJSON_ALLOW_GARBAGE_AT_END)
+#define ALLOW_COMMENTS       (config->strictness & ZZJSON_ALLOW_COMMENTS)
+
+static ZZJSON *parse_array(ZZJSON_CONFIG *config);
+static ZZJSON *parse_object(ZZJSON_CONFIG *config);
+
+static void skipws(ZZJSON_CONFIG *config) {
+    int d, c = GETC();
+morews:
+    while (isspace(c)) c = GETC();
+    if (!ALLOW_COMMENTS) goto endws;
+    if (c != '/') goto endws;
+    d = GETC();
+    if (d != '*') goto endws; /* pushing back c will generate a parse error */
+    c = GETC();
+morecomments:
+    while (c != '*') {
+        if (c == EOF) goto endws;
+        c = GETC();
+    }
+    c = GETC();
+    if (c != '/') goto morecomments;
+    c = GETC();
+    if (isspace(c) || c == '/') goto morews;
+endws:
+    UNGETC(c);
+}
+
+static char *parse_string(ZZJSON_CONFIG *config) {
+    unsigned int len = 16, pos = 0;
+    int c;
+    char *str = NULL;
+
+    SKIPWS();
+    c = GETC();
+    if (c != '"') {
+        ERROR("string: expected \" at the start");
+        return NULL;
+    }
+
+    str = config->malloc(len);
+    if (!str) {
+        MEMERROR();
+        return NULL;
+    }
+    c = GETC();
+    while (c > 0 && c != '"') {
+        if (!ALLOW_CONTROL_CHARS && c >= 0 && c <= 31) {
+            ERROR("string: control characters not allowed");
+            goto errout;
+        }
+        if (c == '\\') {
+            c = GETC();
+            switch (c) {
+                case 'b': c = '\b'; break;
+                case 'f': c = '\f'; break;
+                case 'n': c = '\n'; break;
+                case 'r': c = '\r'; break;
+                case 't': c = '\t'; break;
+                case 'u': {
+                    UNGETC(c);    /* ignore \uHHHH, copy verbatim */
+                    c = '\\';
+                    break;
+                }
+                case '\\': case '/': case '"':
+                          break;
+                default:
+                    if (!ALLOW_ILLEGAL_ESCAPE) {
+                        ERROR("string: illegal escape character");
+                        goto errout;
+                    }
+            }
+        }
+        str[pos++] = c;
+        if (pos == len-1) {
+            void *tmp = str;
+            len *= 2;
+            str = config->realloc(str, len);
+            if (!str) {
+                MEMERROR();
+                str = tmp;
+                goto errout;
+            }
+        }
+        c = GETC();
+    }
+    if (c != '"') {
+        ERROR("string: expected \" at the end");
+        goto errout;
+    }
+    str[pos] = 0;
+    return str;
+
+errout:
+    config->free(str);
+    return NULL;
+}
+
+static ZZJSON *parse_string2(ZZJSON_CONFIG *config) {
+    ZZJSON *zzjson = NULL;
+    char *str;
+
+    str = parse_string(config);
+    if (str) {
+        zzjson = config->calloc(1, sizeof(ZZJSON));
+        if (!zzjson) {
+            MEMERROR();
+            config->free(str);
+            return NULL;
+        }
+        zzjson->type = ZZJSON_STRING;
+        zzjson->value.string.string = str;
+    }
+    return zzjson;
+}
+
+static ZZJSON *parse_number(ZZJSON_CONFIG *config) {
+    ZZJSON *zzjson;
+    unsigned long long ival = 0, expo = 0;
+    double dval = 0.0, frac = 0.0, fracshft = 10.0;
+    int c, dbl = 0, sign = 1, signexpo = 1;
+
+    SKIPWS();
+    c = GETC();
+    if (c == '-') {
+        sign = -1;
+        c = GETC();
+    }
+    if (c == '0') {
+        c = GETC();
+        goto skip;
+    }
+
+    if (!isdigit(c)) {
+        ERROR("number: digit expected");
+        return NULL;
+    }
+
+    while (isdigit(c)) {
+        ival *= 10;
+        ival += c - '0';
+        c = GETC();
+    }
+
+skip:
+    if (c != '.') goto skipfrac;
+
+    dbl = 1;
+
+    c = GETC();
+    if (!isdigit(c)) {
+        ERROR("number: digit expected");
+        return NULL;
+    }
+
+    while (isdigit(c)) {
+        frac += (double)(c - '0') / fracshft;
+        fracshft *= 10.0;
+        c = GETC();
+    }
+
+skipfrac:
+    if (c != 'e' && c != 'E') goto skipexpo;
+
+    dbl = 1;
+
+    c = GETC();
+    if (c == '+')
+        c = GETC();
+    else if (c == '-') {
+        signexpo = -1;
+        c = GETC();
+    }
+
+    if (!isdigit(c)) {
+        ERROR("number: digit expected");
+        return NULL;
+    }
+
+    while (isdigit(c)) {
+        expo *= 10;
+        expo += c - '0';
+        c = GETC();
+    }
+
+skipexpo:
+    UNGETC(c);
+
+    if (dbl) {
+        dval = sign * (long long) ival;
+        dval += sign * frac;
+        dval *= pow(10.0, (double) signexpo * expo);
+    }
+
+    zzjson = config->calloc(1, sizeof(ZZJSON));
+    if (!zzjson) {
+        MEMERROR();
+        return NULL;
+    }
+    if (dbl) {
+        zzjson->type = ZZJSON_NUMBER_DOUBLE;
+        zzjson->value.number.val.dval = dval;
+    } else {
+        zzjson->type = sign < 0 ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
+        zzjson->value.number.val.ival = ival;
+    }
+    
+    return zzjson;
+}
+
+static ZZJSON *parse_literal(ZZJSON_CONFIG *config, char *s, ZZJSON_TYPE t) {
+    char b[strlen(s)+1];
+    unsigned int i;
+
+    for (i=0; i<strlen(s); i++) b[i] = GETC();
+    b[i] = 0;
+
+    if (!strcmp(b,s)) {
+        ZZJSON *zzjson;
+        zzjson = config->calloc(1, sizeof(ZZJSON));
+        if (!zzjson) {
+            MEMERROR();
+            return NULL;
+        }
+        zzjson->type = t;
+        return zzjson;
+    }
+    ERROR("literal: expected %s", s);
+    return NULL;
+}
+
+static ZZJSON *parse_true(ZZJSON_CONFIG *config) {
+    return parse_literal(config, (char *)"true", ZZJSON_TRUE);
+}
+
+static ZZJSON *parse_false(ZZJSON_CONFIG *config) {
+    return parse_literal(config, (char *)"false", ZZJSON_FALSE);
+}
+
+static ZZJSON *parse_null(ZZJSON_CONFIG *config) {
+    return parse_literal(config, (char *)"null", ZZJSON_NULL);
+}
+
+static ZZJSON *parse_value(ZZJSON_CONFIG *config) {
+    ZZJSON *retval = NULL;
+    int c;
+
+    SKIPWS();
+    c = GETC();
+    UNGETC(c);
+    switch (c) {
+        case '"':   retval = parse_string2(config); break;
+        case '0': case '1': case '2': case '3': case '4': case '5':
+        case '6': case '7': case '8': case '9': case '-':
+                    retval = parse_number(config); break;
+        case '{':   retval = parse_object(config); break;
+        case '[':   retval = parse_array(config); break;
+        case 't':   retval = parse_true(config); break;
+        case 'f':   retval = parse_false(config); break;
+        case 'n':   retval = parse_null(config); break;
+    }
+
+    if (!retval) {
+        ERROR("value: invalid value");
+        return retval;
+    }
+
+    return retval;
+}
+
+static ZZJSON *parse_array(ZZJSON_CONFIG *config) {
+    ZZJSON *retval = NULL, **next = &retval;
+    int c;
+
+    SKIPWS();
+    c = GETC();
+    if (c != '[') {
+        ERROR("array: expected '['");
+        return NULL;
+    }
+
+    SKIPWS();
+    c = GETC();
+    while (c > 0 && c != ']') {
+        ZZJSON *zzjson = NULL, *val = NULL;
+
+        UNGETC(c);
+
+        SKIPWS();
+        val = parse_value(config);
+        if (!val) {
+            ERROR("array: value expected");
+            goto errout;
+        }
+
+        SKIPWS();
+        c = GETC();
+        if (c != ',' && c != ']') {
+            ERROR("array: expected ',' or ']'");
+errout_with_val:
+            zzjson_free(config, val);
+            goto errout;
+        }
+        if (c == ',') {
+            SKIPWS();
+            c = GETC();
+            if (c == ']' && !ALLOW_EXTRA_COMMA) {
+                ERROR("array: expected value after ','");
+                goto errout_with_val;
+            }
+        }
+        UNGETC(c);
+
+        zzjson = config->calloc(1, sizeof(ZZJSON));
+        if (!zzjson) {
+            MEMERROR();
+            zzjson_free(config, val);
+            goto errout_with_val;
+        }
+        zzjson->type            = ZZJSON_ARRAY;
+        zzjson->value.array.val = val;
+        *next = zzjson;
+        next = &zzjson->next;
+
+        c = GETC();
+    }
+
+    if (c != ']') {
+        ERROR("array: expected ']'");
+        goto errout;
+    }
+
+    if (!retval) {  /* empty array, [ ] */
+        retval = config->calloc(1, sizeof(ZZJSON));
+        if (!retval) {
+            MEMERROR();
+            return NULL;
+        }
+        retval->type = ZZJSON_ARRAY;
+    }
+            
+    return retval;
+
+errout:
+    zzjson_free(config, retval);
+    return NULL;
+}
+
+static ZZJSON *parse_object(ZZJSON_CONFIG *config) {
+    ZZJSON *retval = NULL;
+    int c;
+    ZZJSON **next = &retval;
+
+    SKIPWS();
+    c = GETC();
+    if (c != '{') {
+        ERROR("object: expected '{'");
+        return NULL;
+    }
+
+    SKIPWS();
+    c = GETC();
+    while (c > 0 && c != '}') {
+        ZZJSON *zzjson = NULL, *val = NULL;
+        char *str;
+
+        UNGETC(c);
+
+        str = parse_string(config);
+        if (!str) {
+            ERROR("object: expected string");
+errout_with_str:
+            config->free(str);
+            goto errout;
+        }
+
+        SKIPWS();
+        c = GETC();
+        if (c != ':') {
+            ERROR("object: expected ':'");
+            goto errout_with_str;
+        }
+
+        SKIPWS();
+        val = parse_value(config);
+        if (!val) {
+            ERROR("object: value expected");
+            goto errout_with_str;
+        }
+
+        SKIPWS();
+        c = GETC();
+        if (c != ',' && c != '}') {
+            ERROR("object: expected ',' or '}'");
+errout_with_str_and_val:
+            zzjson_free(config, val);
+            goto errout_with_str;
+        }
+        if (c == ',') {
+            SKIPWS();
+            c = GETC();
+            if (c == '}' && !ALLOW_EXTRA_COMMA) {
+                ERROR("object: expected pair after ','");
+                goto errout_with_str_and_val;
+            }
+        }
+        UNGETC(c);
+
+        zzjson = config->calloc(1, sizeof(ZZJSON));
+        if (!zzjson) {
+            MEMERROR();
+            goto errout_with_str_and_val;
+        }
+        zzjson->type                = ZZJSON_OBJECT;
+        zzjson->value.object.label  = str;
+        zzjson->value.object.val    = val;
+        *next = zzjson;
+        next = &zzjson->next;
+
+        c = GETC();
+    }
+
+    if (c != '}') {
+        ERROR("object: expected '}'");
+        goto errout;
+    }
+
+    if (!retval) {  /* empty object, { } */
+        retval = config->calloc(1, sizeof(ZZJSON));
+        if (!retval) {
+            MEMERROR();
+            return NULL;
+        }
+        retval->type = ZZJSON_OBJECT;
+    }
+            
+    return retval;
+
+errout:
+    zzjson_free(config, retval);
+    return NULL;
+}
+
+ZZJSON *zzjson_parse(ZZJSON_CONFIG *config) {
+    ZZJSON *retval;
+    int c;
+
+    SKIPWS();   
+    c = GETC();
+    UNGETC(c);
+    if (c == '[')       retval = parse_array(config);
+    else if (c == '{')  retval = parse_object(config);
+    else                { ERROR("expected '[' or '{'"); return NULL; }
+
+    if (!retval) return NULL;
+
+    SKIPWS();
+    c = GETC();
+    if (c >= 0 && !ALLOW_GARBAGE_AT_END) {
+        ERROR("parse: garbage at end of file");
+        zzjson_free(config, retval);
+        return NULL;
+    }
+
+    return retval;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_print.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_print.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_print.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,110 @@
+/* JSON Printer
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+
+#define PRINT(fmt...) if (config->print(config->ohandle, ##fmt) < 0) return -1;
+//#define PUTC(c)       if (config->putchar(c, config->ohandle) < 0) return -1;
+#define PUTC(c)       PRINT("%c",c)
+#define INC 4
+
+static int print_string(ZZJSON_CONFIG *config, char *s) {
+    int c, bs;
+    if (!s) return 0;
+    while ((c = *s++)) {
+        bs = 1;
+        switch (c) {
+//            case '/':                 // useless escape of forward slash
+            case '\\':
+                if (*s == 'u') bs = 0;  // copy \uHHHH verbatim
+                break;
+            case '"':               break;
+            case '\b':  c = 'b';    break;
+            case '\f':  c = 'f';    break;
+            case '\n':  c = 'n';    break;
+            case '\r':  c = 'r';    break;
+            case '\t':  c = 't';    break;
+            default:    bs = 0;     break;
+        }
+        if (bs) PUTC('\\');
+        PUTC(c);
+    }
+    return 0;
+}
+
+static int zzjson_print2(ZZJSON_CONFIG *config, ZZJSON *zzjson,
+                 unsigned int indent, unsigned int objval) {
+    char c = 0, d = 0;
+    if (!zzjson) return -1;
+
+    switch(zzjson->type) {
+        case ZZJSON_OBJECT: c = '{'; d = '}'; break;
+        case ZZJSON_ARRAY:  c = '['; d = ']'; break;
+        default: break;
+    }
+
+    if (c) PRINT("%s%*s%c", indent ? "\n" : "", indent, "", c);
+
+    while (zzjson) {
+        switch(zzjson->type) {
+        case ZZJSON_OBJECT:
+            if (zzjson->value.object.val) {
+                PRINT("\n%*s\"", indent+INC, "");
+                if (print_string(config, zzjson->value.object.label) < 0)
+                    return -1;
+                PRINT("\" :");
+                if (zzjson_print2(config, zzjson->value.object.val,
+                                                indent+INC, 1) < 0) return -1;
+            }
+            break;
+        case ZZJSON_ARRAY:
+            if (zzjson->value.array.val)
+                if (zzjson_print2(config, zzjson->value.array.val,
+                                                indent+INC, 0) < 0) return -1;
+            break;
+        case ZZJSON_STRING:
+            PRINT(objval ? " \"" : "\n%*s\"", indent, "");
+            if (print_string(config, zzjson->value.string.string)<0) return -1;
+            PUTC('"');
+            break;
+        case ZZJSON_FALSE:
+            PRINT(objval ? " false" : "\n%*sfalse", indent, "");
+            break;
+        case ZZJSON_NULL:
+            PRINT(objval ? " null" : "\n%*snull", indent, "");
+            break;
+        case ZZJSON_TRUE:
+            PRINT(objval ? " true" : "\n%*strue", indent, "");
+            break;
+        case ZZJSON_NUMBER_NEGINT:
+        case ZZJSON_NUMBER_POSINT:
+        case ZZJSON_NUMBER_DOUBLE:
+            PRINT(objval ? " " : "\n%*s", indent, "");
+            if (zzjson->type == ZZJSON_NUMBER_DOUBLE) {
+                PRINT("%16.16e", zzjson->value.number.val.dval);
+            } else {
+                if (zzjson->type == ZZJSON_NUMBER_NEGINT) PUTC('-');
+                PRINT("%llu", zzjson->value.number.val.ival);
+            }
+        default:
+            break;
+        }
+        zzjson = zzjson->next;
+        if (zzjson) PUTC(',');
+    }
+
+    if (d) PRINT("\n%*s%c", indent, "", d);
+
+    return 0;
+}
+
+int zzjson_print(ZZJSON_CONFIG *config, ZZJSON *zzjson) {
+    int retval = zzjson_print2(config, zzjson, 0, 0);
+//    if (retval >= 0) retval = config->putchar('\n', config->ohandle);
+#ifndef CONFIG_NO_ERROR_MESSAGES
+    if (retval <  0) config->error(config->ehandle, "print: unable to print");
+#endif
+    return retval;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_query.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_query.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/gpllib/zzjson/zzjson_query.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/* JSON query
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <string.h>
+#include <stdarg.h>
+
+ZZJSON *zzjson_object_find_label(ZZJSON *zzjson, char *label) {
+    if (zzjson->type != ZZJSON_OBJECT) return NULL;
+
+    while (zzjson) {
+        char *string = zzjson->value.object.label;
+
+        if (zzjson->type != ZZJSON_OBJECT) return NULL;
+        if (!string)                       return NULL;
+
+        if (!strcmp(string, label))
+            return zzjson->value.object.val;
+        zzjson = zzjson->next;
+    }
+    return NULL;
+}
+
+ZZJSON *zzjson_object_find_labels(ZZJSON *zzjson, ...) {
+    va_list ap;
+    char *lbl;
+
+    va_start(ap, zzjson);
+    lbl = va_arg(ap, char *);
+    while (lbl) {
+        zzjson = zzjson_object_find_label(zzjson, lbl);
+        if (!zzjson) break;
+        lbl = va_arg(ap, char *);
+    }
+    va_end(ap);
+
+    return zzjson;
+}
+
+unsigned int zzjson_object_count(ZZJSON *zzjson) {
+    unsigned int count = 1;
+
+    if (zzjson->type != ZZJSON_OBJECT) return 0;
+    if (!zzjson->value.object.label)   return 0; /* empty { } */
+
+    while ((zzjson = zzjson->next)) count++;
+
+    return count;
+}
+
+unsigned int zzjson_array_count(ZZJSON *zzjson) {
+    unsigned int count = 1;
+
+    if (zzjson->type != ZZJSON_ARRAY) return 0;
+    if (!zzjson->value.array.val)     return 0; /* empty [ ] */
+
+    while ((zzjson = zzjson->next)) count++;
+
+    return count;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,149 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Hardware Detection Tool
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LIBS      = $(objdir)/com32/libupload/libcom32upload.a
+C_LIBS    += $(objdir)/com32/cmenu/libmenu/libmenu.c32
+CFLAGS    += -I$(com32)/cmenu/libmenu -I$(com32)
+
+MODULES	  = hdt.c32
+TESTFILES =
+
+OBJS	  = $(subst $(SRC)/,,$(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
+VERSION   = $(shell $(SED) -n 's/\#define VERSION \"\(.*\)\"/\1/p' hdt.h)
+CODENAME  = $(shell $(SED) -n 's/\#define CODENAME \"\(.*\)\"/\1/p' hdt.h)
+NODASH_VERSION = $(shell echo $(VERSION) | $(SED) -e 's/-/_/g' | $(SED) -e 's/\./_/g')
+SUM_FILE  = hdt-$(VERSION).checksums
+
+MEMTEST_URL = http://memtest.org/download/4.20/memtest86+-4.20.bin
+MEMTEST     = memtest.bin
+
+KERNEL_VERSION          ?= $(shell uname -r)
+MODULES_ALIAS_FILE      ?= /lib/modules/$(KERNEL_VERSION)/modules.alias
+GZ_MODULES_ALIAS_FILE   ?= modules.alias.gz
+MODULES_PCIMAP_FILE     ?= /lib/modules/$(KERNEL_VERSION)/modules.pcimap
+GZ_MODULES_PCIMAP_FILE  ?= modules.pcimap.gz
+ISO_DIR                 ?= iso
+ISOLINUX_DIR            ?= isolinux
+FLOPPY_DIR		?= floppy
+PCI_IDS_FILE            ?= $(PWD)/$(FLOPPY_DIR)/pci.ids
+GZ_PCI_IDS_FILE         ?= $(PCI_IDS_FILE).gz
+MENU_COM32              ?= $(com32)/menu/menu.c32
+CHAIN_COM32             ?= $(com32)/chain/chain.c32
+ART_DIR                 ?= art/
+QEMU			?= qemu-kvm
+
+all: $(MODULES) $(TESTFILES)
+
+hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+memtest:
+	-[ ! -f $(FLOPPY_DIR)/$(MEMTEST) ] && $(WGET) $(MEMTEST_URL) -O $(FLOPPY_DIR)/$(MEMTEST)
+
+hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtools/syslinux $(MENU_COM32) memtest $(CHAIN_COM32)
+	rm -f hdt*.img
+	$(SED) -e 's/%VERSION%/$(VERSION)/g' $(FLOPPY_DIR)/hdt.cfg |\
+	$(SED) -e 's/%CODENAME%/$(CODENAME)/g' > $(FLOPPY_DIR)/syslinux.cfg
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MFORMAT) -v HDT_$(NODASH_VERSION) -f 1440 -C a:
+	$(topdir)/mtools/syslinux hdt.img
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ -f $(MODULES_ALIAS_FILE) ] &&  cat $(MODULES_ALIAS_FILE) | $(GZIPPROG) - -f | MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) - a:modules.alias
+	-[ -f $(MODULES_PCIMAP_FILE) ] && cat $(MODULES_PCIMAP_FILE) | $(GZIPPROG) - -f | MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) - a:modules.pcimap
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) hdt.c32 a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(MENU_COM32) a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(CHAIN_COM32) a:
+	@ [ -f $(GZ_PCI_IDS_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(GZ_PCI_IDS_FILE) a:pci.ids || printf "\nThe $(GZ_PCI_IDS_FILE) file is missing and can be downloaded from http://pciids.sourceforge.net and gzipped in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/syslinux.cfg a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/$(MEMTEST) a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/backgnd.png a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/display.png a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/red.png a:
+	mv hdt.img hdt-$(VERSION).img
+	ln -sf hdt-$(VERSION).img hdt.img
+
+hdt.img.gz: hdt.img
+	rm -rf hdt*.img.gz
+	$(GZIPPROG) -c hdt-$(VERSION).img >hdt-$(VERSION).img.gz
+	ln -sf hdt-$(VERSION).img.gz hdt.img.gz
+
+hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg memtest
+	rm -rf $(ISO_DIR)
+	rm -f hdt.iso
+	mkdir -p $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(topdir)/core/isolinux.bin $(ISO_DIR)/$(ISOLINUX_DIR)
+	$(SED) -e 's/%VERSION%/$(VERSION)/g' $(FLOPPY_DIR)/hdt.cfg |\
+		$(SED) -e 's/%CODENAME%/$(CODENAME)/g' > $(ISO_DIR)/$(ISOLINUX_DIR)/isolinux.cfg
+	cp hdt.c32 $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(FLOPPY_DIR)/$(MEMTEST) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(MENU_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(CHAIN_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/backgnd.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/display.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/red.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ -f $(MODULES_ALIAS_FILE) ] && cp $(MODULES_ALIAS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)\
+	       	&& $(GZIPPROG) $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias\
+		&& mv $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias.gz $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias
+	-[ -f $(MODULES_PCIMAP_FILE) ] && cp $(MODULES_PCIMAP_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)\
+		&& $(GZIPPROG) $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap\
+		&& mv $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap.gz $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap
+	-[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids.gz ] && cp $(GZ_PCI_IDS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids
+	-[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids ] && printf "\nThe $(FLOPPY_DIR)/pci.ids file is missing and can be downloaded from http://pciids.sourceforge.net and put in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+	$(MKISOFS) -o hdt.iso -b $(ISOLINUX_DIR)/isolinux.bin -c $(ISOLINUX_DIR)/boot.cat \
+		-no-emul-boot -boot-load-size 4 -boot-info-table \
+		$(ISO_DIR)
+	mv hdt.iso hdt-$(VERSION).iso
+	ln -sf hdt-$(VERSION).iso hdt.iso
+
+hdt-hybrid.iso: hdt.iso ../../utils/isohybrid
+	cp hdt-$(VERSION).iso hdt-hybrid-$(VERSION).iso
+	../../utils/isohybrid --partok hdt-hybrid-$(VERSION).iso
+	ln -sf hdt-hybrid-$(VERSION).iso hdt-hybrid.iso
+
+release: spotless hdt.c32 hdt.img hdt.img.gz hdt.iso hdt-hybrid.iso
+	mv hdt.c32 hdt_$(NODASH_VERSION).c32
+	md5sum hdt_$(NODASH_VERSION).c32 >$(SUM_FILE)
+	md5sum hdt-$(VERSION).iso >>$(SUM_FILE)
+	md5sum hdt-hybrid-$(VERSION).iso >>$(SUM_FILE)
+	md5sum hdt-$(VERSION).img >>$(SUM_FILE)
+	md5sum hdt-$(VERSION).img.gz >>$(SUM_FILE)
+
+test: hdt.img
+	$(QEMU) -fda hdt.img
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com hdt*.img hdt*.iso hdt*.img.gz
+	rm -rf $(ISO_DIR)
+	rm -rf $(FLOPPY_DIR)/$(MEMTEST)
+	rm -rf $(FLOPPY_DIR)/pci.ids*
+	rm -rf hdt-*checksums
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+--------------
+Compiling HDT
+--------------
+To build HDT, you just have to do a "make" call in this directory.
+
+---------------------------
+Creating a bootable floppy
+--------------------------
+To build a bootable HDT floppy image, you can do a "make hdt.img" call.
+This will requires the mtools (http://mtools.linux.lu) to be installed.
+The script will try to pick several files from your system :
+- /lib/modules/`uname -r`/modules.alias
+- /lib/modules/`uname -r`/modules.pcimap
+- /usr/share/pci.ids or /usr/share/hwdata/pci.ids
+
+This paths can be overrided with the following command line:
+make MODULES_ALIAS_FILE=$(PWD)/floppy/modules.alias MODULES_PCIMAP_FILE=$(PWD)/floppy/modules.pcimap PCI_IDS_FILE=$(PWD)/floppy/pci.ids hdt.img
+
+If your system doesn't have pci.ids, please download it from http://pciids.sourceforge.net/ and put it into the floppy/ directory.
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="1280px" height="720px" viewBox="0 0 1280 720" enable-background="new 0 0 1280 720" xml:space="preserve">
+<rect fill="#2C3238" width="1280" height="720"/>
+<g>
+	<g>
+		<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="545.0864" y1="489.623" x2="606.1919" y2="489.623">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_1_)" d="M560.927,515.72c0.128,1.287,0.386,2.285,0.771,2.992c0.386,0.707,0.82,1.238,1.303,1.592
+			c0.482,0.354,0.972,0.611,1.471,0.771c0.499,0.16,0.957,0.346,1.375,0.555c0.417,0.209,0.747,0.506,0.989,0.893
+			c0.241,0.385,0.344,0.98,0.312,1.785h-22.044c-0.065-0.869,0.041-1.496,0.313-1.881c0.272-0.387,0.644-0.686,1.11-0.893
+			c0.466-0.209,0.972-0.402,1.519-0.58c0.547-0.176,1.069-0.506,1.568-0.988c0.498-0.482,0.916-1.191,1.254-2.123
+			c0.337-0.932,0.522-2.25,0.555-3.955h0.048v-49.64h-0.048c-0.097-1.445-0.322-2.571-0.675-3.375
+			c-0.355-0.805-0.765-1.407-1.231-1.81c-0.466-0.401-0.965-0.69-1.495-0.867c-0.531-0.177-1.013-0.362-1.448-0.555
+			c-0.434-0.193-0.788-0.467-1.061-0.82c-0.272-0.354-0.393-0.917-0.361-1.688c0-0.064,0-0.12,0-0.17
+			c0-0.047,0.112-0.071,0.337-0.071h21.418c0.16,0,0.248,0.031,0.265,0.097c0.016,0.064,0.023,0.128,0.023,0.192
+			c0,0.74-0.128,1.287-0.386,1.641c-0.258,0.354-0.603,0.627-1.037,0.82c-0.435,0.192-0.901,0.369-1.399,0.53
+			c-0.5,0.161-0.982,0.435-1.447,0.82c-0.466,0.385-0.885,0.956-1.254,1.712c-0.37,0.756-0.603,1.81-0.699,3.16h-0.048V515.72z
+			 M599.807,514.948c0.097,1.447,0.32,2.572,0.675,3.377s0.765,1.408,1.23,1.809c0.466,0.404,0.965,0.691,1.495,0.869
+			c0.53,0.176,1.014,0.361,1.447,0.555c0.435,0.193,0.788,0.475,1.061,0.844c0.273,0.371,0.41,0.941,0.41,1.713
+			c0,0.031-0.007,0.08-0.023,0.145s-0.138,0.096-0.361,0.096c-3.409,0-6.834,0-10.275,0s-7.156-0.016-11.143-0.047
+			c-0.161,0-0.25-0.033-0.265-0.096c-0.017-0.066-0.041-0.131-0.073-0.195c0-0.738,0.137-1.285,0.41-1.639
+			c0.273-0.354,0.619-0.627,1.037-0.82c0.417-0.193,0.885-0.369,1.399-0.531c0.514-0.16,1.004-0.434,1.471-0.82
+			s0.885-0.957,1.254-1.711c0.369-0.758,0.619-1.809,0.748-3.16v-23.493H564.4c-0.708,0-1.085-0.201-1.133-0.602
+			c-0.048-0.404,0.152-0.91,0.603-1.521c0.45-0.611,1.102-1.27,1.954-1.977c0.852-0.707,1.849-1.377,2.991-2.002
+			c1.141-0.627,2.395-1.143,3.762-1.545c1.367-0.402,2.757-0.604,4.172-0.604c1.544,0,2.79,0,3.739,0s1.729,0,2.34,0
+			c0.61,0,1.101-0.008,1.47-0.023c0.37-0.018,0.74-0.031,1.11-0.047c0.369-0.018,0.796-0.033,1.278-0.049
+			c0.482-0.018,1.141-0.041,1.979-0.072c0.643-0.033,1.077-0.217,1.302-0.557c0.224-0.336,0.354-0.617,0.387-0.844l-0.049-18.425
+			c-0.162-1.287-0.427-2.284-0.796-2.991c-0.37-0.707-0.796-1.247-1.278-1.617c-0.482-0.37-0.982-0.627-1.496-0.771
+			c-0.514-0.146-0.973-0.322-1.375-0.53c-0.402-0.211-0.732-0.499-0.989-0.868c-0.258-0.37-0.354-0.974-0.29-1.81l22.093,0.049
+			c0.064,0.867-0.049,1.494-0.338,1.881c-0.289,0.386-0.668,0.674-1.133,0.868c-0.467,0.193-0.974,0.377-1.521,0.554
+			s-1.068,0.5-1.567,0.965c-0.499,0.467-0.916,1.167-1.254,2.099c-0.338,0.934-0.523,2.252-0.555,3.956V514.948z"/>
+	</g>
+	<g>
+		<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="677.4297" y1="509.0273" x2="732.7426" y2="453.7145">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_2_)" d="M734.411,455.47c0.434,0.226,0.587,0.548,0.459,0.965c-0.129,0.419-0.499,0.924-1.109,1.521
+			c-0.611,0.595-1.32,1.245-2.123,1.953c-1.447,1.222-2.99,2.171-4.631,2.846s-3.217,0.981-4.729,0.918h0.05h-14.279v50.698
+			c0.065,1.607,0.266,2.846,0.603,3.715c0.338,0.867,0.74,1.527,1.208,1.979c0.464,0.449,0.964,0.762,1.494,0.939
+			c0.531,0.176,1.013,0.369,1.446,0.578c0.436,0.211,0.788,0.5,1.062,0.867c0.272,0.371,0.379,0.99,0.315,1.859h-9.456h-5.596
+			c-0.74,0-1.464,0-2.171,0s-1.359-0.01-1.953-0.025c-0.596-0.016-1.104-0.023-1.521-0.023c-0.418,0-0.691,0-0.819,0
+			c-0.066-0.869,0.041-1.486,0.314-1.857c0.271-0.369,0.626-0.65,1.061-0.844c0.434-0.193,0.908-0.379,1.422-0.555
+			c0.514-0.178,1.014-0.482,1.496-0.916s0.899-1.07,1.254-1.906c0.354-0.836,0.563-2.041,0.627-3.617v-50.892h-7.525h-15.772
+			c-1.319,0-2.202-0.113-2.654-0.339c-0.449-0.225-0.603-0.546-0.458-0.964c0.145-0.419,0.523-0.916,1.134-1.496
+			c0.611-0.578,1.335-1.238,2.171-1.979c1.446-1.222,2.998-2.17,4.654-2.846s3.225-0.98,4.704-0.916c0.578,0,1.688,0,3.329,0
+			c1.639,0,3.601,0,5.885,0c2.282,0,4.799,0,7.549,0s5.522,0,8.32,0h21.708C733.133,455.133,733.978,455.245,734.411,455.47z"/>
+	</g>
+	<g>
+		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="614.4233" y1="489.5566" x2="671.4414" y2="489.5566">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_3_)" d="M667.872,472.496c1.447,2.51,2.404,5.26,2.869,8.252c0.467,2.99,0.7,6.061,0.7,9.213
+			c0,6.237-1.512,11.931-4.535,17.075c-2.99,5.115-7.268,9.312-12.83,12.592c-2.605,1.512-5.709,2.654-9.311,3.426
+			c-0.933,0.193-1.978,0.369-3.136,0.529c-1.158,0.16-2.276,0.297-3.353,0.41s-2.025,0.201-2.847,0.266
+			c-0.818,0.064-1.357,0.096-1.615,0.096c-0.45,0-0.9-0.006-1.352-0.023c-0.449-0.016-0.674-0.25-0.674-0.699
+			c0-0.289,0.145-0.773,0.434-1.447c0.289-0.676,0.748-1.398,1.375-2.172c0.628-0.77,1.431-1.512,2.413-2.219
+			c0.979-0.707,2.176-1.238,3.593-1.592c1.801-0.643,3.321-1.156,4.559-1.543c1.238-0.385,2.371-0.805,3.4-1.254
+			s2.033-1.014,3.015-1.688c0.98-0.676,2.114-1.609,3.401-2.799c2.604-2.412,4.613-5.209,6.029-8.393
+			c1.415-3.186,2.122-6.739,2.122-10.661c0-1.996-0.104-3.947-0.313-5.863c-0.209-1.912-0.563-3.73-1.061-5.449
+			c-0.5-1.721-1.182-3.33-2.051-4.824s-1.96-2.838-3.279-4.027c-1.094-1.094-2.524-2.1-4.293-3.016s-3.65-1.689-5.645-2.316
+			c-1.995-0.627-4.004-1.116-6.031-1.471c-2.025-0.354-3.851-0.538-5.475-0.555c-1.624-0.016-2.951,0.16-3.979,0.531
+			c-1.03,0.37-1.545,0.957-1.545,1.76l0.049,48.722h0.048v10.951h-14.133c0-0.645,0.12-1.125,0.361-1.449
+			c0.241-0.32,0.538-0.57,0.892-0.746c0.355-0.178,0.741-0.305,1.159-0.387c0.417-0.08,0.812-0.201,1.181-0.361
+			c0.37-0.16,0.692-0.395,0.966-0.699c0.272-0.305,0.458-0.764,0.555-1.375c0-1.865,0-4.115,0-6.752
+			c0-2.639-0.009-5.492-0.024-8.564c-0.018-3.07-0.024-6.254-0.024-9.552c0-3.295,0-6.535,0-9.719s-0.008-6.217-0.023-9.094
+			c-0.017-2.879-0.024-5.443-0.024-7.693c0-2.252,0.008-4.077,0.024-5.476c0.016-1.397,0.023-2.211,0.023-2.436
+			c0.032-1.157,0.596-2.099,1.688-2.823c1.093-0.723,2.468-1.277,4.124-1.663s3.497-0.619,5.523-0.699
+			c2.027-0.08,4.004-0.08,5.935,0c1.929,0.08,3.714,0.218,5.354,0.41c1.641,0.192,2.895,0.401,3.763,0.628
+			c1.479,0.449,3.2,1.091,5.161,1.929c1.961,0.835,3.963,1.929,6.006,3.279c2.043,1.352,4.02,2.967,5.934,4.849
+			C664.888,467.795,666.521,469.99,667.872,472.496z"/>
+	</g>
+</g>
+<g>
+	<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="505.0664" y1="544.8008" x2="510.741" y2="544.8008">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_4_)" d="M509.132,551.499c0.033,0.33,0.099,0.584,0.198,0.766s0.21,0.318,0.334,0.41
+		c0.124,0.09,0.25,0.156,0.378,0.197c0.127,0.041,0.246,0.088,0.353,0.143c0.107,0.055,0.192,0.129,0.253,0.229
+		c0.062,0.1,0.089,0.252,0.081,0.457h-5.658c-0.017-0.221,0.011-0.383,0.08-0.48c0.07-0.1,0.165-0.178,0.286-0.23
+		c0.119-0.053,0.249-0.102,0.39-0.148c0.14-0.045,0.274-0.131,0.402-0.254c0.127-0.123,0.235-0.305,0.322-0.543
+		c0.086-0.242,0.134-0.578,0.143-1.018h0.012v-12.738h-0.012c-0.025-0.371-0.083-0.66-0.174-0.867
+		c-0.091-0.205-0.196-0.359-0.315-0.463c-0.12-0.104-0.248-0.178-0.384-0.223c-0.135-0.045-0.259-0.092-0.371-0.143
+		c-0.111-0.049-0.202-0.121-0.272-0.211c-0.07-0.09-0.101-0.234-0.092-0.432c0-0.018,0-0.033,0-0.045
+		c0-0.014,0.028-0.018,0.086-0.018h5.497c0.041,0,0.063,0.008,0.068,0.023c0.004,0.018,0.006,0.033,0.006,0.051
+		c0,0.189-0.033,0.33-0.099,0.42c-0.066,0.09-0.155,0.162-0.267,0.211c-0.111,0.051-0.231,0.096-0.358,0.135
+		c-0.128,0.043-0.252,0.113-0.372,0.211c-0.12,0.1-0.228,0.246-0.322,0.439c-0.096,0.195-0.155,0.465-0.18,0.812h-0.013V551.499z
+		 M519.11,551.3c0.024,0.371,0.082,0.66,0.173,0.865c0.091,0.209,0.196,0.363,0.316,0.465c0.119,0.104,0.248,0.178,0.384,0.223
+		c0.137,0.047,0.26,0.094,0.371,0.143c0.112,0.051,0.202,0.123,0.272,0.217c0.07,0.096,0.105,0.24,0.105,0.439
+		c0,0.01-0.002,0.021-0.007,0.037c-0.003,0.018-0.035,0.025-0.092,0.025c-0.875,0-1.754,0-2.637,0c-0.883,0-1.836-0.004-2.859-0.014
+		c-0.042,0-0.064-0.006-0.068-0.023c-0.005-0.016-0.011-0.033-0.019-0.049c0-0.191,0.035-0.33,0.104-0.422
+		c0.07-0.09,0.159-0.16,0.267-0.211c0.107-0.049,0.227-0.094,0.359-0.137c0.132-0.039,0.258-0.109,0.378-0.209
+		c0.119-0.1,0.227-0.246,0.322-0.439c0.094-0.193,0.159-0.465,0.192-0.811v-6.029h-6.648c-0.182,0-0.278-0.053-0.292-0.154
+		c-0.012-0.104,0.04-0.234,0.155-0.391c0.115-0.158,0.282-0.326,0.501-0.508c0.218-0.182,0.474-0.354,0.768-0.514
+		c0.292-0.162,0.614-0.291,0.966-0.396c0.35-0.104,0.708-0.154,1.07-0.154c0.396,0,0.716,0,0.96,0c0.243,0,0.443,0,0.6,0
+		s0.283-0.002,0.377-0.008c0.095-0.002,0.19-0.006,0.286-0.01c0.094-0.004,0.204-0.01,0.328-0.014s0.293-0.01,0.508-0.02
+		c0.165-0.006,0.276-0.055,0.334-0.141c0.057-0.088,0.091-0.16,0.099-0.217l-0.012-4.73c-0.042-0.33-0.11-0.586-0.205-0.768
+		s-0.204-0.318-0.328-0.414c-0.124-0.094-0.251-0.16-0.383-0.197c-0.132-0.037-0.25-0.084-0.354-0.137
+		c-0.103-0.053-0.188-0.129-0.253-0.223s-0.091-0.25-0.074-0.465l5.67,0.012c0.017,0.225-0.012,0.385-0.086,0.484
+		c-0.075,0.1-0.171,0.174-0.291,0.223c-0.121,0.049-0.25,0.098-0.391,0.143c-0.14,0.045-0.274,0.127-0.402,0.248
+		c-0.128,0.119-0.236,0.299-0.322,0.537c-0.087,0.24-0.135,0.578-0.143,1.016V551.3z"/>
+	<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="521.4248" y1="547.6602" x2="534.7334" y2="547.6602">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_5_)" d="M533.669,552.858c0.066,0.066,0.142,0.117,0.229,0.148c0.086,0.033,0.177,0.062,0.272,0.082
+		c0.094,0.02,0.183,0.049,0.266,0.086c0.083,0.037,0.15,0.092,0.204,0.162c0.053,0.068,0.085,0.176,0.093,0.314
+		c0,0.033-0.017,0.049-0.049,0.049h-3.318h-0.013v-6.016c0-1.246-0.354-2.27-1.064-3.068c-0.718-0.787-1.646-1.178-2.785-1.178
+		c-1.123,0-2.051,0.389-2.786,1.164c-0.727,0.791-1.089,1.791-1.089,2.996c0,1.246,0.375,2.27,1.126,3.07
+		c0.743,0.791,1.692,1.188,2.847,1.188c0.537,0,1.048-0.09,1.535-0.271c0.248-0.092,0.495-0.205,0.743-0.342
+		c0.247-0.135,0.499-0.299,0.755-0.488v2.328c-0.512,0.279-1.032,0.486-1.56,0.617c-0.272,0.066-0.553,0.115-0.842,0.148
+		c-0.289,0.033-0.582,0.051-0.879,0.051c-0.569,0-1.139-0.086-1.708-0.26c-0.562-0.182-1.073-0.43-1.535-0.742
+		c-0.867-0.604-1.531-1.35-1.994-2.242c-0.462-0.906-0.693-1.91-0.693-3.008c0-1.799,0.57-3.289,1.709-4.469
+		c1.139-1.172,2.587-1.758,4.345-1.758c1.164,0,2.224,0.289,3.182,0.867c0.479,0.287,0.905,0.643,1.282,1.062
+		c0.375,0.422,0.683,0.869,0.922,1.338c0.115,0.23,0.219,0.475,0.31,0.725c0.091,0.252,0.161,0.51,0.21,0.773
+		c0.099,0.562,0.148,1.379,0.148,2.451v3.924C533.557,552.694,533.603,552.794,533.669,552.858z"/>
+	<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="535.335" y1="547.5957" x2="545.2256" y2="547.5957">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_6_)" d="M540.28,541.892c0.627-0.248,1.199-0.379,1.714-0.396c0.516-0.016,0.974,0.035,1.375,0.154
+		c0.399,0.119,0.738,0.281,1.015,0.49c0.276,0.205,0.485,0.41,0.625,0.611c0.14,0.203,0.212,0.379,0.217,0.527
+		c0.004,0.148-0.068,0.221-0.217,0.221c-0.207,0.01-0.398,0.014-0.575,0.014c-0.178,0-0.333,0-0.464,0h-0.434
+		c-0.372,0-0.735,0.016-1.089,0.049c-0.355,0.033-0.692,0.09-1.009,0.168c-0.318,0.08-0.607,0.186-0.866,0.322
+		c-0.261,0.135-0.478,0.307-0.65,0.514c-0.314,0.371-0.557,0.838-0.73,1.398s-0.26,1.242-0.26,2.043v3.641
+		c0.033,0.312,0.09,0.553,0.173,0.725c0.083,0.168,0.18,0.295,0.291,0.383c0.112,0.086,0.225,0.148,0.341,0.186
+		s0.221,0.08,0.316,0.129c0.094,0.051,0.168,0.119,0.223,0.211c0.053,0.09,0.076,0.232,0.067,0.42h-5.001
+		c-0.017-0.197,0.006-0.342,0.068-0.432c0.062-0.092,0.143-0.162,0.241-0.211c0.099-0.051,0.208-0.092,0.328-0.131
+		c0.12-0.035,0.236-0.104,0.347-0.203c0.112-0.1,0.206-0.244,0.285-0.434c0.078-0.189,0.13-0.461,0.154-0.818v-9.828h1.993v1.783
+		C539.137,542.708,539.644,542.196,540.28,541.892z"/>
+	<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="545.4424" y1="545.1094" x2="557.5869" y2="545.1094">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_7_)" d="M546.136,544.8c0.462-0.883,1.135-1.633,2.018-2.252c0.454-0.307,0.965-0.553,1.535-0.744
+		c0.569-0.172,1.143-0.258,1.721-0.258c0.611,0,1.18,0.064,1.708,0.197c0.544,0.139,1.065,0.35,1.56,0.631
+		c-0.173,0.297-0.4,0.549-0.681,0.756c-0.239,0.172-0.553,0.316-0.941,0.432c-0.388,0.117-0.867,0.125-1.436,0.025
+		c-0.272-0.033-0.541-0.025-0.805,0.02s-0.516,0.119-0.755,0.223c-0.239,0.102-0.47,0.232-0.693,0.391
+		c-0.223,0.154-0.425,0.33-0.606,0.518c-0.734,0.77-1.102,1.768-1.102,2.998c0,1.27,0.359,2.301,1.077,3.094
+		c0.718,0.775,1.659,1.164,2.822,1.164c1.131,0,2.055-0.389,2.773-1.164c0.709-0.783,1.064-1.807,1.064-3.07v-10.461
+		c-0.041-0.182-0.124-0.301-0.248-0.359c-0.124-0.059-0.254-0.104-0.39-0.137c-0.137-0.031-0.261-0.084-0.372-0.154
+		c-0.112-0.068-0.171-0.209-0.18-0.414c0-0.033,0.017-0.051,0.05-0.051h3.33v1.623v9c0,0.545-0.015,1.02-0.044,1.424
+		s-0.068,0.744-0.117,1.016c-0.099,0.537-0.268,1.031-0.508,1.484c-0.52,1.033-1.258,1.838-2.216,2.414
+		c-0.966,0.596-2.034,0.893-3.207,0.893c-1.75,0-3.194-0.596-4.333-1.783c-1.147-1.189-1.721-2.686-1.721-4.494
+		C545.442,546.687,545.673,545.7,546.136,544.8z"/>
+	<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="558.8647" y1="547.7764" x2="578.2983" y2="547.7764">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_8_)" d="M578.211,541.567c0.025,0,0.045,0.01,0.062,0.027c0.033,0.033,0.033,0.086,0,0.16
+		c-0.05,0.115-0.124,0.295-0.223,0.539c-0.1,0.244-0.231,0.6-0.396,1.07l-2.984,8.318c-0.264,0.834-0.553,1.412-0.866,1.734
+		c-0.314,0.338-0.71,0.508-1.189,0.508c-0.487,0-0.887-0.17-1.201-0.508c-0.148-0.166-0.272-0.389-0.371-0.668
+		c-0.1-0.281-0.215-0.629-0.347-1.041h-0.013l-2.08-5.521l-1.981,5.57c-0.264,0.826-0.553,1.4-0.867,1.723
+		c-0.313,0.336-0.714,0.506-1.201,0.506c-0.479,0-0.875-0.164-1.188-0.494c-0.157-0.166-0.283-0.391-0.377-0.676
+		c-0.096-0.285-0.209-0.633-0.341-1.045l-0.013,0.012l-3.095-8.256c-0.182-0.463-0.322-0.816-0.421-1.059
+		c-0.099-0.244-0.173-0.424-0.223-0.539c-0.041-0.074-0.045-0.129-0.012-0.162c0.017-0.018,0.041-0.023,0.074-0.023
+		c0.396-0.016,0.784,0.053,1.164,0.209c0.157,0.066,0.322,0.154,0.495,0.268c0.174,0.111,0.341,0.252,0.501,0.426
+		c0.162,0.174,0.316,0.381,0.465,0.619c0.148,0.24,0.281,0.521,0.396,0.842l2.612,6.809l2.513-6.857
+		c0.066-0.189,0.136-0.361,0.21-0.514s0.153-0.299,0.235-0.439c0.272-0.33,0.549-0.537,0.829-0.619
+		c0.124-0.033,0.252-0.039,0.384-0.018c0.132,0.02,0.269,0.086,0.409,0.197s0.283,0.275,0.427,0.496
+		c0.144,0.219,0.287,0.508,0.427,0.871l2.625,6.822l2.501-6.859c0.107-0.32,0.235-0.604,0.383-0.848
+		c0.149-0.242,0.304-0.451,0.464-0.625c0.161-0.174,0.328-0.316,0.502-0.434c0.173-0.115,0.342-0.211,0.507-0.285
+		C577.399,541.64,577.799,541.562,578.211,541.567z"/>
+	<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="579.251" y1="547.6602" x2="592.5596" y2="547.6602">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_9_)" d="M591.495,552.858c0.065,0.066,0.143,0.117,0.229,0.148c0.086,0.033,0.177,0.062,0.272,0.082
+		c0.094,0.02,0.183,0.049,0.266,0.086s0.15,0.092,0.205,0.162c0.052,0.068,0.084,0.176,0.092,0.314c0,0.033-0.017,0.049-0.05,0.049
+		h-3.317h-0.013v-6.016c0-1.246-0.354-2.27-1.064-3.068c-0.718-0.787-1.646-1.178-2.786-1.178c-1.123,0-2.051,0.389-2.786,1.164
+		c-0.727,0.791-1.089,1.791-1.089,2.996c0,1.246,0.375,2.27,1.126,3.07c0.743,0.791,1.692,1.188,2.847,1.188
+		c0.537,0,1.048-0.09,1.536-0.271c0.248-0.092,0.495-0.205,0.743-0.342c0.247-0.135,0.499-0.299,0.755-0.488v2.328
+		c-0.512,0.279-1.031,0.486-1.56,0.617c-0.272,0.066-0.553,0.115-0.842,0.148s-0.582,0.051-0.879,0.051
+		c-0.569,0-1.138-0.086-1.708-0.26c-0.562-0.182-1.074-0.43-1.536-0.742c-0.867-0.604-1.531-1.35-1.994-2.242
+		c-0.462-0.906-0.693-1.91-0.693-3.008c0-1.799,0.57-3.289,1.709-4.469c1.139-1.172,2.587-1.758,4.346-1.758
+		c1.164,0,2.224,0.289,3.182,0.867c0.478,0.287,0.905,0.643,1.281,1.062c0.375,0.422,0.683,0.869,0.922,1.338
+		c0.115,0.23,0.219,0.475,0.31,0.725c0.091,0.252,0.161,0.51,0.21,0.773c0.1,0.562,0.149,1.379,0.149,2.451v3.924
+		C591.384,552.694,591.429,552.794,591.495,552.858z"/>
+	<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="593.1611" y1="547.5957" x2="603.0527" y2="547.5957">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_10_)" d="M598.105,541.892c0.628-0.248,1.199-0.379,1.715-0.396c0.516-0.016,0.974,0.035,1.375,0.154
+		c0.399,0.119,0.738,0.281,1.015,0.49c0.276,0.205,0.485,0.41,0.625,0.611c0.141,0.203,0.213,0.379,0.218,0.527
+		c0.003,0.148-0.069,0.221-0.218,0.221c-0.206,0.01-0.398,0.014-0.575,0.014c-0.178,0-0.333,0-0.465,0h-0.433
+		c-0.372,0-0.735,0.016-1.09,0.049s-0.691,0.09-1.009,0.168c-0.317,0.08-0.606,0.186-0.866,0.322
+		c-0.261,0.135-0.478,0.307-0.65,0.514c-0.313,0.371-0.557,0.838-0.73,1.398s-0.26,1.242-0.26,2.043v3.641
+		c0.033,0.312,0.091,0.553,0.173,0.725c0.082,0.168,0.18,0.295,0.291,0.383c0.111,0.086,0.225,0.148,0.341,0.186
+		c0.115,0.037,0.221,0.08,0.315,0.129c0.095,0.051,0.169,0.119,0.224,0.211c0.053,0.09,0.075,0.232,0.067,0.42h-5.002
+		c-0.017-0.197,0.007-0.342,0.068-0.432c0.062-0.092,0.143-0.162,0.241-0.211c0.1-0.051,0.208-0.092,0.328-0.131
+		c0.12-0.035,0.235-0.104,0.347-0.203c0.112-0.1,0.207-0.244,0.285-0.434s0.13-0.461,0.155-0.818v-9.828h1.992v1.783
+		C596.963,542.708,597.471,542.196,598.105,541.892z"/>
+	<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="603.1699" y1="547.7412" x2="615.2402" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_11_)" d="M612.888,549.776c0.38-0.346,0.715-0.596,1.009-0.748c0.293-0.152,0.539-0.254,0.736-0.303
+		c0.231-0.059,0.434-0.07,0.607-0.039c-0.074,0.43-0.17,0.824-0.285,1.184s-0.254,0.693-0.415,1.002
+		c-0.161,0.311-0.346,0.6-0.558,0.873c-0.209,0.271-0.451,0.533-0.724,0.781c-1.098,0.998-2.426,1.498-3.986,1.498
+		c-0.536,0-1.064-0.076-1.584-0.225c-0.529-0.139-1.02-0.35-1.474-0.631c-0.949-0.578-1.695-1.35-2.24-2.314
+		c-0.537-0.957-0.805-2.002-0.805-3.133c0-0.42,0.038-0.828,0.116-1.225c0.079-0.396,0.192-0.785,0.341-1.166
+		c0.306-0.748,0.751-1.43,1.338-2.041c0.586-0.594,1.246-1.049,1.98-1.361c0.768-0.314,1.551-0.471,2.352-0.471
+		c1.222,0,2.315,0.32,3.281,0.965c0.966,0.652,1.746,1.588,2.34,2.811l-7.91,4.383c-0.083-0.363-0.079-0.727,0.012-1.09
+		c0.074-0.312,0.236-0.646,0.489-1.002c0.251-0.355,0.662-0.686,1.231-0.99c0.041-0.025,0.117-0.07,0.229-0.137
+		c0.111-0.066,0.248-0.145,0.408-0.236c0.161-0.09,0.337-0.189,0.526-0.297s0.38-0.215,0.569-0.322
+		c0.454-0.256,0.949-0.535,1.485-0.84c-0.355-0.396-0.76-0.697-1.213-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.081,0-1.993,0.404-2.735,1.215c-0.743,0.809-1.114,1.807-1.114,2.996c0,1.188,0.371,2.182,1.114,2.982
+		c0.742,0.818,1.654,1.227,2.735,1.227c1.031,0,1.891-0.34,2.575-1.016c0.231-0.197,0.415-0.391,0.551-0.576
+		C612.535,550.13,612.697,549.95,612.888,549.776z"/>
+	<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="623.3115" y1="544.7832" x2="637.9443" y2="544.7832">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_12_)" d="M637.028,540.405c0.372,0.645,0.617,1.35,0.737,2.117c0.119,0.768,0.179,1.555,0.179,2.363
+		c0,1.602-0.388,3.062-1.163,4.385c-0.769,1.311-1.865,2.389-3.294,3.23c-0.668,0.387-1.464,0.682-2.389,0.879
+		c-0.24,0.051-0.508,0.096-0.805,0.135c-0.297,0.043-0.584,0.078-0.859,0.105c-0.278,0.029-0.521,0.053-0.731,0.068
+		c-0.21,0.018-0.35,0.025-0.415,0.025c-0.116,0-0.23-0.002-0.347-0.006c-0.115-0.004-0.173-0.064-0.173-0.18
+		c0-0.076,0.036-0.197,0.111-0.371c0.073-0.174,0.191-0.359,0.352-0.557c0.163-0.199,0.368-0.389,0.62-0.57
+		c0.251-0.182,0.559-0.318,0.922-0.41c0.462-0.164,0.852-0.297,1.17-0.395c0.318-0.1,0.608-0.207,0.873-0.32
+		c0.264-0.117,0.522-0.262,0.773-0.436c0.252-0.172,0.543-0.412,0.873-0.717c0.668-0.619,1.186-1.338,1.548-2.154
+		c0.363-0.818,0.545-1.729,0.545-2.736c0-0.512-0.028-1.014-0.08-1.504c-0.055-0.49-0.146-0.957-0.273-1.4
+		c-0.127-0.439-0.303-0.854-0.526-1.238c-0.223-0.383-0.503-0.727-0.841-1.033c-0.281-0.281-0.648-0.537-1.102-0.773
+		c-0.455-0.234-0.938-0.434-1.449-0.594s-1.027-0.287-1.548-0.377c-0.52-0.092-0.988-0.139-1.405-0.143s-0.758,0.041-1.021,0.137
+		s-0.396,0.244-0.396,0.451l0.014,12.504h0.013v2.809h-3.628c0-0.164,0.031-0.287,0.093-0.369s0.139-0.146,0.229-0.193
+		c0.092-0.045,0.19-0.078,0.298-0.098c0.107-0.021,0.207-0.053,0.304-0.094c0.095-0.041,0.177-0.102,0.248-0.18
+		c0.068-0.076,0.116-0.195,0.142-0.354c0-0.479,0-1.057,0-1.732c0-0.678-0.003-1.408-0.007-2.197s-0.005-1.604-0.005-2.451
+		c0-0.846,0-1.678,0-2.494c0-0.818-0.003-1.596-0.007-2.334c-0.006-0.74-0.007-1.396-0.007-1.975s0.001-1.045,0.007-1.406
+		c0.004-0.357,0.007-0.566,0.007-0.625c0.007-0.297,0.151-0.537,0.433-0.723c0.28-0.188,0.633-0.328,1.057-0.428
+		c0.426-0.098,0.899-0.158,1.419-0.18c0.521-0.02,1.027-0.02,1.522,0c0.495,0.021,0.954,0.055,1.374,0.104
+		c0.422,0.051,0.743,0.105,0.966,0.162c0.38,0.117,0.822,0.281,1.324,0.496c0.505,0.215,1.018,0.494,1.542,0.842
+		c0.523,0.346,1.03,0.762,1.523,1.244C636.264,539.198,636.682,539.763,637.028,540.405z"/>
+	<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="639.6777" y1="547.7412" x2="651.748" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_13_)" d="M649.396,549.776c0.379-0.346,0.717-0.596,1.009-0.748c0.293-0.152,0.539-0.254,0.737-0.303
+		c0.231-0.059,0.433-0.07,0.606-0.039c-0.074,0.43-0.169,0.824-0.285,1.184c-0.115,0.359-0.254,0.693-0.415,1.002
+		c-0.159,0.311-0.347,0.6-0.556,0.873c-0.211,0.271-0.453,0.533-0.725,0.781c-1.099,0.998-2.427,1.498-3.987,1.498
+		c-0.535,0-1.063-0.076-1.584-0.225c-0.529-0.139-1.02-0.35-1.474-0.631c-0.948-0.578-1.696-1.35-2.24-2.314
+		c-0.536-0.957-0.805-2.002-0.805-3.133c0-0.42,0.039-0.828,0.118-1.225c0.077-0.396,0.19-0.785,0.339-1.166
+		c0.307-0.748,0.753-1.43,1.337-2.041c0.588-0.594,1.248-1.049,1.981-1.361c0.769-0.314,1.551-0.471,2.354-0.471
+		c1.221,0,2.314,0.32,3.279,0.965c0.966,0.652,1.745,1.588,2.34,2.811l-7.91,4.383c-0.082-0.363-0.079-0.727,0.013-1.09
+		c0.073-0.312,0.235-0.646,0.488-1.002c0.252-0.355,0.662-0.686,1.231-0.99c0.042-0.025,0.117-0.07,0.23-0.137
+		c0.11-0.066,0.247-0.145,0.408-0.236c0.16-0.09,0.336-0.189,0.525-0.297c0.19-0.107,0.38-0.215,0.569-0.322
+		c0.454-0.256,0.949-0.535,1.485-0.84c-0.354-0.396-0.759-0.697-1.213-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.08,0-1.992,0.404-2.735,1.215c-0.743,0.809-1.114,1.807-1.114,2.996c0,1.188,0.371,2.182,1.114,2.982
+		c0.743,0.818,1.655,1.227,2.735,1.227c1.033,0,1.892-0.34,2.575-1.016c0.23-0.197,0.415-0.391,0.552-0.576
+		S649.207,549.95,649.396,549.776z"/>
+	<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="653.9395" y1="545.9385" x2="660.0059" y2="545.9385">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_14_)" d="M659.721,550.778c0.024,0.01,0.037,0.021,0.037,0.039v2.871v0.012h-0.719c-0.09,0-0.176,0-0.259,0
+		c-0.082,0-0.17-0.004-0.261-0.012h-0.024c-1.437-0.074-2.53-0.439-3.28-1.102c-0.852-0.742-1.275-1.863-1.275-3.367v-8.406v-0.049
+		v-0.484c0.008-0.461,0.123-0.83,0.347-1.105c0.223-0.277,0.47-0.49,0.742-0.639c0.314-0.174,0.673-0.293,1.077-0.359v2.945v0.533
+		v7.182c0,0.973,0.235,1.682,0.706,2.129c0.445,0.42,1.144,0.643,2.091,0.668c0.133-0.033,0.222-0.096,0.267-0.186
+		c0.045-0.092,0.081-0.184,0.106-0.279c0.023-0.094,0.063-0.18,0.118-0.26C659.445,550.831,659.557,550.788,659.721,550.778z
+		 M656.7,541.581h0.26c0.157,0.01,0.31,0.014,0.457,0.014H658c0.438,0.008,0.787,0.119,1.052,0.334
+		c0.264,0.213,0.467,0.449,0.606,0.705c0.166,0.297,0.281,0.635,0.348,1.016h-2.811h-0.508L656.7,541.581z"/>
+	<linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="661.4053" y1="547.7412" x2="673.4746" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_15_)" d="M671.123,549.776c0.379-0.346,0.715-0.596,1.009-0.748c0.292-0.152,0.538-0.254,0.735-0.303
+		c0.231-0.059,0.434-0.07,0.607-0.039c-0.074,0.43-0.169,0.824-0.284,1.184c-0.116,0.359-0.255,0.693-0.415,1.002
+		c-0.161,0.311-0.347,0.6-0.558,0.873c-0.21,0.271-0.451,0.533-0.724,0.781c-1.098,0.998-2.427,1.498-3.986,1.498
+		c-0.536,0-1.065-0.076-1.585-0.225c-0.528-0.139-1.019-0.35-1.474-0.631c-0.947-0.578-1.695-1.35-2.24-2.314
+		c-0.537-0.957-0.804-2.002-0.804-3.133c0-0.42,0.038-0.828,0.116-1.225c0.079-0.396,0.192-0.785,0.341-1.166
+		c0.306-0.748,0.751-1.43,1.337-2.041c0.586-0.594,1.247-1.049,1.98-1.361c0.768-0.314,1.552-0.471,2.353-0.471
+		c1.222,0,2.314,0.32,3.281,0.965c0.965,0.652,1.745,1.588,2.339,2.811l-7.91,4.383c-0.083-0.363-0.078-0.727,0.012-1.09
+		c0.074-0.312,0.237-0.646,0.49-1.002c0.251-0.355,0.662-0.686,1.23-0.99c0.042-0.025,0.118-0.07,0.23-0.137
+		c0.11-0.066,0.247-0.145,0.407-0.236c0.162-0.09,0.337-0.189,0.527-0.297c0.188-0.107,0.38-0.215,0.568-0.322
+		c0.455-0.256,0.95-0.535,1.485-0.84c-0.354-0.396-0.759-0.697-1.212-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.081,0-1.992,0.404-2.736,1.215c-0.742,0.809-1.114,1.807-1.114,2.996c0,1.188,0.372,2.182,1.114,2.982
+		c0.744,0.818,1.655,1.227,2.736,1.227c1.031,0,1.89-0.34,2.574-1.016c0.231-0.197,0.415-0.391,0.552-0.576
+		S670.933,549.95,671.123,549.776z"/>
+	<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="675.1084" y1="547.6904" x2="683.2793" y2="547.6904">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_16_)" d="M678.711,544.813c-0.908,0.732-1.36,1.699-1.36,2.895c0,1.189,0.452,2.152,1.36,2.887
+		c0.009,0,0.021,0.008,0.037,0.023l-0.049-0.049c0.206,0.164,0.412,0.309,0.619,0.434c0.692,0.379,1.502,0.598,2.426,0.656h0.396
+		c0.132-0.025,0.229-0.072,0.291-0.143c0.062-0.07,0.109-0.152,0.142-0.248c0.033-0.094,0.06-0.195,0.082-0.303
+		c0.02-0.107,0.049-0.205,0.085-0.291c0.038-0.086,0.092-0.16,0.162-0.223c0.069-0.062,0.176-0.098,0.314-0.105
+		c0.043,0,0.062,0.016,0.062,0.049l-0.013,3.33h-1.076h-0.149l-0.396-0.012c-1.906-0.092-3.446-0.641-4.618-1.646
+		c-1.278-1.107-1.919-2.57-1.919-4.395c0-0.99,0.229-1.912,0.681-2.76c0.472-0.852,1.122-1.564,1.957-2.143
+		c0.595-0.396,1.222-0.682,1.882-0.855c0.396-0.105,0.802-0.172,1.22-0.197c0.416-0.023,0.863-0.045,1.343-0.062h1.076v2.068v1.262
+		c0,0.033-0.012,0.049-0.037,0.049c-0.14-0.006-0.247-0.039-0.321-0.098c-0.074-0.057-0.127-0.133-0.161-0.223
+		c-0.032-0.092-0.061-0.188-0.081-0.291c-0.02-0.104-0.047-0.201-0.08-0.297s-0.082-0.18-0.148-0.254s-0.161-0.125-0.284-0.148
+		c-0.742-0.033-1.396,0.053-1.957,0.26S679.141,544.466,678.711,544.813z"/>
+	<linearGradient id="SVGID_17_" gradientUnits="userSpaceOnUse" x1="685.3955" y1="545.9385" x2="691.4629" y2="545.9385">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_17_)" d="M691.178,550.778c0.024,0.01,0.038,0.021,0.038,0.039v2.871v0.012h-0.72c-0.09,0-0.177,0-0.259,0
+		c-0.083,0-0.17-0.004-0.26-0.012h-0.026c-1.436-0.074-2.528-0.439-3.279-1.102c-0.851-0.742-1.276-1.863-1.276-3.367v-8.406v-0.049
+		v-0.484c0.01-0.461,0.126-0.83,0.347-1.105c0.225-0.277,0.472-0.49,0.743-0.639c0.313-0.174,0.673-0.293,1.077-0.359v2.945v0.533
+		v7.182c0,0.973,0.236,1.682,0.705,2.129c0.446,0.42,1.145,0.643,2.094,0.668c0.132-0.033,0.22-0.096,0.266-0.186
+		c0.045-0.092,0.08-0.184,0.104-0.279c0.025-0.094,0.064-0.18,0.119-0.26C690.903,550.831,691.013,550.788,691.178,550.778z
+		 M688.157,541.581h0.26c0.157,0.01,0.31,0.014,0.458,0.014h0.582c0.438,0.008,0.788,0.119,1.053,0.334
+		c0.264,0.213,0.466,0.449,0.607,0.705c0.164,0.297,0.28,0.635,0.346,1.016h-2.811h-0.507L688.157,541.581z"/>
+	<linearGradient id="SVGID_18_" gradientUnits="userSpaceOnUse" x1="692.9678" y1="545.2891" x2="698.0781" y2="545.2891">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_18_)" d="M696.601,551.263c0.008,0.404,0.052,0.717,0.131,0.936c0.078,0.217,0.174,0.385,0.287,0.5
+		c0.112,0.115,0.232,0.193,0.36,0.236c0.13,0.041,0.248,0.086,0.356,0.135c0.108,0.051,0.195,0.119,0.263,0.211
+		c0.067,0.09,0.092,0.238,0.074,0.445h-5.1c-0.017-0.207,0.009-0.355,0.075-0.445c0.065-0.092,0.153-0.158,0.262-0.205
+		c0.108-0.045,0.227-0.09,0.355-0.135c0.13-0.047,0.251-0.125,0.363-0.236c0.111-0.111,0.208-0.275,0.287-0.494
+		s0.123-0.529,0.131-0.936v-9.619c0.427,0.01,0.804,0.154,1.132,0.434c0.139,0.123,0.275,0.281,0.406,0.471
+		c0.132,0.189,0.247,0.428,0.346,0.719c0.098,0.287,0.172,0.629,0.222,1.021c0.049,0.391,0.064,0.85,0.049,1.379V551.263z
+		 M696.563,540.491c-0.346-0.057-0.656-0.156-0.936-0.297c-0.245-0.115-0.481-0.277-0.708-0.488
+		c-0.226-0.211-0.375-0.488-0.449-0.836v-2.018c0.336-0.008,0.646,0.037,0.924,0.137c0.123,0.039,0.244,0.102,0.363,0.18
+		c0.117,0.078,0.23,0.174,0.338,0.289c0.106,0.115,0.202,0.258,0.283,0.422c0.081,0.166,0.143,0.359,0.185,0.582v0.123V540.491z"/>
+	<linearGradient id="SVGID_19_" gradientUnits="userSpaceOnUse" x1="699.4717" y1="547.6787" x2="711.6787" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_19_)" d="M699.472,547.659c0-0.824,0.157-1.621,0.471-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.578-0.594,1.23-1.043,1.956-1.35c0.718-0.305,1.49-0.457,2.315-0.457c0.842,0,1.621,0.152,2.34,0.457
+		c0.751,0.314,1.407,0.764,1.969,1.35c0.585,0.602,1.03,1.279,1.337,2.031c0.305,0.742,0.457,1.543,0.457,2.4
+		c0,0.859-0.152,1.668-0.457,2.428c-0.314,0.775-0.76,1.451-1.337,2.029c-0.562,0.588-1.218,1.035-1.969,1.35
+		c-0.743,0.314-1.523,0.471-2.34,0.471c-0.802,0-1.572-0.156-2.315-0.471c-0.726-0.305-1.378-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C699.629,549.306,699.472,548.501,699.472,547.659z M701.726,547.636
+		c0,1.162,0.375,2.152,1.127,2.971c0.76,0.826,1.667,1.238,2.724,1.238c1.063,0,1.972-0.412,2.724-1.238
+		c0.76-0.809,1.139-1.799,1.139-2.971c0-1.156-0.376-2.145-1.127-2.971c-0.759-0.809-1.672-1.215-2.735-1.215
+		c-1.057,0-1.964,0.406-2.724,1.215C702.101,545.491,701.726,546.479,701.726,547.636z"/>
+	<linearGradient id="SVGID_20_" gradientUnits="userSpaceOnUse" x1="712.3057" y1="547.5791" x2="725.4473" y2="547.5791">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_20_)" d="M712.312,553.726c-0.018-0.207,0.007-0.352,0.072-0.439c0.066-0.086,0.149-0.154,0.248-0.203
+		s0.212-0.096,0.342-0.137c0.127-0.041,0.245-0.113,0.352-0.217c0.108-0.104,0.2-0.258,0.278-0.465
+		c0.078-0.205,0.127-0.498,0.144-0.879v-4.244c0-1.75,0.469-3.143,1.41-4.174c0.934-1.023,2.179-1.535,3.739-1.535
+		c1.552,0,2.794,0.512,3.727,1.535c0.925,1.023,1.387,2.414,1.387,4.174v4.295c0.016,0.363,0.065,0.643,0.148,0.842
+		c0.082,0.197,0.177,0.348,0.285,0.451c0.106,0.104,0.222,0.176,0.347,0.217c0.122,0.041,0.235,0.088,0.339,0.137
+		c0.104,0.049,0.185,0.119,0.242,0.211c0.058,0.09,0.083,0.234,0.074,0.432h-2.203h-2.799c-0.016-0.197,0.008-0.342,0.069-0.432
+		c0.061-0.092,0.142-0.162,0.24-0.211s0.209-0.094,0.328-0.131c0.12-0.037,0.235-0.105,0.347-0.203
+		c0.112-0.1,0.207-0.244,0.285-0.436c0.077-0.188,0.129-0.461,0.155-0.814v-4.754c0-0.951-0.276-1.727-0.83-2.328
+		c-0.561-0.594-1.276-0.891-2.142-0.891c-0.867,0-1.584,0.297-2.155,0.891c-0.561,0.611-0.842,1.387-0.842,2.328v4.914
+		c0.034,0.312,0.093,0.557,0.175,0.73c0.083,0.172,0.18,0.303,0.29,0.389c0.111,0.088,0.226,0.148,0.341,0.188
+		c0.115,0.035,0.221,0.08,0.314,0.129c0.096,0.049,0.17,0.121,0.225,0.209c0.053,0.094,0.075,0.232,0.068,0.422H712.312z"/>
+	<linearGradient id="SVGID_21_" gradientUnits="userSpaceOnUse" x1="730.5518" y1="544.8242" x2="746.6016" y2="544.8242">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_21_)" d="M746.473,536.036c0.11,0.057,0.15,0.141,0.117,0.246c-0.033,0.107-0.127,0.238-0.285,0.391
+		c-0.155,0.154-0.337,0.32-0.545,0.502c-0.37,0.312-0.767,0.557-1.188,0.729c-0.419,0.176-0.825,0.254-1.211,0.236h0.011h-3.664
+		v13.012c0.016,0.412,0.068,0.73,0.155,0.953c0.085,0.223,0.188,0.391,0.309,0.508c0.119,0.115,0.248,0.195,0.385,0.24
+		c0.135,0.047,0.26,0.096,0.37,0.148c0.111,0.055,0.203,0.129,0.273,0.223c0.068,0.096,0.098,0.256,0.08,0.477h-2.426h-1.437
+		c-0.19,0-0.376,0-0.558,0s-0.349,0-0.501-0.006c-0.153-0.004-0.283-0.006-0.391-0.006s-0.177,0-0.211,0
+		c-0.016-0.223,0.012-0.381,0.081-0.477c0.07-0.094,0.162-0.166,0.273-0.217c0.11-0.049,0.233-0.096,0.365-0.143
+		c0.132-0.045,0.259-0.123,0.383-0.234s0.231-0.273,0.322-0.488s0.144-0.525,0.16-0.93V538.14h-1.932h-4.047
+		c-0.339,0-0.564-0.027-0.681-0.086c-0.115-0.059-0.155-0.141-0.117-0.248c0.037-0.107,0.134-0.234,0.289-0.385
+		c0.158-0.148,0.344-0.316,0.559-0.508c0.37-0.312,0.77-0.557,1.193-0.73c0.425-0.172,0.828-0.25,1.208-0.232
+		c0.148,0,0.434,0,0.854,0c0.422,0,0.924,0,1.511,0c0.586,0,1.231,0,1.937,0c0.708,0,1.419,0,2.137,0h5.57
+		C746.145,535.95,746.361,535.978,746.473,536.036z"/>
+	<linearGradient id="SVGID_22_" gradientUnits="userSpaceOnUse" x1="743.793" y1="547.6787" x2="755.999" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_22_)" d="M743.793,547.659c0-0.824,0.156-1.621,0.47-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.577-0.594,1.229-1.043,1.956-1.35c0.718-0.305,1.489-0.457,2.315-0.457c0.842,0,1.621,0.152,2.339,0.457
+		c0.751,0.314,1.408,0.764,1.969,1.35c0.585,0.602,1.031,1.279,1.337,2.031c0.305,0.742,0.458,1.543,0.458,2.4
+		c0,0.859-0.153,1.668-0.458,2.428c-0.313,0.775-0.759,1.451-1.337,2.029c-0.561,0.588-1.218,1.035-1.969,1.35
+		c-0.743,0.314-1.523,0.471-2.339,0.471c-0.802,0-1.573-0.156-2.315-0.471c-0.727-0.305-1.379-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C743.949,549.306,743.793,548.501,743.793,547.659z M746.045,547.636
+		c0,1.162,0.375,2.152,1.128,2.971c0.759,0.826,1.667,1.238,2.724,1.238c1.062,0,1.971-0.412,2.724-1.238
+		c0.759-0.809,1.139-1.799,1.139-2.971c0-1.156-0.376-2.145-1.127-2.971c-0.76-0.809-1.673-1.215-2.735-1.215
+		c-1.057,0-1.965,0.406-2.724,1.215C746.42,545.491,746.045,546.479,746.045,547.636z"/>
+	<linearGradient id="SVGID_23_" gradientUnits="userSpaceOnUse" x1="757.584" y1="547.6787" x2="769.79" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_23_)" d="M757.584,547.659c0-0.824,0.156-1.621,0.47-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.577-0.594,1.229-1.043,1.956-1.35c0.718-0.305,1.489-0.457,2.314-0.457c0.841,0,1.622,0.152,2.34,0.457
+		c0.751,0.314,1.407,0.764,1.968,1.35c0.588,0.602,1.033,1.279,1.337,2.031c0.308,0.742,0.459,1.543,0.459,2.4
+		c0,0.859-0.151,1.668-0.459,2.428c-0.313,0.775-0.759,1.451-1.337,2.029c-0.561,0.588-1.217,1.035-1.968,1.35
+		c-0.743,0.314-1.521,0.471-2.34,0.471c-0.8,0-1.572-0.156-2.314-0.471c-0.727-0.305-1.379-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C757.74,549.306,757.584,548.501,757.584,547.659z M759.836,547.636
+		c0,1.162,0.377,2.152,1.127,2.971c0.759,0.826,1.667,1.238,2.724,1.238c1.065,0,1.974-0.412,2.723-1.238
+		c0.76-0.809,1.14-1.799,1.14-2.971c0-1.156-0.375-2.145-1.126-2.971c-0.76-0.809-1.671-1.215-2.736-1.215
+		c-1.057,0-1.965,0.406-2.724,1.215C760.213,545.491,759.836,546.479,759.836,547.636z"/>
+	<linearGradient id="SVGID_24_" gradientUnits="userSpaceOnUse" x1="771.0596" y1="544.9199" x2="776.0684" y2="544.9199">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_24_)" d="M774.805,552.327c0.082,0.189,0.177,0.332,0.284,0.428c0.107,0.094,0.22,0.164,0.341,0.203
+		c0.119,0.043,0.229,0.084,0.327,0.131c0.1,0.045,0.178,0.113,0.236,0.205c0.056,0.09,0.082,0.234,0.073,0.432h-2.451
+		c-0.312,0-0.619,0-0.917,0c-0.297,0-0.563-0.002-0.797-0.006c-0.235-0.004-0.43-0.006-0.582-0.006c-0.153,0-0.238,0-0.255,0
+		c-0.017-0.189,0.005-0.33,0.062-0.42c0.058-0.092,0.134-0.16,0.229-0.205c0.095-0.047,0.2-0.088,0.315-0.123
+		c0.115-0.039,0.229-0.1,0.34-0.188c0.112-0.086,0.208-0.211,0.291-0.377c0.082-0.164,0.142-0.404,0.174-0.719v-15.561
+		c0.403-0.033,0.767,0.059,1.09,0.273c0.132,0.088,0.265,0.215,0.396,0.369c0.132,0.158,0.247,0.359,0.346,0.602
+		c0.1,0.244,0.18,0.537,0.241,0.879s0.093,0.744,0.093,1.207v12.07C774.667,551.868,774.722,552.138,774.805,552.327z"/>
+</g>
+<g>
+	
+		<linearGradient id="SVGID_25_" gradientUnits="userSpaceOnUse" x1="765.6445" y1="277.7368" x2="808.3828" y2="277.7368" gradientTransform="matrix(0 1.7627 -0.5313 0 746.2548 -985.7871)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="596.305" y="363.814" fill="url(#SVGID_25_)" width="4.777" height="75.334"/>
+	
+		<linearGradient id="SVGID_26_" gradientUnits="userSpaceOnUse" x1="756.1133" y1="247.3013" x2="811.0918" y2="247.3013" gradientTransform="matrix(0 1.8836 -0.5313 0 746.2548 -1090.623)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="611.807" y="333.592" fill="url(#SVGID_26_)" width="6.113" height="103.557"/>
+	
+		<linearGradient id="SVGID_27_" gradientUnits="userSpaceOnUse" x1="762.0664" y1="215.625" x2="817.0459" y2="215.625" gradientTransform="matrix(0 2.3897 -0.5313 0 746.2548 -1517.3457)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="628.637" y="303.764" fill="url(#SVGID_27_)" width="6.113" height="131.385"/>
+	
+		<linearGradient id="SVGID_28_" gradientUnits="userSpaceOnUse" x1="553.5811" y1="411.0479" x2="599.8867" y2="411.0479" gradientTransform="matrix(0.7605 0 0 0.5313 144.8682 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="565.866" y="363.814" fill="url(#SVGID_28_)" width="35.216" height="4.777"/>
+	
+		<linearGradient id="SVGID_29_" gradientUnits="userSpaceOnUse" x1="557.6221" y1="354.8657" x2="612.6035" y2="354.8657" gradientTransform="matrix(0.9408 0 0 0.5313 41.583 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="566.193" y="333.297" fill="url(#SVGID_29_)" width="51.727" height="6.113"/>
+	
+		<linearGradient id="SVGID_30_" gradientUnits="userSpaceOnUse" x1="555.4624" y1="299.3047" x2="614.6807" y2="299.3047" gradientTransform="matrix(1.1577 0 0 0.5313 -76.8652 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="566.193" y="303.777" fill="url(#SVGID_30_)" width="68.557" height="6.113"/>
+	<linearGradient id="SVGID_31_" gradientUnits="userSpaceOnUse" x1="616.7539" y1="416.6992" x2="663.481" y2="463.4263">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<path fill="url(#SVGID_31_)" d="M593.305,440.148c0,0,36.604-12.721,47.389-12.721s43.484,11.75,46.117,12.5s-40.199-5-45.533-5"/>
+	
+		<radialGradient id="SVGID_32_" cx="576.5234" cy="382.7012" r="10.5059" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_32_)" d="M546.176,366.203c0-5.803,4.704-10.506,10.506-10.506s10.506,4.703,10.506,10.506
+		s-4.704,10.506-10.506,10.506S546.176,372.006,546.176,366.203z M556.682,372.906c1.851,0,3.526-0.751,4.739-1.964
+		s1.963-2.889,1.963-4.739c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703
+		C549.979,369.904,552.979,372.906,556.682,372.906z"/>
+	
+		<radialGradient id="SVGID_33_" cx="546.9448" cy="382.7012" r="10.5056" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_33_)" d="M546.176,336.624c0-5.802,4.704-10.505,10.506-10.505s10.506,4.703,10.506,10.505
+		c0,5.803-4.704,10.506-10.506,10.506S546.176,342.427,546.176,336.624z M556.682,343.327c1.851,0,3.526-0.75,4.739-1.963
+		s1.963-2.889,1.963-4.74c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703S552.979,343.327,556.682,343.327z"/>
+	
+		<radialGradient id="SVGID_34_" cx="517.1543" cy="382.7012" r="10.5059" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_34_)" d="M546.176,306.834c0-5.802,4.704-10.506,10.506-10.506s10.506,4.704,10.506,10.506
+		c0,5.803-4.704,10.506-10.506,10.506S546.176,312.637,546.176,306.834z M556.682,313.537c1.851,0,3.526-0.751,4.739-1.963
+		c1.213-1.214,1.963-2.89,1.963-4.74c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703
+		C549.979,310.535,552.979,313.537,556.682,313.537z"/>
+	
+		<linearGradient id="SVGID_35_" gradientUnits="userSpaceOnUse" x1="765.6445" y1="357.6123" x2="808.3828" y2="357.6123" gradientTransform="matrix(0 1.7627 0.5313 0 491.3075 -985.7871)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="678.918" y="363.814" fill="url(#SVGID_35_)" width="4.777" height="75.334"/>
+	
+		<linearGradient id="SVGID_36_" gradientUnits="userSpaceOnUse" x1="756.1133" y1="327.1772" x2="811.0918" y2="327.1772" gradientTransform="matrix(0 1.8836 0.5313 0 491.3075 -1090.623)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="662.08" y="333.592" fill="url(#SVGID_36_)" width="6.113" height="103.557"/>
+	
+		<linearGradient id="SVGID_37_" gradientUnits="userSpaceOnUse" x1="762.0664" y1="295.5005" x2="817.0459" y2="295.5005" gradientTransform="matrix(0 2.3897 0.5313 0 491.3075 -1517.3457)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="645.25" y="303.764" fill="url(#SVGID_37_)" width="6.113" height="131.385"/>
+	
+		<linearGradient id="SVGID_38_" gradientUnits="userSpaceOnUse" x1="497.7793" y1="411.0479" x2="544.084" y2="411.0479" gradientTransform="matrix(-0.7605 0 0 0.5313 1092.6943 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="678.918" y="363.814" fill="url(#SVGID_38_)" width="35.215" height="4.777"/>
+	
+		<linearGradient id="SVGID_39_" gradientUnits="userSpaceOnUse" x1="512.5137" y1="354.8657" x2="567.4951" y2="354.8657" gradientTransform="matrix(-0.9408 0 0 0.5313 1195.9795 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="662.08" y="333.297" fill="url(#SVGID_39_)" width="51.727" height="6.113"/>
+	
+		<linearGradient id="SVGID_40_" gradientUnits="userSpaceOnUse" x1="518.8047" y1="299.3047" x2="578.0229" y2="299.3047" gradientTransform="matrix(-1.1577 0 0 0.5313 1314.4268 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="645.25" y="303.777" fill="url(#SVGID_40_)" width="68.557" height="6.113"/>
+	
+		<radialGradient id="SVGID_41_" cx="576.5234" cy="340.2637" r="10.5059" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_41_)" d="M723.318,376.709c-5.803,0-10.506-4.703-10.506-10.506s4.703-10.506,10.506-10.506
+		c5.801,0,10.506,4.703,10.506,10.506S729.119,376.709,723.318,376.709z M730.021,366.203c0-3.702-3.002-6.703-6.703-6.703
+		s-6.703,3.001-6.703,6.703c0,1.851,0.75,3.526,1.963,4.739s2.889,1.964,4.74,1.964C727.02,372.906,730.021,369.904,730.021,366.203
+		z"/>
+	
+		<radialGradient id="SVGID_42_" cx="546.9448" cy="340.2637" r="10.5056" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_42_)" d="M723.318,347.13c-5.803,0-10.506-4.703-10.506-10.506c0-5.802,4.703-10.505,10.506-10.505
+		c5.801,0,10.506,4.703,10.506,10.505C733.824,342.427,729.119,347.13,723.318,347.13z M730.021,336.624
+		c0-3.702-3.002-6.703-6.703-6.703s-6.703,3.001-6.703,6.703c0,1.852,0.75,3.527,1.963,4.74s2.889,1.963,4.74,1.963
+		C727.02,343.327,730.021,340.326,730.021,336.624z"/>
+	
+		<radialGradient id="SVGID_43_" cx="517.1543" cy="340.2637" r="10.5059" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_43_)" d="M723.318,317.34c-5.803,0-10.506-4.703-10.506-10.506c0-5.802,4.703-10.506,10.506-10.506
+		c5.801,0,10.506,4.704,10.506,10.506C733.824,312.637,729.119,317.34,723.318,317.34z M730.021,306.834
+		c0-3.702-3.002-6.703-6.703-6.703s-6.703,3.001-6.703,6.703c0,1.851,0.75,3.526,1.963,4.74c1.213,1.212,2.889,1.963,4.74,1.963
+		C727.02,313.537,730.021,310.535,730.021,306.834z"/>
+</g>
+</svg>
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,115 @@
+UI menu.c32
+DEFAULT hdt
+PROMPT 0
+TIMEOUT 50
+MENU TITLE Hardware Detection Tool (HDT) version %VERSION% (%CODENAME%)
+MENU MARGIN 0
+MENU ROWS 15
+MENU TABMSG
+MENU TABMSGROW -3
+MENU CMDLINEROW -3
+MENU HELPMSGROW -4
+MENU HELPMSGENDROW -1
+
+MENU COLOR SCREEN 37;40
+MENU COLOR BORDER 34;40
+MENU COLOR TITLE 1;33;40
+MENU COLOR SCROLLBAR 34;46
+MENU COLOR SEL 30;47
+MENU COLOR UNSEL 36;40
+MENU COLOR CMDMARK 37;40
+MENU COLOR CMDLINE 37;40
+MENU COLOR TABMSG 37;40
+MENU COLOR DISABLED 37;40
+MENU COLOR HELP 32;40
+
+LABEL hdt
+MENU LABEL Menu mode
+MENU DEFAULT
+TEXT HELP
+ Starts HDT using the MENU mode
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet
+
+LABEL cli
+MENU LABEL CLI (VESA mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet nomenu vesa
+
+LABEL vesa
+MENU LABEL CLI (Text mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is disabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet nomenu
+
+LABEL summary
+MENU LABEL CLI (Auto summary)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) and run 'show summary'
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show summary'
+
+LABEL verbose
+MENU LABEL CLI (VESA mode & Verbose)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) using the verbose mode
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids vesa nomenu verbose
+
+LABEL verbose-text
+MENU LABEL CLI (Text mode & Verbose)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is disabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids verbose nomenu
+
+LABEL dump
+MENU LABEL Dump hardware config to TFTP server 
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) and run 'dump'
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='dump'
+
+LABEL postexec
+MENU LABEL Dump memory info, sleep 5 and start memtest entry 
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI), show an item, say a message reboot and start memtest
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show memory;say `########`;say `Starting memtest in 5 sec`;sleep 5;exit' postexec='memtest'
+
+LABEL display
+MENU LABEL Display feature (VESA mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is enabled
+ A Picture is shown by using the display command
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids silent nomenu vesa auto='display display.png; sleep 5000; display red.png'
+
+MENU SEPARATOR
+
+LABEL memtest
+MENU LABEL Memtest86+ 4.20
+TEXT HELP
+ Starts Memtest86+ 4.20
+ENDTEXT
+LINUX memtest.bin
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2 @@
+# Floppy image for HDT
+drive a: file="hdt.img"
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include <disk/geom.h>
+#include <disk/util.h>
+
+#include "com32io.h"
+#include "hdt-common.h"
+#include "hdt-ata.h"
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_ATA_H
+#define DEFINE_HDT_ATA_H
+#include <com32io.h>
+
+#include <disk/geom.h>
+#include "hdt.h"
+
+struct ata_identify_device {
+    unsigned short words000_009[10];
+    unsigned char serial_no[20];
+    unsigned short words020_022[3];
+    unsigned char fw_rev[8];
+    unsigned char model[40];
+    unsigned short words047_079[33];
+    unsigned short major_rev_num;
+    unsigned short minor_rev_num;
+    unsigned short command_set_1;
+    unsigned short command_set_2;
+    unsigned short command_set_extension;
+    unsigned short cfs_enable_1;
+    unsigned short word086;
+    unsigned short csf_default;
+    unsigned short words088_255[168];
+} ATTR_PACKED;
+
+struct ata_driveinfo {
+    struct ata_identify_device aid;	/* IDENTIFY xxx DEVICE data */
+    char host_bus_type[5];
+    char interface_type[9];
+    char interface_port;
+} ATTR_PACKED;
+
+/* Useless stuff until I manage how to send ata packets */
+#ifdef ATA
+enum {
+    ATA_ID_FW_REV = 23,
+    ATA_ID_PROD = 27,
+    ATA_ID_FW_REV_LEN = 8,
+    ATA_ID_PROD_LEN = 40,
+};
+void ata_id_c_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
+		     unsigned int len);
+void ata_id_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
+		   unsigned int len);
+void printregs(const com32sys_t * r);
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,290 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <acpi/acpi.h>
+
+/* Print ACPI's table header in a defined formating */
+static void show_header(void *address, s_acpi_description_header * h)
+{
+    more_printf("%-4s v%03x %-6s %-8s 0x%08x %-7s 0x%08x @ 0x%p\n",
+		h->signature, h->revision, h->oem_id, h->oem_table_id,
+		h->oem_revision, h->creator_id, h->creator_revision, address)
+}
+
+/* That's an helper to visualize columns*/
+static void show_table_separator(void)
+{
+    more_printf
+	("----|----|------|--------|----------|-------|-----------|--------------------\n");
+}
+
+/* Display the main header before displaying the ACPI tables */
+static void show_table_name(void)
+{
+    more_printf
+	("ACPI rev  oem    table_id oem_rev    creator creat_rev  @ address \n");
+    show_table_separator();
+}
+
+/* called by "show acpi" */
+void main_show_acpi(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (hardware->is_acpi_valid == false) {
+	more_printf("No ACPI Tables detected\n");
+	return;
+    }
+
+    show_table_name();
+
+    /* RSDP tables aren't using the same headers as the other
+     * So let's use a dedicated rendering */
+    if (hardware->acpi.rsdp.valid) {
+	s_rsdp *r = &hardware->acpi.rsdp;
+	more_printf
+	    ("RSDP v%03x %-6s                                        @ %p\n",
+	     r->revision, r->oem_id, r->address);
+    }
+
+    if (hardware->acpi.rsdt.valid)
+	show_header(hardware->acpi.rsdt.address,
+		       &hardware->acpi.rsdt.header);
+
+    if (hardware->acpi.xsdt.valid)
+	show_header(hardware->acpi.xsdt.address,
+		       &hardware->acpi.xsdt.header);
+
+    if (hardware->acpi.fadt.valid)
+	show_header(hardware->acpi.fadt.address, &hardware->acpi.fadt.header);
+
+    if (hardware->acpi.dsdt.valid)
+	show_header(hardware->acpi.dsdt.address, &hardware->acpi.dsdt.header);
+
+    /* SSDT includes many optional tables, let's display them */
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+	if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+	    show_header(hardware->acpi.ssdt[i]->address,
+			&hardware->acpi.ssdt[i]->header);
+    }
+
+    if (hardware->acpi.sbst.valid)
+	show_header(hardware->acpi.sbst.address, &hardware->acpi.sbst.header);
+
+    if (hardware->acpi.ecdt.valid)
+	show_header(hardware->acpi.ecdt.address, &hardware->acpi.ecdt.header);
+
+    if (hardware->acpi.hpet.valid)
+	show_header(hardware->acpi.hpet.address, &hardware->acpi.hpet.header);
+
+    if (hardware->acpi.tcpa.valid)
+	show_header(hardware->acpi.tcpa.address, &hardware->acpi.tcpa.header);
+
+    if (hardware->acpi.mcfg.valid)
+	show_header(hardware->acpi.mcfg.address, &hardware->acpi.mcfg.header);
+
+    if (hardware->acpi.slic.valid)
+	show_header(hardware->acpi.slic.address, &hardware->acpi.slic.header);
+
+    if (hardware->acpi.boot.valid)
+	show_header(hardware->acpi.boot.address, &hardware->acpi.boot.header);
+
+    /* FACS isn't having the same headers, let's use a dedicated rendering */
+    if (hardware->acpi.facs.valid) {
+	s_facs *fa = &hardware->acpi.facs;
+	more_printf
+	    ("FACS                                                    @ 0x%p\n",
+	     fa->address);
+    }
+
+    if (hardware->acpi.madt.valid)
+	show_header(hardware->acpi.madt.address, &hardware->acpi.madt.header);
+
+    more_printf("\nLocal APIC at 0x%08x\n", hardware->acpi.madt.local_apic_address);
+}
+
+/* Let's display the Processor Local APIC configuration */
+static void show_local_apic(s_madt * madt)
+{
+    if (madt->processor_local_apic_count == 0) {
+	more_printf("No Processor Local APIC found\n");
+	return;
+    }
+
+    /* For all detected logical CPU */
+    for (int i = 0; i < madt->processor_local_apic_count; i++) {
+	s_processor_local_apic *sla = &madt->processor_local_apic[i];
+	char buffer[8];
+	memset(buffer, 0, sizeof(buffer));
+	strcpy(buffer, "disable");
+	/* Let's check if the flags reports the cpu as enabled */
+	if ((sla->flags & PROCESSOR_LOCAL_APIC_ENABLE) ==
+	    PROCESSOR_LOCAL_APIC_ENABLE)
+	    strcpy(buffer, "enable");
+	more_printf("CPU #%u, LAPIC (acpi_id[0x%02x] apic_id[0x%02x]) %s\n",
+		    sla->apic_id, sla->acpi_id, sla->apic_id, buffer);
+    }
+}
+
+/* Display the local apic NMI configuration */
+static void show_local_apic_nmi(s_madt * madt)
+{
+    if (madt->local_apic_nmi_count == 0) {
+	more_printf("No Local APIC NMI found\n");
+	return;
+    }
+
+    for (int i = 0; i < madt->local_apic_nmi_count; i++) {
+	s_local_apic_nmi *slan = &madt->local_apic_nmi[i];
+	char buffer[20];
+	more_printf("LAPIC_NMI (acpi_id[0x%02x] %s lint(0x%02x))\n",
+		    slan->acpi_processor_id, flags_to_string(buffer,
+							     slan->flags),
+		    slan->local_apic_lint);
+    }
+}
+
+/* Display the IO APIC configuration */
+static void show_io_apic(s_madt * madt)
+{
+    if (madt->io_apic_count == 0) {
+	more_printf("No IO APIC found\n");
+	return;
+    }
+
+    /* For all IO APICS */
+    for (int i = 0; i < madt->io_apic_count; i++) {
+	s_io_apic *sio = &madt->io_apic[i];
+	char buffer[15];
+	memset(buffer, 0, sizeof(buffer));
+	/* GSI base reports the GSI configuration
+	 * Let's interpret it as string */
+	switch (sio->global_system_interrupt_base) {
+	case 0:
+	    strcpy(buffer, "GSI 0-23");
+	    break;
+	case 24:
+	    strcpy(buffer, "GSI 24-39");
+	    break;
+	case 40:
+	    strcpy(buffer, "GSI 40-55");
+	    break;
+	default:
+	    strcpy(buffer, "GSI Unknown");
+	    break;
+	}
+
+	more_printf("IO_APIC[%d] : apic_id[0x%02x] address[0x%08x] %s\n",
+		    i, sio->io_apic_id, sio->io_apic_address, buffer);
+    }
+}
+
+/* Display the interrupt source override configuration */
+static void show_interrupt_source_override(s_madt * madt)
+{
+    if (madt->interrupt_source_override_count == 0) {
+	more_printf("No interrupt source override found\n");
+	return;
+    }
+
+    /* Let's process each interrupt source override */
+    for (int i = 0; i < madt->interrupt_source_override_count; i++) {
+	s_interrupt_source_override *siso = &madt->interrupt_source_override[i];
+	char buffer[20];
+	char bus_type[10];
+	memset(bus_type, 0, sizeof(bus_type));
+	/* Spec report bus type 0 as ISA */
+	if (siso->bus == 0)
+	    strcpy(bus_type, "ISA");
+	else
+	    strcpy(bus_type, "unknown");
+
+	more_printf("INT_SRC_OVR (bus %s (%d) bus_irq %d global_irq %d %s)\n",
+		    bus_type, siso->bus, siso->source,
+		    siso->global_system_interrupt, flags_to_string(buffer,
+								   siso->
+								   flags));
+    }
+}
+
+/* Display the apic configuration
+ * This is called by acpi> show apic */
+static void show_acpi_apic(int argc __unused, char **argv __unused,
+			   struct s_hardware *hardware)
+{
+    if (hardware->is_acpi_valid == false) {
+	more_printf("No ACPI Tables detected\n");
+	return;
+    }
+
+    s_madt *madt = &hardware->acpi.madt;
+
+    if (madt->valid == false) {
+	more_printf("No APIC (MADT) table found\n");
+	return;
+    }
+
+    more_printf("Local APIC at 0x%08x\n", madt->local_apic_address);
+    show_local_apic(madt);
+    show_local_apic_nmi(madt);
+    show_io_apic(madt);
+    show_interrupt_source_override(madt);
+}
+
+struct cli_callback_descr list_acpi_show_modules[] = {
+    {
+     .name = "apic",
+     .exec = show_acpi_apic,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr acpi_show_modules = {
+    .modules = list_acpi_show_modules,
+    .default_callback = main_show_acpi,
+};
+
+struct cli_mode_descr acpi_mode = {
+    .mode = ACPI_MODE,
+    .name = CLI_ACPI,
+    .default_modules = NULL,
+    .show_modules = &acpi_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,263 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_cpu(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    char features[81];
+    /* We know the total number of logical cores and we
+     * know the number of cores of the first CPU. Let's consider
+     * the system as symetrical, and so compute the number of
+     * physical CPUs. This is only possible if ACPI is present */
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	more_printf("CPU (%d logical / %d phys)\n",
+		    hardware->acpi.madt.processor_local_apic_count,
+		    hardware->physical_cpu_count);
+    } else
+	more_printf("CPU\n");
+    more_printf(" Manufacturer : %s \n", hardware->cpu.vendor);
+    more_printf(" Product      : %s \n", hardware->cpu.model);
+    more_printf(" CPU Cores    : %d \n", hardware->cpu.num_cores);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf(" CPU Threads  : %d \n", hardware->dmi.processor.thread_count);
+    more_printf(" L2 Cache     : %dK\n", hardware->cpu.l2_cache_size);
+
+    memset(features, 0, sizeof(features));
+    snprintf(features, sizeof(features), " Features     : %d Mhz : ",
+	     hardware->dmi.processor.current_speed);
+    if (hardware->cpu.flags.lm)
+	strcat(features, "x86_64 64bit ");
+    else
+	strcat(features, "x86 32bit ");
+    if (hardware->cpu.flags.smp)
+	strcat(features, "SMP ");
+
+    /* This CPU is featuring Intel or AMD Virtualisation Technology */
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm)
+	strcat(features, "HwVIRT ");
+
+    more_printf("%s\n", features);
+}
+
+/* Let's compute the cpu flags display
+ * We have to maximize the number of flags per line */
+static void show_flag(char *buffer, bool flag, char *flag_name, bool flush)
+{
+    char output_buffer[81];
+    /* Flush is only set when no more flags are present
+     * When it's set, or if the line is complete,
+     * we have to end the string computation and display the line.
+     * Before adding the flag into the buffer, let's check that adding it
+     * will not overflow the rendering.*/
+    if ((((strlen(buffer) + strlen(flag_name)) > 66) && flag) || flush) {
+	snprintf(output_buffer, sizeof output_buffer, "Flags     : %s\n",
+		 buffer);
+	more_printf("%s", output_buffer);
+	memset(buffer, 0, sizeof(buffer));
+	if (flush)
+	    return;
+    }
+    /* Let's add the flag name only if the flag is present */
+    if (flag)
+	strcat(buffer, flag_name);
+}
+
+static void show_cpu(int argc __unused, char **argv __unused,
+		     struct s_hardware *hardware)
+{
+    char buffer[81];
+    reset_more_printf();
+    /* We know the total number of logical cores and we
+     * know the number of cores of the first CPU. Let's consider
+     * the system as symetrical, and so compute the number of
+     * physical CPUs. This is only possible if ACPI is present*/
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	more_printf("CPU (%d logical / %d phys)\n",
+		    hardware->acpi.madt.processor_local_apic_count,
+		    hardware->acpi.madt.processor_local_apic_count /
+		    hardware->cpu.num_cores);
+    } else
+	more_printf("CPU\n");
+    more_printf("Vendor    : %s\n", hardware->cpu.vendor);
+    more_printf("Model     : %s\n", hardware->cpu.model);
+    more_printf("CPU Cores : %d\n", hardware->cpu.num_cores);
+    if (hardware->dmi.processor.core_enabled != 0)
+        more_printf("CPU Enable: %d\n", hardware->dmi.processor.core_enabled);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf("CPU Thread: %d \n", hardware->dmi.processor.thread_count);
+    more_printf("L1 Cache  : %dK + %dK (I + D) \n",
+		hardware->cpu.l1_instruction_cache_size,
+		hardware->cpu.l1_data_cache_size);
+    more_printf("L2 Cache  : %dK\n", hardware->cpu.l2_cache_size);
+    more_printf("Family ID : %d\n", hardware->cpu.family);
+    more_printf("Model  ID : %d\n", hardware->cpu.model_id);
+    more_printf("Stepping  : %d\n", hardware->cpu.stepping);
+    if (hardware->is_dmi_valid) {
+	more_printf("FSB       : %d MHz\n",
+		    hardware->dmi.processor.external_clock);
+	more_printf("Cur. Speed: %d MHz\n",
+		    hardware->dmi.processor.current_speed);
+	more_printf("Max Speed : %d MHz\n", hardware->dmi.processor.max_speed);
+	more_printf("Upgrade   : %s\n", hardware->dmi.processor.upgrade);
+	more_printf("Voltage   : %d.%02d\n",
+		    hardware->dmi.processor.voltage_mv / 1000,
+		    hardware->dmi.processor.voltage_mv -
+		    ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+    }
+
+    if (hardware->cpu.flags.smp) {
+	more_printf("SMP       : yes\n");
+    } else {
+	more_printf("SMP       : no\n");
+    }
+
+    if (hardware->cpu.flags.lm) {
+	more_printf("x86_64    : yes\n");
+    } else {
+	more_printf("x86_64    : no\n");
+    }
+
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm) {
+	more_printf("HwVirt    : yes\n");
+    } else {
+	more_printf("HwVirt    : no\n");
+    }
+
+    /* Let's display the supported cpu flags */
+    memset(buffer, 0, sizeof(buffer));
+    show_flag(buffer, hardware->cpu.flags.fpu, "fpu ", false);
+    show_flag(buffer, hardware->cpu.flags.vme, "vme ", false);
+    show_flag(buffer, hardware->cpu.flags.de, "de ", false);
+    show_flag(buffer, hardware->cpu.flags.pse, "pse ", false);
+    show_flag(buffer, hardware->cpu.flags.tsc, "tsc ", false);
+    show_flag(buffer, hardware->cpu.flags.msr, "msr ", false);
+    show_flag(buffer, hardware->cpu.flags.pae, "pae ", false);
+    show_flag(buffer, hardware->cpu.flags.mce, "mce ", false);
+    show_flag(buffer, hardware->cpu.flags.cx8, "cx8 ", false);
+    show_flag(buffer, hardware->cpu.flags.apic, "apic ", false);
+    show_flag(buffer, hardware->cpu.flags.sep, "sep ", false);
+    show_flag(buffer, hardware->cpu.flags.mtrr, "mtrr ", false);
+    show_flag(buffer, hardware->cpu.flags.pge, "pge ", false);
+    show_flag(buffer, hardware->cpu.flags.mca, "mca ", false);
+    show_flag(buffer, hardware->cpu.flags.cmov, "cmov ", false);
+    show_flag(buffer, hardware->cpu.flags.pat, "pat ", false);
+    show_flag(buffer, hardware->cpu.flags.pse_36, "pse_36 ", false);
+    show_flag(buffer, hardware->cpu.flags.psn, "psn ", false);
+    show_flag(buffer, hardware->cpu.flags.clflsh, "clflsh ", false);
+    show_flag(buffer, hardware->cpu.flags.dts, "dts ", false);
+    show_flag(buffer, hardware->cpu.flags.acpi, "acpi ", false);
+    show_flag(buffer, hardware->cpu.flags.mmx, "mmx ", false);
+    show_flag(buffer, hardware->cpu.flags.sse, "sse ", false);
+    show_flag(buffer, hardware->cpu.flags.sse2, "sse2 ", false);
+    show_flag(buffer, hardware->cpu.flags.ss, "ss ", false);
+    show_flag(buffer, hardware->cpu.flags.htt, "ht ", false);
+    show_flag(buffer, hardware->cpu.flags.acc, "acc ", false);
+    show_flag(buffer, hardware->cpu.flags.syscall, "syscall ", false);
+    show_flag(buffer, hardware->cpu.flags.mp, "mp ", false);
+    show_flag(buffer, hardware->cpu.flags.nx, "nx ", false);
+    show_flag(buffer, hardware->cpu.flags.mmxext, "mmxext ", false);
+    show_flag(buffer, hardware->cpu.flags.lm, "lm ", false);
+    show_flag(buffer, hardware->cpu.flags.nowext, "3dnowext ", false);
+    show_flag(buffer, hardware->cpu.flags.now, "3dnow! ", false);
+    show_flag(buffer, hardware->cpu.flags.svm, "svm ", false);
+    show_flag(buffer, hardware->cpu.flags.vmx, "vmx ", false);
+    show_flag(buffer, hardware->cpu.flags.pbe, "pbe ", false);
+    show_flag(buffer, hardware->cpu.flags.fxsr_opt, "fxsr_opt ", false);
+    show_flag(buffer, hardware->cpu.flags.gbpages, "gbpages ", false);
+    show_flag(buffer, hardware->cpu.flags.rdtscp, "rdtscp ", false);
+    show_flag(buffer, hardware->cpu.flags.pni, "pni ", false);
+    show_flag(buffer, hardware->cpu.flags.pclmulqd, "pclmulqd ", false);
+    show_flag(buffer, hardware->cpu.flags.dtes64, "dtes64 ", false);
+    show_flag(buffer, hardware->cpu.flags.smx, "smx ", false);
+    show_flag(buffer, hardware->cpu.flags.est, "est ", false);
+    show_flag(buffer, hardware->cpu.flags.tm2, "tm2 ", false);
+    show_flag(buffer, hardware->cpu.flags.sse3, "sse3 ", false);
+    show_flag(buffer, hardware->cpu.flags.fma, "fma ", false);
+    show_flag(buffer, hardware->cpu.flags.cx16, "cx16 ", false);
+    show_flag(buffer, hardware->cpu.flags.xtpr, "xtpr ", false);
+    show_flag(buffer, hardware->cpu.flags.pdcm, "pdcm ", false);
+    show_flag(buffer, hardware->cpu.flags.dca, "dca ", false);
+    show_flag(buffer, hardware->cpu.flags.xmm4_1, "xmm4_1 ", false);
+    show_flag(buffer, hardware->cpu.flags.xmm4_2, "xmm4_2 ", false);
+    show_flag(buffer, hardware->cpu.flags.x2apic, "x2apic ", false);
+    show_flag(buffer, hardware->cpu.flags.movbe, "movbe ", false);
+    show_flag(buffer, hardware->cpu.flags.popcnt, "popcnt ", false);
+    show_flag(buffer, hardware->cpu.flags.aes, "aes ", false);
+    show_flag(buffer, hardware->cpu.flags.xsave, "xsave ", false);
+    show_flag(buffer, hardware->cpu.flags.osxsave, "osxsave ", false);
+    show_flag(buffer, hardware->cpu.flags.avx, "avx ", false);
+    show_flag(buffer, hardware->cpu.flags.hypervisor, "hypervisor ", false);
+    show_flag(buffer, hardware->cpu.flags.ace2, "ace2 ", false);
+    show_flag(buffer, hardware->cpu.flags.ace2_en, "ace2_en ", false);
+    show_flag(buffer, hardware->cpu.flags.phe, "phe ", false);
+    show_flag(buffer, hardware->cpu.flags.phe_en, "phe_en ", false);
+    show_flag(buffer, hardware->cpu.flags.pmm, "pmm ", false);
+    show_flag(buffer, hardware->cpu.flags.pmm_en, "pmm_en ", false);
+    show_flag(buffer, hardware->cpu.flags.extapic, "extapic ", false);
+    show_flag(buffer, hardware->cpu.flags.cr8_legacy, "cr8_legacy ", false);
+    show_flag(buffer, hardware->cpu.flags.abm, "abm ", false);
+    show_flag(buffer, hardware->cpu.flags.sse4a, "sse4a ", false);
+    show_flag(buffer, hardware->cpu.flags.misalignsse, "misalignsse ", false);
+    show_flag(buffer, hardware->cpu.flags.nowprefetch, "3dnowprefetch ", false);
+    show_flag(buffer, hardware->cpu.flags.osvw, "osvw ", false);
+    show_flag(buffer, hardware->cpu.flags.ibs, "ibs ", false);
+    show_flag(buffer, hardware->cpu.flags.sse5, "sse5 ", false);
+    show_flag(buffer, hardware->cpu.flags.skinit, "skinit ", false);
+    show_flag(buffer, hardware->cpu.flags.wdt, "wdt ", false);
+    show_flag(buffer, hardware->cpu.flags.ida, "ida ", false);
+    show_flag(buffer, hardware->cpu.flags.arat, "arat ", false);
+    show_flag(buffer, hardware->cpu.flags.tpr_shadow, "tpr_shadow ", false);
+    show_flag(buffer, hardware->cpu.flags.vnmi, "vnmi ", false);
+    show_flag(buffer, hardware->cpu.flags.flexpriority, "flexpriority ", false);
+    show_flag(buffer, hardware->cpu.flags.ept, "ept ", false);
+    show_flag(buffer, hardware->cpu.flags.vpid, "vpid ", false);
+
+    /* No more flags, let's display the remaining flags */
+    show_flag(buffer, false, "", true);
+}
+
+struct cli_module_descr cpu_show_modules = {
+    .modules = NULL,
+    .default_callback = show_cpu,
+};
+
+struct cli_mode_descr cpu_mode = {
+    .mode = CPU_MODE,
+    .name = CLI_CPU,
+    .default_modules = NULL,
+    .show_modules = &cpu_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,253 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include "hdt-util.h"
+
+/**
+ * show_partition_information - print information about a partition
+ * @ptab:	part_entry describing the partition
+ * @i:		Partition number (UI purposes only)
+ * @ptab_root:	part_entry describing the root partition (extended only)
+ * @drive_info:	driveinfo struct describing the drive on which the partition
+ *		is
+ *
+ * Note on offsets (from hpa, see chain.c32):
+ *
+ *  To make things extra confusing: data partition offsets are relative to where
+ *  the data partition record is stored, whereas extended partition offsets
+ *  are relative to the beginning of the extended partition all the way back
+ *  at the MBR... but still not absolute!
+ **/
+static void show_partition_information(struct driveinfo *drive_info,
+				       struct part_entry *ptab,
+				       int partition_offset,
+				       int nb_partitions_seen)
+{
+    char size[11];
+    char bootloader_name[9];
+    char *parttype;
+    unsigned int start, end;
+
+    int i = nb_partitions_seen;
+
+    reset_more_printf();
+
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+	sectors_to_size(ptab->length, size);
+    else
+	memset(size, 0, sizeof size);
+
+    if (i == 1)
+	more_printf(" #  B       Start         End    Size Id Type\n");
+
+    get_label(ptab->ostype, &parttype);
+    more_printf("%2d  %s %11d %11d %s %02X %s",
+		i, (ptab->active_flag == 0x80) ? "x" : " ",
+		start, end, size, ptab->ostype, parttype);
+
+    /* Extra info */
+    if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
+	more_printf("%s", " (Swsusp sig. detected)");
+
+    if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
+	more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);
+
+    more_printf("\n");
+
+    free(parttype);
+}
+
+void main_show_disk(int argc, char **argv, struct s_hardware *hardware)
+{
+    if (!argc) {
+	more_printf("Which disk?\n");
+	return;
+    }
+
+    int drive = strtol(argv[0], (char **)NULL, 16);
+
+    if (drive < 0x80 || drive >= 0xff) {
+	more_printf("Invalid disk: %d.\n", drive);
+	return;
+    }
+
+    int i = drive - 0x80;
+    struct driveinfo *d = &hardware->disk_info[i];
+    char disk_size[11];
+    char mbr_name[50];
+
+    reset_more_printf();
+
+    if (!hardware->disk_info[i].cbios) {
+	more_printf("No disk found\n");
+	return;			/* Invalid geometry */
+    }
+
+    get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);
+
+    if ((int)d->edd_params.sectors > 0)
+	sectors_to_size((int)d->edd_params.sectors, disk_size);
+    else
+	memset(disk_size, 0, sizeof disk_size);
+
+    more_printf("DISK 0x%X:\n"
+		"  C/H/S: %d cylinders, %d heads, %d sectors/track\n"
+		"    EDD: Version: %X\n"
+		"         Size: %s, %d bytes/sector, %d sectors/track\n"
+		"         Host bus: %s, Interface type: %s\n"
+		"    MBR: %s (id 0x%X)\n\n",
+		d->disk,
+		d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
+		d->legacy_sectors_per_track, d->edd_version, disk_size,
+		(int)d->edd_params.bytes_per_sector,
+		(int)d->edd_params.sectors_per_track,
+		remove_spaces((char *)d->edd_params.host_bus_type),
+		remove_spaces((char *)d->edd_params.interface_type), mbr_name,
+		hardware->mbr_ids[i]);
+    display_line_nb += 6;
+
+    if (parse_partition_table(d, &show_partition_information)) {
+	if (errno_disk) {
+	    fprintf(stderr, "I/O error parsing disk 0x%X\n", d->disk);
+	    get_error("parse_partition_table");
+	} else {
+	    fprintf(stderr, "Disk 0x%X: unrecognized partition layout\n",
+		    d->disk);
+	}
+	fprintf(stderr, "\n");
+    }
+
+    more_printf("\n");
+}
+
+void main_show_disks(int argc __unused, char **argv __unused,
+		     struct s_hardware *hardware)
+{
+    bool found = false;
+    reset_more_printf();
+
+    int first_one = 0;
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	if (hardware->disk_info[drive - 0x80].cbios) {
+	    found = true;
+	    if (!first_one) {
+		first_one = 1;
+	    } else {
+		pause_printf();
+	    }
+	    char buf[5] = "";
+	    sprintf(buf, "0x%x", drive);
+	    char *argv[1] = { buf };
+	    main_show_disk(1, argv, hardware);
+	}
+    }
+
+    if (found == false)
+	more_printf("No disk found\n");
+}
+
+void disks_summary(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    int i = -1;
+    bool found = false;
+
+    reset_more_printf();
+
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	i++;
+	if (!hardware->disk_info[i].cbios)
+	    continue;		/* Invalid geometry */
+
+	found = true;
+	struct driveinfo *d = &hardware->disk_info[i];
+	char disk_size[11];
+
+	if ((int)d->edd_params.sectors > 0)
+	    sectors_to_size((int)d->edd_params.sectors, disk_size);
+	else
+	    memset(disk_size, 0, sizeof disk_size);
+
+	more_printf("DISK 0x%X:\n", d->disk);
+	more_printf("  C/H/S: %d cylinders, %d heads, %d sectors/track\n",
+		    d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
+		    d->legacy_sectors_per_track);
+	more_printf("  EDD:   Version: %X, size: %s\n", d->edd_version,
+		    disk_size);
+
+	/* Do not print Host Bus & Interface if EDD isn't 3.0 or more */
+	if (d->edd_version >= 0x30)
+	    more_printf("         Host bus: %s, Interface type: %s\n\n",
+			remove_spaces((char *)d->edd_params.host_bus_type),
+			remove_spaces((char *)d->edd_params.interface_type));
+    }
+
+    if (found == false)
+	more_printf("No disk found\n");
+}
+
+struct cli_callback_descr list_disk_show_modules[] = {
+    {
+     .name = "disks",
+     .exec = main_show_disks,
+     .nomodule = false,
+     },
+    {
+     .name = "disk",
+     .exec = main_show_disk,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr disk_show_modules = {
+    .modules = list_disk_show_modules,
+    .default_callback = disks_summary,
+};
+
+struct cli_mode_descr disk_mode = {
+    .mode = DISK_MODE,
+    .name = CLI_DISK,
+    .default_modules = NULL,
+    .show_modules = &disk_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,705 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+static void show_dmi_modules(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    char available_dmi_commands[1024];
+    reset_more_printf();
+    memset(available_dmi_commands, 0, sizeof(available_dmi_commands));
+
+    more_printf("Available DMI modules on your system:\n");
+    if (hardware->dmi.base_board.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BASE_BOARD);
+    if (hardware->dmi.battery.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BATTERY);
+    if (hardware->dmi.bios.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BIOS);
+    if (hardware->dmi.chassis.filled == true)
+	more_printf("\t%s\n", CLI_DMI_CHASSIS);
+    for (int i = 0; i < hardware->dmi.memory_count; i++) {
+	if (hardware->dmi.memory[i].filled == true) {
+	    more_printf("\tbank <number>\n");
+	    break;
+	}
+    }
+    for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
+	if (hardware->dmi.memory_module[i].filled == true) {
+	    more_printf("\tmodule <number>\n");
+	    break;
+	}
+    }
+    if (hardware->dmi.processor.filled == true)
+	more_printf("\t%s\n", CLI_DMI_PROCESSOR);
+    if (hardware->dmi.system.filled == true)
+	more_printf("\t%s\n", CLI_DMI_SYSTEM);
+    if (hardware->dmi.ipmi.filled == true)
+	more_printf("\t%s\n", CLI_DMI_IPMI);
+    if (hardware->dmi.cache_count)
+	more_printf("\t%s\n", CLI_DMI_CACHE);
+    if (strlen(hardware->dmi.oem_strings))
+	more_printf("\t%s\n", CLI_DMI_OEM);
+    if (hardware->dmi.hardware_security.filled)
+	more_printf("\t%s\n", CLI_DMI_SECURITY);
+}
+
+static void show_dmi_base_board(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    if (hardware->dmi.base_board.filled == false) {
+	more_printf("base_board information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Base board\n");
+    more_printf(" Manufacturer : %s\n", hardware->dmi.base_board.manufacturer);
+    more_printf(" Product Name : %s\n", hardware->dmi.base_board.product_name);
+    more_printf(" Version      : %s\n", hardware->dmi.base_board.version);
+    more_printf(" Serial       : %s\n", hardware->dmi.base_board.serial);
+    more_printf(" Asset Tag    : %s\n", hardware->dmi.base_board.asset_tag);
+    more_printf(" Location     : %s\n", hardware->dmi.base_board.location);
+    more_printf(" Type         : %s\n", hardware->dmi.base_board.type);
+    for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
+	    more_printf(" %s\n", base_board_features_strings[i]);
+	}
+    }
+
+    for (unsigned int i = 0;
+	 i <
+	 sizeof hardware->dmi.base_board.devices_information /
+	 sizeof *hardware->dmi.base_board.devices_information; i++) {
+	if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
+	    more_printf("On Board Device #%u Information\n", i)
+		more_printf("  Type        : %s\n",
+			    hardware->dmi.base_board.devices_information[i].
+			    type);
+	    more_printf("  Status      : %s\n",
+			hardware->dmi.base_board.devices_information[i].
+			status ? "Enabled" : "Disabled");
+	    more_printf("  Description : %s\n",
+			hardware->dmi.base_board.devices_information[i].
+			description);
+	}
+    }
+}
+
+static void show_dmi_system(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware)
+{
+    if (hardware->dmi.system.filled == false) {
+	more_printf("system information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("System\n");
+    more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
+    more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
+    more_printf(" Version      : %s\n", hardware->dmi.system.version);
+    more_printf(" Serial       : %s\n", hardware->dmi.system.serial);
+    more_printf(" UUID         : %s\n", hardware->dmi.system.uuid);
+    more_printf(" Wakeup Type  : %s\n", hardware->dmi.system.wakeup_type);
+    more_printf(" SKU Number   : %s\n", hardware->dmi.system.sku_number);
+    more_printf(" Family       : %s\n", hardware->dmi.system.family);
+
+    if (strlen(hardware->dmi.system.configuration_options)) {
+	more_printf("System Configuration Options\n");
+	more_printf("%s\n", hardware->dmi.system.configuration_options);
+    }
+
+    if (hardware->dmi.system.system_reset.filled) {
+	more_printf("System Reset\n");
+	more_printf("  Status               : %s\n",
+		    (hardware->dmi.system.system_reset.
+		     status ? "Enabled" : "Disabled"));
+	more_printf("  Watchdog Timer       : %s\n",
+		    (hardware->dmi.system.system_reset.
+		     watchdog ? "Present" : "Not Present"));
+	if (strlen(hardware->dmi.system.system_reset.boot_option))
+	    more_printf("  Boot Option          : %s\n",
+			hardware->dmi.system.system_reset.boot_option);
+	if (strlen(hardware->dmi.system.system_reset.boot_option_on_limit))
+	    more_printf("  Boot Option On Limit : %s\n",
+			hardware->dmi.system.system_reset.boot_option_on_limit);
+	if (strlen(hardware->dmi.system.system_reset.reset_count))
+	    more_printf("  Reset Count          : %s\n",
+			hardware->dmi.system.system_reset.reset_count);
+	if (strlen(hardware->dmi.system.system_reset.reset_limit))
+	    more_printf("  Reset Limit          : %s\n",
+			hardware->dmi.system.system_reset.reset_limit);
+	if (strlen(hardware->dmi.system.system_reset.timer_interval))
+	    more_printf("  Timer Interval       : %s\n",
+			hardware->dmi.system.system_reset.timer_interval);
+	if (strlen(hardware->dmi.system.system_reset.timeout))
+	    more_printf("  Timeout              : %s\n",
+			hardware->dmi.system.system_reset.timeout);
+    }
+
+    more_printf("System Boot Information\n");
+    more_printf(" Status       : %s\n",
+		hardware->dmi.system.system_boot_status);
+}
+
+static void show_dmi_bios(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    if (hardware->dmi.bios.filled == false) {
+	more_printf("bios information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("BIOS\n");
+    more_printf(" Vendor            : %s\n", hardware->dmi.bios.vendor);
+    more_printf(" Version           : %s\n", hardware->dmi.bios.version);
+    more_printf(" Release Date      : %s\n", hardware->dmi.bios.release_date);
+    more_printf(" Bios Revision     : %s\n", hardware->dmi.bios.bios_revision);
+    if (strlen(hardware->dmi.bios.firmware_revision))
+	more_printf(" Firmware Revision : %s\n",
+		    hardware->dmi.bios.firmware_revision);
+    more_printf(" Address           : 0x%04X0\n", hardware->dmi.bios.address);
+    more_printf(" Runtime address   : %u %s\n",
+		hardware->dmi.bios.runtime_size,
+		hardware->dmi.bios.runtime_size_unit);
+    more_printf(" Rom size          : %u %s\n", hardware->dmi.bios.rom_size,
+		hardware->dmi.bios.rom_size_unit);
+
+    for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
+	    more_printf(" %s\n", bios_charac_strings[i]);
+	}
+    }
+    for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
+	    more_printf(" %s\n", bios_charac_x1_strings[i]);
+	}
+    }
+
+    for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
+	    more_printf(" %s\n", bios_charac_x2_strings[i]);
+	}
+    }
+
+}
+
+static void show_dmi_chassis(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    if (hardware->dmi.chassis.filled == false) {
+	more_printf("chassis information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Chassis\n");
+    more_printf(" Manufacturer       : %s\n",
+		hardware->dmi.chassis.manufacturer);
+    more_printf(" Type               : %s\n", hardware->dmi.chassis.type);
+    more_printf(" Lock               : %s\n", hardware->dmi.chassis.lock);
+    more_printf(" Version            : %s\n", hardware->dmi.chassis.version);
+    more_printf(" Serial             : %s\n", hardware->dmi.chassis.serial);
+    more_printf(" Asset Tag          : %s\n",
+		del_multi_spaces(hardware->dmi.chassis.asset_tag));
+    more_printf(" Boot up state      : %s\n",
+		hardware->dmi.chassis.boot_up_state);
+    more_printf(" Power supply state : %s\n",
+		hardware->dmi.chassis.power_supply_state);
+    more_printf(" Thermal state      : %s\n",
+		hardware->dmi.chassis.thermal_state);
+    more_printf(" Security Status    : %s\n",
+		hardware->dmi.chassis.security_status);
+    more_printf(" OEM Information    : %s\n",
+		hardware->dmi.chassis.oem_information);
+    more_printf(" Height             : %u\n", hardware->dmi.chassis.height);
+    more_printf(" NB Power Cords     : %u\n",
+		hardware->dmi.chassis.nb_power_cords);
+}
+
+static void show_dmi_ipmi(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    if (hardware->dmi.ipmi.filled == false) {
+	more_printf("IPMI module not available\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("IPMI\n");
+    more_printf(" Interface Type     : %s\n",
+		hardware->dmi.ipmi.interface_type);
+    more_printf(" Specification Ver. : %u.%u\n",
+		hardware->dmi.ipmi.major_specification_version,
+		hardware->dmi.ipmi.minor_specification_version);
+    more_printf(" I2C Slave Address  : 0x%02x\n",
+		hardware->dmi.ipmi.I2C_slave_address);
+    more_printf(" Nv Storage Address : %u\n", hardware->dmi.ipmi.nv_address);
+    uint32_t high = hardware->dmi.ipmi.base_address >> 32;
+    uint32_t low = hardware->dmi.ipmi.base_address & 0xFFFF;
+    more_printf(" Base Address       : %08X%08X\n", high, (low & ~1));
+    more_printf(" IRQ                : %d\n", hardware->dmi.ipmi.irq);
+}
+
+static void show_dmi_battery(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    if (hardware->dmi.battery.filled == false) {
+	more_printf("battery information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Battery \n");
+    more_printf(" Vendor             : %s\n",
+		hardware->dmi.battery.manufacturer);
+    more_printf(" Manufacture Date   : %s\n",
+		hardware->dmi.battery.manufacture_date);
+    more_printf(" Serial             : %s\n", hardware->dmi.battery.serial);
+    more_printf(" Name               : %s\n", hardware->dmi.battery.name);
+    more_printf(" Chemistry          : %s\n", hardware->dmi.battery.chemistry);
+    more_printf(" Design Capacity    : %s\n",
+		hardware->dmi.battery.design_capacity);
+    more_printf(" Design Voltage     : %s\n",
+		hardware->dmi.battery.design_voltage);
+    more_printf(" SBDS               : %s\n", hardware->dmi.battery.sbds);
+    more_printf(" SBDS Manuf. Date   : %s\n",
+		hardware->dmi.battery.sbds_manufacture_date);
+    more_printf(" SBDS Chemistry     : %s\n",
+		hardware->dmi.battery.sbds_chemistry);
+    more_printf(" Maximum Error      : %s\n",
+		hardware->dmi.battery.maximum_error);
+    more_printf(" OEM Info           : %s\n", hardware->dmi.battery.oem_info);
+}
+
+static void show_dmi_cpu(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    if (hardware->dmi.processor.filled == false) {
+	more_printf("processor information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("CPU\n");
+    more_printf(" Socket Designation : %s\n",
+		hardware->dmi.processor.socket_designation);
+    more_printf(" Type               : %s\n", hardware->dmi.processor.type);
+    more_printf(" Family             : %s\n", hardware->dmi.processor.family);
+    more_printf(" Manufacturer       : %s\n",
+		hardware->dmi.processor.manufacturer);
+    more_printf(" Version            : %s\n", hardware->dmi.processor.version);
+    more_printf(" External Clock     : %u\n",
+		hardware->dmi.processor.external_clock);
+    more_printf(" Max Speed          : %u\n",
+		hardware->dmi.processor.max_speed);
+    more_printf(" Current Speed      : %u\n",
+		hardware->dmi.processor.current_speed);
+    more_printf(" Cpu Type           : %u\n",
+		hardware->dmi.processor.signature.type);
+    more_printf(" Cpu Family         : %u\n",
+		hardware->dmi.processor.signature.family);
+    more_printf(" Cpu Model          : %u\n",
+		hardware->dmi.processor.signature.model);
+    more_printf(" Cpu Stepping       : %u\n",
+		hardware->dmi.processor.signature.stepping);
+    more_printf(" Cpu Minor Stepping : %u\n",
+		hardware->dmi.processor.signature.minor_stepping);
+    more_printf("Voltage             : %d.%02d\n",
+                hardware->dmi.processor.voltage_mv / 1000,
+                hardware->dmi.processor.voltage_mv -
+                ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+    more_printf(" Status             : %s\n", hardware->dmi.processor.status);
+    more_printf(" Upgrade            : %s\n", hardware->dmi.processor.upgrade);
+    more_printf(" Cache L1 Handle    : %s\n", hardware->dmi.processor.cache1);
+    more_printf(" Cache L2 Handle    : %s\n", hardware->dmi.processor.cache2);
+    more_printf(" Cache L3 Handle    : %s\n", hardware->dmi.processor.cache3);
+    more_printf(" Serial             : %s\n", hardware->dmi.processor.serial);
+    more_printf(" Part Number        : %s\n",
+		hardware->dmi.processor.part_number);
+    if (hardware->dmi.processor.core_count != 0)
+        more_printf(" Cores Count        : %d\n", hardware->dmi.processor.core_count);
+    if (hardware->dmi.processor.core_enabled != 0)
+        more_printf(" Cores Enabled      : %d\n", hardware->dmi.processor.core_enabled);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf(" Threads Count      : %d\n", hardware->dmi.processor.thread_count);
+
+    more_printf(" ID                 : %s\n", hardware->dmi.processor.id);
+    for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
+	    more_printf(" %s\n", cpu_flags_strings[i]);
+	}
+    }
+}
+
+void show_dmi_memory_bank(int argc, char **argv, struct s_hardware *hardware)
+{
+    int bank = -1;
+
+    /* Sanitize arguments */
+    if (argc > 0)
+	bank = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE || bank < 0) {
+	more_printf("This bank number is incorrect\n");
+	return;
+    }
+
+    if ((bank >= hardware->dmi.memory_count) || (bank < 0)) {
+	more_printf("Bank %d number doesn't exist\n", bank);
+	return;
+    }
+    if (hardware->dmi.memory[bank].filled == false) {
+	more_printf("Bank %d doesn't contain any information\n", bank);
+	return;
+    }
+
+    reset_more_printf();
+    more_printf("Memory Bank %d\n", bank);
+    more_printf(" Form Factor  : %s\n", hardware->dmi.memory[bank].form_factor);
+    more_printf(" Type         : %s\n", hardware->dmi.memory[bank].type);
+    more_printf(" Type Detail  : %s\n", hardware->dmi.memory[bank].type_detail);
+    more_printf(" Speed        : %s\n", hardware->dmi.memory[bank].speed);
+    more_printf(" Size         : %s\n", hardware->dmi.memory[bank].size);
+    more_printf(" Device Set   : %s\n", hardware->dmi.memory[bank].device_set);
+    more_printf(" Device Loc.  : %s\n",
+		hardware->dmi.memory[bank].device_locator);
+    more_printf(" Bank Locator : %s\n",
+		hardware->dmi.memory[bank].bank_locator);
+    more_printf(" Total Width  : %s\n", hardware->dmi.memory[bank].total_width);
+    more_printf(" Data Width   : %s\n", hardware->dmi.memory[bank].data_width);
+    more_printf(" Error        : %s\n", hardware->dmi.memory[bank].error);
+    more_printf(" Vendor       : %s\n",
+		hardware->dmi.memory[bank].manufacturer);
+    more_printf(" Serial       : %s\n", hardware->dmi.memory[bank].serial);
+    more_printf(" Asset Tag    : %s\n", hardware->dmi.memory[bank].asset_tag);
+    more_printf(" Part Number  : %s\n", hardware->dmi.memory[bank].part_number);
+}
+
+static void show_dmi_cache(int argc, char **argv, struct s_hardware *hardware)
+{
+    if (!hardware->dmi.cache_count) {
+	more_printf("cache information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+
+    int cache = strtol(argv[0], NULL, 10);
+
+    if (argc != 1 || cache > hardware->dmi.cache_count) {
+	more_printf("show cache [0-%d]\n", hardware->dmi.cache_count - 1);
+	return;
+    }
+
+    reset_more_printf();
+
+    more_printf("Cache Information #%d\n", cache);
+    more_printf("  Socket Designation    : %s\n",
+		hardware->dmi.cache[cache].socket_designation);
+    more_printf("  Configuration         : %s\n",
+		hardware->dmi.cache[cache].configuration);
+    more_printf("  Operational Mode      : %s\n",
+		hardware->dmi.cache[cache].mode);
+    more_printf("  Location              : %s\n",
+		hardware->dmi.cache[cache].location);
+    more_printf("  Installed Size        : %u KB",
+		hardware->dmi.cache[cache].installed_size);
+    more_printf("\n");
+    more_printf("  Maximum Size          : %u KB",
+		hardware->dmi.cache[cache].max_size);
+    more_printf("\n");
+    more_printf("  Supported SRAM Types  : %s",
+		hardware->dmi.cache[cache].supported_sram_types);
+    more_printf("\n");
+    more_printf("  Installed SRAM Type   : %s",
+		hardware->dmi.cache[cache].installed_sram_types);
+    more_printf("\n");
+    more_printf("  Speed                 : %u ns",
+		hardware->dmi.cache[cache].speed);
+    more_printf("\n");
+    more_printf("  Error Correction Type : %s\n",
+		hardware->dmi.cache[cache].error_correction_type);
+    more_printf("  System Type           : %s\n",
+		hardware->dmi.cache[cache].system_type);
+    more_printf("  Associativity         : %s\n",
+		hardware->dmi.cache[cache].associativity);
+}
+
+void show_dmi_memory_module(int argc, char **argv, struct s_hardware *hardware)
+{
+    int module = -1;
+
+    /* Sanitize arguments */
+    if (argc > 0)
+	module = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE || module < 0) {
+	more_printf("This module number is incorrect\n");
+	return;
+    }
+
+    if ((module >= hardware->dmi.memory_module_count) || (module < 0)) {
+	more_printf("Module number %d doesn't exist\n", module);
+	return;
+    }
+
+    if (hardware->dmi.memory_module[module].filled == false) {
+	more_printf("Module %d doesn't contain any information\n", module);
+	return;
+    }
+
+    reset_more_printf();
+    more_printf("Memory Module %d\n", module);
+    more_printf(" Socket Designation : %s\n",
+		hardware->dmi.memory_module[module].socket_designation);
+    more_printf(" Bank Connections   : %s\n",
+		hardware->dmi.memory_module[module].bank_connections);
+    more_printf(" Current Speed      : %s\n",
+		hardware->dmi.memory_module[module].speed);
+    more_printf(" Type               : %s\n",
+		hardware->dmi.memory_module[module].type);
+    more_printf(" Installed Size     : %s\n",
+		hardware->dmi.memory_module[module].installed_size);
+    more_printf(" Enabled Size       : %s\n",
+		hardware->dmi.memory_module[module].enabled_size);
+    more_printf(" Error Status       : %s\n",
+		hardware->dmi.memory_module[module].error_status);
+}
+
+void main_show_dmi(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+
+    if (hardware->is_dmi_valid == false) {
+	more_printf("No valid DMI table found, exiting.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("DMI Table version %u.%u found\n",
+		hardware->dmi.dmitable.major_version,
+		hardware->dmi.dmitable.minor_version);
+
+    show_dmi_modules(0, NULL, hardware);
+}
+
+void show_dmi_memory_modules(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    /* Do we have so display unpopulated banks ? */
+    int show_free_banks = 1;
+
+    more_printf("Memory Size   : %lu MB (%lu KB)\n",
+		(hardware->detected_memory_size + (1 << 9)) >> 10,
+		hardware->detected_memory_size);
+
+    if ((hardware->dmi.memory_count <= 0)
+	&& (hardware->dmi.memory_module_count <= 0)) {
+	more_printf("No memory bank found\n");
+	return;
+    }
+
+    /* Sanitize arguments */
+    if (argc > 0) {
+	/* When we display a summary, there is no need to show the unpopulated banks
+	 * The first argv is set to define this behavior
+	 */
+	show_free_banks = strtol(argv[0], NULL, 10);
+	if (errno == ERANGE || show_free_banks < 0 || show_free_banks > 1)
+	    goto usage;
+    }
+
+    reset_more_printf();
+    /* If type 17 is available */
+    if (hardware->dmi.memory_count > 0) {
+	char bank_number[255];
+	more_printf("Memory Banks\n");
+	for (int i = 0; i < hardware->dmi.memory_count; i++) {
+	    if (hardware->dmi.memory[i].filled == true) {
+		memset(bank_number, 0, sizeof(bank_number));
+		snprintf(bank_number, sizeof(bank_number), "%d ", i);
+		if (show_free_banks == false) {
+		    if (strncmp(hardware->dmi.memory[i].size, "Free", 4))
+			more_printf(" bank %02d      : %s %s@%s\n",
+				    i, hardware->dmi.memory[i].size,
+				    hardware->dmi.memory[i].type,
+				    hardware->dmi.memory[i].speed);
+		} else {
+		    more_printf(" bank %02d      : %s %s@%s\n", i,
+				hardware->dmi.memory[i].size,
+				hardware->dmi.memory[i].type,
+				hardware->dmi.memory[i].speed);
+		}
+	    }
+	}
+    } else if (hardware->dmi.memory_module_count > 0) {
+	/* Let's use type 6 as a fallback of type 17 */
+	more_printf("Memory Modules\n");
+	for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
+	    if (hardware->dmi.memory_module[i].filled == true) {
+		more_printf(" module %02d    : %s %s@%s\n", i,
+			    hardware->dmi.memory_module[i].enabled_size,
+			    hardware->dmi.memory_module[i].type,
+			    hardware->dmi.memory_module[i].speed);
+	    }
+	}
+    }
+
+    return;
+    //printf("Type 'show bank<bank_number>' for more details.\n");
+
+usage:
+    more_printf("show memory <clear screen? <show free banks?>>\n");
+    return;
+}
+
+void show_dmi_oem_strings(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (strlen(hardware->dmi.oem_strings))
+	more_printf("OEM Strings\n%s", hardware->dmi.oem_strings);
+}
+
+void show_dmi_hardware_security(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (!hardware->dmi.hardware_security.filled)
+	return;
+
+    more_printf("Hardware Security\n");
+    more_printf("  Power-On Password Status      : %s\n",
+		hardware->dmi.hardware_security.power_on_passwd_status);
+    more_printf("  Keyboard Password Status      : %s\n",
+		hardware->dmi.hardware_security.keyboard_passwd_status);
+    more_printf("  Administrator Password Status : %s\n",
+		hardware->dmi.hardware_security.administrator_passwd_status);
+    more_printf("  Front Panel Reset Status      : %s\n",
+		hardware->dmi.hardware_security.front_panel_reset_status);
+}
+
+struct cli_callback_descr list_dmi_show_modules[] = {
+    {
+     .name = CLI_DMI_BASE_BOARD,
+     .exec = show_dmi_base_board,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_BIOS,
+     .exec = show_dmi_bios,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_BATTERY,
+     .exec = show_dmi_battery,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_CHASSIS,
+     .exec = show_dmi_chassis,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_MEMORY,
+     .exec = show_dmi_memory_modules,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_MEMORY_BANK,
+     .exec = show_dmi_memory_bank,
+     .nomodule = false,
+     },
+    {
+     .name = "module",
+     .exec = show_dmi_memory_module,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_PROCESSOR,
+     .exec = show_dmi_cpu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_SYSTEM,
+     .exec = show_dmi_system,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_OEM,
+     .exec = show_dmi_oem_strings,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_SECURITY,
+     .exec = show_dmi_hardware_security,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_IPMI,
+     .exec = show_dmi_ipmi,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_CACHE,
+     .exec = show_dmi_cache,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_LIST,
+     .exec = show_dmi_modules,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr dmi_show_modules = {
+    .modules = list_dmi_show_modules,
+    .default_callback = main_show_dmi,
+};
+
+struct cli_mode_descr dmi_mode = {
+    .mode = DMI_MODE,
+    .name = CLI_DMI,
+    .default_modules = NULL,
+    .show_modules = &dmi_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,491 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslinux/config.h>
+#include <syslinux/reboot.h>
+
+#include "hdt-menu.h"
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+/**
+ * cli_clear_screen - clear (erase) the entire screen
+ **/
+static void cli_clear_screen(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    clear_screen();
+}
+
+/**
+ * main_show_modes - show availables modes
+ **/
+static void main_show_modes(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware __unused)
+{
+    int i = 0;
+
+    reset_more_printf();
+    more_printf("Available modes:\n");
+    while (list_modes[i]) {
+	printf("%s ", list_modes[i]->name);
+	i++;
+    }
+    more_printf("\n");
+}
+
+/**
+ * cli_set_mode - set the mode of the cli, in the cli
+ *
+ * The mode number must be supplied in argv, position 0.
+ **/
+static void cli_set_mode(int argc, char **argv, struct s_hardware *hardware)
+{
+    cli_mode_t new_mode;
+
+    reset_more_printf();
+    if (argc <= 0) {
+	more_printf("Which mode?\n");
+	return;
+    }
+
+    /*
+     * Note! argv[0] is a string representing the mode, we need the
+     * equivalent cli_mode_t to pass it to set_mode.
+     */
+    new_mode = mode_s_to_mode_t(argv[0]);
+    set_mode(new_mode, hardware);
+}
+
+/**
+ * do_exit - shared helper to exit a mode
+ **/
+static void do_exit(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    int new_mode = HDT_MODE;
+
+    switch (hdt_cli.mode) {
+    case HDT_MODE:
+	new_mode = EXIT_MODE;
+	break;
+    default:
+	new_mode = HDT_MODE;
+	break;
+    }
+
+    dprintf("CLI DEBUG: Switching from mode %d to mode %d\n", hdt_cli.mode,
+	    new_mode);
+    set_mode(new_mode, hardware);
+}
+
+/**
+ * show_cli_help - shared helper to show available commands
+ **/
+static void show_cli_help(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware __unused)
+{
+    int j = 0;
+    struct cli_mode_descr *current_mode;
+    struct cli_callback_descr *associated_module = NULL;
+
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+
+    more_printf("Available commands are:\n");
+
+    /* List first default modules of the mode */
+    if (current_mode->default_modules && current_mode->default_modules->modules) {
+	while (current_mode->default_modules->modules[j].name) {
+	    printf("%s ", current_mode->default_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List finally the default modules of the hdt mode */
+    if (current_mode->mode != hdt_mode.mode &&
+	hdt_mode.default_modules && hdt_mode.default_modules->modules) {
+	j = 0;
+	while (hdt_mode.default_modules->modules[j].name) {
+	    /*
+	     * Any default command that is present in hdt mode but
+	     * not in the current mode is available. A default
+	     * command can be redefined in the current mode though.
+	     * This next call test this use case: if it is
+	     * overwritten, do not print it again.
+	     */
+	    find_cli_callback_descr(hdt_mode.default_modules->modules[j].name,
+				    current_mode->default_modules,
+				    &associated_module);
+	    if (associated_module == NULL)
+		printf("%s ", hdt_mode.default_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List secondly the show modules of the mode */
+    if (current_mode->show_modules && current_mode->show_modules->modules) {
+	more_printf("\nshow commands:\n");
+	j = 0;
+	while (current_mode->show_modules->modules[j].name) {
+	    printf("%s ", current_mode->show_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List thirdly the set modules of the mode */
+    if (current_mode->set_modules && current_mode->set_modules->modules) {
+	more_printf("\nset commands:\n");
+	j = 0;
+	while (current_mode->set_modules->modules[j].name) {
+	    printf("%s ", current_mode->set_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+
+    printf("\n");
+    main_show_modes(argc, argv, hardware);
+}
+
+/**
+ * show_cli_help - shared helper to show available commands
+ **/
+static void goto_menu(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    char version_string[256];
+    snprintf(version_string, sizeof version_string, "%s %s (%s)",
+	     PRODUCT_NAME, VERSION, CODENAME);
+    start_menu_mode(hardware, version_string);
+    return;
+}
+
+/**
+ * main_show_summary - give an overview of the system
+ **/
+void main_show_summary(int argc __unused, char **argv __unused,
+		       struct s_hardware *hardware)
+{
+    reset_more_printf();
+    clear_screen();
+    main_show_cpu(argc, argv, hardware);
+    if (hardware->is_dmi_valid) {
+	more_printf("System\n");
+	more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
+	more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
+	more_printf(" Serial       : %s\n", hardware->dmi.system.serial);
+	more_printf("Bios\n");
+	more_printf(" Version      : %s\n", hardware->dmi.bios.version);
+	more_printf(" Release      : %s\n", hardware->dmi.bios.release_date);
+	more_printf("Memory Size   : %lu MB (%lu KB)\n",
+		    (hardware->detected_memory_size + (1 << 9)) >> 10,
+		    hardware->detected_memory_size);
+    }
+    main_show_pci(argc, argv, hardware);
+
+    if (hardware->is_pxe_valid)
+	main_show_pxe(argc, argv, hardware);
+
+    main_show_kernel(argc, argv, hardware);
+}
+
+void main_show_hdt(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware __unused)
+{
+    reset_more_printf();
+    more_printf("HDT\n");
+    more_printf(" Product        : %s\n", PRODUCT_NAME);
+    more_printf(" Version        : %s (%s)\n", VERSION, CODENAME);
+    more_printf(" Website        : %s\n", WEBSITE_URL);
+    more_printf(" IRC Channel    : %s\n", IRC_CHANNEL);
+    more_printf(" Mailing List   : %s\n", CONTACT);
+    more_printf(" Project Leader : %s\n", AUTHOR);
+    more_printf(" Core Developer : %s\n", CORE_DEVELOPER);
+    char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+    for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+	more_printf(" Contributor    : %s\n", contributors[c]);
+    }
+}
+
+/**
+ * do_reboot - reboot the system
+ **/
+static void do_reboot(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    (void) hardware;
+    /* Let's call the internal rebooting call */
+    syslinux_reboot(1);
+}
+
+/**
+ * do_dump - dump info
+ **/
+static void do_dump(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    dump(hardware);
+}
+
+/**
+ * do_sleep - sleep a number of milliseconds
+ **/ 
+static void do_sleep(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if (argc != 1) return;
+   more_printf("Sleep %d milliseconds\n",atoi(argv[0]));
+   msleep(atoi(argv[0]));
+}
+
+/**
+ * do_display - display an image to user
+ **/
+static void do_display(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if ((argc != 1) || (vesamode == false)) return;
+   more_printf("Display %s file\n",argv[0]);
+   vesacon_load_background(argv[0]);
+}
+
+/**
+ * do_say - say message to user
+ **/
+static void do_say(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if (argc == 0) return;
+
+   char text_to_say[255]={0};
+   int arg=0;
+#if DEBUG
+   for (int i=0; i<argc;i++) dprintf("SAY: arg[%d]={%s}\n",i,argv[i]);
+#endif
+   char *argument = strchr(argv[arg],'`');
+   if ( argument != NULL) {
+	argument++;
+   	strcat(text_to_say, argument);
+
+   	while ((strchr(argument, '`') == NULL) && (arg+1<argc)) {
+		arg++;
+		argument = (char *)argv[arg];
+		strcat(text_to_say, " ");
+		strcat(text_to_say, argument);
+   	}
+    
+	/* Removing last ` if any */
+    	char *last_quote = strrchr(text_to_say,'`');
+    	if ( last_quote != NULL ) {
+	*last_quote='\0';
+	dprintf("SAY CMD = [%s]\n",text_to_say);	   
+    	}
+
+  	more_printf("%s\n",text_to_say);
+  }
+}
+
+/* Default hdt mode */
+struct cli_callback_descr list_hdt_default_modules[] = {
+    {
+     .name = CLI_CLEAR,
+     .exec = cli_clear_screen,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_EXIT,
+     .exec = do_exit,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HELP,
+     .exec = show_cli_help,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_MENU,
+     .exec = goto_menu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_REBOOT,
+     .exec = do_reboot,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HISTORY,
+     .exec = print_history,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DUMP,
+     .exec = do_dump,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_SAY,
+     .exec = do_say,
+     .nomodule = true,
+     },
+    {
+     .name = CLI_DISPLAY,
+     .exec = do_display,
+     .nomodule = true,
+     },
+    {
+     .name = CLI_SLEEP,
+     .exec = do_sleep,
+     .nomodule = true,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false},
+};
+
+struct cli_callback_descr list_hdt_show_modules[] = {
+    {
+     .name = CLI_SUMMARY,
+     .exec = main_show_summary,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_PCI,
+     .exec = main_show_pci,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI,
+     .exec = main_show_dmi,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_CPU,
+     .exec = main_show_cpu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DISK,
+     .exec = disks_summary,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_PXE,
+     .exec = main_show_pxe,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_SYSLINUX,
+     .exec = main_show_syslinux,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_KERNEL,
+     .exec = main_show_kernel,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_VESA,
+     .exec = main_show_vesa,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HDT,
+     .exec = main_show_hdt,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_VPD,
+     .exec = main_show_vpd,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_MEMORY,
+     .exec = show_dmi_memory_modules,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_ACPI,
+     .exec = main_show_acpi,
+     .nomodule = false,
+     },
+    {
+     .name = "modes",
+     .exec = main_show_modes,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_callback_descr list_hdt_set_modules[] = {
+    {
+     .name = CLI_MODE,
+     .exec = cli_set_mode,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr hdt_default_modules = {
+    .modules = list_hdt_default_modules,
+};
+
+struct cli_module_descr hdt_show_modules = {
+    .modules = list_hdt_show_modules,
+    .default_callback = main_show_summary,
+};
+
+struct cli_module_descr hdt_set_modules = {
+    .modules = list_hdt_set_modules,
+};
+
+struct cli_mode_descr hdt_mode = {
+    .mode = HDT_MODE,
+    .name = CLI_HDT,
+    .default_modules = &hdt_default_modules,
+    .show_modules = &hdt_show_modules,
+    .set_modules = &hdt_set_modules,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,148 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_kernel(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    char buffer[1024] = {0};
+    struct pci_device *pci_device;
+    bool found = false;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    reset_more_printf();
+    more_printf("Kernel modules\n");
+
+// more_printf(" PCI device no: %d \n", p->pci_device_pos);
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP)
+	&& (hardware->modules_alias_return_code == -ENOMODULESALIAS)) {
+	more_printf(" modules.pcimap and modules.alias files are missing\n");
+	return;
+    }
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+
+	if ((pci_device->dev_info->linux_kernel_module_count > 0)
+	    && (!strstr(buffer, kernel_modules))) {
+	    found = true;
+	    if (pci_device->dev_info->linux_kernel_module_count > 1)
+		strncat(buffer, "(", 1);
+	    strncat(buffer, kernel_modules, sizeof(kernel_modules));
+	    if (pci_device->dev_info->linux_kernel_module_count > 1)
+		strncat(buffer, ")", 1);
+	    strncat(buffer, " # ", 3);
+	}
+
+    }
+    if (found == true) {
+	strncat(buffer, "\n", 1);
+	more_printf("%s", buffer);
+    }
+}
+
+static void show_kernel_modules(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    char modules[MAX_PCI_CLASSES][256] = {{0}};
+    char category_name[MAX_PCI_CLASSES][256] = {{0}};
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	more_printf(" Missing pci.ids, we can't compute the list\n");
+	return;
+    }
+
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	more_printf(" Missing modules.pcimap, we can't compute the list\n");
+	return;
+    }
+
+    reset_more_printf();
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	    strncat(kernel_modules, " ", 1);
+	}
+
+	if ((pci_device->dev_info->linux_kernel_module_count > 0)
+	    && (!strstr(modules[pci_device->class[2]], kernel_modules))) {
+	    strncat(modules[pci_device->class[2]], kernel_modules,
+		    sizeof(kernel_modules));
+	    snprintf(category_name[pci_device->class[2]],
+		     sizeof(category_name[pci_device->class[2]]),
+		     "%s", pci_device->dev_info->category_name);
+	}
+    }
+    /* Print the found items */
+    for (int i = 0; i < MAX_PCI_CLASSES; i++) {
+	if (strlen(category_name[i]) > 1) {
+	    more_printf("%s : %s\n", category_name[i], modules[i]);
+	}
+    }
+}
+
+struct cli_module_descr kernel_show_modules = {
+    .modules = NULL,
+    .default_callback = show_kernel_modules,
+};
+
+struct cli_mode_descr kernel_mode = {
+    .mode = KERNEL_MODE,
+    .name = CLI_KERNEL,
+    .default_modules = NULL,
+    .show_modules = &kernel_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,139 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <memory.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+static void show_memory_e820(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    struct e820entry map[E820MAX];
+    unsigned long memsize = 0;
+    int count = 0;
+    char type[14];
+
+    detect_memory_e820(map, E820MAX, &count);
+    memsize = memsize_e820(map, count);
+    reset_more_printf();
+    more_printf("Detected RAM                       : %lu MiB (%lu KiB)\n",
+		(memsize + (1 << 9)) >> 10, memsize);
+    more_printf("BIOS-provided physical RAM e820 map:\n");
+    for (int i = 0; i < count; i++) {
+	get_type(map[i].type, type, 14);
+	more_printf("%016llx - %016llx %016llx (%s)\n",
+		    map[i].addr, map[i].size, map[i].addr + map[i].size,
+		    remove_spaces(type));
+    }
+    struct e820entry nm[E820MAX];
+
+    /* Clean up, adjust and copy the BIOS-supplied E820-map. */
+    int nr = sanitize_e820_map(map, nm, count);
+
+    more_printf("\n");
+    more_printf("Sanitized e820 map:\n");
+    for (int i = 0; i < nr; i++) {
+	get_type(nm[i].type, type, 14);
+	more_printf("%016llx - %016llx %016llx (%s)\n",
+		    nm[i].addr, nm[i].size, nm[i].addr + nm[i].size,
+		    remove_spaces(type));
+    }
+}
+
+static void show_memory_e801(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    int mem_low, mem_high = 0;
+
+    reset_more_printf();
+    if (detect_memory_e801(&mem_low, &mem_high)) {
+	more_printf("e801 bogus!\n");
+    } else {
+	more_printf("Detected RAM : %d MiB(%d KiB)\n",
+		    (mem_low >> 10) + (mem_high >> 4),
+		    mem_low + (mem_high << 6));
+	more_printf("e801 details : %d Kb (%d MiB) - %d Kb (%d MiB)\n", mem_low,
+		    mem_low >> 10, mem_high << 6, mem_high >> 4);
+    }
+}
+
+static void show_memory_88(int argc __unused, char **argv __unused,
+			   struct s_hardware *hardware __unused)
+{
+    int mem_size = 0;
+
+    reset_more_printf();
+    if (detect_memory_88(&mem_size)) {
+	more_printf("8800h bogus!\n");
+    } else {
+	more_printf("8800h memory size: %d Kb (%d MiB)\n", mem_size,
+		    mem_size >> 10);
+    }
+}
+
+struct cli_callback_descr list_memory_show_modules[] = {
+    {
+     .name = "e820",
+     .exec = show_memory_e820,
+     .nomodule=false,
+     },
+    {
+     .name = "e801",
+     .exec = show_memory_e801,
+     .nomodule=false,
+     },
+    {
+     .name = "88",
+     .exec = show_memory_88,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_DMI_MEMORY_BANK,
+     .exec = show_dmi_memory_bank,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr memory_show_modules = {
+    .modules = list_memory_show_modules,
+    .default_callback = show_dmi_memory_modules,
+};
+
+struct cli_mode_descr memory_mode = {
+    .mode = MEMORY_MODE,
+    .name = CLI_MEMORY,
+    .default_modules = NULL,
+    .show_modules = &memory_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,294 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_pci(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    reset_more_printf();
+    more_printf("PCI\n");
+    more_printf(" NB Devices   : %d\n", hardware->nb_pci_devices);
+}
+
+static void show_pci_device(int argc, char **argv, struct s_hardware *hardware)
+{
+    int i = 0;
+    struct pci_device *pci_device = NULL, *temp_pci_device;
+    int pcidev = -1;
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfiles = false;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    int bus = 0, slot = 0, func = 0;
+
+    reset_more_printf();
+    /* Sanitize arguments */
+    if (argc <= 0) {
+	more_printf("show device <number>\n");
+	return;
+    } else
+	pcidev = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE) {
+	more_printf("This PCI device number is incorrect\n");
+	return;
+    }
+    if ((pcidev > hardware->nb_pci_devices) || (pcidev <= 0)) {
+	more_printf("PCI device %d doesn't exist\n", pcidev);
+	return;
+    }
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_alias_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+    nomodulesfiles = nomodulespcimap && nomodulesalias;
+    for_each_pci_func(temp_pci_device, hardware->pci_domain) {
+	i++;
+	if (i == pcidev) {
+	    bus = __pci_bus;
+	    slot = __pci_slot;
+	    func = __pci_func;
+	    pci_device = temp_pci_device;
+	}
+    }
+
+    if (pci_device == NULL) {
+	more_printf("We were enabled to find PCI device %d\n", pcidev);
+	return;
+    }
+
+    memset(kernel_modules, 0, sizeof kernel_modules);
+    for (int kmod = 0;
+	 kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	if (kmod > 0) {
+	    strncat(kernel_modules, " | ", 3);
+	}
+	strncat(kernel_modules,
+		pci_device->dev_info->linux_kernel_module[kmod],
+		LINUX_KERNEL_MODULE_SIZE - 1);
+    }
+    if (pci_device->dev_info->linux_kernel_module_count == 0)
+	strlcpy(kernel_modules, "unknown", 7);
+
+    more_printf("PCI Device %d\n", pcidev);
+
+    if (nopciids == false) {
+	more_printf("Vendor Name   : %s\n", pci_device->dev_info->vendor_name);
+	more_printf("Product Name  : %s\n", pci_device->dev_info->product_name);
+	more_printf("Class Name    : %s\n", pci_device->dev_info->class_name);
+    }
+
+    if (nomodulesfiles == false) {
+	more_printf("Kernel module : %s\n", kernel_modules);
+    }
+
+    more_printf("Vendor ID     : %04x\n", pci_device->vendor);
+    more_printf("Product ID    : %04x\n", pci_device->product);
+    more_printf("SubVendor ID  : %04x\n", pci_device->sub_vendor);
+    more_printf("SubProduct ID : %04x\n", pci_device->sub_product);
+    more_printf("Class ID      : %02x.%02x.%02x\n", pci_device->class[2],
+		pci_device->class[1], pci_device->class[0]);
+    more_printf("Revision      : %02x\n", pci_device->revision);
+    if ((pci_device->dev_info->irq > 0)
+	&& (pci_device->dev_info->irq < 255))
+	more_printf("IRQ           : %0d\n", pci_device->dev_info->irq);
+    more_printf("Latency       : %0d\n", pci_device->dev_info->latency);
+    more_printf("PCI Bus       : %02d\n", bus);
+    more_printf("PCI Slot      : %02d\n", slot);
+    more_printf("PCI Func      : %02d\n", func);
+
+    if (hardware->is_pxe_valid == true) {
+	if ((hardware->pxe.pci_device != NULL)
+	    && (hardware->pxe.pci_device == pci_device)) {
+	    more_printf("Mac Address   : %s\n", hardware->pxe.mac_addr);
+	    more_printf("PXE           : Current boot device\n");
+	}
+    }
+}
+
+static void show_pci_devices(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    int i = 1;
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfile = false;
+    char first_line[81];
+    char second_line[81];
+
+    reset_more_printf();
+    more_printf("%d PCI devices detected\n", hardware->nb_pci_devices);
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+
+    nomodulesfile = nomodulespcimap && nomodulesalias;
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	if (nopciids == false) {
+	    snprintf(first_line, sizeof(first_line),
+		     "%02d: %s %s \n", i,
+		     pci_device->dev_info->vendor_name,
+		     pci_device->dev_info->product_name);
+	    if (nomodulesfile == false)
+		snprintf(second_line, sizeof(second_line),
+			 "    # %-25s # Kmod: %s\n",
+			 pci_device->dev_info->class_name, kernel_modules);
+	    else
+		snprintf(second_line, sizeof(second_line),
+			 "    # %-25s # ID:%04x:%04x[%04x:%04x]\n",
+			 pci_device->dev_info->class_name,
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->sub_vendor, pci_device->sub_product);
+
+	    more_printf("%s", first_line);
+	    more_printf("%s", second_line);
+	    more_printf("\n");
+	} else if (nopciids == true) {
+	    if (nomodulesfile == true) {
+		more_printf("%02d: %04x:%04x [%04x:%04x] \n",
+			    i, pci_device->vendor,
+			    pci_device->product,
+			    pci_device->sub_vendor, pci_device->sub_product);
+	    } else {
+		more_printf
+		    ("%02d: %04x:%04x [%04x:%04x] Kmod:%s\n", i,
+		     pci_device->vendor, pci_device->product,
+		     pci_device->sub_vendor,
+		     pci_device->sub_product, kernel_modules);
+	    }
+	}
+	i++;
+    }
+}
+
+static void show_pci_irq(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    struct pci_device *pci_device;
+    bool nopciids = false;
+
+    reset_more_printf();
+    more_printf("%d PCI devices detected\n", hardware->nb_pci_devices);
+    more_printf("IRQ : product\n");
+    more_printf("-------------\n");
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	/* Only display valid IRQs */
+	if ((pci_device->dev_info->irq > 0)
+	    && (pci_device->dev_info->irq < 255)) {
+	    if (nopciids == false) {
+		more_printf("%02d  : %s %s \n",
+			    pci_device->dev_info->irq,
+			    pci_device->dev_info->vendor_name,
+			    pci_device->dev_info->product_name);
+	    } else {
+		more_printf("%02d  : %04x:%04x [%04x:%04x] \n",
+			    pci_device->dev_info->irq,
+			    pci_device->vendor,
+			    pci_device->product,
+			    pci_device->sub_vendor, pci_device->sub_product);
+	    }
+	}
+    }
+}
+
+struct cli_callback_descr list_pci_show_modules[] = {
+    {
+     .name = CLI_IRQ,
+     .exec = show_pci_irq,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_PCI_DEVICE,
+     .exec = show_pci_device,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr pci_show_modules = {
+    .modules = list_pci_show_modules,
+    .default_callback = show_pci_devices,
+};
+
+struct cli_mode_descr pci_mode = {
+    .mode = PCI_MODE,
+    .name = CLI_PCI,
+    .default_modules = NULL,
+    .show_modules = &pci_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+#include <sys/gpxe.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_pxe(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    char buffer[81];
+    memset(buffer, 0, sizeof(81));
+    reset_more_printf();
+    if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	more_printf("You are not currently using PXELINUX\n");
+	return;
+    }
+
+    more_printf("PXE\n");
+    if (hardware->is_pxe_valid == false) {
+	more_printf(" No valid PXE ROM found\n");
+	return;
+    }
+
+    struct s_pxe *p = &hardware->pxe;
+    more_printf(" PCI device no: %d \n", p->pci_device_pos);
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS || (p->pci_device == NULL)) {
+	snprintf(buffer, sizeof(buffer),
+		 " PCI ID       : %04x:%04x[%04x:%04X] rev(%02x)\n",
+		 p->vendor_id, p->product_id, p->subvendor_id,
+		 p->subproduct_id, p->rev);
+	snprintf(buffer, sizeof(buffer),
+		 " PCI Bus pos. : %02x:%02x.%02x\n", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	more_printf("%s", buffer);
+    } else {
+	snprintf(buffer, sizeof(buffer), " Manufacturer : %s \n",
+		 p->pci_device->dev_info->vendor_name);
+	more_printf("%s", buffer);
+	snprintf(buffer, sizeof(buffer), " Product      : %s \n",
+		 p->pci_device->dev_info->product_name);
+	more_printf("%s", buffer);
+    }
+    more_printf(" Addresses    : %d.%d.%d.%d @ %s\n", p->ip_addr[0],
+		p->ip_addr[1], p->ip_addr[2], p->ip_addr[3], p->mac_addr);
+
+    if (is_gpxe())
+	more_printf(" gPXE Detected: Yes\n")
+    else
+	more_printf(" gPXE Detected: No\n");
+}
+
+struct cli_module_descr pxe_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_pxe,
+};
+
+struct cli_mode_descr pxe_mode = {
+    .mode = PXE_MODE,
+    .name = CLI_PXE,
+    .default_modules = NULL,
+    .show_modules = &pxe_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_syslinux(int argc __unused, char **argv __unused,
+			struct s_hardware *hardware)
+{
+    reset_more_printf();
+    more_printf("SYSLINUX\n");
+    more_printf(" Bootloader : %s\n", hardware->syslinux_fs);
+    more_printf(" Version    : %s\n", hardware->sv->version_string);
+    more_printf(" Version    : %u\n", hardware->sv->version);
+    more_printf(" Max API    : %u\n", hardware->sv->max_api);
+    more_printf(" Copyright  : %s\n", hardware->sv->copyright_string);
+}
+
+struct cli_module_descr syslinux_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_syslinux,
+};
+
+struct cli_mode_descr syslinux_mode = {
+    .mode = SYSLINUX_MODE,
+    .name = CLI_SYSLINUX,
+    .default_modules = NULL,
+    .show_modules = &syslinux_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+void main_show_vesa(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    reset_more_printf();
+    if (hardware->is_vesa_valid == false) {
+	more_printf("No VESA BIOS detected\n");
+	return;
+    }
+    more_printf("VESA\n");
+    more_printf(" Vesa version : %d.%d\n", hardware->vesa.major_version,
+		hardware->vesa.minor_version);
+    more_printf(" Vendor       : %s\n", hardware->vesa.vendor);
+    more_printf(" Product      : %s\n", hardware->vesa.product);
+    more_printf(" Product rev. : %s\n", hardware->vesa.product_revision);
+    more_printf(" Software rev.: %d\n", hardware->vesa.software_rev);
+    more_printf(" Memory (KB)  : %d\n", hardware->vesa.total_memory * 64);
+    more_printf(" Modes        : %d\n", hardware->vesa.vmi_count);
+}
+
+static void show_vesa_modes(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware)
+{
+    reset_more_printf();
+    if (hardware->is_vesa_valid == false) {
+	more_printf("No VESA BIOS detected\n");
+	return;
+    }
+    more_printf(" ResH. x ResV x Bits : vga= : Vesa Mode\n");
+    more_printf("----------------------------------------\n");
+
+    for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+	struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+	/*
+	 * Sometimes, vesa bios reports 0x0 modes.
+	 * We don't need to display that ones.
+	 */
+	if ((mi->h_res == 0) || (mi->v_res == 0))
+	    continue;
+	more_printf("%5u %5u    %3u     %3d     0x%04x\n",
+		    mi->h_res, mi->v_res, mi->bpp,
+		    hardware->vesa.vmi[i].mode + 0x200,
+		    hardware->vesa.vmi[i].mode);
+    }
+}
+
+static void enable_vesa(int argc __unused, char **argv __unused,
+			struct s_hardware *hardware)
+{
+    vesamode = true;
+    max_console_lines = MAX_VESA_CLI_LINES;
+    init_console(hardware);
+}
+
+static void disable_vesa(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    vesamode = false;
+    max_console_lines = MAX_CLI_LINES;
+    init_console(hardware);
+}
+
+struct cli_callback_descr list_vesa_show_modules[] = {
+    {
+     .name = CLI_MODES,
+     .exec = show_vesa_modes,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_callback_descr list_vesa_commands[] = {
+    {
+     .name = CLI_ENABLE,
+     .exec = enable_vesa,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_DISABLE,
+     .exec = disable_vesa,
+     .nomodule=false,
+     },
+
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr vesa_show_modules = {
+    .modules = list_vesa_show_modules,
+    .default_callback = main_show_vesa,
+};
+
+struct cli_module_descr vesa_commands = {
+    .modules = list_vesa_commands,
+    .default_callback = enable_vesa,
+};
+
+struct cli_mode_descr vesa_mode = {
+    .mode = VESA_MODE,
+    .name = CLI_VESA,
+    .default_modules = &vesa_commands,
+    .show_modules = &vesa_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <string.h>
+#include <vpd/vpd.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_vpd(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (!hardware->is_vpd_valid) {
+	more_printf("No VPD structure detected.\n");
+	return;
+    }
+
+    more_printf("VPD present at address : %s\n", hardware->vpd.base_address);
+    if (strlen(hardware->vpd.bios_build_id) > 0)
+	more_printf("Bios Build ID                 : %s\n",
+		    hardware->vpd.bios_build_id);
+    if (strlen(hardware->vpd.bios_release_date) > 0)
+	more_printf("Bios Release Date             : %s\n",
+		    hardware->vpd.bios_release_date);
+    if (strlen(hardware->vpd.bios_version) > 0)
+	more_printf("Bios Version                  : %s\n",
+		    hardware->vpd.bios_version);
+    if (strlen(hardware->vpd.default_flash_filename) > 0)
+	more_printf("Default Flash Filename        : %s\n",
+		    hardware->vpd.default_flash_filename);
+    if (strlen(hardware->vpd.box_serial_number) > 0)
+	more_printf("Box Serial Number             : %s\n",
+		    hardware->vpd.box_serial_number);
+    if (strlen(hardware->vpd.motherboard_serial_number) > 0)
+	more_printf("Motherboard Serial Number     : %s\n",
+		    hardware->vpd.motherboard_serial_number);
+    if (strlen(hardware->vpd.machine_type_model) > 0)
+	more_printf("Machine Type/Model            : %s\n",
+		    hardware->vpd.machine_type_model);
+}
+
+struct cli_module_descr vpd_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_vpd,
+};
+
+struct cli_mode_descr vpd_mode = {
+    .mode = VPD_MODE,
+    .name = CLI_VPD,
+    .default_modules = NULL,
+    .show_modules = &vpd_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1141 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <getkey.h>
+#include <acpi/acpi.h>
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+struct cli_mode_descr *list_modes[] = {
+    &hdt_mode,
+    &dmi_mode,
+    &syslinux_mode,
+    &pxe_mode,
+    &kernel_mode,
+    &cpu_mode,
+    &pci_mode,
+    &vesa_mode,
+    &disk_mode,
+    &vpd_mode,
+    &memory_mode,
+    &acpi_mode,
+    NULL,
+};
+
+/*
+ * .aliases = {"q", "quit"} won't work since it is an array of pointers, not an
+ * array of variables. There is no easy way around it besides declaring the arrays of
+ * strings first.
+ */
+const char *exit_aliases[] = { "q", "quit" };
+const char *help_aliases[] = { "h", "?" };
+
+/* List of aliases */
+struct cli_alias hdt_aliases[] = {
+    {
+     .command = CLI_EXIT,
+     .nb_aliases = 2,
+     .aliases = exit_aliases,
+     },
+    {
+     .command = CLI_HELP,
+     .nb_aliases = 2,
+     .aliases = help_aliases,
+     },
+};
+
+struct cli_mode_descr *current_mode;
+int autocomplete_backlog;
+
+struct autocomplete_list {
+    char autocomplete_token[MAX_LINE_SIZE];
+    struct autocomplete_list *next;
+};
+struct autocomplete_list *autocomplete_head = NULL;
+struct autocomplete_list *autocomplete_tail = NULL;
+struct autocomplete_list *autocomplete_last_seen = NULL;
+
+static void autocomplete_add_token_to_list(const char *token)
+{
+    struct autocomplete_list *new = malloc(sizeof(struct autocomplete_list));
+
+    strlcpy(new->autocomplete_token, token, sizeof(new->autocomplete_token));
+    new->next = NULL;
+    autocomplete_backlog++;
+
+    if (autocomplete_tail != NULL)
+	autocomplete_tail->next = new;
+    if (autocomplete_head == NULL)
+	autocomplete_head = new;
+    autocomplete_tail = new;
+}
+
+static void autocomplete_destroy_list(void)
+{
+    struct autocomplete_list *tmp = NULL;
+
+    while (autocomplete_head != NULL) {
+	tmp = autocomplete_head->next;
+	free(autocomplete_head);
+	autocomplete_head = tmp;
+    }
+    autocomplete_backlog = 0;
+    autocomplete_tail = NULL;
+    autocomplete_last_seen = NULL;
+}
+
+/**
+ * set_mode - set the current mode of the cli
+ * @mode:	mode to set
+ *
+ * Unlike cli_set_mode, this function is not used by the cli directly.
+ **/
+void set_mode(cli_mode_t mode, struct s_hardware *hardware)
+{
+    int i = 0;
+
+    switch (mode) {
+    case EXIT_MODE:
+	hdt_cli.mode = mode;
+	break;
+    case HDT_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_HDT);
+	break;
+    case PXE_MODE:
+	if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	    more_printf("You are not currently using PXELINUX\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PXE);
+	break;
+    case KERNEL_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_KERNEL);
+	break;
+    case SYSLINUX_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_SYSLINUX);
+	break;
+    case VESA_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VESA);
+	break;
+    case PCI_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PCI);
+	break;
+    case CPU_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_CPU);
+	break;
+    case DMI_MODE:
+	if (!hardware->is_dmi_valid) {
+	    more_printf("No valid DMI table found, exiting.\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DMI);
+	break;
+    case DISK_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DISK);
+	break;
+    case VPD_MODE:
+	if (!hardware->is_vpd_valid) {
+	    more_printf("No valid VPD table found, exiting.\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VPD);
+	break;
+    case MEMORY_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_MEMORY);
+	break;
+    case ACPI_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_ACPI);
+	break;
+    default:
+	/* Invalid mode */
+	more_printf("Unknown mode, please choose among:\n");
+	while (list_modes[i]) {
+	    more_printf("\t%s\n", list_modes[i]->name);
+	    i++;
+	}
+    }
+
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+    /* There is not cli_mode_descr struct for the exit mode */
+    if (current_mode == NULL && hdt_cli.mode != EXIT_MODE) {
+	/* Shouldn't get here... */
+	more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+    }
+}
+
+/**
+ * mode_s_to_mode_t - given a mode string, return the cli_mode_t representation
+ **/
+cli_mode_t mode_s_to_mode_t(char *name)
+{
+    int i = 0;
+
+    while (list_modes[i]) {
+	if (!strncmp(name, list_modes[i]->name, sizeof(list_modes[i]->name)))
+	    break;
+	i++;
+    }
+
+    if (!list_modes[i])
+	return INVALID_MODE;
+    else
+	return list_modes[i]->mode;
+}
+
+/**
+ * find_cli_mode_descr - find the cli_mode_descr struct associated to a mode
+ * @mode:	mode to look for
+ * @mode_found:	store the mode if found, NULL otherwise
+ *
+ * Given a mode name, return a pointer to the associated cli_mode_descr
+ * structure.
+ * Note: the current mode name is stored in hdt_cli.mode.
+ **/
+void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found)
+{
+    int i = 0;
+
+    while (list_modes[i] && list_modes[i]->mode != mode)
+	i++;
+
+    /* Shouldn't get here... */
+    if (!list_modes[i])
+	*mode_found = NULL;
+    else
+	*mode_found = list_modes[i];
+}
+
+/**
+ * expand_aliases - resolve aliases mapping
+ * @line:	command line to parse
+ * @command:	first token in the line
+ * @module:	second token in the line
+ * @argc:	number of arguments
+ * @argv:	array of arguments
+ *
+ * We maintain a small list of static alises to enhance user experience.
+ * Only commands can be aliased (first token). Otherwise it can become really hairy...
+ **/
+static void expand_aliases(char *line __unused, char **command, char **module,
+			   int *argc, char **argv)
+{
+    struct cli_mode_descr *mode;
+    int i, j;
+
+    find_cli_mode_descr(mode_s_to_mode_t(*command), &mode);
+    if (mode != NULL && *module == NULL) {
+	/*
+	 * The user specified a mode instead of `set mode...', e.g.
+	 * `dmi' instead of `set mode dmi'
+	 */
+
+	/* *argv is NULL since *module is NULL */
+	*argc = 1;
+	*argv = malloc(*argc * sizeof(char *));
+	argv[0] = malloc((sizeof(*command) + 1) * sizeof(char));
+	strlcpy(argv[0], *command, sizeof(*command) + 1);
+	dprintf("CLI DEBUG: ALIAS %s ", *command);
+
+	strlcpy(*command, CLI_SET, sizeof(CLI_SET));	/* set */
+
+	*module = malloc(sizeof(CLI_MODE) * sizeof(char));
+	strlcpy(*module, CLI_MODE, sizeof(CLI_MODE));	/* mode */
+
+	dprintf("--> %s %s %s\n", *command, *module, argv[0]);
+	goto out;
+    }
+
+    /* Simple aliases mapping a single command to another one */
+    for (i = 0; i < MAX_ALIASES; i++) {
+	for (j = 0; j < hdt_aliases[i].nb_aliases; j++) {
+	    if (!strncmp(*command, hdt_aliases[i].aliases[j],
+			 sizeof(hdt_aliases[i].aliases[j]))) {
+		dprintf("CLI DEBUG: ALIAS %s ", *command);
+		strlcpy(*command, hdt_aliases[i].command,
+			sizeof(hdt_aliases[i].command) + 1);
+		dprintf("--> %s\n", *command);
+		goto out;	/* Don't allow chaining aliases */
+	    }
+	}
+    }
+    return;
+
+out:
+    dprintf("CLI DEBUG: New parameters:\n");
+    dprintf("CLI DEBUG: command = %s\n", *command);
+    dprintf("CLI DEBUG: module  = %s\n", *module);
+    dprintf("CLI DEBUG: argc    = %d\n", *argc);
+    for (i = 0; i < *argc; i++)
+	dprintf("CLI DEBUG: argv[%d] = %s\n", i, argv[0]);
+    return;
+}
+
+/**
+ * parse_command_line - low level parser for the command line
+ * @line:	command line to parse
+ * @command:	first token in the line
+ * @module:	second token in the line
+ * @argc:	number of arguments
+ * @argv:	array of arguments
+ *
+ * The format of the command line is:
+ *	<main command> [<module on which to operate> [<args>]]
+ *	command is always malloc'ed (even for an empty line)
+ **/
+static void parse_command_line(char *line, char **command, char **module,
+			       int *argc, char **argv)
+{
+    int argc_iter = 0, args_pos = 0, token_found = 0, token_len = 0;
+    int args_len = 0;
+    char *pch = NULL, *pch_next = NULL, *tmp_pch_next = NULL;
+
+    *command = NULL;
+    *module = NULL;
+    *argc = 0;
+
+    pch = line;
+    while (pch != NULL) {
+	pch_next = strchr(pch + 1, ' ');
+	tmp_pch_next = pch_next;
+
+	/*
+	 * Skip whitespaces if the user entered
+	 * 'set   mode        foo' for 'set mode foo'
+	 *  ^   ^
+	 *  |___|___ pch
+	 *      |___ pch_next <- wrong!
+	 *
+	 *  We still keep the position into tmp_pch_next to compute
+	 *  the lenght of the current token.
+	 */
+	while (pch_next != NULL && !strncmp(pch_next, CLI_SPACE, 1))
+	    pch_next++;
+
+	/* End of line guaranteed to be zeroed */
+	if (pch_next == NULL) {
+	    token_len = (int)(strchr(pch + 1, '\0') - pch);
+	    args_len = token_len;
+	} else {
+	    token_len = (int)(tmp_pch_next - pch);
+	    args_len = (int)(pch_next - pch);
+	}
+
+	if (token_found == 0) {
+	    /* Main command to execute */
+	    *command = malloc((token_len + 1) * sizeof(char));
+	    strlcpy(*command, pch, token_len);
+	    (*command)[token_len] = '\0';
+	    dprintf("CLI DEBUG parse: command = %s\n", *command);
+	    args_pos += args_len;
+	} else if (token_found == 1) {
+	    /* Module */
+	    *module = malloc((token_len + 1) * sizeof(char));
+	    strlcpy(*module, pch, token_len);
+	    (*module)[token_len] = '\0';
+	    dprintf("CLI DEBUG parse: module  = %s\n", *module);
+	    args_pos += args_len;
+	} else
+	    (*argc)++;
+
+	token_found++;
+	pch = pch_next;
+    }
+    dprintf("CLI DEBUG parse: argc    = %d\n", *argc);
+
+    /* Skip arguments handling if none is supplied */
+    if (!*argc)
+	return;
+
+    /* Transform the arguments string into an array */
+    *argv = malloc(*argc * sizeof(char *));
+    pch = strtok(line + args_pos, CLI_SPACE);
+    while (pch != NULL) {
+	dprintf("CLI DEBUG parse: argv[%d] = %s\n", argc_iter, pch);
+	argv[argc_iter] = malloc(strlen(pch) * sizeof(char));
+	strlcpy(argv[argc_iter], pch, strlen(pch));
+	argc_iter++;
+	pch = strtok(NULL, CLI_SPACE);
+	/*
+	 * strtok(NULL, CLI_SPACE) over a stream of spaces
+	 * will return an empty string
+	 */
+	while (pch != NULL && !strncmp(pch, "", 1))
+	    pch = strtok(NULL, CLI_SPACE);
+    }
+}
+
+/**
+ * find_cli_callback_descr - find a callback in a list of modules
+ * @module_name:	Name of the module to find
+ * @modules_list:	Lits of modules among which to find @module_name
+ * @module_found:	Pointer to the matched module, NULL if not found
+ *
+ * Given a module name and a list of possible modules, find the corresponding
+ * module structure that matches the module name and store it in @module_found.
+ **/
+void find_cli_callback_descr(const char *module_name,
+			     struct cli_module_descr *modules_list,
+			     struct cli_callback_descr **module_found)
+{
+    int modules_iter = 0;
+
+    if (modules_list == NULL)
+	goto not_found;
+
+    /* Find the callback to execute */
+    while (modules_list->modules[modules_iter].name &&
+	   strcmp(module_name, modules_list->modules[modules_iter].name) != 0)
+	modules_iter++;
+
+    if (modules_list->modules[modules_iter].name) {
+	*module_found = &(modules_list->modules[modules_iter]);
+	dprintf("CLI DEBUG: module %s found\n", (*module_found)->name);
+	return;
+    }
+
+not_found:
+    *module_found = NULL;
+    return;
+}
+
+/**
+ * autocomplete_command - print matching commands
+ * @command:	Beginning of the command
+ *
+ * Given a string @command, print all availables commands starting with
+ * @command. Commands are found within the list of commands for the current
+ * mode and the hdt mode (if the current mode is not hdt).
+ **/
+static void autocomplete_command(char *command)
+{
+    int j = 0;
+    struct cli_callback_descr *associated_module = NULL;
+
+    /* First take care of the two special commands: 'show' and 'set' */
+    if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
+	printf("%s\n", CLI_SHOW);
+	autocomplete_add_token_to_list(CLI_SHOW);
+    }
+    if (strncmp(CLI_SET, command, strlen(command)) == 0) {
+	printf("%s\n", CLI_SET);
+	autocomplete_add_token_to_list(CLI_SET);
+    }
+
+    /*
+     * Then, go through the modes for the special case
+     *      '<mode>' -> 'set mode <mode>'
+     */
+    while (list_modes[j]) {
+	if (strncmp(list_modes[j]->name, command, strlen(command)) == 0) {
+	    printf("%s\n", list_modes[j]->name);
+	    autocomplete_add_token_to_list(list_modes[j]->name);
+	}
+	j++;
+    }
+
+    /*
+     * Let's go now through the list of default_modules for the current mode
+     * (single token commands for the current_mode)
+     */
+    j = 0;
+    if (current_mode->default_modules && current_mode->default_modules->modules) {
+	while (current_mode->default_modules->modules[j].name) {
+	    if (strncmp(current_mode->default_modules->modules[j].name,
+			command, strlen(command)) == 0) {
+		printf("%s\n", current_mode->default_modules->modules[j].name);
+		autocomplete_add_token_to_list(current_mode->default_modules->
+					       modules[j].name);
+	    }
+	    j++;
+	}
+    }
+
+    /*
+     * Finally, if the current_mode is not hdt, list the available
+     * default_modules of hdt (these are always available from any mode).
+     */
+    if (current_mode->mode == HDT_MODE)
+	return;
+
+    if (!hdt_mode.default_modules || !hdt_mode.default_modules->modules)
+	return;
+
+    j = 0;
+    while (hdt_mode.default_modules &&
+	   hdt_mode.default_modules->modules[j].name) {
+	/*
+	 * Any default command that is present in hdt mode but
+	 * not in the current mode is available. A default
+	 * command can be redefined in the current mode though.
+	 * This next call tests this use case: if it is
+	 * overwritten, do not print it again.
+	 */
+	find_cli_callback_descr(hdt_mode.default_modules->modules[j].name,
+				current_mode->default_modules,
+				&associated_module);
+	if (associated_module == NULL &&
+	    strncmp(command,
+		    hdt_mode.default_modules->modules[j].name,
+		    strlen(command)) == 0) {
+	    printf("%s\n", hdt_mode.default_modules->modules[j].name);
+	    autocomplete_add_token_to_list(hdt_mode.default_modules->modules[j].
+					   name);
+	}
+	j++;
+    }
+}
+
+/**
+ * autocomplete_module - print matching modules
+ * @command:	Command on the command line (not NULL)
+ * @module:	Beginning of the module
+ *
+ * Given a command @command and a string @module, print all availables modules
+ * starting with @module for command @command. Commands are found within the
+ * list of commands for the current mode and the hdt mode (if the current mode
+ * is not hdt).
+ **/
+static void autocomplete_module(char *command, char *module)
+{
+    int j = 0;
+    char autocomplete_full_line[MAX_LINE_SIZE];
+
+    if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
+	if (!current_mode->show_modules || !current_mode->show_modules->modules)
+	    return;
+
+	while (current_mode->show_modules->modules[j].name) {
+	    if (strncmp(current_mode->show_modules->modules[j].name,
+			module, strlen(module)) == 0) {
+		printf("%s\n", current_mode->show_modules->modules[j].name);
+		sprintf(autocomplete_full_line, "%s %s",
+			CLI_SHOW, current_mode->show_modules->modules[j].name);
+		autocomplete_add_token_to_list(autocomplete_full_line);
+	    }
+	    j++;
+	}
+    } else if (strncmp(CLI_SET, command, strlen(command)) == 0) {
+	j = 0;
+	if (!current_mode->set_modules || !current_mode->set_modules->modules)
+	    return;
+
+	while (current_mode->set_modules->modules[j].name) {
+	    if (strncmp(current_mode->set_modules->modules[j].name,
+			module, strlen(module)) == 0) {
+		printf("%s\n", current_mode->set_modules->modules[j].name);
+		sprintf(autocomplete_full_line, "%s %s",
+			CLI_SET, current_mode->set_modules->modules[j].name);
+		autocomplete_add_token_to_list(autocomplete_full_line);
+	    }
+	    j++;
+	}
+    }
+}
+
+/**
+ * autocomplete - find possible matches for a command line
+ * @line:	command line to parse
+ **/
+static void autocomplete(char *line)
+{
+    int i;
+    int argc = 0;
+    char *command = NULL, *module = NULL;
+    char **argv = NULL;
+
+    parse_command_line(line, &command, &module, &argc, argv);
+
+    dprintf("CLI DEBUG autocomplete: before checking args\n");
+    /* If the user specified arguments, there is nothing we can complete */
+    if (argc != 0)
+	goto out;
+
+    /* No argument, (the start of) a module has been specified */
+    if (module != NULL) {
+	autocomplete_module(command, module);
+	free(module);
+	goto out;
+    }
+
+    /* No argument, no module, (the start of) a command has been specified */
+    if (command != NULL) {
+	autocomplete_command(command);
+	free(command);
+	goto out;
+    }
+
+out:
+    /* Let's not forget to clean ourselves */
+    for (i = 0; i < argc; i++)
+	free(argv[i]);
+    if (argc > 0)
+	free(argv);
+    return;
+}
+
+/**
+ * exec_command - main logic to map the command line to callbacks
+ **/
+static void exec_command(char *line, struct s_hardware *hardware)
+{
+    int argc, i = 0;
+    char *command = NULL, *module = NULL;
+    char **argv = NULL;
+    struct cli_callback_descr *current_module = NULL;
+
+    /* This will allocate memory for command and module */
+    parse_command_line(line, &command, &module, &argc, argv);
+
+    dprintf("CLI DEBUG exec: Checking for aliases\n");
+    /*
+     * Expand shortcuts, if needed
+     * This will allocate memory for argc/argv
+     */
+    expand_aliases(line, &command, &module, &argc, argv);
+    
+    find_cli_callback_descr(command, current_mode->default_modules,
+				&current_module);
+
+    if ((module == NULL) || (current_module->nomodule == true)) {
+	dprintf("CLI DEBUG exec : single command detected\n");
+	/*
+	 * A single word was specified: look at the list of default
+	 * commands in the current mode to see if there is a match.
+	 * If not, it may be a generic function (exit, help, ...). These
+	 * are stored in the list of default commands of the hdt mode.
+	 */
+
+	/* First of all it the command doesn't need module, let's rework the arguments */
+	if ((current_module->nomodule == true) && ( module != NULL)) {
+		dprintf("CLI_DEBUG exec: Reworking arguments with argc=%d\n",argc);
+		char **new_argv=NULL;
+    		new_argv=malloc((argc + 2)*sizeof(char *));
+		for (int argc_iter=0; argc_iter<argc; argc_iter++) {
+			dprintf("CLI_DEBUG exec rework : copy %d to %d (%s)\n",argc_iter,argc_iter+1,argv[argc_iter]);
+			new_argv[argc_iter+1] = malloc(strlen(argv[argc_iter]));
+			strlcpy(new_argv[argc_iter+1], argv[argc_iter], strlen(argv[argc_iter]));
+			free(argv[argc_iter]);
+		}
+		new_argv[0] = malloc(strlen(module)*sizeof(char));
+		strlcpy(new_argv[0], module, strlen(module));
+		argc++;
+		free(argv);
+		argv=new_argv;
+	}
+
+	if (current_module != NULL)
+	    current_module->exec(argc, argv, hardware);
+	else if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1) &&
+		 current_mode->show_modules != NULL &&
+		 current_mode->show_modules->default_callback != NULL)
+	    current_mode->show_modules->default_callback(argc, argv, hardware);
+	else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1) &&
+		 current_mode->set_modules != NULL &&
+		 current_mode->set_modules->default_callback != NULL)
+	    current_mode->set_modules->default_callback(argc, argv, hardware);
+	else {
+	    find_cli_callback_descr(command, hdt_mode.default_modules,
+				    &current_module);
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else
+		more_printf("unknown command: '%s'\n", command);
+	}
+    } else {
+	/*
+	 * A module has been specified! We now need to find the type of command.
+	 *
+	 * The syntax of the cli is the following:
+	 *    <type of command> <module on which to operate> <args>
+	 * e.g.
+	 *    dmi> show system
+	 *    dmi> show bank 1
+	 *    dmi> show memory 0 1
+	 *    pci> show device 12
+	 *    hdt> set mode dmi
+	 */
+	if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
+	    dprintf("CLI DEBUG exec: %s command detected\n", CLI_SHOW);
+	    /* Look first for a 'show' callback in the current mode */
+	    find_cli_callback_descr(module, current_mode->show_modules,
+				    &current_module);
+	    /* Execute the callback, if found */
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else {
+		dprintf("CLI DEBUG exec: Looking for callback\n");
+		/* Look now for a 'show' callback in the hdt mode */
+		find_cli_callback_descr(module, hdt_mode.show_modules,
+					&current_module);
+		/* Execute the callback, if found */
+		if (current_module != NULL)
+		    current_module->exec(argc, argv, hardware);
+		else
+		    printf("unknown module: '%s'\n", module);
+	    }
+	} else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1)) {
+	    dprintf("CLI DEBUG exec : %s command detected\n", CLI_SET);
+	    /* Look now for a 'set' callback in the hdt mode */
+	    find_cli_callback_descr(module, current_mode->set_modules,
+				    &current_module);
+	    /* Execute the callback, if found */
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else {
+		/* Look now for a 'set' callback in the hdt mode */
+		find_cli_callback_descr(module, hdt_mode.set_modules,
+					&current_module);
+		/* Execute the callback, if found */
+		if (current_module != NULL)
+		    current_module->exec(argc, argv, hardware);
+		else
+		    printf("unknown module: '%s'\n", module);
+	    }
+	}
+    }
+
+    /* Let's not forget to clean ourselves */
+    if (command != NULL)
+	free(command);
+    if (module != NULL)
+	free(module);
+    for (i = 0; i < argc; i++)
+	free(argv[i]);
+    if (argc > 0)
+	free(argv);
+}
+
+static void reset_prompt(void)
+{
+    /* No need to display the prompt if we exit */
+    if (hdt_cli.mode != EXIT_MODE) {
+	printf("%s", hdt_cli.prompt);
+	/* Reset the line */
+	hdt_cli.cursor_pos = 0;
+    }
+}
+
+void start_auto_mode(struct s_hardware *hardware)
+{
+    char *mypch;
+    int nb_commands = 0;
+    char *commands[MAX_NB_AUTO_COMMANDS];
+
+    more_printf("\nEntering Auto mode\n");
+
+    /* Protecting the auto_label from the strtok modifications */
+    char *temp = strdup(hardware->auto_label);
+
+    /* Searching & saving all commands */
+    mypch = strtok(temp, AUTO_SEPARATOR);
+    while (mypch != NULL) {
+	if ((strlen(remove_spaces(mypch)) > 0) &&
+	    (remove_spaces(mypch)[0] != AUTO_SEPARATOR[0])) {
+	    nb_commands++;
+	    if ((commands[nb_commands] = malloc(AUTO_COMMAND_SIZE)) != NULL) {
+		sprintf(commands[nb_commands], "%s", remove_spaces(mypch));
+	    } else
+		nb_commands--;
+	}
+	mypch = strtok(NULL, AUTO_SEPARATOR);
+    }
+
+    free(temp);
+
+    /* Executing found commands */
+    for (int i = 1; i <= nb_commands; i++) {
+	if (commands[i]) {
+	    if (!quiet)
+		more_printf("%s%s\n", hdt_cli.prompt, commands[i]);
+	    exec_command(commands[i], hardware);
+	    free(commands[i]);
+	}
+    }
+
+    if (!quiet)
+	more_printf("\nExiting Auto mode\n");
+
+    more_printf("\n");
+}
+
+void print_history(int argc, char **argv, struct s_hardware * hardware)
+{
+    (void)argc;
+    (void)argv;
+    (void)hardware;
+
+    reset_more_printf();
+    for (int i = 1; i <= MAX_HISTORY_SIZE; i++) {
+	if (i == hdt_cli.history_pos) {
+	    more_printf("*%d:'%s'\n", i, hdt_cli.history[i]);
+	    continue;
+	}
+	if (strlen(hdt_cli.history[i]) == 0)
+	    continue;
+	more_printf(" %d:'%s'\n", i, hdt_cli.history[i]);
+    }
+}
+
+/* Code that manages the cli mode */
+void start_cli_mode(struct s_hardware *hardware)
+{
+    int current_key = 0;
+    int future_history_pos = 1;	/* position of the next position in the history */
+    int current_future_history_pos = 1;	/* Temp variable */
+    bool display_history = true;	/* Temp Variable */
+    char temp_command[MAX_LINE_SIZE];
+
+    hdt_cli.cursor_pos = 0;
+    memset(hdt_cli.history, 0, sizeof(hdt_cli.history));
+    hdt_cli.history_pos = 1;
+    hdt_cli.max_history_pos = 1;
+
+    /* Find the mode selected */
+    set_mode(HDT_MODE, hardware);
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+    if (current_mode == NULL) {
+	/* Shouldn't get here... */
+	more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+	return;
+    }
+
+    /* Start the auto mode if the command line is set */
+    if (strlen(hardware->auto_label) > 0) {
+	start_auto_mode(hardware);
+    }
+
+    more_printf("Entering CLI mode\n");
+
+    reset_prompt();
+
+    while (hdt_cli.mode != EXIT_MODE) {
+
+	/* Display the cursor */
+	display_cursor(true);
+
+	/* Let's put the cursor blinking until we get an input */
+	set_cursor_blink(true);
+
+	/* We wait endlessly for a keyboard input */
+	current_key = get_key(stdin, 0);
+
+	/* We have to cancel the blinking mode to prevent
+	 * input text to blink */
+	set_cursor_blink(false);
+
+	/* Reset autocomplete buffer unless TAB is pressed */
+	if (current_key != KEY_TAB)
+	    autocomplete_destroy_list();
+
+	switch (current_key) {
+	    /* clear until then end of line */
+	case KEY_CTRL('k'):
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+	    memset(&INPUT[hdt_cli.cursor_pos], 0,
+		   strlen(INPUT) - hdt_cli.cursor_pos);
+	    break;
+
+	case KEY_CTRL('c'):
+	    printf("\n");
+	    reset_prompt();
+	    break;
+
+	case KEY_LEFT:
+	    if (hdt_cli.cursor_pos > 0) {
+		move_cursor_left(1);
+		hdt_cli.cursor_pos--;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	    if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
+		move_cursor_right(1);
+		hdt_cli.cursor_pos++;
+	    }
+	    break;
+
+	case KEY_CTRL('e'):
+	case KEY_END:
+	    /* Calling with a 0 value will make the cursor move */
+	    /* So, let's move the cursor only if needed */
+	    if ((strlen(INPUT) - hdt_cli.cursor_pos) > 0) {
+		/* Return to the begining of line */
+		move_cursor_right(strlen(INPUT) - hdt_cli.cursor_pos);
+		hdt_cli.cursor_pos = strlen(INPUT);
+	    }
+	    break;
+
+	case KEY_CTRL('a'):
+	case KEY_HOME:
+	    /* Calling with a 0 value will make the cursor move */
+	    /* So, let's move the cursor only if needed */
+	    if (hdt_cli.cursor_pos > 0) {
+		/* Return to the begining of line */
+		move_cursor_left(hdt_cli.cursor_pos);
+		hdt_cli.cursor_pos = 0;
+	    }
+	    break;
+
+	case KEY_UP:
+
+	    /* Saving future position */
+	    current_future_history_pos = future_history_pos;
+
+	    /* We have to compute the next position */
+	    if (future_history_pos == 1) {
+		future_history_pos = MAX_HISTORY_SIZE;
+	    } else {
+		future_history_pos--;
+	    }
+
+	    /* Does the next position is valid */
+	    if (strlen(hdt_cli.history[future_history_pos]) == 0) {
+		/* Position is invalid, restoring position */
+		future_history_pos = current_future_history_pos;
+		break;
+	    }
+
+	    /* Let's make that future position the one we use */
+	    memset(INPUT, 0, sizeof(INPUT));
+	    strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
+
+	    /* Clear the line */
+	    clear_line();
+
+	    /* Move to the begining of line */
+	    move_cursor_to_column(0);
+
+	    reset_prompt();
+	    printf("%s", INPUT);
+	    hdt_cli.cursor_pos = strlen(INPUT);
+	    break;
+
+	case KEY_DOWN:
+	    display_history = true;
+
+	    /* Saving future position */
+	    current_future_history_pos = future_history_pos;
+
+	    if (future_history_pos == MAX_HISTORY_SIZE) {
+		future_history_pos = 1;
+	    } else {
+		future_history_pos++;
+	    }
+
+	    /* Does the next position is valid */
+	    if (strlen(hdt_cli.history[future_history_pos]) == 0)
+		display_history = false;
+
+	    /* An exception is made to reach the last empty line */
+	    if (future_history_pos == hdt_cli.max_history_pos)
+		display_history = true;
+
+	    if (display_history == false) {
+		/* Position is invalid, restoring position */
+		future_history_pos = current_future_history_pos;
+		break;
+	    }
+
+	    /* Let's make that future position the one we use */
+	    memset(INPUT, 0, sizeof(INPUT));
+	    strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
+
+	    /* Clear the line */
+	    clear_line();
+
+	    /* Move to the begining of line */
+	    move_cursor_to_column(0);
+
+	    reset_prompt();
+	    printf("%s", INPUT);
+	    hdt_cli.cursor_pos = strlen(INPUT);
+	    break;
+
+	case KEY_TAB:
+	    if (autocomplete_backlog) {
+		clear_line();
+		/* Move to the begining of line */
+		move_cursor_to_column(0);
+		reset_prompt();
+		printf("%s", autocomplete_last_seen->autocomplete_token);
+		strlcpy(INPUT,
+			autocomplete_last_seen->autocomplete_token,
+			sizeof(INPUT));
+		hdt_cli.cursor_pos = strlen(INPUT);
+
+		/* Cycle through the list */
+		autocomplete_last_seen = autocomplete_last_seen->next;
+		if (autocomplete_last_seen == NULL)
+		    autocomplete_last_seen = autocomplete_head;
+	    } else {
+		printf("\n");
+		autocomplete(skip_spaces(INPUT));
+		autocomplete_last_seen = autocomplete_head;
+
+		printf("%s%s", hdt_cli.prompt, INPUT);
+	    }
+	    break;
+
+	case KEY_ENTER:
+	    printf("\n");
+	    if (strlen(remove_spaces(INPUT)) < 1) {
+		reset_prompt();
+		break;
+	    }
+	    exec_command(remove_spaces(INPUT), hardware);
+	    hdt_cli.history_pos++;
+
+	    /* Did we reach the end of the history ?*/
+	    if (hdt_cli.history_pos > MAX_HISTORY_SIZE) {
+		/* Let's return at the beginning */    
+		hdt_cli.history_pos = 1;
+	    }
+
+	    /* Does the next position is already used ?
+	     * If yes, we are cycling in history */
+	    if (strlen(INPUT) > 0) {
+		/* Let's clean that entry */
+		memset(&INPUT,0,sizeof(INPUT));
+	    }
+
+	    future_history_pos = hdt_cli.history_pos;
+	    if (hdt_cli.history_pos > hdt_cli.max_history_pos)
+		hdt_cli.max_history_pos = hdt_cli.history_pos;
+	    reset_prompt();
+	    break;
+
+	case KEY_CTRL('d'):
+	case KEY_DELETE:
+	    /* No need to delete when input is empty */
+	    if (strlen(INPUT) == 0)
+		break;
+	    /* Don't delete when cursor is at the end of the line */
+	    if (hdt_cli.cursor_pos >= strlen(INPUT))
+		break;
+
+	    for (int c = hdt_cli.cursor_pos; c < (int)strlen(INPUT) - 1; c++)
+		INPUT[c] = INPUT[c + 1];
+	    INPUT[strlen(INPUT) - 1] = '\0';
+
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+
+	    /* Print the resulting buffer */
+	    printf("%s", INPUT + hdt_cli.cursor_pos);
+
+	    /* Replace the cursor at the proper place */
+	    if (strlen(INPUT + hdt_cli.cursor_pos) > 0)
+		move_cursor_left(strlen(INPUT + hdt_cli.cursor_pos));
+	    break;
+
+	case KEY_DEL:
+	case KEY_BACKSPACE:
+	    /* Don't delete prompt */
+	    if (hdt_cli.cursor_pos == 0)
+		break;
+
+	    for (int c = hdt_cli.cursor_pos - 1;
+		 c < (int)strlen(INPUT) - 1; c++)
+		INPUT[c] = INPUT[c + 1];
+	    INPUT[strlen(INPUT) - 1] = '\0';
+
+	    /* Get one char back */
+	    move_cursor_left(1);
+
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+
+	    /* Print the resulting buffer */
+	    printf("%s", INPUT + hdt_cli.cursor_pos - 1);
+
+	    /* Realing to a char before the place we were */
+	    hdt_cli.cursor_pos--;
+	    move_cursor_to_column(strlen(hdt_cli.prompt) + hdt_cli.cursor_pos +
+				  1);
+
+	    break;
+
+	case KEY_F1:
+	    printf("\n");
+	    exec_command(CLI_HELP, hardware);
+	    reset_prompt();
+	    break;
+
+	default:
+	    if ((current_key < 0x20) || (current_key > 0x7e))
+		break;
+	    /* Prevent overflow */
+	    if (hdt_cli.cursor_pos > MAX_LINE_SIZE - 2)
+		break;
+	    /* If we aren't at the end of the input line, let's insert */
+	    if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
+		char key[2];
+		int trailing_chars = strlen(INPUT) - hdt_cli.cursor_pos;
+		memset(temp_command, 0, sizeof(temp_command));
+		strlcpy(temp_command, INPUT, hdt_cli.cursor_pos);
+		sprintf(key, "%c", current_key);
+		strncat(temp_command, key, 1);
+		strncat(temp_command,
+			INPUT + hdt_cli.cursor_pos, trailing_chars);
+		memset(INPUT, 0, sizeof(INPUT));
+		snprintf(INPUT, sizeof(INPUT), "%s", temp_command);
+
+		/* Clear the end of the line */
+		clear_end_of_line();
+
+		/* Print the resulting buffer */
+		printf("%s", INPUT + hdt_cli.cursor_pos);
+
+		/* Return where we must put the new char */
+		move_cursor_left(trailing_chars);
+
+	    } else {
+		putchar(current_key);
+		INPUT[hdt_cli.cursor_pos] = current_key;
+	    }
+	    hdt_cli.cursor_pos++;
+	    break;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,216 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_CLI_H
+#define DEFINE_HDT_CLI_H
+#include <stdio.h>
+#include <getkey.h>
+#include <dprintf.h>
+
+#include "hdt-common.h"
+
+#define MAX_LINE_SIZE 256
+
+#define CLI_SPACE " "
+#define CLI_LF "\n"
+#define CLI_MENU "menu"
+#define CLI_CLEAR "clear"
+#define CLI_EXIT "exit"
+#define CLI_HELP "help"
+#define CLI_REBOOT "reboot"
+#define CLI_SHOW "show"
+#define CLI_SET "set"
+#define CLI_MODE "mode"
+#define CLI_HDT  "hdt"
+#define CLI_PCI  "pci"
+#define CLI_PXE  "pxe"
+#define CLI_KERNEL "kernel"
+#define CLI_SYSLINUX "syslinux"
+#define CLI_VESA "vesa"
+#define CLI_SUMMARY "summary"
+#define CLI_COMMANDS "commands"
+#define CLI_DMI  "dmi"
+#define CLI_CPU  "cpu"
+#define CLI_DISK  "disk"
+#define CLI_SHOW_LIST "list"
+#define CLI_IRQ "irq"
+#define CLI_MODES "modes"
+#define CLI_VPD  "vpd"
+#define CLI_MEMORY  "memory"
+#define CLI_ACPI "acpi"
+#define CLI_ENABLE "enable"
+#define CLI_DISABLE "disable"
+#define CLI_DUMP "dump"
+#define CLI_SAY "say"
+#define CLI_DISPLAY "display"
+#define CLI_SLEEP "sleep"
+
+typedef enum {
+    INVALID_MODE,
+    EXIT_MODE,
+    HDT_MODE,
+    PCI_MODE,
+    DMI_MODE,
+    CPU_MODE,
+    PXE_MODE,
+    KERNEL_MODE,
+    SYSLINUX_MODE,
+    VESA_MODE,
+    DISK_MODE,
+    VPD_MODE,
+    MEMORY_MODE,
+    ACPI_MODE
+} cli_mode_t;
+
+#define PROMPT_SIZE 32
+#define MAX_HISTORY_SIZE 32
+#define INPUT hdt_cli.history[hdt_cli.history_pos]
+struct s_cli {
+    cli_mode_t mode;
+    char prompt[PROMPT_SIZE];
+    uint8_t cursor_pos;
+    char history[MAX_HISTORY_SIZE+1][MAX_LINE_SIZE];
+    int history_pos;
+    int max_history_pos;
+};
+struct s_cli hdt_cli;
+
+/* Describe a cli mode */
+struct cli_mode_descr {
+    const unsigned int mode;
+    const char *name;
+    /* Handle 1-token commands */
+    struct cli_module_descr *default_modules;
+    /* Handle show <module> <args> */
+    struct cli_module_descr *show_modules;
+    /* Handle set <module> <args> */
+    struct cli_module_descr *set_modules;
+};
+
+/* Describe a subset of commands in a module (default, show, set, ...) */
+struct cli_module_descr {
+    struct cli_callback_descr *modules;
+    void (*default_callback) (int argc, char **argv,
+			      struct s_hardware * hardware);
+};
+
+/* Describe a callback (belongs to a mode and a module) */
+struct cli_callback_descr {
+    const char *name;
+    void (*exec) (int argc, char **argv, struct s_hardware * hardware);
+    bool nomodule;
+};
+
+/* Manage aliases */
+#define MAX_ALIASES 2
+struct cli_alias {
+    const char *command;	/* Original command */
+    const int nb_aliases;	/* Size of aliases array */
+    const char **aliases;	/* List of aliases */
+};
+
+/* List of implemented modes */
+extern struct cli_mode_descr *list_modes[];
+struct cli_mode_descr hdt_mode;
+struct cli_mode_descr dmi_mode;
+struct cli_mode_descr syslinux_mode;
+struct cli_mode_descr pxe_mode;
+struct cli_mode_descr kernel_mode;
+struct cli_mode_descr cpu_mode;
+struct cli_mode_descr pci_mode;
+struct cli_mode_descr vesa_mode;
+struct cli_mode_descr disk_mode;
+struct cli_mode_descr vpd_mode;
+struct cli_mode_descr memory_mode;
+struct cli_mode_descr acpi_mode;
+
+/* cli helpers */
+void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found);
+void find_cli_callback_descr(const char *module_name,
+			     struct cli_module_descr *modules_list,
+			     struct cli_callback_descr **module_found);
+cli_mode_t mode_s_to_mode_t(char *name);
+
+void set_mode(cli_mode_t mode, struct s_hardware *hardware);
+void start_cli_mode(struct s_hardware *hardware);
+void start_auto_mode(struct s_hardware *hardware);
+void main_show(char *item, struct s_hardware *hardware);
+
+#define CLI_HISTORY "history"
+void print_history(int argc, char **argv, struct s_hardware * hardware);
+
+// DMI STUFF
+#define CLI_DMI_BASE_BOARD "base_board"
+#define CLI_DMI_BATTERY "battery"
+#define CLI_DMI_BIOS "bios"
+#define CLI_DMI_CHASSIS "chassis"
+#define CLI_DMI_MEMORY "memory"
+#define CLI_DMI_MEMORY_BANK "bank"
+#define CLI_DMI_PROCESSOR "cpu"
+#define CLI_DMI_SYSTEM "system"
+#define CLI_DMI_IPMI "ipmi"
+#define CLI_DMI_CACHE "cache"
+#define CLI_DMI_OEM "oem"
+#define CLI_DMI_SECURITY "security"
+#define CLI_DMI_LIST CLI_SHOW_LIST
+void main_show_dmi(int argc, char **argv, struct s_hardware *hardware);
+void show_dmi_memory_modules(int argc, char **argv,
+			     struct s_hardware *hardware);
+void show_dmi_memory_bank(int argc, char **argv, struct s_hardware *hardware);
+
+// PCI STUFF
+#define CLI_PCI_DEVICE "device"
+void main_show_pci(int argc, char **argv, struct s_hardware *hardware);
+
+// CPU STUFF
+void main_show_cpu(int argc, char **argv, struct s_hardware *hardware);
+
+// DISK STUFF
+void disks_summary(int argc, char **argv, struct s_hardware *hardware);
+
+// PXE STUFF
+void main_show_pxe(int argc, char **argv, struct s_hardware *hardware);
+
+// KERNEL STUFF
+void main_show_kernel(int argc, char **argv, struct s_hardware *hardware);
+
+// SYSLINUX STUFF
+void main_show_syslinux(int argc, char **argv, struct s_hardware *hardware);
+
+// VESA STUFF
+void main_show_vesa(int argc, char **argv, struct s_hardware *hardware);
+
+// VPD STUFF
+void main_show_vpd(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware);
+
+// ACPI STUFF
+void main_show_acpi(int argc __unused, char **argv __unused,
+		                    struct s_hardware *hardware);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,792 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <getkey.h>
+#include "syslinux/config.h"
+#include "../lib/sys/vesa/vesa.h"
+#include "hdt-common.h"
+#include <disk/util.h>
+#include <disk/mbrs.h>
+#include <memory.h>
+
+/* ISOlinux requires a 8.3 format */
+void convert_isolinux_filename(char *filename, struct s_hardware *hardware)
+{
+    /* Exit if we are not running ISOLINUX */
+    if (hardware->sv->filesystem != SYSLINUX_FS_ISOLINUX)
+	return;
+    /* Searching the dot */
+    char *dot = strchr(filename, '.');
+    /* Exiting if no dot exists in that string */
+    if (dot == NULL)
+	return;
+    /* Exiting if the extension is 3 char or less */
+    if (strlen(dot) <= 4)
+	return;
+
+    /* We have an extension bigger than .blah
+     * so we have to shorten it to 3*/
+    dot[4] = '\0';
+}
+
+void detect_parameters(const int argc, const char *argv[],
+		       struct s_hardware *hardware)
+{
+    /* Quiet mode - make the output more quiet */
+    quiet = true;
+
+    /* Silent mode - make not output at all */
+    silent = false;
+
+    /* Vesa mode isn't set until we explictly call it */
+    vesamode = false;
+
+    /* Automode isn't the default*/
+    automode = false;
+
+    /* Menu mode is the default*/
+    menumode = true;
+
+    for (int i = 1; i < argc; i++) {
+	if (!strncmp(argv[i], "quiet", 5)) {
+	    quiet = true;
+	} else if (!strncmp(argv[i], "silent", 6)) {
+	    silent = true;
+	} else	if (!strncmp(argv[i], "verbose", 7)) {
+	    quiet = false;
+	} else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
+	    strlcpy(hardware->modules_pcimap_path, argv[i] + 15,
+		    sizeof(hardware->modules_pcimap_path));
+	    convert_isolinux_filename(hardware->modules_pcimap_path, hardware);
+	} else if (!strncmp(argv[i], "pciids=", 7)) {
+	    strlcpy(hardware->pciids_path, argv[i] + 7,
+		    sizeof(hardware->pciids_path));
+	    convert_isolinux_filename(hardware->pciids_path, hardware);
+	} else if (!strncmp(argv[i], "modules_alias=", 14)) {
+	    strlcpy(hardware->modules_alias_path, argv[i] + 14,
+		    sizeof(hardware->modules_alias_path));
+	    convert_isolinux_filename(hardware->modules_alias_path, hardware);
+	} else if (!strncmp(argv[i], "memtest=", 8)) {
+	    strlcpy(hardware->memtest_label, argv[i] + 8,
+		    sizeof(hardware->memtest_label));
+	    convert_isolinux_filename(hardware->memtest_label, hardware);
+	} else if (!strncmp(argv[i], "vesa", 4)) {
+	    vesamode = true;
+	    max_console_lines = MAX_VESA_CLI_LINES;
+	    /* If the user defines a background image */
+	    if (!strncmp(argv[i], "vesa=", 5)) {
+		strlcpy(hardware->vesa_background, argv[i] + 5,
+			sizeof(hardware->vesa_background));
+	    }
+	} else if (!strncmp(argv[i], "novesa", 6)) {
+	    vesamode = false;
+	    max_console_lines = MAX_CLI_LINES;
+	} else if (!strncmp(argv[i], "nomenu", 6)) {
+	    menumode = false;
+	} else if (!strncmp(argv[i], "dump_filename=", 14)) {
+	    strlcpy(hardware->dump_filename, argv[i] + 14,
+		    sizeof(hardware->dump_filename));
+	} else if (!strncmp(argv[i], "dump_path=", 10)) {
+	    strlcpy(hardware->dump_path, argv[i] + 10,
+		    sizeof(hardware->dump_path));
+	} else if (!strncmp(argv[i], "tftp_ip=", 8)) {
+	    strlcpy(hardware->tftp_ip, argv[i] + 8,
+		    sizeof(hardware->tftp_ip));
+	} else if (!strncmp(argv[i], "postexec=", 9)) {
+	    /* The postexec= parameter is separated in several argv[]
+	     * as it can contains spaces.
+	     * We use the AUTO_DELIMITER char to define the limits
+	     * of this parameter.
+	     * i.e postexec='linux memtest.bin'
+	     */
+
+	    char *argument = (char*)argv[i]+10;
+	    /* Extracting the first parameter */
+	    strcpy(hardware->postexec, argument);
+
+	    /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
+	    while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
+		i++;
+	    	argument = (char *)argv[i];
+		strcat(hardware->postexec, " ");
+		strcat(hardware->postexec, argument);
+	    } 
+	
+	     hardware->postexec[strlen(hardware->postexec) - 1] = 0;
+	} else if (!strncmp(argv[i], "auto=", 5)) {
+	    /* The auto= parameter is separated in several argv[]
+	     * as it can contains spaces.
+	     * We use the AUTO_DELIMITER char to define the limits
+	     * of this parameter.
+	     * i.e auto='show dmi; show pci'
+	     */
+
+	    automode=true;
+	    char *argument = (char*)argv[i]+6;
+	    /* Extracting the first parameter */
+	    strcpy(hardware->auto_label, argument);
+
+	    /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
+	    while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
+		i++;
+	    	argument = (char *)argv[i];
+		strcat(hardware->auto_label, " ");
+		strcat(hardware->auto_label, argument);
+	    } 
+
+	     hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
+	}
+    }
+}
+
+void detect_syslinux(struct s_hardware *hardware)
+{
+    hardware->sv = syslinux_version();
+    switch (hardware->sv->filesystem) {
+    case SYSLINUX_FS_SYSLINUX:
+	strlcpy(hardware->syslinux_fs, "SYSlinux", 9);
+	break;
+    case SYSLINUX_FS_PXELINUX:
+	strlcpy(hardware->syslinux_fs, "PXElinux", 9);
+	break;
+    case SYSLINUX_FS_ISOLINUX:
+	strlcpy(hardware->syslinux_fs, "ISOlinux", 9);
+	break;
+    case SYSLINUX_FS_EXTLINUX:
+	strlcpy(hardware->syslinux_fs, "EXTlinux", 9);
+	break;
+    case SYSLINUX_FS_UNKNOWN:
+    default:
+	strlcpy(hardware->syslinux_fs, "Unknown Bootloader",
+		sizeof hardware->syslinux_fs);
+	break;
+    }
+}
+
+void init_hardware(struct s_hardware *hardware)
+{
+    hardware->pci_ids_return_code = 0;
+    hardware->modules_pcimap_return_code = 0;
+    hardware->modules_alias_return_code = 0;
+    hardware->cpu_detection = false;
+    hardware->pci_detection = false;
+    hardware->disk_detection = false;
+    hardware->disks_count = 0;
+    hardware->dmi_detection = false;
+    hardware->pxe_detection = false;
+    hardware->vesa_detection = false;
+    hardware->vpd_detection = false;
+    hardware->memory_detection = false;
+    hardware->acpi_detection = false;
+    hardware->nb_pci_devices = 0;
+    hardware->is_dmi_valid = false;
+    hardware->is_pxe_valid = false;
+    hardware->is_vpd_valid = false;
+    hardware->is_acpi_valid = false;
+    hardware->pci_domain = NULL;
+    hardware->detected_memory_size = 0;
+    hardware->physical_cpu_count =1; /* we have at least one cpu */
+
+    /* Cleaning structures */
+    memset(hardware->disk_info, 0, sizeof(hardware->disk_info));
+    memset(hardware->mbr_ids, 0, sizeof(hardware->mbr_ids));
+    memset(&hardware->dmi, 0, sizeof(s_dmi));
+    memset(&hardware->cpu, 0, sizeof(s_cpu));
+    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
+    memset(&hardware->vesa, 0, sizeof(struct s_vesa));
+    memset(&hardware->vpd, 0, sizeof(s_vpd));
+    memset(&hardware->acpi, 0, sizeof(s_acpi));
+    memset(hardware->syslinux_fs, 0, sizeof hardware->syslinux_fs);
+    memset(hardware->pciids_path, 0, sizeof hardware->pciids_path);
+    memset(hardware->modules_pcimap_path, 0,
+	   sizeof hardware->modules_pcimap_path);
+    memset(hardware->modules_alias_path, 0,
+	   sizeof hardware->modules_alias_path);
+    memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
+    memset(hardware->auto_label, 0, sizeof hardware->auto_label);
+    memset(hardware->dump_path, 0, sizeof hardware->dump_path);
+    memset(hardware->dump_filename, 0, sizeof hardware->dump_filename);
+    memset(hardware->vesa_background, 0, sizeof hardware->vesa_background);
+    memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip);
+    memset(hardware->postexec, 0, sizeof hardware->postexec);
+    strcat(hardware->dump_path, "hdt");
+    strcat(hardware->dump_filename, "%{m}+%{p}+%{v}");
+    strcat(hardware->pciids_path, "pci.ids");
+    strcat(hardware->modules_pcimap_path, "modules.pcimap");
+    strcat(hardware->modules_alias_path, "modules.alias");
+    strcat(hardware->memtest_label, "memtest");
+    strlcpy(hardware->vesa_background, CLI_DEFAULT_BACKGROUND,
+	    sizeof(hardware->vesa_background));
+}
+
+/*
+ * Detecting if a DMI table exist
+ * if yes, let's parse it
+ */
+int detect_dmi(struct s_hardware *hardware)
+{
+    if (hardware->dmi_detection == true)
+	return -1;
+    hardware->dmi_detection = true;
+    if (dmi_iterate(&hardware->dmi) == -ENODMITABLE) {
+	hardware->is_dmi_valid = false;
+	return -ENODMITABLE;
+    }
+
+    parse_dmitable(&hardware->dmi);
+    hardware->is_dmi_valid = true;
+    return 0;
+}
+
+/*
+ * Detecting ACPI
+ * if yes, let's parse it
+ */
+int detect_acpi(struct s_hardware *hardware)
+{
+    int retval;
+    if (hardware->acpi_detection == true)
+	return -1;
+    hardware->acpi_detection = true;
+    if ((retval=parse_acpi(&hardware->acpi)) != ACPI_FOUND) {
+	hardware->is_acpi_valid = false;
+	return retval;
+    }
+
+    hardware->is_acpi_valid = true;
+    return retval;
+}
+
+/**
+ * vpd_detection - populate the VPD structure
+ *
+ * VPD is a structure available on IBM machines.
+ * It is documented at:
+ *    http://www.pc.ibm.com/qtechinfo/MIGR-45120.html
+ * (XXX the page seems to be gone)
+ **/
+int detect_vpd(struct s_hardware *hardware)
+{
+    if (hardware->vpd_detection)
+	return -1;
+    else
+	hardware->vpd_detection = true;
+
+    if (vpd_decode(&hardware->vpd) == -ENOVPDTABLE) {
+	hardware->is_vpd_valid = false;
+	return -ENOVPDTABLE;
+    } else {
+	hardware->is_vpd_valid = true;
+	return 0;
+    }
+}
+
+/* Detection vesa stuff*/
+int detect_vesa(struct s_hardware *hardware)
+{
+    static com32sys_t rm;
+    struct vesa_general_info *gi;
+    struct vesa_mode_info *mi;
+    uint16_t mode, *mode_ptr;
+    char *oem_ptr;
+    int rv = -1;
+
+    if (hardware->vesa_detection == true)
+	return -1;
+
+    hardware->vesa_detection = true;
+    hardware->is_vesa_valid = false;
+
+    gi = lmalloc(sizeof(*gi));
+    if (!gi)
+	return -1;
+
+    mi = lmalloc(sizeof(*mi));
+    if (!mi)
+	goto out;
+
+    gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    memset(&rm, 0, sizeof rm);
+    rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gi);
+    rm.es = SEG(gi);
+    __intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F) {
+	goto out;
+    };
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+    oem_ptr = GET_PTR(gi->oem_vendor_name_ptr);
+    strlcpy(hardware->vesa.vendor, oem_ptr, sizeof(hardware->vesa.vendor));
+    oem_ptr = GET_PTR(gi->oem_product_name_ptr);
+    strlcpy(hardware->vesa.product, oem_ptr, sizeof(hardware->vesa.product));
+    oem_ptr = GET_PTR(gi->oem_product_rev_ptr);
+    strlcpy(hardware->vesa.product_revision, oem_ptr,
+	    sizeof(hardware->vesa.product_revision));
+
+    hardware->vesa.major_version = (gi->version >> 8) & 0xff;
+    hardware->vesa.minor_version = gi->version & 0xff;
+    hardware->vesa.total_memory = gi->total_memory;
+    hardware->vesa.software_rev = gi->oem_software_rev;
+
+    hardware->vesa.vmi_count = 0;
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+
+        memset(&rm, 0, sizeof rm);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mi);
+	rm.es = SEG(mi);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	/* Saving detected values */
+	memcpy(&hardware->vesa.vmi[hardware->vesa.vmi_count].mi, mi,
+	       sizeof(struct vesa_mode_info));
+	hardware->vesa.vmi[hardware->vesa.vmi_count].mode = mode;
+
+	hardware->vesa.vmi_count++;
+    }
+    hardware->is_vesa_valid = true;
+
+    rv = 0;
+out:
+    lfree(mi);
+    lfree(gi);
+    return rv;
+}
+
+/* Try to detect disks from port 0x80 to 0xff */
+void detect_disks(struct s_hardware *hardware)
+{
+    int i = -1;
+    int err;
+
+    if (hardware->disk_detection)
+	return;
+
+    hardware->disk_detection = true;
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	i++;
+	hardware->disk_info[i].disk = drive;
+	err = get_drive_parameters(&hardware->disk_info[i]);
+
+	/*
+	 * Do not print output when drive does not exist or
+	 * doesn't support int13 (cdrom, ...)
+	 */
+	if (err == -1 || !hardware->disk_info[i].cbios)
+	    continue;
+
+	/* Detect MBR */
+	hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
+
+	hardware->disks_count++;
+    }
+}
+
+int detect_pxe(struct s_hardware *hardware)
+{
+    void *dhcpdata;
+
+    size_t dhcplen;
+    t_PXENV_UNDI_GET_NIC_TYPE gnt;
+
+    if (hardware->pxe_detection == true)
+	return -1;
+    hardware->pxe_detection = true;
+    hardware->is_pxe_valid = false;
+    memset(&gnt, 0, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
+    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
+
+    /* This code can only work if pxelinux is loaded */
+    if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	return -1;
+    }
+// printf("PXE: PXElinux detected\n");
+    if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	pxe_bootp_t *dhcp = &hardware->pxe.dhcpdata;
+	memcpy(&hardware->pxe.dhcpdata, dhcpdata,
+	       sizeof(hardware->pxe.dhcpdata));
+	snprintf(hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr),
+		 "%02x:%02x:%02x:%02x:%02x:%02x", dhcp->CAddr[0],
+		 dhcp->CAddr[1], dhcp->CAddr[2], dhcp->CAddr[3],
+		 dhcp->CAddr[4], dhcp->CAddr[5]);
+
+	/* Saving our IP address in a easy format */
+	hardware->pxe.ip_addr[0] = hardware->pxe.dhcpdata.yip & 0xff;
+	hardware->pxe.ip_addr[1] = hardware->pxe.dhcpdata.yip >> 8 & 0xff;
+	hardware->pxe.ip_addr[2] = hardware->pxe.dhcpdata.yip >> 16 & 0xff;
+	hardware->pxe.ip_addr[3] = hardware->pxe.dhcpdata.yip >> 24 & 0xff;
+
+	if (!pxe_get_nic_type(&gnt)) {
+	    switch (gnt.NicType) {
+	    case PCI_NIC:
+		hardware->is_pxe_valid = true;
+		hardware->pxe.vendor_id = gnt.info.pci.Vendor_ID;
+		hardware->pxe.product_id = gnt.info.pci.Dev_ID;
+		hardware->pxe.subvendor_id = gnt.info.pci.SubVendor_ID;
+		hardware->pxe.subproduct_id =
+		    gnt.info.pci.SubDevice_ID,
+		    hardware->pxe.rev = gnt.info.pci.Rev;
+		hardware->pxe.pci_bus = (gnt.info.pci.BusDevFunc >> 8) & 0xff;
+		hardware->pxe.pci_dev = (gnt.info.pci.BusDevFunc >> 3) & 0x7;
+		hardware->pxe.pci_func = gnt.info.pci.BusDevFunc & 0x03;
+		hardware->pxe.base_class = gnt.info.pci.Base_Class;
+		hardware->pxe.sub_class = gnt.info.pci.Sub_Class;
+		hardware->pxe.prog_intf = gnt.info.pci.Prog_Intf;
+		hardware->pxe.nictype = gnt.NicType;
+		break;
+	    case CardBus_NIC:
+		hardware->is_pxe_valid = true;
+		hardware->pxe.vendor_id = gnt.info.cardbus.Vendor_ID;
+		hardware->pxe.product_id = gnt.info.cardbus.Dev_ID;
+		hardware->pxe.subvendor_id = gnt.info.cardbus.SubVendor_ID;
+		hardware->pxe.subproduct_id =
+		    gnt.info.cardbus.SubDevice_ID,
+		    hardware->pxe.rev = gnt.info.cardbus.Rev;
+		hardware->pxe.pci_bus =
+		    (gnt.info.cardbus.BusDevFunc >> 8) & 0xff;
+		hardware->pxe.pci_dev =
+		    (gnt.info.cardbus.BusDevFunc >> 3) & 0x7;
+		hardware->pxe.pci_func = gnt.info.cardbus.BusDevFunc & 0x03;
+		hardware->pxe.base_class = gnt.info.cardbus.Base_Class;
+		hardware->pxe.sub_class = gnt.info.cardbus.Sub_Class;
+		hardware->pxe.prog_intf = gnt.info.cardbus.Prog_Intf;
+		hardware->pxe.nictype = gnt.NicType;
+		break;
+	    case PnP_NIC:
+	    default:
+		return -1;
+		break;
+	    }
+
+	    /* The firt pass try to find the exact pci device */
+	    hardware->pxe.pci_device = NULL;
+	    hardware->pxe.pci_device_pos = 0;
+	    struct pci_device *pci_device;
+	    int pci_number = 0;
+	    for_each_pci_func(pci_device, hardware->pci_domain) {
+		pci_number++;
+		if ((__pci_bus == hardware->pxe.pci_bus) &&
+		    (__pci_slot == hardware->pxe.pci_dev) &&
+		    (__pci_func == hardware->pxe.pci_func) &&
+		    (pci_device->vendor == hardware->pxe.vendor_id)
+		    && (pci_device->product == hardware->pxe.product_id)) {
+		    hardware->pxe.pci_device = pci_device;
+		    hardware->pxe.pci_device_pos = pci_number;
+		    return 0;
+		}
+	    }
+
+	    /* If we reach that part, it means the pci device pointed by
+	     * the pxe rom wasn't found in our list.
+	     * Let's try to find the device only by its pci ids.
+	     * The pci device we'll match is maybe not exactly the good one
+	     * as we can have the same pci id several times.
+	     * At least, the pci id, the vendor/product will be right.
+	     * That's clearly a workaround for some weird cases.
+	     * This should happend very unlikely */
+	    hardware->pxe.pci_device = NULL;
+	    hardware->pxe.pci_device_pos = 0;
+	    pci_number = 0;
+	    for_each_pci_func(pci_device, hardware->pci_domain) {
+		pci_number++;
+		if ((pci_device->vendor == hardware->pxe.vendor_id)
+		    && (pci_device->product == hardware->pxe.product_id)) {
+		    hardware->pxe.pci_device = pci_device;
+		    hardware->pxe.pci_device_pos = pci_number;
+		    return 0;
+		}
+	    }
+
+	}
+    }
+    return 0;
+}
+
+void detect_memory(struct s_hardware *hardware) {
+     if (hardware->memory_detection == false) {
+	     hardware->memory_detection = true;
+     hardware->detected_memory_size = detect_memsize();
+     }
+}
+
+void detect_pci(struct s_hardware *hardware)
+{
+    if (hardware->pci_detection == true)
+	return;
+    hardware->pci_detection = true;
+
+    hardware->nb_pci_devices = 0;
+
+    /* Scanning to detect pci buses and devices */
+    hardware->pci_domain = pci_scan();
+
+    if (!hardware->pci_domain)
+	return;
+
+    /* Gathering addtional information */
+    gather_additional_pci_config(hardware->pci_domain);
+
+    struct pci_device *pci_device;
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	hardware->nb_pci_devices++;
+    }
+
+    if (!quiet) {
+	more_printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
+	more_printf("PCI: Resolving names\n");
+    }
+    /* Assigning product & vendor name for each device */
+    hardware->pci_ids_return_code =
+	get_name_from_pci_ids(hardware->pci_domain, hardware->pciids_path);
+
+    if (!quiet)
+	more_printf("PCI: Resolving class names\n");
+    /* Assigning class name for each device */
+    hardware->pci_ids_return_code =
+	get_class_name_from_pci_ids(hardware->pci_domain,
+				    hardware->pciids_path);
+
+    if (!quiet)
+	more_printf("PCI: Resolving module names\n");
+    /* Detecting which kernel module should match each device using modules.pcimap */
+    hardware->modules_pcimap_return_code =
+	get_module_name_from_pcimap(hardware->pci_domain,
+				    hardware->modules_pcimap_path);
+
+    /* Detecting which kernel module should match each device using modules.alias */
+    hardware->modules_alias_return_code =
+	get_module_name_from_alias(hardware->pci_domain,
+				   hardware->modules_alias_path);
+
+}
+
+void cpu_detect(struct s_hardware *hardware)
+{
+    if (hardware->cpu_detection == true)
+	return;
+    detect_cpu(&hardware->cpu);
+    /* Old processors doesn't manage the identify commands 
+     * Let's use the dmi value in that case */
+    if (strlen(remove_spaces(hardware->cpu.model)) == 0)
+	strlcpy(hardware->cpu.model, hardware->dmi.processor.version,
+		sizeof(hardware->cpu.model));
+
+    /* Some CPUs like to put many spaces in the model name
+     * That makes some weird display in console/menu
+     * Let's remove that mulitple spaces */
+    strlcpy(hardware->cpu.model,del_multi_spaces(hardware->cpu.model),sizeof(hardware->cpu.model));
+
+    if ((hardware->is_acpi_valid) && (hardware->acpi.madt.valid)) {
+    	hardware->physical_cpu_count=hardware->acpi.madt.processor_local_apic_count / hardware->cpu.num_cores;
+    }
+    hardware->cpu_detection = true;
+}
+
+/*
+ * Find the last instance of a particular command line argument
+ * (which should include the final =; do not use for boolean arguments)
+ */
+const char *find_argument(const char **argv, const char *argument)
+{
+    int la = strlen(argument);
+    const char **arg;
+    const char *ptr = NULL;
+
+    for (arg = argv; *arg; arg++) {
+	if (!memcmp(*arg, argument, la))
+	    ptr = *arg + la;
+    }
+
+    return ptr;
+}
+
+void clear_screen(void)
+{
+    move_cursor_to_next_line();
+    disable_utf8();
+    set_g1_special_char();
+    set_us_g0_charset();
+    display_cursor(false);
+    clear_entire_screen();
+    gotoxy(0,0);
+    reset_more_printf();
+}
+
+/* remove begining spaces */
+char *skip_spaces(char *p)
+{
+    while (*p && *p <= ' ') {
+	p++;
+    }
+
+    return p;
+}
+
+/* remove trailing & begining spaces */
+char *remove_spaces(char *p)
+{
+    char *save = p;
+    p += strlen(p) - 1;
+    while (*p && *p <= ' ') {
+	*p = '\0';
+	p--;
+    }
+    p = save;
+    while (*p && *p <= ' ') {
+	p++;
+    }
+
+    return p;
+}
+
+/* remove trailing LF */
+char *remove_trailing_lf(char *p)
+{
+    char *save = p;
+    p += strlen(p) - 1;
+    while (*p && *p == 10) {
+	*p = '\0';
+	p--;
+    }
+    p = save;
+
+    return p;
+}
+
+/* delete multiple spaces, one is enough */
+char *del_multi_spaces(char *p)
+{
+    /* Saving the original pointer */
+    char *save = p;
+
+    /* Let's parse the complete string
+     * As we search for a double spacing
+     * we have to be sure then string is
+     * long enough to be processed */
+    while (*p && *(p + 1)) {
+
+	/* If we have two consecutive spaces */
+	if ((*p == ' ') && (*(p + 1) == ' ')) {
+
+	    /* Let's copy to the current position
+	     * the content from the second space*/
+	    strlcpy(p, p + 1, strlen(p + 1));
+
+	    /* Don't increment the pointer as we
+	     * changed the content of the current position*/
+	    continue;
+	}
+
+	/* Nothing as been found, let's see on the next char */
+	p++;
+    }
+    /* Returning the original pointer */
+    return save;
+}
+
+/* Reset the more_printf counter */
+void reset_more_printf(void)
+{
+    display_line_nb = 0;
+}
+
+int draw_background(const char *what)
+{
+    if (!what)
+	return vesacon_default_background();
+    else
+	return vesacon_load_background(what);
+}
+
+void init_console(struct s_hardware *hardware)
+{
+    if (vesamode) {
+	openconsole(&dev_rawcon_r, &dev_vesaserial_w);
+	draw_background(hardware->vesa_background);
+    } else
+	console_ansi_raw();
+}
+
+void detect_hardware(struct s_hardware *hardware)
+{
+    if (!quiet)
+        more_printf("ACPI: Detecting\n");
+    detect_acpi(hardware);
+
+    if (!quiet)
+        more_printf("MEMORY: Detecting\n");
+    detect_memory(hardware);
+
+    if (!quiet)
+        more_printf("DMI: Detecting Table\n");
+    if (detect_dmi(hardware) == -ENODMITABLE) {
+        more_printf("DMI: ERROR ! Table not found ! \n");
+        more_printf("DMI: Many hardware components will not be detected ! \n");
+    } else {
+        if (!quiet)
+            more_printf("DMI: Table found ! (version %u.%u)\n",
+                        hardware->dmi.dmitable.major_version,
+                        hardware->dmi.dmitable.minor_version);
+    }
+
+    if (!quiet)
+        more_printf("CPU: Detecting\n");
+    cpu_detect(hardware);
+
+    if (!quiet)
+        more_printf("DISKS: Detecting\n");
+    detect_disks(hardware);
+
+    if (!quiet)
+        more_printf("VPD: Detecting\n");
+    detect_vpd(hardware);
+
+    detect_pci(hardware);
+    if (!quiet)
+        more_printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
+ 
+   if (!quiet)
+        more_printf("PXE: Detecting\n");
+    detect_pxe(hardware);
+
+    if (!quiet)
+        more_printf("VESA: Detecting\n");
+    detect_vesa(hardware);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,250 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_COMMON_H
+#define DEFINE_HDT_COMMON_H
+#include <stdio.h>
+#include <syslinux/pxe.h>
+#include <console.h>
+#include <consoles.h>
+#include <syslinux/vesacon.h>
+#include "sys/pci.h"
+
+#include <disk/bootloaders.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
+#include <disk/geom.h>
+#include <disk/mbrs.h>
+#include <disk/msdos.h>
+#include <disk/partition.h>
+#include <disk/swsusp.h>
+#include <disk/read.h>
+
+#include "cpuid.h"
+#include "dmi/dmi.h"
+#include "hdt-ata.h"
+#include <lib/sys/vesa/vesa.h>
+#include <vpd/vpd.h>
+#include <libansi.h>
+#include <acpi/acpi.h>
+#include <libupload/upload_backend.h>
+
+/* This two values are used for switching for the menu to the CLI mode */
+#define HDT_SWITCH_TO_CLI "hdt_switch_to_cli"
+#define HDT_DUMP "hdt_dump"
+#define HDT_RETURN_TO_CLI 100
+#define MAX_VESA_MODES 255
+
+/* This value is used for rebooting from the menu mode */
+#define HDT_REBOOT "hdt_reboot"
+
+/* The maximum number of commands we can process */
+#define MAX_NB_AUTO_COMMANDS 255
+/* The maximum size of a command */
+#define AUTO_COMMAND_SIZE 255
+/* The char that separate two commands */
+#define AUTO_SEPARATOR ";"
+/* The char that surround the list of commands */
+#define AUTO_DELIMITER '\'' 
+
+/* Graphic to load in background when using the vesa mode */
+#define CLI_DEFAULT_BACKGROUND "backgnd.png"
+
+/* The maximum number of lines */
+#define MAX_CLI_LINES 20
+#define MAX_VESA_CLI_LINES 24
+
+struct upload_backend *upload;
+
+/* Defines if the cli is quiet*/
+bool quiet;
+
+/* Defines if the cli is totally silent*/
+bool silent;
+
+/* Defines if we must use the vesa mode */
+bool vesamode;
+
+/* Defines if we must use the menu mode */
+bool menumode;
+
+/* Defines if we are running the auto mode */
+bool automode;
+
+/* Defines the number of lines in the console
+ * Default is 20 for a std console */
+extern int max_console_lines;
+
+extern int display_line_nb;
+extern bool disable_more_printf;
+
+#define pause_printf() do {\
+       printf("--More--");\
+       get_key(stdin, 0);\
+       printf("\033[2K\033[1G\033[1F\n");\
+} while (0);
+
+/* The brokeness of that macro is that
+ * it assumes that __VA_ARGS__ contains
+ * one \n (and only one)
+ */
+#define more_printf(...) do {\
+ if (__likely(!silent)) {\
+  if (__likely(!disable_more_printf)) {\
+   if (display_line_nb == max_console_lines) {\
+    display_line_nb=0;\
+    printf("\n--More--");\
+    get_key(stdin, 0);\
+    printf("\033[2K\033[1G\033[1F");\
+   }\
+   display_line_nb++;\
+  }\
+  printf(__VA_ARGS__);\
+ }\
+} while (0);
+
+/* Display CPU registers for debugging purposes */
+static inline void printregs(const com32sys_t * r)
+{
+    printf("eflags = %08x  ds = %04x  es = %04x  fs = %04x  gs = %04x\n"
+	   "eax = %08x  ebx = %08x  ecx = %08x  edx = %08x\n"
+	   "ebp = %08x  esi = %08x  edi = %08x  esp = %08x\n",
+	   r->eflags.l, r->ds, r->es, r->fs, r->gs,
+	   r->eax.l, r->ebx.l, r->ecx.l, r->edx.l,
+	   r->ebp.l, r->esi.l, r->edi.l, r->_unused_esp.l);
+}
+
+struct s_pxe {
+    uint16_t vendor_id;
+    uint16_t product_id;
+    uint16_t subvendor_id;
+    uint16_t subproduct_id;
+    uint8_t rev;
+    uint8_t pci_bus;
+    uint8_t pci_dev;
+    uint8_t pci_func;
+    uint8_t base_class;
+    uint8_t sub_class;
+    uint8_t prog_intf;
+    uint8_t nictype;
+    char mac_addr[18];		/* The current mac address */
+    uint8_t ip_addr[4];
+    pxe_bootp_t dhcpdata;	/* The dhcp answer */
+    struct pci_device *pci_device;	/* The matching pci device */
+    uint8_t pci_device_pos;	/* It position in our pci sorted list */
+};
+
+struct s_vesa_mode_info {
+    struct vesa_mode_info mi;
+    uint16_t mode;
+};
+
+struct s_vesa {
+    uint8_t major_version;
+    uint8_t minor_version;
+    struct s_vesa_mode_info vmi[MAX_VESA_MODES];
+    uint8_t vmi_count;
+    uint16_t total_memory;
+    char vendor[256];
+    char product[256];
+    char product_revision[256];
+    uint16_t software_rev;
+};
+
+struct s_hardware {
+    s_dmi dmi;			/* DMI table */
+    s_cpu cpu;			/* CPU information */
+    uint8_t physical_cpu_count; /* Number of physical cpu */
+    s_vpd vpd;			/* VPD information */
+    s_acpi acpi;
+    struct pci_domain *pci_domain;	/* PCI Devices */
+    struct driveinfo disk_info[256];	/* Disk Information */
+    uint32_t mbr_ids[256];	/* MBR ids */
+    int disks_count;		/* Number of detected disks */
+    struct s_pxe pxe;
+    struct s_vesa vesa;
+    unsigned long detected_memory_size;	/* The detected memory size (in KB) */
+
+    int pci_ids_return_code;
+    int modules_pcimap_return_code;
+    int modules_alias_return_code;
+    int nb_pci_devices;
+    bool is_dmi_valid;
+    bool is_pxe_valid;
+    bool is_vesa_valid;
+    bool is_vpd_valid;
+    bool is_acpi_valid;
+
+    bool dmi_detection;		/* Does the dmi stuff has already been detected? */
+    bool pci_detection;		/* Does the pci stuff has already been detected? */
+    bool cpu_detection;		/* Does the cpu stuff has already been detected? */
+    bool disk_detection;	/* Does the disk stuff has already been detected? */
+    bool pxe_detection;		/* Does the pxe stuff has already been detected? */
+    bool vesa_detection;	/* Does the vesa sutff have been already detected? */
+    bool vpd_detection;		/* Does the vpd stuff has already been detected? */
+    bool memory_detection;	/* Does the memory size got detected ?*/
+    bool acpi_detection;	/* Does the acpi got detected ?*/
+
+    char syslinux_fs[22];
+    const struct syslinux_version *sv;
+    char modules_pcimap_path[255];
+    char modules_alias_path[255];
+    char pciids_path[255];
+    char dump_path[255]; /* Dump path on the tftp server */
+    char dump_filename[255]; /* Dump filename on the tftp server */
+    char tftp_ip[255];   /* IP address of tftp server (dump mode) */
+    char memtest_label[255];
+    char auto_label[AUTO_COMMAND_SIZE];
+    char vesa_background[255];
+    char postexec[255];
+};
+
+void reset_more_printf(void);
+const char *find_argument(const char **argv, const char *argument);
+char *remove_spaces(char *p);
+char *remove_trailing_lf(char *p);
+char *skip_spaces(char *p);
+char *del_multi_spaces(char *p);
+int detect_dmi(struct s_hardware *hardware);
+int detect_vpd(struct s_hardware *hardware);
+void detect_disks(struct s_hardware *hardware);
+void detect_pci(struct s_hardware *hardware);
+void cpu_detect(struct s_hardware *hardware);
+int detect_pxe(struct s_hardware *hardware);
+void init_hardware(struct s_hardware *hardware);
+void clear_screen(void);
+void detect_syslinux(struct s_hardware *hardware);
+int detect_acpi(struct s_hardware *hardware);
+void detect_parameters(const int argc, const char *argv[],
+		       struct s_hardware *hardware);
+int detect_vesa(struct s_hardware *hardware);
+void detect_memory(struct s_hardware *hardware);
+void init_console(struct s_hardware *hardware);
+void detect_hardware(struct s_hardware *hardware);
+void dump(struct s_hardware *hardware);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,600 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void show_header(char *name, void *address, s_acpi_description_header *h, ZZJSON_CONFIG *config, ZZJSON **item)
+{
+	char signature[10]={0};
+	char revision[10]={0};
+	char s_address[16]={0};
+	char oem_id[16]={0};
+	char oem_table_id[16]={0};
+	char oem_revision[16]={0};
+	char creator_revision[16]={0};
+	char creator_id[16]={0};
+	snprintf(signature,sizeof(signature),"%s",h->signature);
+	snprintf(revision,sizeof(revision),"0x%03x",h->revision);
+	snprintf(oem_id,sizeof(oem_id),"%s",h->oem_id);
+	snprintf(oem_table_id,sizeof(oem_table_id),"%s",h->oem_table_id);
+	snprintf(creator_id,sizeof(creator_id),"%s",h->creator_id);
+	snprintf(oem_revision,sizeof(oem_revision),"0x%08x",h->oem_revision);
+	snprintf(creator_revision,sizeof(creator_revision),"0x%08x",h->creator_revision);
+	snprintf(s_address,sizeof(s_address),"%p",address);
+
+	char address_name[32]={0};
+	char signature_name[32]={0};
+	char revision_name[32]={0};
+	char oem_id_name[32]={0};
+	char oem_table_id_name[32]={0};
+	char oem_revision_name[32]={0};
+	char creator_revision_name[32]={0};
+	char creator_id_name[32]={0};
+	snprintf(signature_name,sizeof(signature_name),"acpi.%s.signature",name);
+	snprintf(revision_name,sizeof(revision_name),"acpi.%s.revision",name);
+	snprintf(address_name,sizeof(address_name),"acpi.%s.address",name);
+	snprintf(oem_id_name,sizeof(oem_id_name),"acpi.%s.oem_id",name);
+	snprintf(oem_table_id_name,sizeof(oem_table_id_name),"acpi.%s.oem_table_id",name);
+	snprintf(oem_revision_name,sizeof(oem_revision_name),"acpi.%s.oem_revision",name);
+	snprintf(creator_revision_name,sizeof(creator_revision_name),"acpi.%s.creator_revision",name);
+	snprintf(creator_id_name,sizeof(creator_id_name),"acpi.%s.creator_id",name);
+
+	APPEND_ARRAY
+		add_as(signature_name,signature)
+		add_as(revision_name,revision)
+		add_as(oem_id_name,oem_id)
+		add_as(oem_table_id_name,oem_table_id)
+		add_as(oem_revision_name,oem_revision)
+		add_as(creator_id_name,creator_id)
+		add_as(creator_revision_name,creator_revision)
+		add_as(address_name,s_address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_rsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","rsdt")
+		add_as("acpi.rsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->rsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("rsdt",acpi->rsdt.address, &acpi->rsdt.header, config, item);	
+}
+
+void dump_xsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->xsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","xsdt")
+		add_as("acpi.xsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->xsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("xsdt",acpi->xsdt.address, &acpi->xsdt.header, config, item);	
+}
+
+void dump_fadt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","fadt")
+		add_as("acpi.fadt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->fadt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("fadt",acpi->fadt.address, &acpi->fadt.header, config, item);	
+}
+
+void dump_dsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->dsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","dsdt")
+		add_as("acpi.dsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->dsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("dsdt",acpi->dsdt.address, &acpi->dsdt.header, config, item);	
+}
+
+void dump_sbst(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->sbst.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","sbst")
+		add_as("acpi.sbst.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->sbst.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("sbst",acpi->sbst.address, &acpi->sbst.header, config, item);	
+}
+
+void dump_ecdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->ecdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","ecdt")
+		add_as("acpi.ecdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->ecdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("ecdt",acpi->ecdt.address, &acpi->ecdt.header, config, item);	
+}
+
+void dump_hpet(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->hpet.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","hpet")
+		add_as("acpi.hpet.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->hpet.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("hpet",acpi->hpet.address, &acpi->hpet.header, config, item);	
+}
+
+void dump_tcpa(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->tcpa.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","tcpa")
+		add_as("acpi.tcpa.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->tcpa.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("tcpa",acpi->tcpa.address, &acpi->tcpa.header, config, item);	
+}
+
+void dump_mcfg(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->mcfg.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","mcfg")
+		add_as("acpi.mcfg.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->mcfg.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("mcfg",acpi->mcfg.address, &acpi->mcfg.header, config, item);	
+}
+
+void dump_slic(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->slic.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","slic")
+		add_as("acpi.slic.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->slic.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("slic",acpi->slic.address, &acpi->slic.header, config, item);	
+}
+
+
+void dump_boot(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->boot.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","boot")
+		add_as("acpi.boot.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->boot.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("boot",acpi->boot.address, &acpi->boot.header, config, item);	
+}
+
+void dump_madt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->madt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","madt")
+		add_as("acpi.madt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->madt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("madt",acpi->madt.address, &acpi->madt.header, config, item);	
+}
+
+void dump_ssdt(s_ssdt *ssdt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (ssdt->valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","ssdt")
+		add_as("acpi.ssdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (ssdt->valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("ssdt",ssdt->address, &ssdt->header, config, item);	
+}
+
+void dump_rsdp(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdp.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","rsdp")
+		add_as("acpi.rsdp.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->rsdp.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	s_rsdp *r = &acpi->rsdp;
+	char revision[10]={0};
+	char address[16]={0};
+	char oem_id[16]={0};
+	snprintf(revision,sizeof(revision),"0x%03x",r->revision);
+	snprintf(address,sizeof(address),"%p",r->address);
+	snprintf(oem_id,sizeof(oem_id),"%s",r->oem_id);
+	APPEND_ARRAY
+		add_as("acpi.rsdp.revision",revision)
+		add_as("acpi.rsdp.oem_id",oem_id)
+		add_as("acpi.rsdp.address",address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_facs(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->facs.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","facs")
+		add_as("acpi.facs.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->facs.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	s_facs *fa = &acpi->facs;
+	char address[16]={0};
+	snprintf(address,sizeof(address),"%p",fa->address);
+	APPEND_ARRAY
+		add_as("acpi.facs.address",address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_interrupt_source_override(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","interrupt_source_override")
+    	add_ai("acpi.interrupt_source_override.count", madt->interrupt_source_override_count)
+    END_OF_ARRAY;
+
+    if (madt->interrupt_source_override_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    /* Let's process each interrupt source override */
+    for (int i = 0; i < madt->interrupt_source_override_count; i++) {
+	s_interrupt_source_override *siso = &madt->interrupt_source_override[i];
+	char buffer[20] = {0};
+	char bus_type[10]= {0};
+	
+	/* Spec report bus type 0 as ISA */
+	if (siso->bus == 0)
+	    strcpy(bus_type, "ISA");
+	else
+	    strcpy(bus_type, "unknown");
+
+	APPEND_ARRAY
+		add_as("acpi.interrupt_source_override.bus_type",bus_type)
+		add_ai("acpi.interrupt_source_override.bus",siso->bus)
+		add_ai("acpi.interrupt_source_override.bus_irq",siso->source)
+		add_ai("acpi.interrupt_source_override.global_irq",siso->global_system_interrupt)
+		add_as("acpi.interrupt_source_override.flags",flags_to_string(buffer,siso->flags))
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_io_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","io_apic")
+    	add_ai("acpi.io_apic.count", madt->io_apic_count)
+    END_OF_ARRAY;
+
+    if (madt->io_apic_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    /* For all IO APICS */
+    for (int i = 0; i < madt->io_apic_count; i++) {
+	s_io_apic *sio = &madt->io_apic[i];
+	char buffer[15]={0};
+	memset(buffer, 0, sizeof(buffer));
+	/* GSI base reports the GSI configuration
+	 * Let's interpret it as string */
+	switch (sio->global_system_interrupt_base) {
+	case 0:
+	    strcpy(buffer, "0-23");
+	    break;
+	case 24:
+	    strcpy(buffer,"24-39");
+	    break;
+	case 40:
+	    strcpy(buffer, "40-55");
+	    break;
+	default:
+	    strcpy(buffer,"Unknown");
+	    break;
+	}
+
+	char apic_id[16] = { 0 };
+	char address[16] = { 0 };
+	snprintf(apic_id,sizeof(apic_id),"0x%02x",sio->io_apic_id);
+	snprintf(address,sizeof(address),"0x%08x",sio->io_apic_address);
+	APPEND_ARRAY
+		add_ai("acpi.io_apic.number",i)
+		add_as("acpi.io_apic.apic_id",apic_id)
+		add_as("acpi.io_apic.adress",address)
+		add_as("acpi.io_apic.gsi",buffer)
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_local_apic_nmi(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","local_apic_nmi")
+    	add_ai("acpi.local_apic_nmi.count", madt->local_apic_nmi_count)
+    END_OF_ARRAY;
+
+    if (madt->local_apic_nmi_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    for (int i = 0; i < madt->local_apic_nmi_count; i++) {
+	s_local_apic_nmi *slan = &madt->local_apic_nmi[i];
+	char buffer[20]={0};
+	char acpi_id[16] = { 0 };
+	char local_apic_lint[16] = { 0 };
+	snprintf(acpi_id, sizeof(acpi_id), "0x%02x", slan->acpi_processor_id);
+	snprintf(local_apic_lint, sizeof(local_apic_lint), "0x%02x", slan->local_apic_lint);
+	APPEND_ARRAY
+		add_as("acpi.processor_id", acpi_id)
+		add_as("acpi.local_apic_nmi.flags", flags_to_string(buffer,slan->flags))
+		add_as("acpi.local_apic_nmi.lint",local_apic_lint)
+	END_OF_APPEND;
+    }
+
+    FLUSH_OBJECT;
+}
+
+void dump_local_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    char buffer[16] = { 0 };
+    snprintf(buffer, sizeof(buffer), "0x%08x", madt->local_apic_address);
+
+    CREATE_ARRAY
+	add_as("acpi.item","local_apic")
+    	add_as("acpi.local_apic.address", buffer)
+    	add_ai("acpi.processor_local_apic.count", madt->processor_local_apic_count)
+    END_OF_ARRAY;
+
+    if (madt->processor_local_apic_count ==0) {
+        FLUSH_OBJECT;
+	return;
+    }
+
+    /* For all detected logical CPU */
+    for (int i = 0; i < madt->processor_local_apic_count; i++) {
+	s_processor_local_apic *sla = &madt->processor_local_apic[i];
+	char lapic_status[16] = { 0 };
+	char acpi_id[16] = { 0 };
+	char apic_id[16] = { 0 };
+
+	snprintf(lapic_status,sizeof(lapic_status),"%s","disabled");
+	/* Let's check if the flags reports the cpu as enabled */
+	if ((sla->flags & PROCESSOR_LOCAL_APIC_ENABLE) ==
+	    PROCESSOR_LOCAL_APIC_ENABLE)
+	    snprintf(lapic_status,sizeof(lapic_status),"%s","enabled");
+	snprintf(acpi_id, sizeof(acpi_id), "0x%02x", sla->acpi_id);
+	snprintf(apic_id, sizeof(apic_id), "0x%02x", sla->apic_id);
+	APPEND_ARRAY
+		add_ai("acpi.cpu.apic_id", sla->apic_id)
+		add_as("acpi.cpu.apic_id (hex)", apic_id)
+		add_as("acpi.cpu.acpi_id (hex)", acpi_id)
+		add_as("acpi.lapic.enabled", lapic_status)
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+	       ZZJSON ** item)
+{
+    CREATE_NEW_OBJECT;
+    add_hb(is_acpi_valid);
+    if (hardware->is_acpi_valid == false)
+	goto exit;
+
+    s_madt *madt = &hardware->acpi.madt;
+    add_b("acpi.apic.detected", madt->valid);
+    if (madt->valid == false) {
+	goto exit;
+    }
+
+    FLUSH_OBJECT;
+
+    dump_local_apic(madt, config, item);
+    dump_local_apic_nmi(madt, config, item);
+    dump_io_apic(madt, config, item);
+    dump_interrupt_source_override(madt, config, item);
+
+    dump_rsdp(&hardware->acpi,config,item);
+    dump_rsdt(&hardware->acpi,config,item);
+    dump_xsdt(&hardware->acpi,config,item);
+    dump_fadt(&hardware->acpi,config,item);
+    dump_dsdt(&hardware->acpi,config,item);
+    dump_sbst(&hardware->acpi,config,item);
+    dump_ecdt(&hardware->acpi,config,item);
+    dump_hpet(&hardware->acpi,config,item);
+    dump_tcpa(&hardware->acpi,config,item);
+    dump_mcfg(&hardware->acpi,config,item);
+    dump_slic(&hardware->acpi,config,item);
+    dump_boot(&hardware->acpi,config,item);
+    dump_madt(&hardware->acpi,config,item);
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+            if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+		    dump_ssdt(hardware->acpi.ssdt[i], config, item);
+    }
+    dump_facs(&hardware->acpi,config,item);
+
+exit:
+    to_cpio("acpi");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+        CREATE_NEW_OBJECT;
+	add_hs(cpu.vendor);
+	add_hs(cpu.model);
+	add_hi(cpu.vendor_id);
+	add_hi(cpu.family);
+	add_hi(cpu.model_id);
+	add_hi(cpu.stepping);
+	add_hi(cpu.num_cores);
+	add_hi(cpu.l1_data_cache_size);
+	add_hi(cpu.l1_instruction_cache_size);
+	add_hi(cpu.l2_cache_size);
+	size_t i;
+	for (i = 0; i < cpu_flags_count; i++) {
+		char temp[128]={0};
+		snprintf(temp,sizeof(temp),"cpu.flags.%s",cpu_flags_names[i]);
+		add_b(temp,get_cpu_flag_value_from_name(&hardware->cpu,cpu_flags_names[i]));
+	}
+	FLUSH_OBJECT;
+	to_cpio("cpu");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include "hdt-util.h"
+
+ZZJSON_CONFIG *config;
+ZZJSON **item;
+
+static void show_partition_information(struct driveinfo *drive_info,
+                                       struct part_entry *ptab,
+                                       int partition_offset,
+                                       int nb_partitions_seen) {
+    char size[11] = {0};
+    char bootloader_name[9] = {0};
+    char ostype[64]={0};
+    char *parttype;
+    unsigned int start, end;
+    char bootable[6] = {0};
+
+    int i = nb_partitions_seen;
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+        sectors_to_size(ptab->length, size);
+
+    get_label(ptab->ostype, &parttype);
+    get_bootloader_string(drive_info, ptab, bootloader_name, 9);
+    if (ptab->active_flag == 0x80)
+    	snprintf(bootable,sizeof(bootable),"%s","true");
+    else
+	snprintf(bootable,sizeof(bootable),"%s","false");
+
+    snprintf(ostype,sizeof(ostype),"%02X",ptab->ostype);
+
+    APPEND_ARRAY
+	    add_ai("partition->number",i)
+	    add_ai("partition->sector_start",start)
+	    add_ai("partition->sector_end",end)
+	    add_as("partition->size",size)
+	    add_as("partition->type",parttype)
+	    add_as("partition->os_type",ostype)
+	    add_as("partition->boot_flag",bootable)
+    END_OF_APPEND;
+    free(parttype);
+}
+
+
+
+void show_disk(struct s_hardware *hardware, ZZJSON_CONFIG *conf, ZZJSON **it, int drive) {
+	config=conf;
+	item=it;
+	int i = drive - 0x80;
+	struct driveinfo *d = &hardware->disk_info[i];
+	char mbr_name[50]={0};
+	char disk_size[11]={0};
+
+	get_mbr_string(hardware->mbr_ids[i], &mbr_name,sizeof(mbr_name));
+	if ((int)d->edd_params.sectors > 0)
+		sectors_to_size((int)d->edd_params.sectors, disk_size);
+
+	char disk[5]={0};
+	char edd_version[5]={0};
+	snprintf(disk,sizeof(disk),"0x%X",d->disk);
+	snprintf(edd_version,sizeof(edd_version),"%X",d->edd_version);
+	zzjson_print(config, *item);
+	zzjson_free(config, *item);
+
+	CREATE_ARRAY
+		add_as("disk->number",disk) 
+		add_ai("disk->cylinders",d->legacy_max_cylinder +1) 
+		add_ai("disk->heads",d->legacy_max_head +1)
+		add_ai("disk->sectors_per_track",d->legacy_sectors_per_track)
+		add_as("disk->edd_version",edd_version)
+		add_as("disk->size",disk_size)
+		add_ai("disk->bytes_per_sector",(int)d->edd_params.bytes_per_sector)
+		add_ai("disk->sectors_per_track",(int)d->edd_params.sectors_per_track)
+		add_as("disk->host_bus",remove_spaces((char *)d->edd_params.host_bus_type))
+		add_as("disk->interface_type",remove_spaces((char *)d->edd_params.interface_type))
+		add_as("disk->mbr_name",mbr_name)
+		add_ai("disk->mbr_id",hardware->mbr_ids[i])
+	END_OF_ARRAY;
+
+	if (parse_partition_table(d, &show_partition_information)) {
+	        if (errno_disk) { 
+			APPEND_ARRAY
+				add_as("disk->error", "IO Error")
+			END_OF_APPEND;
+		} else  {
+			APPEND_ARRAY
+				add_as("disk->error", "Unrecognized Partition Layout")
+			END_OF_APPEND;
+		}
+	}
+}
+
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	bool found=false;
+
+ 	if (hardware->disks_count > 0)  
+	    for (int drive = 0x80; drive < 0xff; drive++) {
+	        if (hardware->disk_info[drive - 0x80].cbios) {
+			if (found==false) {
+				CREATE_NEW_OBJECT;
+				add_b("disks->is_valid",true);
+       				found=true;
+			}
+			show_disk(hardware, config, item, drive);
+		}
+	}
+
+	if (found==false) {
+		CREATE_NEW_OBJECT;
+		add_b("disks->is_valid",false);
+	}
+	FLUSH_OBJECT;
+	to_cpio("disks");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,447 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_hardware_security(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (!hardware->dmi.hardware_security.filled) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No hardware security structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+	
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","hardware_security");
+		add_hs(dmi.hardware_security.power_on_passwd_status);
+		add_hs(dmi.hardware_security.keyboard_passwd_status);
+		add_hs(dmi.hardware_security.administrator_passwd_status);
+		add_hs(dmi.hardware_security.front_panel_reset_status);
+	FLUSH_OBJECT;
+}
+
+void dump_oem_strings(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (strlen(hardware->dmi.oem_strings) == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No OEM structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","OEM");
+		add_hs(dmi.oem_strings);
+	FLUSH_OBJECT;
+}
+
+void dump_memory_size(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","memory size");
+		add_i("dmi.memory_size (KB)",hardware->detected_memory_size);
+		add_i("dmi.memory_size (MB)",(hardware->detected_memory_size + (1 << 9)) >> 10);
+	FLUSH_OBJECT;
+}
+
+void dump_memory_modules(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.memory_module_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No memory module structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int module=0; module<hardware->dmi.memory_module_count;module++) {
+		if (hardware->dmi.memory_module[module].filled == false) {
+			char msg[64]={0};
+			snprintf(msg,sizeof(msg),"Module %d doesn't contain any information", module);
+
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning",msg);
+			FLUSH_OBJECT;
+			continue;
+		}
+
+		CREATE_NEW_OBJECT;
+		add_i("Memory module", module);
+		add_s("dmi.memory_module.socket_designation", hardware->dmi.memory_module[module].socket_designation);
+		add_s("dmi.memory_module.bank_connections", hardware->dmi.memory_module[module].bank_connections);
+		add_s("dmi.memory_module.speed", hardware->dmi.memory_module[module].speed);
+		add_s("dmi.memory_module.type", hardware->dmi.memory_module[module].type);
+		add_s("dmi.memory_module.installed_size", hardware->dmi.memory_module[module].installed_size);
+		add_s("dmi.memory_module.enabled_size", hardware->dmi.memory_module[module].enabled_size);
+		add_s("dmi.memory_module.error_status", hardware->dmi.memory_module[module].error_status);
+		FLUSH_OBJECT;
+	}
+}
+	
+void dump_cache(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.cache_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No cache structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int cache=0; cache<hardware->dmi.cache_count;cache++) {
+		CREATE_NEW_OBJECT;
+		add_i("Cache", cache);
+		add_s("dmi.cache.socket_designation", hardware->dmi.cache[cache].socket_designation);
+		add_s("dmi.cache.configuration", hardware->dmi.cache[cache].configuration);
+		add_s("dmi.cache.mode", hardware->dmi.cache[cache].mode);
+		add_s("dmi.cache.location", hardware->dmi.cache[cache].location);
+		add_i("dmi.cache.installed_size (KB)", hardware->dmi.cache[cache].installed_size);
+		add_i("dmi.cache.max_size (KB)", hardware->dmi.cache[cache].max_size);
+		add_s("dmi.cache.supported_sram_types", hardware->dmi.cache[cache].supported_sram_types);
+		add_s("dmi.cache.installed_sram_types", hardware->dmi.cache[cache].installed_sram_types);
+		add_i("dmi.cache.speed (ns)", hardware->dmi.cache[cache].speed);
+		add_s("dmi.cache.error_correction_type", hardware->dmi.cache[cache].error_correction_type);
+		add_s("dmi.cache.system_type", hardware->dmi.cache[cache].system_type);
+		add_s("dmi.cache.associativity", hardware->dmi.cache[cache].associativity);
+		FLUSH_OBJECT;
+	}
+}
+void dump_memory_banks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.memory_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No memory bank structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int bank=0; bank<hardware->dmi.memory_count;bank++) {
+
+		if (hardware->dmi.memory[bank].filled == false) {
+			char msg[64]={0};
+			snprintf(msg,sizeof(msg),"Bank %d doesn't contain any information", bank);
+
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning",msg);
+			FLUSH_OBJECT;
+			continue;
+		}
+
+		CREATE_NEW_OBJECT;
+		add_i("Memory Bank", bank);
+		add_s("dmi.memory.form_factor", hardware->dmi.memory[bank].form_factor);
+		add_s("dmi.memory.type", hardware->dmi.memory[bank].type);
+		add_s("dmi.memory.type_detail", hardware->dmi.memory[bank].type_detail);
+		add_s("dmi.memory.speed", hardware->dmi.memory[bank].speed);
+		add_s("dmi.memory.size", hardware->dmi.memory[bank].size);
+		add_s("dmi.memory.device_set", hardware->dmi.memory[bank].device_set);
+		add_s("dmi.memory.device_locator", hardware->dmi.memory[bank].device_locator);
+		add_s("dmi.memory.bank_locator", hardware->dmi.memory[bank].bank_locator);
+		add_s("dmi.memory.total_width", hardware->dmi.memory[bank].total_width);
+		add_s("dmi.memory.data_width", hardware->dmi.memory[bank].data_width);
+		add_s("dmi.memory.error", hardware->dmi.memory[bank].error);
+		add_s("dmi.memory.vendor", hardware->dmi.memory[bank].manufacturer);
+		add_s("dmi.memory.serial", hardware->dmi.memory[bank].serial);
+		add_s("dmi.memory.asset_tag", hardware->dmi.memory[bank].asset_tag);
+		add_s("dmi.memory.part_number", hardware->dmi.memory[bank].part_number);
+		FLUSH_OBJECT;
+	}
+}
+
+void dump_processor(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.processor.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no processor structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	char voltage[16]={0};
+	snprintf(voltage,sizeof(voltage),"%d.%02d",
+		hardware->dmi.processor.voltage_mv / 1000,
+		hardware->dmi.processor.voltage_mv - ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","processor");
+	add_hs(dmi.processor.socket_designation);
+	add_hs(dmi.processor.type);
+	add_hs(dmi.processor.family);
+	add_hs(dmi.processor.manufacturer);
+	add_hs(dmi.processor.version);
+	add_hi(dmi.processor.external_clock);
+	add_hi(dmi.processor.max_speed);
+	add_hi(dmi.processor.current_speed);
+	add_hi(dmi.processor.signature.type);
+	add_hi(dmi.processor.signature.family);
+	add_hi(dmi.processor.signature.model);
+	add_hi(dmi.processor.signature.stepping);
+	add_hi(dmi.processor.signature.minor_stepping);
+	add_s("dmi.processor.voltage",voltage);
+	add_hs(dmi.processor.status);
+	add_hs(dmi.processor.upgrade);
+	add_hs(dmi.processor.cache1);
+	add_hs(dmi.processor.cache2);
+	add_hs(dmi.processor.cache3);
+	add_hs(dmi.processor.serial);
+	add_hs(dmi.processor.part_number);
+	add_hi(dmi.processor.core_count);
+	add_hi(dmi.processor.core_enabled);
+	add_hi(dmi.processor.thread_count);
+	add_hs(dmi.processor.id);
+	for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
+	            add_s("dmi.processor.flag",(char *)cpu_flags_strings[i]);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_battery(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.battery.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no battery structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","battery");
+	add_hs(dmi.battery.manufacturer);
+	add_hs(dmi.battery.manufacture_date);
+	add_hs(dmi.battery.serial);
+	add_hs(dmi.battery.name);
+	add_hs(dmi.battery.chemistry);
+	add_hs(dmi.battery.design_capacity);
+	add_hs(dmi.battery.design_voltage);
+	add_hs(dmi.battery.sbds);
+	add_hs(dmi.battery.sbds_manufacture_date);
+	add_hs(dmi.battery.sbds_chemistry);
+	add_hs(dmi.battery.maximum_error);
+	add_hs(dmi.battery.oem_info);
+	FLUSH_OBJECT;
+}
+
+void dump_ipmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.ipmi.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no IPMI structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	char spec_ver[16]={0};
+	char i2c[16]={0};
+	char base[16]={0};
+	snprintf(spec_ver,sizeof(spec_ver),"%u.%u",
+			hardware->dmi.ipmi.major_specification_version,
+			hardware->dmi.ipmi.minor_specification_version);
+
+	snprintf(i2c,sizeof(i2c),"0x%02x", hardware->dmi.ipmi.I2C_slave_address);
+	snprintf(base,sizeof(base),"%08X%08X",
+			(uint32_t)(hardware->dmi.ipmi.base_address >> 32),
+			(uint32_t)((hardware->dmi.ipmi.base_address & 0xFFFF) & ~1));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","ipmi");
+	add_hs(dmi.ipmi.interface_type);
+	add_s("dmi.ipmi.spec_version",spec_ver);
+	add_hi(dmi.ipmi.I2C_slave_address);
+	add_hi(dmi.ipmi.nv_address);
+	add_s("dmi.ipmi.base_address",base);
+	add_hi(dmi.ipmi.irq);
+	FLUSH_OBJECT;
+}
+
+void dump_chassis(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.chassis.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no chassis structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","bios");
+	add_hs(dmi.chassis.manufacturer);
+	add_hs(dmi.chassis.type);
+	add_hs(dmi.chassis.lock);
+	add_hs(dmi.chassis.version);
+	add_hs(dmi.chassis.serial);
+	add_s("dmi.chassis.asset_tag",del_multi_spaces(hardware->dmi.chassis.asset_tag));
+	add_hs(dmi.chassis.boot_up_state);
+	add_hs(dmi.chassis.power_supply_state);
+	add_hs(dmi.chassis.thermal_state);
+	add_hs(dmi.chassis.security_status);
+	add_hs(dmi.chassis.oem_information);
+	add_hi(dmi.chassis.height);
+	add_hi(dmi.chassis.nb_power_cords);
+	FLUSH_OBJECT;
+}
+
+void dump_bios(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.bios.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no bios structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+	char address[16]={0};
+	char runtime[16]={0};
+	char rom[16]={0};
+	snprintf(address,sizeof(address),"0x%04X0",hardware->dmi.bios.address);
+	snprintf(runtime,sizeof(runtime),"%u %s",hardware->dmi.bios.runtime_size, hardware->dmi.bios.runtime_size_unit);
+	snprintf(rom,sizeof(rom),"%u %s",hardware->dmi.bios.rom_size, hardware->dmi.bios.rom_size_unit);
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","bios");
+	add_hs(dmi.bios.vendor);
+	add_hs(dmi.bios.version);
+	add_hs(dmi.bios.release_date);
+	add_hs(dmi.bios.bios_revision);
+	add_hs(dmi.bios.firmware_revision);
+	add_s("dmi.bios.address",address);
+	add_s("dmi.bios.runtime_size",runtime);
+	add_s("dmi.bios.rom_size",rom);
+	for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_strings[i]);
+		}
+	}
+	
+	for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_x1_strings[i]);
+		}
+	}
+
+	for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_x2_strings[i]);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_system(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.system.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no system structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+	char system_reset_status[10]={0};
+	char watchdog_timer[15]={0};
+	snprintf(system_reset_status,sizeof(system_reset_status),"%s", (hardware->dmi.system.system_reset.status ? "Enabled" :"Disabled"));
+	snprintf(watchdog_timer,sizeof(watchdog_timer),"%s", (hardware->dmi.system.system_reset.watchdog ? "Present" :"Not Present"));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","system");
+	add_hs(dmi.system.manufacturer);
+	add_hs(dmi.system.product_name);
+	add_hs(dmi.system.version);
+	add_hs(dmi.system.serial);
+	add_hs(dmi.system.uuid);
+	add_hs(dmi.system.wakeup_type);
+	add_hs(dmi.system.sku_number);
+	add_hs(dmi.system.family);
+	add_hs(dmi.system.configuration_options);
+	add_s("dmi.system.system_reset.status",system_reset_status);
+	add_s("dmi.system.system_reset.watchdog",watchdog_timer);
+	add_hs(dmi.system.system_reset.boot_option);
+	add_hs(dmi.system.system_reset.boot_option_on_limit);
+	add_hs(dmi.system.system_reset.reset_count);
+	add_hs(dmi.system.system_reset.reset_limit);
+	add_hs(dmi.system.system_reset.timer_interval);
+	add_hs(dmi.system.system_reset.timeout);
+	add_hs(dmi.system.system_boot_status);
+	FLUSH_OBJECT;
+}
+
+void dump_base_board(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.base_board.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no base_board structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","base_board");
+	add_hs(dmi.base_board.manufacturer);
+	add_hs(dmi.base_board.product_name);
+	add_hs(dmi.base_board.version);
+	add_hs(dmi.base_board.serial);
+	add_hs(dmi.base_board.asset_tag);
+	add_hs(dmi.base_board.location);
+	add_hs(dmi.base_board.type);
+	for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+		if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
+			add_s("dmi.base_board.features",(char *)base_board_features_strings[i]);
+		}
+	}
+
+	for (unsigned int i = 0; i < sizeof hardware->dmi.base_board.devices_information /
+		         sizeof *hardware->dmi.base_board.devices_information; i++) {
+	        if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
+			add_s("dmi.base_board.devices_information.type", hardware->dmi.base_board.devices_information[i].type);
+			add_i("dmi.base_board.devices_information.status", hardware->dmi.base_board.devices_information[i].status);
+			add_s("dmi.base_board.devices_information.description", hardware->dmi.base_board.devices_information[i].description);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_dmi_valid);
+
+	if (hardware->is_dmi_valid == false) {
+		FLUSH_OBJECT;
+		goto exit;
+	} else {
+		char buffer[8]={0};
+		snprintf(buffer,sizeof(buffer),"%d.%d",hardware->dmi.dmitable.major_version, hardware->dmi.dmitable.minor_version);
+		add_s("dmi.version",buffer);
+		FLUSH_OBJECT;
+	}
+
+	dump_base_board(hardware,config,item);
+	dump_system(hardware,config,item);
+	dump_bios(hardware,config,item);
+	dump_chassis(hardware,config,item);
+	dump_ipmi(hardware,config,item);
+	dump_battery(hardware,config,item);
+	dump_processor(hardware,config,item);
+	dump_cache(hardware,config,item);
+	dump_memory_banks(hardware,config,item);
+	dump_memory_modules(hardware,config,item);
+	dump_memory_size(hardware,config,item);
+	dump_oem_strings(hardware,config,item);
+	dump_hardware_security(hardware,config,item);
+exit:
+	to_cpio("dmi");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	CREATE_NEW_OBJECT;
+	add_s("hdt.product_name",PRODUCT_NAME);
+	add_s("hdt.version",VERSION);
+	add_s("hdt.code_name",CODENAME);
+	add_s("hdt.author", AUTHOR);
+	add_s("hdt.core_developer", CORE_DEVELOPER);
+	char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+	for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+		add_s("hdt.contributor", contributors[c]);
+	}
+	add_s("hdt.website",WEBSITE_URL);
+	add_s("hdt.irc_channel",IRC_CHANNEL);
+	FLUSH_OBJECT
+	to_cpio("hdt");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+		 ZZJSON ** item)
+{
+    struct pci_device *pci_device = NULL;
+    CREATE_ARRAY
+	    add_as("Linux Kernel modules", "")
+    END_OF_ARRAY;
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	APPEND_ARRAY 
+		add_as("Error", "No pci.ids file")
+	END_OF_APPEND FLUSH_OBJECT;
+	return;
+    }
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP)
+	&&(hardware->modules_pcimap_return_code == -ENOMODULESALIAS)) {
+	APPEND_ARRAY
+		add_as("Error", "No modules.pcimap or modules.alias file")
+	END_OF_APPEND FLUSH_OBJECT;
+	return;
+
+	}
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	if (pci_device == NULL)
+	    continue;
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    APPEND_ARRAY
+		    add_as(pci_device->dev_info->category_name, pci_device->dev_info->linux_kernel_module[kmod])
+	    END_OF_APPEND;
+	}
+    }
+    FLUSH_OBJECT;
+    to_cpio("kernel");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <memory.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_88(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	int mem_size = 0;
+	CREATE_NEW_OBJECT;
+	if (detect_memory_88(&mem_size)) {
+		add_s("memory.error","8800h memory configuration is invalid");
+		FLUSH_OBJECT
+		return;
+	}
+
+	add_s("dmi.item","memory via 88");
+	add_i("memory.size (KiB)", mem_size);
+	add_i("memory.size (MiB)", mem_size >> 10);
+	FLUSH_OBJECT;
+}
+
+void dump_e801(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	int mem_low, mem_high = 0;
+	CREATE_NEW_OBJECT;
+	if (detect_memory_e801(&mem_low,&mem_high)) {
+		add_s("memory.error","e801 memory configuration is invalid");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	add_s("dmi.item","memory via e801");
+	add_i("memory.total.size (KiB)", mem_low + (mem_high << 6));
+	add_i("memory.total.size (MiB)", (mem_low >> 10) + (mem_high >> 4));
+	add_i("memory.low.size (KiB)", mem_low );
+	add_i("memory.low.size (MiB)", mem_low >> 10);
+	add_i("memory.high.size (KiB)", mem_high << 6);
+	add_i("memory.high.size (MiB)", mem_high >> 4);
+	FLUSH_OBJECT;
+
+}
+void dump_e820(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+    
+	(void) hardware;
+	struct e820entry map[E820MAX];
+	struct e820entry nm[E820MAX];
+	unsigned long memsize = 0;
+	int count = 0;
+	char type[14] = {0};
+	
+	detect_memory_e820(map, E820MAX, &count);
+ 	memsize = memsize_e820(map, count);
+	
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","memory via e820");
+		add_i("memory.total.size (KiB)", memsize);
+		add_i("memory.total.size (MiB)", (memsize + (1 << 9)) >> 10);
+	FLUSH_OBJECT;
+
+	for (int i = 0; i < count; i++) {
+		get_type(map[i].type, type, sizeof(type));
+		char begin[24]={0};
+		char size[24]={0};
+		char end[24]={0};
+		snprintf(begin,sizeof(begin),"0x%016llx",map[i].addr);
+		snprintf(size,sizeof(size),"0x%016llx",map[i].size);
+		snprintf(end,sizeof(end),"0x%016llx",map[i].addr+map[i].size);
+		CREATE_NEW_OBJECT;
+			add_s("memory.segment.start",begin);
+			add_s("memory.segment.size ",size);
+			add_s("memory.segment.end  ",end);
+			add_s("memory.segment.type ",remove_spaces(type));
+		FLUSH_OBJECT;
+	}
+
+	int nr = sanitize_e820_map(map, nm, count);
+	for (int i = 0; i < nr; i++) {
+		get_type(nm[i].type, type, sizeof(type));
+		char begin[24]={0};
+		char size[24]={0};
+		char end[24]={0};
+		snprintf(begin,sizeof(begin),"0x%016llx",nm[i].addr);
+		snprintf(size,sizeof(size),"0x%016llx",nm[i].size);
+		snprintf(end,sizeof(end),"0x%016llx",nm[i].addr+nm[i].size);
+		CREATE_NEW_OBJECT;
+			add_s("sanitized_memory.segment.start",begin);
+			add_s("sanitized_memory.segment.size ",size);
+			add_s("sanitized_memory.segment.end  ",end);
+			add_s("sanitized_memory.segment.type ",remove_spaces(type));
+		FLUSH_OBJECT;
+	}
+}
+
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+		add_s("Memory configuration","true");
+	FLUSH_OBJECT;
+
+	dump_88(hardware,config,item);
+	dump_e801(hardware,config,item);
+	dump_e820(hardware,config,item);
+	to_cpio("memory");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+	      ZZJSON ** item)
+{
+    int i = 1;
+    struct pci_device *pci_device=NULL;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfile = false;
+    int bus = 0, slot = 0, func = 0;
+    
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+
+    nomodulesfile = nomodulespcimap && nomodulesalias;
+
+    CREATE_NEW_OBJECT;
+
+    add_i("pci_device.count", hardware->nb_pci_devices);
+
+    FLUSH_OBJECT;
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	if (pci_device == NULL)
+	    continue;
+	char v[10] = { 0 };
+	char sv[10] = { 0 };
+	char p[10] = { 0 };
+	char sp[10] = { 0 };
+	char c[10] = { 0 };
+	char r[10] = { 0 };
+
+	CREATE_NEW_OBJECT;
+	bus = __pci_bus;
+	slot = __pci_slot;
+	func = __pci_func;
+
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	add_i("pci_device.number", i);
+	if (nopciids == false) {
+	    add_s("pci_device.vendor_name", pci_device->dev_info->vendor_name);
+	    add_s("pci_device.product_name",
+		   pci_device->dev_info->product_name);
+	}
+	if (nomodulesfile == false) {
+	    add_s("pci_device.class_name", pci_device->dev_info->class_name);
+	    add_s("pci_device.kernel_module", kernel_modules);
+	}
+
+	snprintf(v, sizeof(v), "%04x", pci_device->vendor);
+	snprintf(p, sizeof(p), "%04x", pci_device->product);
+	snprintf(sv, sizeof(sv), "%04x", pci_device->sub_vendor);
+	snprintf(sp, sizeof(sp), "%04x", pci_device->sub_product);
+	snprintf(c, sizeof(c), "%02x.%02x.%02x",
+		 pci_device->class[2],
+		 pci_device->class[1], pci_device->class[0]);
+	snprintf(r, sizeof(r), "%02x", pci_device->revision);
+	add_s("pci_device.vendor_id", v);
+	add_s("pci_device.product_id", p);
+	add_s("pci_device.sub_vendor_id", sv);
+	add_s("pci_device.sub_product_id", sp);
+	add_s("pci_device.class_id", c);
+	add_s("pci_device.revision", r);
+	if ((pci_device->dev_info->irq > 0)
+	    && (pci_device->dev_info->irq < 255))
+	    add_i("pci_device.irq", pci_device->dev_info->irq);
+
+	add_i("pci_device.latency", pci_device->dev_info->latency);
+	add_i("pci_device.bus", bus);
+	add_i("pci_device.slot", slot);
+	add_i("pci_device.func", func);
+
+	if (hardware->is_pxe_valid == true) {
+	    if ((hardware->pxe.pci_device != NULL)
+		&& (hardware->pxe.pci_device == pci_device)) {
+		add_hs(pxe.mac_addr);
+		add_s("pxe", "Current boot device");
+	    }
+	}
+	i++;
+	FLUSH_OBJECT;
+    }
+    to_cpio("pci");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <sys/gpxe.h>
+#include <netinet/in.h>
+
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	struct in_addr in;
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_pxe_valid);
+	if (hardware->is_pxe_valid) {
+		char buffer[32] = {0};
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.vendor_id);
+		add_s("pxe.vendor_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.product_id);
+		add_s("pxe.product_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subvendor_id);
+		add_s("pxe.subvendor_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subproduct_id);
+		add_s("pxe.subproduct_id",buffer);
+
+		if (hardware->pci_ids_return_code == -ENOPCIIDS || (hardware->pxe.pci_device == NULL)) { 
+			add_s("Manufacturer_name","no_pci_ids_file or no device found");
+			add_s("Product_name","no_pci_ids_file or no device found");
+		} else {
+			add_s("Manufacturer_name", hardware->pxe.pci_device->dev_info->vendor_name);
+			add_s("Product_name", hardware->pxe.pci_device->dev_info->product_name);
+		}
+
+		add_hi(pxe.rev);
+		add_hi(pxe.pci_bus);
+		add_hi(pxe.pci_dev);
+		add_hi(pxe.pci_func);
+		add_hi(pxe.base_class);
+		add_hi(pxe.sub_class);
+		add_hi(pxe.prog_intf);
+		add_hi(pxe.nictype);
+		add_hs(pxe.mac_addr);
+	
+		in.s_addr = hardware->pxe.dhcpdata.cip;
+		add_s("pxe.client_ip", inet_ntoa(in));
+		in.s_addr = hardware->pxe.dhcpdata.sip;
+		add_s("pxe.next_server_ip",inet_ntoa(in));
+		in.s_addr = hardware->pxe.dhcpdata.gip;
+		add_s("pxe.relay_agent_ip",inet_ntoa(in));
+		memcpy(&in, hardware->pxe.ip_addr, sizeof in);
+		add_s("pxe.ipaddr",inet_ntoa(in));
+		add_b("gpxe_detected",is_gpxe());
+	}
+	FLUSH_OBJECT;
+	to_cpio("pxe");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hs(syslinux_fs);
+	add_hs(sv->version_string);
+	add_hi(sv->version);
+	add_hi(sv->max_api);
+	add_hs(sv->copyright_string);
+	FLUSH_OBJECT
+	to_cpio("syslinux");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_vesa_valid);
+	if (hardware->is_vesa_valid) {
+		char buffer[64]={0};
+		snprintf(buffer,sizeof(buffer),"%d.%d", hardware->vesa.major_version, hardware->vesa.minor_version);
+		add_s("vesa.version",buffer);
+		add_hs(vesa.vendor);
+		add_hs(vesa.product);
+		add_hs(vesa.product_revision);
+		add_hi(vesa.software_rev);
+		memset(buffer,0,sizeof(buffer));
+		snprintf(buffer,sizeof(buffer),"%d KB",hardware->vesa.total_memory*64);
+		add_s("vesa.memory",buffer);
+		add_i("vesa.modes",hardware->vesa.vmi_count);
+		FLUSH_OBJECT;
+		for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+		        struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+		        if ((mi->h_res == 0) || (mi->v_res == 0))
+				continue;
+			CREATE_NEW_OBJECT;
+			memset(buffer,0,sizeof(buffer));
+			snprintf(buffer,sizeof(buffer),"0x%04x",hardware->vesa.vmi[i].mode + 0x200);
+			add_s("vesa.kernel_mode",buffer);
+			add_i("vesa.hres",mi->h_res);
+			add_i("vesa.vres",mi->v_res);
+			add_i("vesa.bpp",mi->bpp);
+			FLUSH_OBJECT;
+		}
+	} else {
+		FLUSH_OBJECT;
+	}
+	to_cpio("vesa");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_vpd_valid);
+    	if (hardware->is_vpd_valid) {
+		add_hs(vpd.bios_build_id);
+		add_hs(vpd.bios_release_date);
+		add_hs(vpd.bios_version);
+		add_hs(vpd.default_flash_filename);
+		add_hs(vpd.box_serial_number);
+		add_hs(vpd.motherboard_serial_number);
+		add_hs(vpd.machine_type_model);
+	}
+	FLUSH_OBJECT;
+	to_cpio("vpd");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <getkey.h>
+#include <syslinux/config.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+struct print_buf p_buf;
+
+struct dump_option {
+    char *flag;
+    char *item;
+};
+
+char *get_value_from_option(struct s_hardware *hardware, char *option)
+{
+    struct dump_option dump_options[10];
+    dump_options[0].flag = "%{m}";
+    dump_options[0].item = hardware->pxe.mac_addr;
+
+    dump_options[1].flag = "%{v}";
+    dump_options[1].item = hardware->dmi.system.manufacturer;
+
+    dump_options[2].flag = "%{p}";
+    dump_options[2].item = hardware->dmi.system.product_name;
+
+    dump_options[3].flag = "%{ba}";
+    dump_options[3].item = hardware->dmi.base_board.asset_tag;
+
+    dump_options[4].flag = "%{bs}";
+    dump_options[4].item = hardware->dmi.base_board.serial;
+
+    dump_options[5].flag = "%{ca}";
+    dump_options[5].item = hardware->dmi.chassis.asset_tag;
+
+    dump_options[6].flag = "%{cs}";
+    dump_options[6].item = hardware->dmi.chassis.serial;
+
+    dump_options[7].flag = "%{sk}";
+    dump_options[7].item = hardware->dmi.system.sku_number;
+
+    dump_options[8].flag = "%{ss}";
+    dump_options[8].item = hardware->dmi.system.serial;
+
+    dump_options[9].flag = NULL;
+    dump_options[9].item = NULL;
+
+    for (int i = 0; i < 9; i++) {
+	if (strcmp(option, dump_options[i].flag) == 0) {
+	    return remove_spaces(dump_options[i].item);
+	}
+    }
+
+    return NULL;
+}
+
+char *compute_filename(struct s_hardware *hardware)
+{
+
+    char *filename = malloc(512);
+    snprintf(filename, 512, "%s/%s", hardware->dump_path,
+	     hardware->dump_filename);
+
+    /* Until we found some dump parameters */
+    char *buffer;
+    while ((buffer = strstr(filename, "%{"))) {
+	// Find the end of the parameter
+	char *buffer_end = strstr(buffer, "}");
+
+	// Extracting the parameter between %{ and }
+	char option[8] = { 0 };
+	strncpy(option, buffer, buffer_end - buffer + 1);
+
+	/* Replace this option by its value in the filename 
+	 * Filename is longer than the previous filename we had
+	 * so let's restart from the beginning */
+	filename =
+	    strreplace(filename, option,
+		       get_value_from_option(hardware, option));
+    }
+
+    /* We replace the ":" in the filename by some "-"
+     * This will avoid Microsoft FS turning crazy */
+    chrreplace(filename, ':', '-');
+
+    /* Avoid space to make filename easier to manipulate */
+    chrreplace(filename, ' ', '_');
+
+    return filename;
+}
+
+int dumpprintf(FILE * p, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    (void)p;
+    va_start(ap, format);
+    rv = vbufprintf(&p_buf, format, ap);
+    va_end(ap);
+    return rv;
+}
+
+void to_cpio(char *filename)
+{
+    cpio_writefile(upload, filename, p_buf.buf, p_buf.len);
+    if ((p_buf.buf) && (p_buf.len > 0)) {
+	memset(p_buf.buf, 0, p_buf.len);
+	free(p_buf.buf);
+	p_buf.buf = NULL;
+	p_buf.size = 0;
+	p_buf.len = 0;
+    }
+}
+
+void flush(ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    zzjson_print(config, *item);
+    zzjson_free(config, *item);
+    *item = NULL;
+}
+
+/**
+ * dump - dump info
+ **/
+void dump(struct s_hardware *hardware)
+{
+    if (hardware->is_pxe_valid == false) {
+	more_printf("PXE stack was not detected, Dump feature is not available\n");
+	return;
+    }
+
+    const union syslinux_derivative_info *sdi = syslinux_derivative_info();
+    int err = 0;
+    ZZJSON *json = NULL;
+    ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+	(int (*)(void *))fgetc,
+	NULL,
+	malloc, calloc, free, realloc,
+	stderr, NULL, stdout,
+	(int (*)(void *, const char *,...))dumpprintf,
+	(int (*)(int, void *))fputc
+    };
+
+    memset(&p_buf, 0, sizeof(p_buf));
+
+    /* By now, we only support TFTP reporting */
+    upload = &upload_tftp;
+    upload->name = "tftp";
+
+    /* The following defines the behavior of the reporting */
+    char *arg[64];
+    char *filename = compute_filename(hardware);
+
+    /* The filename */
+    arg[0] = filename;
+    /* The server to upload the file */
+    if (strlen(hardware->tftp_ip) != 0) {
+	arg[1] = hardware->tftp_ip;
+	arg[2] = NULL;
+    } else {
+	arg[1] = NULL;
+	snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip),
+		 "%u.%u.%u.%u",
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[0],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[1],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[2],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[3]);
+
+    }
+
+    /* We initiate the cpio to send */
+    cpio_init(upload, (const char **)arg);
+
+    dump_cpu(hardware, &config, &json);
+    dump_pxe(hardware, &config, &json);
+    dump_syslinux(hardware, &config, &json);
+    dump_vpd(hardware, &config, &json);
+    dump_vesa(hardware, &config, &json);
+    dump_disks(hardware, &config, &json);
+    dump_dmi(hardware, &config, &json);
+    dump_memory(hardware, &config, &json);
+    dump_pci(hardware, &config, &json);
+    dump_acpi(hardware, &config, &json);
+    dump_kernel(hardware, &config, &json);
+    dump_hdt(hardware, &config, &json);
+
+    /* We close & flush the file to send */
+    cpio_close(upload);
+
+    if ((err = flush_data(upload)) != TFTP_OK) {
+	/* As we manage a tftp connection, let's display the associated error message */
+	more_printf("Dump failed !\n");
+	more_printf("TFTP ERROR on  : %s:/%s \n", hardware->tftp_ip, filename);
+	more_printf("TFTP ERROR msg : %s \n", tftp_string_error_message[-err]);
+    } else {
+	more_printf("Dump file sent at %s:/%s\n", hardware->tftp_ip, filename);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,85 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 20011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <bufprintf.h>
+#include <zzjson/zzjson.h>
+#include "hdt-common.h"
+
+// Macros to manipulate Arrays
+#define APPEND_ARRAY ZZJSON *temp_array; temp_array = zzjson_array_append(config, *item, zzjson_create_object(config,
+#define APPEND_OBJECT_ARRAY(value) ZZJSON *temp_ar; temp_ar = zzjson_array_append(config, *item, value); *item=temp_ar; 
+#define CREATE_ARRAY *item = zzjson_create_array(config, zzjson_create_object(config, 
+#define add_ai(name,value) name,zzjson_create_number_i(config,value),
+#define add_ahi(value) add_ai(#value,hardware->value)
+#define add_as(name,value) name,zzjson_create_string(config,value),
+#define add_ahs(value) add_as(#value,hardware->value)
+#define END_OF_ARRAY NULL),NULL)
+#define END_OF_APPEND NULL)); *item=temp_array;
+
+// Macros to manipulate objects
+#define CREATE_NEW_OBJECT   *item = zzjson_create_object(config, NULL);
+#define FLUSH_OBJECT flush(config, item); 
+
+// Macros to manipulate integers as objects
+#define add_i(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_number_i(config, value))
+#define add_hi(value) add_i(#value,hardware->value)
+
+// Macros to manipulate strings as objects
+#define add_s(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_string(config, value))
+#define add_hs(value) add_s(#value,(char *)hardware->value)
+
+// Macros to manipulate bool as objects
+#define add_bool_true(name) *item = zzjson_object_append(config, *item, (char *)name, zzjson_create_true(config))
+#define add_bool_false(name) *item = zzjson_object_append(config, *item, (char*)name, zzjson_create_false(config))
+#define add_b(name,value) if (value==true) {add_bool_true(name);} else {add_bool_false(name);}
+#define add_hb(value) add_b(#value,hardware->value)
+
+extern struct print_buf p_buf;
+
+void print_and_flush(ZZJSON_CONFIG *config, ZZJSON **item);
+int dumpprintf(FILE *p, const char *format, ...);
+void flush (ZZJSON_CONFIG *config, ZZJSON ** item);
+void to_cpio(char *filename);
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump(struct s_hardware *hardware);
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,92 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Computing About menu*/
+void compute_aboutmenu(struct s_my_menu *menu)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" About ", -1);
+    menu->items_count = 0;
+
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Product        : %s", PRODUCT_NAME);
+    snprintf(statbuffer, sizeof statbuffer, "Product : %s", PRODUCT_NAME);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version        : %s (%s)", VERSION,
+	     CODENAME);
+    snprintf(statbuffer, sizeof statbuffer, "Version : %s (%s)", VERSION,
+	     CODENAME);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Website        : %s", WEBSITE_URL);
+    snprintf(statbuffer, sizeof statbuffer, "Website : %s",WEBSITE_URL);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IRC Channel    : %s", IRC_CHANNEL);
+    snprintf(statbuffer, sizeof statbuffer, "IRC Channel : %s",IRC_CHANNEL);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Mailing List   : %s", CONTACT);
+    snprintf(statbuffer, sizeof statbuffer, "Mailing List: %s", CONTACT);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Project Leader : %s", AUTHOR);
+    snprintf(statbuffer, sizeof statbuffer, "Project Leader  : %s", AUTHOR);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Core Developer : %s", CORE_DEVELOPER);
+    snprintf(statbuffer, sizeof statbuffer, "Core Developer  : %s",
+	     CORE_DEVELOPER);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+    for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+	snprintf(buffer, sizeof buffer, "Contributor    : %s", contributors[c]);
+	snprintf(statbuffer, sizeof statbuffer, "Contributor : %s",
+		 contributors[c]);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    printf("MENU: About menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,134 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+void compute_table(struct s_my_menu *menu, void *address, s_acpi_description_header * h) {
+    char buffer[SUBMENULEN + 1] = { 0 };
+    char statbuffer[STATLEN + 1] = { 0 };
+
+    snprintf(buffer, sizeof buffer, "%-4s v%03x %-6s %-8s %-7s %08x", 
+		    h->signature, h->revision, h->oem_id, h->oem_table_id, h->creator_id, h->creator_revision);
+    snprintf(statbuffer, sizeof statbuffer, "%-4s v%03x %-6s %-7s 0x%08x %-4s    0x%08x @ 0x%p", 
+		    h->signature, h->revision, h->oem_id, h->oem_table_id,
+		    h->oem_revision, h->creator_id, h->creator_revision, address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Submenu for the vesa card */
+static void compute_acpi_tables(struct s_my_menu *menu,
+			      struct s_hardware *hardware)
+{
+    menu->menu = add_menu(" ACPI Tables ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    char buffer[SUBMENULEN + 1] = { 0 };
+
+    snprintf(buffer, sizeof buffer, "%-4s %-4s %-6s %-8s %-7s %-8s", 
+		    "ACPI", "rev", "oem", "table_id", "creator", "creator_rev");
+    add_item(buffer, "Description", OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    if (hardware->acpi.rsdt.valid)
+        compute_table(menu,hardware->acpi.rsdt.address,
+                       &hardware->acpi.rsdt.header);
+
+    if (hardware->acpi.xsdt.valid)
+        compute_table(menu,hardware->acpi.xsdt.address,
+                       &hardware->acpi.xsdt.header);
+
+    if (hardware->acpi.fadt.valid)
+        compute_table(menu,hardware->acpi.fadt.address, &hardware->acpi.fadt.header);
+
+    if (hardware->acpi.dsdt.valid)
+        compute_table(menu,hardware->acpi.dsdt.address, &hardware->acpi.dsdt.header);
+
+    /* SSDT includes many optional tables, let's display them */
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+        if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+            compute_table(menu,hardware->acpi.ssdt[i]->address,
+                        &hardware->acpi.ssdt[i]->header);
+    }
+
+    if (hardware->acpi.sbst.valid)
+        compute_table(menu,hardware->acpi.sbst.address, &hardware->acpi.sbst.header);
+
+    if (hardware->acpi.ecdt.valid)
+        compute_table(menu,hardware->acpi.ecdt.address, &hardware->acpi.ecdt.header);
+
+    if (hardware->acpi.hpet.valid)
+        compute_table(menu,hardware->acpi.hpet.address, &hardware->acpi.hpet.header);
+
+    if (hardware->acpi.tcpa.valid)
+        compute_table(menu,hardware->acpi.tcpa.address, &hardware->acpi.tcpa.header);
+
+    if (hardware->acpi.mcfg.valid)
+        compute_table(menu,hardware->acpi.mcfg.address, &hardware->acpi.mcfg.header);
+    
+    if (hardware->acpi.slic.valid)
+        compute_table(menu,hardware->acpi.slic.address, &hardware->acpi.slic.header);
+
+    if (hardware->acpi.boot.valid)
+        compute_table(menu,hardware->acpi.boot.address, &hardware->acpi.boot.header);
+
+    /* FACS isn't having the same headers, let's use a dedicated rendering */
+    if (hardware->acpi.facs.valid) {
+	s_facs *fa = &hardware->acpi.facs;
+        char buffer[SUBMENULEN + 1] = { 0 };
+        char statbuffer[STATLEN + 1] = { 0 };
+
+	snprintf(buffer, sizeof buffer, "%-4s", fa->signature); 
+	snprintf(statbuffer, sizeof statbuffer, "%-4s @ 0x%p", fa->signature, fa->address);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    	menu->items_count++;
+    }
+
+    if (hardware->acpi.madt.valid)
+        compute_table(menu,hardware->acpi.madt.address, &hardware->acpi.madt.header);
+
+}
+
+/* Main ACPI Menu*/
+int compute_ACPI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    compute_acpi_tables(&hdt_menu->acpi_tables_menu, hardware);
+    hdt_menu->acpi_menu.menu = add_menu(" ACPI ", -1);
+    hdt_menu->acpi_menu.items_count = 0;
+
+    add_item("Tables", "Tables", OPT_SUBMENU, NULL,
+	     hdt_menu->acpi_tables_menu.menu);
+    hdt_menu->acpi_menu.items_count++;
+    printf("MENU: ACPI menu done (%d items)\n",
+	   hdt_menu->acpi_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,264 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+
+#include "hdt-menu.h"
+#include "hdt-util.h"
+
+static int dn;
+
+static void show_partition_information(struct driveinfo *drive_info,
+				       struct part_entry *ptab __unused,
+				       int partition_offset __unused,
+				       int nb_partitions_seen)
+{
+    char menu_title[MENULEN + 1];
+    char menu_title_ref[MENULEN + 1];
+
+    if (nb_partitions_seen == 1)
+	add_sep();
+
+    memset(menu_title, 0, sizeof menu_title);
+    memset(menu_title_ref, 0, sizeof menu_title_ref);
+    snprintf(menu_title_ref, sizeof menu_title_ref, "disk_%x_part_%d",
+	     drive_info[dn].disk, nb_partitions_seen);
+    snprintf(menu_title, sizeof menu_title, "Partition %d", nb_partitions_seen);
+
+    add_item(menu_title,
+	     "Partition information (start, end, length, type, ...)",
+	     OPT_SUBMENU, menu_title_ref, 0);
+}
+
+/**
+ * compute_partition_information - print information about a partition
+ * @ptab:       part_entry describing the partition
+ * @i:          Partition number (UI purposes only)
+ * @ptab_root:  part_entry describing the root partition (extended only)
+ * @drive_info: driveinfo struct describing the drive on which the partition
+ *              is
+ *
+ * Note on offsets (from hpa, see chain.c32):
+ *
+ *  To make things extra confusing: data partition offsets are relative to where
+ *  the data partition record is stored, whereas extended partition offsets
+ *  are relative to the beginning of the extended partition all the way back
+ *  at the MBR... but still not absolute!
+ **/
+static void compute_partition_information(struct driveinfo *drive_info,
+					  struct part_entry *ptab,
+					  int partition_offset,
+					  int nb_partitions_seen)
+{
+    char size[11];
+    char bootloader_name[9];
+    char *parttype;
+    unsigned int start, end;
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    char menu_title[MENULEN + 1];
+    char menu_title_ref[MENULEN + 1];
+
+    memset(buffer, 0, sizeof buffer);
+    memset(statbuffer, 0, sizeof statbuffer);
+    memset(menu_title, 0, sizeof menu_title);
+    memset(menu_title_ref, 0, sizeof menu_title_ref);
+    snprintf(menu_title_ref, sizeof menu_title_ref, "disk_%x_part_%d",
+	     drive_info[dn].disk, nb_partitions_seen);
+    snprintf(menu_title, sizeof menu_title, "Partition %d", nb_partitions_seen);
+
+    add_named_menu(menu_title_ref, menu_title, -1);
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+	sectors_to_size(ptab->length, size);
+    else
+	memset(size, 0, sizeof size);
+
+    get_label(ptab->ostype, &parttype);
+
+    snprintf(buffer, sizeof buffer, "Size        : %s", remove_spaces(size));
+    snprintf(statbuffer, sizeof statbuffer, "Size : %s", remove_spaces(size));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Type        : %s", parttype);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", parttype);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0) {
+	snprintf(buffer, sizeof buffer, "Bootloader  : %s", bootloader_name);
+	snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+		 bootloader_name);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+
+    snprintf(buffer, sizeof buffer, "Boot Flag   : %s",
+	     (ptab->active_flag == 0x80) ? "Yes" : "No");
+    snprintf(statbuffer, sizeof statbuffer, "Boot Flag: %s",
+	     (ptab->active_flag == 0x80) ? "Yes" : "No");
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Start       : %d", start);
+    snprintf(statbuffer, sizeof statbuffer, "Start: %d", start);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "End         : %d", end);
+    snprintf(statbuffer, sizeof statbuffer, "End: %d", end);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Id          : %X", ptab->ostype);
+    snprintf(statbuffer, sizeof statbuffer, "Id: %X", ptab->ostype);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    free(parttype);
+
+    /* Extra info */
+    if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab) != -1) {
+	snprintf(buffer, sizeof buffer, "%s", "Swsusp sig  : detected");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "Swsusp sig  : detected");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+}
+
+/* Compute the disk submenu */
+static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
+			       const struct s_hardware *hardware,
+			       int disk_number)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    char mbr_name[50];
+    struct driveinfo *d = (struct driveinfo *)hardware->disk_info;
+
+    snprintf(buffer, sizeof buffer, " Disk <0x%X> (EDD %X)",
+	     d[disk_number].disk, d[disk_number].edd_version);
+    menu[nb_sub_disk_menu].menu = add_menu(buffer, -1);
+    menu[nb_sub_disk_menu].items_count = 0;
+
+    int previous_size, size;
+    char previous_unit[3], unit[3];	// GB
+    char size_iec[11];		// GiB
+    char size_dec[11];		// GB
+    sectors_to_size_dec(previous_unit, &previous_size, unit, &size,
+			d[disk_number].edd_params.sectors);
+    sectors_to_size(d[disk_number].edd_params.sectors, size_iec);
+    sectors_to_size_dec2(d[disk_number].edd_params.sectors, size_dec);
+
+    snprintf(buffer, sizeof buffer, "Size              : %s/%s (%d %s)",
+	     remove_spaces(size_iec), remove_spaces(size_dec), previous_size,
+	     previous_unit);
+    snprintf(statbuffer, sizeof statbuffer, "Size: %s/%s (%d %s)",
+	     remove_spaces(size_iec), remove_spaces(size_dec), previous_size,
+	     previous_unit);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    /* Do not print Host Bus & Interface if EDD isn't 3.0 or more */
+    if (d[disk_number].edd_version >= 0x30) {
+	snprintf(buffer, sizeof buffer, "Host Bus/Interface: %s / %s",
+		 remove_spaces((char *)d[disk_number].edd_params.host_bus_type),
+		 d[disk_number].edd_params.interface_type);
+	snprintf(statbuffer, sizeof statbuffer, "Host Bus / Interface: %s / %s",
+		 remove_spaces((char *)d[disk_number].edd_params.host_bus_type),
+		 d[disk_number].edd_params.interface_type);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu[nb_sub_disk_menu].items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "C / H / S         : %d / %d / %d",
+	     d[disk_number].legacy_max_cylinder + 1,
+	     d[disk_number].legacy_max_head + 1,
+	     (int)d[disk_number].edd_params.sectors);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Cylinders / Heads / Sectors: %d / %d / %d",
+	     d[disk_number].legacy_max_cylinder + 1,
+	     d[disk_number].legacy_max_head + 1,
+	     (int)d[disk_number].edd_params.sectors);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    snprintf(buffer, sizeof buffer, "Sectors/Track     : %d",
+	     d[disk_number].legacy_sectors_per_track);
+    snprintf(statbuffer, sizeof statbuffer, "Sectors per Track: %d",
+	     d[disk_number].legacy_sectors_per_track);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    get_mbr_string(hardware->mbr_ids[disk_number], &mbr_name, 50);
+
+    snprintf(buffer, sizeof buffer, "MBR               : %s (0x%X)",
+	     remove_spaces(mbr_name), hardware->mbr_ids[disk_number]);
+    snprintf(statbuffer, sizeof statbuffer, "MBR: %s (id 0x%X)",
+	     remove_spaces(mbr_name), hardware->mbr_ids[disk_number]);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    dn = disk_number;
+
+    parse_partition_table(&d[disk_number], &show_partition_information);
+    if (!parse_partition_table(&d[disk_number], &compute_partition_information)) {
+	get_error("parse_partition_table");
+	menu[nb_sub_disk_menu].items_count++;
+    }
+
+    return 0;
+}
+
+/* Compute the Disks menu */
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[MENULEN + 1];
+    int nb_sub_disk_menu = 0;
+
+    /* No need to compute that menu if no disks were detected */
+    menu->disk_menu.items_count = 0;
+    if (hardware->disks_count == 0)
+	return;
+
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	if (!hardware->disk_info[drive - 0x80].cbios)
+	    continue;		/* Invalid geometry */
+	compute_disk_module
+	    ((struct s_my_menu *)&(menu->disk_sub_menu), nb_sub_disk_menu,
+	     hardware, drive - 0x80);
+	nb_sub_disk_menu++;
+    }
+
+    menu->disk_menu.menu = add_menu(" Disks ", -1);
+
+    for (int i = 0; i < nb_sub_disk_menu; i++) {
+	snprintf(buffer, sizeof buffer, " Disk <%d> ", i + 1);
+	add_item(buffer, "Disk", OPT_SUBMENU, NULL,
+		 menu->disk_sub_menu[i].menu);
+	menu->disk_menu.items_count++;
+    }
+    printf("MENU: Disks menu done (%d items)\n", menu->disk_menu.items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,381 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Compute System main menu */
+void compute_system(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" System ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", dmi->system.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->system.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product   : %s", dmi->system.product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     dmi->system.product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->system.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s", dmi->system.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->system.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->system.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "UUID      : %s", dmi->system.uuid);
+    snprintf(statbuffer, sizeof statbuffer, "UUID: %s", dmi->system.uuid);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Wakeup    : %s", dmi->system.wakeup_type);
+    snprintf(statbuffer, sizeof statbuffer, "Wakeup Type: %s",
+	     dmi->system.wakeup_type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SKU Number: %s", dmi->system.sku_number);
+    snprintf(statbuffer, sizeof statbuffer, "SKU Number: %s",
+	     dmi->system.sku_number);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Family    : %s", dmi->system.family);
+    snprintf(statbuffer, sizeof statbuffer, "Family: %s", dmi->system.family);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: System menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Chassis menu */
+void compute_chassis(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" Chassis ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s",
+	     dmi->chassis.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->chassis.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type      : %s", dmi->chassis.type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->chassis.type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->chassis.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     dmi->chassis.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->chassis.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->chassis.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag : %s",
+	     del_multi_spaces(dmi->chassis.asset_tag));
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     del_multi_spaces(dmi->chassis.asset_tag));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Lock      : %s", dmi->chassis.lock);
+    snprintf(statbuffer, sizeof statbuffer, "Lock: %s", dmi->chassis.lock);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Chassis menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute BIOS menu */
+void compute_bios(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" BIOS ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", dmi->bios.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s", dmi->bios.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->bios.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s", dmi->bios.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Release   : %s", dmi->bios.release_date);
+    snprintf(statbuffer, sizeof statbuffer, "Release Date: %s",
+	     dmi->bios.release_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bios Rev. : %s", dmi->bios.bios_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Bios Revision: %s",
+	     dmi->bios.bios_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Fw.  Rev. : %s",
+	     dmi->bios.firmware_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Firmware Revision : %s",
+	     dmi->bios.firmware_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    printf("MENU: BIOS menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Motherboard main menu */
+void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" Motherboard ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s",
+	     dmi->base_board.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->base_board.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product   : %s",
+	     dmi->base_board.product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     dmi->base_board.product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->base_board.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     dmi->base_board.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->base_board.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->base_board.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag : %s",
+	     dmi->base_board.asset_tag);
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     dmi->base_board.asset_tag);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Location  : %s", dmi->base_board.location);
+    snprintf(statbuffer, sizeof statbuffer, "Location: %s",
+	     dmi->base_board.location);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type      : %s", dmi->base_board.type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->base_board.type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Motherboard menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Main IPMI menu */
+void compute_ipmi(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" IPMI ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Interface Type  : %s",
+	     dmi->ipmi.interface_type);
+    snprintf(statbuffer, sizeof statbuffer, "Interface Type: %s",
+	     dmi->ipmi.interface_type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Spec. Version   : %u.%u",
+	     dmi->ipmi.major_specification_version,
+	     dmi->ipmi.minor_specification_version);
+    snprintf(statbuffer, sizeof statbuffer, "Specification Version: %u.%u",
+	     dmi->ipmi.major_specification_version,
+	     dmi->ipmi.minor_specification_version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "I2C Slave @     : 0x%02x",
+	     dmi->ipmi.I2C_slave_address);
+    snprintf(statbuffer, sizeof statbuffer, "I2C Slave Address: 0x%02x",
+	     dmi->ipmi.I2C_slave_address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "NV Storage @    : %u",
+	     dmi->ipmi.nv_address);
+    snprintf(statbuffer, sizeof statbuffer, "NV Storage Address: %u",
+	     dmi->ipmi.nv_address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    uint32_t high = dmi->ipmi.base_address >> 32;
+    uint32_t low = dmi->ipmi.base_address & 0xFFFF;
+
+    snprintf(buffer, sizeof buffer, "Base Address    : %08X%08X",
+	     high, (low & ~1));
+    snprintf(statbuffer, sizeof statbuffer, "Base Address : %08X%08X",
+	     high, (low & ~1));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IRQ             : %d", dmi->ipmi.irq);
+    snprintf(statbuffer, sizeof statbuffer, "IRQ : %d", dmi->ipmi.irq);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: IPMI menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Main Battery menu */
+void compute_battery(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" Battery ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor          : %s",
+	     dmi->battery.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->battery.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Manufacture Date: %s",
+	     dmi->battery.manufacture_date);
+    snprintf(statbuffer, sizeof statbuffer, "Manufacture Date: %s",
+	     dmi->battery.manufacture_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial          : %s",
+	     dmi->battery.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial: %s", dmi->battery.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Name            : %s", dmi->battery.name);
+    snprintf(statbuffer, sizeof statbuffer, "Name: %s", dmi->battery.name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Chemistry       : %s",
+	     dmi->battery.chemistry);
+    snprintf(statbuffer, sizeof statbuffer, "Chemistry: %s",
+	     dmi->battery.chemistry);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Design Capacity : %s",
+	     dmi->battery.design_capacity);
+    snprintf(statbuffer, sizeof statbuffer, "Design Capacity: %s",
+	     dmi->battery.design_capacity);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Design Voltage  : %s",
+	     dmi->battery.design_voltage);
+    snprintf(statbuffer, sizeof statbuffer, "Design Voltage : %s",
+	     dmi->battery.design_voltage);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS            : %s", dmi->battery.sbds);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS: %s", dmi->battery.sbds);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS Manuf. Date: %s",
+	     dmi->battery.sbds_manufacture_date);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS Manufacture Date: %s",
+	     dmi->battery.sbds_manufacture_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS Chemistry  : %s",
+	     dmi->battery.sbds_chemistry);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS Chemistry : %s",
+	     dmi->battery.sbds_chemistry);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Maximum Error   : %s",
+	     dmi->battery.maximum_error);
+    snprintf(statbuffer, sizeof statbuffer, "Maximum Error (percent) : %s",
+	     dmi->battery.maximum_error);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "OEM Info        : %s",
+	     dmi->battery.oem_info);
+    snprintf(statbuffer, sizeof statbuffer, "OEM Info: %s",
+	     dmi->battery.oem_info);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Battery menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,87 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Main Kernel menu */
+void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char infobar[STATLEN + 1];
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    struct pci_device *pci_device;
+
+    menu->menu = add_menu(" Kernel Modules ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) &&
+	(hardware->modules_alias_return_code == -ENOMODULESALIAS)) {
+	add_item("The modules.{pcimap|alias} file is missing",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("Kernel modules can't be computed.",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("Please put one of them in same dir as hdt",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("", "", OPT_SEP, "", 0);
+    } else {
+	/*
+	 * For every detected pci device, grab its kernel module to
+	 * compute this submenu
+	 */
+	for_each_pci_func(pci_device, hardware->pci_domain) {
+	    memset(kernel_modules, 0, sizeof kernel_modules);
+	    for (int i = 0;
+		 i < pci_device->dev_info->linux_kernel_module_count; i++) {
+		if (i > 0) {
+		    strncat(kernel_modules, " | ", 3);
+		}
+		strncat(kernel_modules,
+			pci_device->dev_info->linux_kernel_module[i],
+			LINUX_KERNEL_MODULE_SIZE - 1);
+	    }
+	    /* No need to add unknown kernel modules */
+	    if (strlen(kernel_modules) > 0) {
+		snprintf(buffer, sizeof buffer, "%s (%s)",
+			 kernel_modules, pci_device->dev_info->class_name);
+		snprintf(infobar, sizeof infobar,
+			 "%04x:%04x %s : %s",
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->dev_info->vendor_name,
+			 pci_device->dev_info->product_name);
+
+		add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+		menu->items_count++;
+	    }
+	}
+    }
+
+    printf("MENU: Kernel menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,382 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <memory.h>
+#include "hdt-menu.h"
+#define E820MAX 128
+
+/* Compute the e820 submenu */
+static void compute_e820(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " e820 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    struct e820entry map[E820MAX];
+    int count = 0;
+    char type[14];
+
+    detect_memory_e820(map, E820MAX, &count);
+    unsigned long memory_size = memsize_e820(map, count);
+    snprintf(buffer, sizeof buffer, "Detected Memory  - %lu MiB (%lu KiB)",
+	     memory_size >> 10, memory_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Detected Memory : %lu MiB (%lu KiB)", memory_size >> 10,
+	     memory_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    add_item("", "", OPT_SEP, "", 0);
+
+    for (int j = 0; j < count; j++) {
+	get_type(map[j].type, type, 14);
+	snprintf(buffer, sizeof buffer,
+		 "%016llx - %016llx (%s)",
+		 map[j].addr, map[j].size, remove_spaces(type));
+	snprintf(statbuffer, sizeof statbuffer,
+		 "%016llx - %016llx (%s)",
+		 map[j].addr, map[j].size, remove_spaces(type));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+}
+
+/* Compute the e801 submenu */
+static void compute_e801(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " e801 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    int mem_low, mem_high = 0;
+    if (detect_memory_e801(&mem_low, &mem_high)) {
+	snprintf(buffer, sizeof buffer, "%s", "e801 output is bogus");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "e801 output is bogus");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    } else {
+	snprintf(buffer, sizeof buffer, "Detected Memory  : %d MiB (%d KiB)",
+		 (mem_high >> 4) + (mem_low >> 10), mem_low + (mem_high << 6));
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Detected Memory : %d MiB (%d KiB)",
+		 (mem_high >> 4) + (mem_low >> 10), mem_low + (mem_high << 6));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+	add_item("", "", OPT_SEP, "", 0);
+	snprintf(buffer, sizeof buffer, "Low Memory       : %d KiB (%d MiB)",
+		 mem_low, mem_low >> 10);
+	snprintf(statbuffer, sizeof statbuffer, "Low Memory : %d KiB (%d MiB)",
+		 mem_low, mem_low >> 10);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+	snprintf(buffer, sizeof buffer, "High Memory      : %d KiB (%d MiB)",
+		 mem_high << 6, mem_high >> 4);
+	snprintf(statbuffer, sizeof statbuffer, "High Memory : %d KiB (%d MiB)",
+		 mem_high << 6, mem_high >> 4);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    }
+    menu->items_count++;
+}
+
+/* Compute the 88 submenu */
+static void compute_88(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " 88 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    int mem_size = 0;
+    if (detect_memory_88(&mem_size)) {
+	snprintf(buffer, sizeof buffer, "%s", "88 output is bogus");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "88 output is bogus");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    } else {
+	snprintf(buffer, sizeof buffer, "Detected Memory : %d MiB (%d KiB)",
+		 mem_size >> 10, mem_size);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Detected Memory : %d MiB (%d KiB)", mem_size >> 10, mem_size);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+    menu->items_count++;
+}
+
+/* Compute the Memory submenu */
+static void compute_memory_module(struct s_my_menu *menu, s_dmi * dmi,
+				  int slot_number)
+{
+    int i = slot_number;
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " Bank <%d> ", i);
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    snprintf(buffer, sizeof buffer, "Form Factor  : %s",
+	     dmi->memory[i].form_factor);
+    snprintf(statbuffer, sizeof statbuffer, "Form Factor: %s",
+	     dmi->memory[i].form_factor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type         : %s", dmi->memory[i].type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->memory[i].type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type Details : %s",
+	     dmi->memory[i].type_detail);
+    snprintf(statbuffer, sizeof statbuffer, "Type Details: %s",
+	     dmi->memory[i].type_detail);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Speed        : %s", dmi->memory[i].speed);
+    snprintf(statbuffer, sizeof statbuffer, "Speed (Mhz): %s",
+	     dmi->memory[i].speed);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Size         : %s", dmi->memory[i].size);
+    snprintf(statbuffer, sizeof statbuffer, "Size: %s", dmi->memory[i].size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Device Set   : %s",
+	     dmi->memory[i].device_set);
+    snprintf(statbuffer, sizeof statbuffer, "Device Set: %s",
+	     dmi->memory[i].device_set);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Device Loc.  : %s",
+	     dmi->memory[i].device_locator);
+    snprintf(statbuffer, sizeof statbuffer, "Device Location: %s",
+	     dmi->memory[i].device_locator);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bank Locator : %s",
+	     dmi->memory[i].bank_locator);
+    snprintf(statbuffer, sizeof statbuffer, "Bank Locator: %s",
+	     dmi->memory[i].bank_locator);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Total Width  : %s",
+	     dmi->memory[i].total_width);
+    snprintf(statbuffer, sizeof statbuffer, "Total bit Width: %s",
+	     dmi->memory[i].total_width);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Data Width   : %s",
+	     dmi->memory[i].data_width);
+    snprintf(statbuffer, sizeof statbuffer, "Data bit Width: %s",
+	     dmi->memory[i].data_width);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Error        : %s", dmi->memory[i].error);
+    snprintf(statbuffer, sizeof statbuffer, "Error: %s", dmi->memory[i].error);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Vendor       : %s",
+	     dmi->memory[i].manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->memory[i].manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial       : %s", dmi->memory[i].serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial: %s",
+	     dmi->memory[i].serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag    : %s",
+	     dmi->memory[i].asset_tag);
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     dmi->memory[i].asset_tag);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Part Number  : %s",
+	     dmi->memory[i].part_number);
+    snprintf(statbuffer, sizeof statbuffer, "Part Number: %s",
+	     dmi->memory[i].part_number);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Compute the Memory submenu when type 6 is used*/
+static void compute_memory_module_type6(struct s_my_menu *menu, s_dmi * dmi,
+					int slot_number)
+{
+    int i = slot_number;
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " Bank <%d> ", i);
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    snprintf(buffer, sizeof buffer, "Socket Designation : %s",
+	     dmi->memory_module[i].socket_designation);
+    snprintf(statbuffer, sizeof statbuffer, "Socket Designation : %s",
+	     dmi->memory_module[i].socket_designation);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bank Connections   : %s",
+	     dmi->memory_module[i].bank_connections);
+    snprintf(statbuffer, sizeof statbuffer, "Bank Connections: %s",
+	     dmi->memory_module[i].bank_connections);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type               : %s",
+	     dmi->memory_module[i].type);
+    snprintf(statbuffer, sizeof statbuffer, "Type : %s",
+	     dmi->memory_module[i].type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Current Speed      : %s",
+	     dmi->memory_module[i].speed);
+    snprintf(statbuffer, sizeof statbuffer, "Current Speed : %s",
+	     dmi->memory_module[i].speed);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Installed Size     : %s",
+	     dmi->memory_module[i].installed_size);
+    snprintf(statbuffer, sizeof statbuffer, "Installed Size : %s",
+	     dmi->memory_module[i].installed_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Enabled Size       : %s",
+	     dmi->memory_module[i].enabled_size);
+    snprintf(statbuffer, sizeof statbuffer, "Enabled Size : %s",
+	     dmi->memory_module[i].enabled_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Error Status       : %s",
+	     dmi->memory_module[i].error_status);
+    snprintf(statbuffer, sizeof statbuffer, "Error Status : %s",
+	     dmi->memory_module[i].error_status);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Compute the Memory menu */
+void compute_memory(struct s_hdt_menu *menu, s_dmi * dmi,
+		    struct s_hardware *hardware)
+{
+    char buffer[MENULEN + 1];
+    int i = 0;
+    int memory_count = 0;
+
+    /* If memory type 17 is available */
+    if (dmi->memory_count > 0) {
+	memory_count = dmi->memory_count;
+	for (i = 0; i < dmi->memory_count; i++) {
+	    compute_memory_module(&(menu->memory_sub_menu[i]), dmi, i);
+	}
+    } else if (dmi->memory_module_count > 0) {
+	memory_count = dmi->memory_module_count;
+	/* Memory Type 17 isn't available, let's fallback on type 6 */
+	for (i = 0; i < dmi->memory_module_count; i++) {
+	    compute_memory_module_type6(&(menu->memory_sub_menu[i]), dmi, i);
+	}
+    }
+
+    compute_e820(&(menu->memory_sub_menu[++i]));
+    compute_e801(&(menu->memory_sub_menu[++i]));
+    compute_88(&(menu->memory_sub_menu[++i]));
+
+    menu->memory_menu.menu = add_menu(" Memory ", -1);
+    menu->memory_menu.items_count = 0;
+
+    snprintf(buffer, sizeof(buffer), " %lu MB detected ",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10);
+    add_item(buffer, "Detected Memory", OPT_INACTIVE, NULL,
+	     menu->memory_sub_menu[0].menu);
+    menu->memory_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    if (memory_count == 0) {
+	snprintf(buffer, sizeof buffer, " No memory bank detected ");
+	add_item(buffer, "Memory Bank", OPT_INACTIVE, NULL,
+		 menu->memory_sub_menu[1].menu);
+	menu->memory_menu.items_count++;
+    } else
+	for (i = 0; i < memory_count; i++) {
+	    snprintf(buffer, sizeof buffer, " Bank <%d> ", i);
+	    add_item(buffer, "Memory Bank", OPT_SUBMENU, NULL,
+		     menu->memory_sub_menu[i].menu);
+	    menu->memory_menu.items_count++;
+	}
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, " e820 ");
+    add_item(buffer, "e820 mapping", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    snprintf(buffer, sizeof buffer, " e801 ");
+    add_item(buffer, "e801 information", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    snprintf(buffer, sizeof buffer, " 88 ");
+    add_item(buffer, "88 information", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+    printf("MENU: Memory menu done (%d items)\n",
+	   menu->memory_menu.items_count);
+    add_item("Run Test", "Run Test", OPT_RUN, hardware->memtest_label, 0);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,203 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Dynamic submenu for pci devices */
+static void compute_pci_device(struct s_my_menu *menu,
+			       struct pci_device *pci_device,
+			       int pci_bus, int pci_slot, int pci_func,
+			       struct s_hardware *hardware)
+{
+    char buffer[56];
+    char statbuffer[STATLEN];
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    menu->menu = add_menu(" Details ", -1);
+    menu->items_count = 0;
+    set_menu_pos(5, 17);
+
+    snprintf(buffer, sizeof buffer, "Vendor  : %s",
+	     pci_device->dev_info->vendor_name);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor Name: %s",
+	     pci_device->dev_info->vendor_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product : %s",
+	     pci_device->dev_info->product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name  %s",
+	     pci_device->dev_info->product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Class   : %s",
+	     pci_device->dev_info->class_name);
+    snprintf(statbuffer, sizeof statbuffer, "Class Name: %s",
+	     pci_device->dev_info->class_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Location: %02x:%02x.%01x", pci_bus,
+	     pci_slot, pci_func);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Location on the PCI Bus: %02x:%02x.%01x", pci_bus, pci_slot,
+	     pci_func);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "PCI ID  : %04x:%04x[%04x:%04x]",
+	     pci_device->vendor, pci_device->product,
+	     pci_device->sub_vendor, pci_device->sub_product);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "vendor:product[sub_vendor:sub_product] : %04x:%04x[%04x:%04x]",
+	     pci_device->vendor, pci_device->product,
+	     pci_device->sub_vendor, pci_device->sub_product);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if ((pci_device->dev_info->irq > 0) && (pci_device->dev_info->irq < 255)) {
+	snprintf(buffer, sizeof buffer, "IRQ     : %d",
+		 pci_device->dev_info->irq);
+	snprintf(statbuffer, sizeof statbuffer, "IRQ : %d",
+		 pci_device->dev_info->irq);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "Latency : %d",
+	     pci_device->dev_info->latency);
+    snprintf(statbuffer, sizeof statbuffer, "Latency : %d",
+	     pci_device->dev_info->latency);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    memset(kernel_modules, 0, sizeof(kernel_modules));
+
+    if (pci_device->dev_info->linux_kernel_module_count > 1) {
+	for (int i = 0;
+	     i < pci_device->dev_info->linux_kernel_module_count; i++) {
+	    if (i > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[i],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	snprintf(buffer, sizeof buffer, "Modules : %s", kernel_modules);
+	snprintf(statbuffer, sizeof statbuffer, "Kernel Modules: %s",
+		 kernel_modules);
+    } else {
+	snprintf(buffer, sizeof buffer, "Module  : %s",
+		 pci_device->dev_info->linux_kernel_module[0]);
+	snprintf(statbuffer, sizeof statbuffer, "Kernel Module: %s",
+		 pci_device->dev_info->linux_kernel_module[0]);
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_pxe_valid == true) {
+	if ((hardware->pxe.pci_device != NULL)
+	    && (hardware->pxe.pci_device == pci_device)) {
+
+	    snprintf(buffer, sizeof buffer, "MAC Addr: %s",
+		     hardware->pxe.mac_addr);
+	    snprintf(statbuffer, sizeof statbuffer, "MAC Address : %s",
+		     hardware->pxe.mac_addr);
+	    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	    menu->items_count++;
+
+	    snprintf(buffer, sizeof buffer, "PXE     : %s",
+		     "Current Boot device");
+	    snprintf(statbuffer, sizeof statbuffer, "PXE : %s",
+		     "Current Boot device");
+	    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	    menu->items_count++;
+	}
+    }
+}
+
+/* Main PCI menu */
+int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    int i = 0;
+    char menuname[255][MENULEN + 1];
+    char infobar[255][STATLEN + 1];
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	compute_pci_device(&(hdt_menu->pci_sub_menu[i]), pci_device,
+			   __pci_bus, __pci_slot, __pci_func, hardware);
+	snprintf(menuname[i], 59, "%s|%s",
+		 pci_device->dev_info->vendor_name,
+		 pci_device->dev_info->product_name);
+	snprintf(infobar[i], STATLEN,
+		 "%02x:%02x.%01x # %s # ID:%04x:%04x[%04x:%04x] # Kmod:%s",
+		 __pci_bus, __pci_slot, __pci_func,
+		 pci_device->dev_info->class_name, pci_device->vendor,
+		 pci_device->product, pci_device->sub_vendor,
+		 pci_device->sub_product, kernel_modules);
+	i++;
+    }
+
+    hdt_menu->pci_menu.menu = add_menu(" PCI Devices ", -1);
+    hdt_menu->pci_menu.items_count = 0;
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	add_item("The pci.ids file is missing", "Missing pci.ids file",
+		 OPT_INACTIVE, NULL, 0);
+	add_item("PCI Device names  can't be computed.",
+		 "Missing pci.ids file", OPT_INACTIVE, NULL, 0);
+	add_item("Please put one in same dir as hdt",
+		 "Missing pci.ids file", OPT_INACTIVE, NULL, 0);
+	add_item("", "", OPT_SEP, "", 0);
+    }
+    for (int j = 0; j < i; j++) {
+	add_item(menuname[j], infobar[j], OPT_SUBMENU, NULL,
+		 hdt_menu->pci_sub_menu[j].menu);
+	hdt_menu->pci_menu.items_count++;
+    }
+    printf("MENU: PCI menu done (%d items)\n", hdt_menu->pci_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,313 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+static void show_flag(struct s_my_menu *menu, char *buffer, bool flag,
+		      char *flag_name, bool flush)
+{
+    char output_buffer[SUBMENULEN + 1];
+    char statbuffer[SUBMENULEN + 1];
+    if ((((strlen(buffer) + strlen(flag_name)) > 35) && flag) || flush) {
+	snprintf(output_buffer, sizeof output_buffer, "Flags     : %s", buffer);
+	snprintf(statbuffer, sizeof statbuffer, "Flags: %s", buffer);
+	add_item(output_buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	memset(buffer, 0, sizeof(buffer));
+	if (flush)
+	    return;
+    }
+    if (flag)
+	strcat(buffer, flag_name);
+}
+
+/* Compute Processor menu */
+void compute_processor(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char buffer1[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	snprintf(buffer, sizeof buffer,
+		 " Main Processors (%d logical / %d phys. ) ",
+		 hardware->acpi.madt.processor_local_apic_count,
+		 hardware->physical_cpu_count);
+	menu->menu = add_menu(buffer, -1);
+	menu->items_count = 0;
+	set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    } else {
+	menu->menu = add_menu(" Main Processor ", -1);
+	menu->items_count = 0;
+	set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    }
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", hardware->cpu.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s", hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Model     : %s", hardware->cpu.model);
+    snprintf(statbuffer, sizeof statbuffer, "Model: %s", hardware->cpu.model);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "CPU Cores : %d", hardware->cpu.num_cores);
+    snprintf(statbuffer, sizeof statbuffer, "Number of CPU cores: %d",
+	     hardware->cpu.num_cores);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->dmi.processor.core_enabled != 0) {
+        snprintf(buffer, sizeof buffer, "CPU Enable: %d", hardware->dmi.processor.core_enabled);
+        snprintf(statbuffer, sizeof statbuffer, "Number of CPU Enabled : %d",
+	     hardware->dmi.processor.core_enabled);
+        add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+        menu->items_count++;
+    }
+
+    if (hardware->dmi.processor.thread_count != 0) {
+        snprintf(buffer, sizeof buffer, "CPU Thread: %d", hardware->dmi.processor.thread_count);
+        snprintf(statbuffer, sizeof statbuffer, "Number of CPU Threads : %d",
+	     hardware->dmi.processor.thread_count);
+        add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+        menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "L1 Cache  : %dK + %dK (I+D)",
+	     hardware->cpu.l1_instruction_cache_size,
+	     hardware->cpu.l1_data_cache_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "L1 Cache Size: %dK + %dK (Instruction + Data)",
+	     hardware->cpu.l1_instruction_cache_size,
+	     hardware->cpu.l1_data_cache_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "L2 Cache  : %dK",
+	     hardware->cpu.l2_cache_size);
+    snprintf(statbuffer, sizeof statbuffer, "L2 Cache Size: %dK",
+	     hardware->cpu.l2_cache_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Family ID : %d", hardware->cpu.family);
+    snprintf(statbuffer, sizeof statbuffer, "Family ID: %d",
+	     hardware->cpu.family);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Model  ID : %d", hardware->cpu.model_id);
+    snprintf(statbuffer, sizeof statbuffer, "Model  ID: %d",
+	     hardware->cpu.model_id);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Stepping  : %d", hardware->cpu.stepping);
+    snprintf(statbuffer, sizeof statbuffer, "Stepping: %d",
+	     hardware->cpu.stepping);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_dmi_valid) {
+	snprintf(buffer, sizeof buffer, "FSB       : %d",
+		 hardware->dmi.processor.external_clock);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Front Side Bus (MHz): %d",
+		 hardware->dmi.processor.external_clock);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Cur. Speed: %d",
+		 hardware->dmi.processor.current_speed);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Current Speed (MHz): %d",
+		 hardware->dmi.processor.current_speed);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Max Speed : %d",
+		 hardware->dmi.processor.max_speed);
+	snprintf(statbuffer, sizeof statbuffer, "Max Speed (MHz): %d",
+		 hardware->dmi.processor.max_speed);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Upgrade   : %s",
+		 hardware->dmi.processor.upgrade);
+	snprintf(statbuffer, sizeof statbuffer, "Upgrade: %s",
+		 hardware->dmi.processor.upgrade);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Voltage   : %d.%02d",
+		 hardware->dmi.processor.voltage_mv / 1000,
+		 hardware->dmi.processor.voltage_mv -
+		 ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+	snprintf(statbuffer, sizeof statbuffer, "Voltage (V) : %d.%02d",
+		 hardware->dmi.processor.voltage_mv / 1000,
+		 hardware->dmi.processor.voltage_mv -
+		 ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (hardware->cpu.flags.smp) {
+	snprintf(buffer, sizeof buffer, "SMP       : Yes");
+	snprintf(statbuffer, sizeof statbuffer, "SMP: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "SMP       : No");
+	snprintf(statbuffer, sizeof statbuffer, "SMP: No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->cpu.flags.lm) {
+	snprintf(buffer, sizeof buffer, "x86_64    : Yes");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "x86_64 compatible processor: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "X86_64    : No");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "X86_64 compatible processor: No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if ((hardware->cpu.flags.vmx) || (hardware->cpu.flags.svm)) {
+	snprintf(buffer, sizeof buffer, "Hw Virt.  : Yes");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Hardware Virtualisation Capable: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "Hw Virt.  : No");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Hardware Virtualisation Capabable : No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    memset(buffer1, 0, sizeof(buffer1));
+    show_flag(menu, buffer1, hardware->cpu.flags.fpu, "fpu ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vme, "vme ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.de, "de ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pse, "pse ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tsc, "tsc ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.msr, "msr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pae, "pae ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mce, "mce ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cx8, "cx8 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.apic, "apic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sep, "sep ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mtrr, "mtrr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pge, "pge ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mca, "mca ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cmov, "cmov ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pat, "pat ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pse_36, "pse_36 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.psn, "psn ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.clflsh, "clflsh ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dts, "dts ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.acpi, "acpi ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mmx, "mmx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse, "sse ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse2, "sse2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ss, "ss ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.htt, "ht ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.acc, "acc ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.syscall, "syscall ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mp, "mp ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nx, "nx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mmxext, "mmxext ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.lm, "lm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nowext, "3dnowext ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.now, "3dnow! ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.svm, "svm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vmx, "vmx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pbe, "pbe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.fxsr_opt, "fxsr_opt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.gbpages, "gbpages ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.rdtscp, "rdtscp ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pni, "pni ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pclmulqd, "pclmulqd ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dtes64, "dtes64 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.smx, "smx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.est, "est ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tm2, "tm2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse3, "sse3 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.fma, "fma ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cx16, "cx16 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xtpr, "xtpr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pdcm, "pdcm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dca, "dca ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xmm4_1, "xmm4_1 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xmm4_2, "xmm4_2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.x2apic, "x2apic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.movbe, "movbe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.popcnt, "popcnt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.aes, "aes ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xsave, "xsave ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.osxsave, "osxsave ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.avx, "avx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.hypervisor, "hypervisor ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ace2, "ace2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ace2_en, "ace2_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.phe, "phe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.phe_en, "phe_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pmm, "pmm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pmm_en, "pmm_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.extapic, "extapic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cr8_legacy, "cr8_legacy ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.abm, "abm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse4a, "sse4a ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.misalignsse, "misalignsse ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nowprefetch, "3dnowprefetch ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.osvw, "osvw ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ibs, "ibs ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse5, "sse5 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.skinit, "skinit ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.wdt, "wdt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ida, "ida ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.arat, "arat ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tpr_shadow, "tpr_shadow ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vnmi, "vnmi ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.flexpriority, "flexpriority ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ept, "ept ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vpid, "vpid ", false);
+
+    /* Let's flush the remaining flags */
+    show_flag(menu, buffer1, false, "", true);
+
+    printf("MENU: Processor menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+#include <sys/gpxe.h>
+
+/* Main Kernel menu */
+void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char infobar[STATLEN + 1];
+    char gpxe[4]={0};
+
+    if (hardware->is_pxe_valid == false)
+	return;
+
+    menu->menu = add_menu(" PXE ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    struct s_pxe *p = &hardware->pxe;
+
+    if ((hardware->pci_ids_return_code == -ENOPCIIDS)
+	|| (p->pci_device == NULL)) {
+	snprintf(buffer, sizeof buffer, "PCI Vendor    : %d", p->vendor_id);
+	snprintf(infobar, sizeof infobar, "PCI Vendor    : %d", p->vendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI Product   : %d", p->vendor_id);
+	snprintf(infobar, sizeof infobar, "PCI Product   : %d", p->vendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI SubVendor  : %d", p->subvendor_id);
+	snprintf(infobar, sizeof infobar, "PCI SubVendor  : %d",
+		 p->subvendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI SubProduct : %d",
+		 p->subproduct_id);
+	snprintf(infobar, sizeof infobar, "PCI SubProduct : %d",
+		 p->subproduct_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI Revision   : %d", p->rev);
+	snprintf(infobar, sizeof infobar, "PCI Revision   : %d", p->rev);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer,
+		 "PCI Bus Pos.   : %02x:%02x.%02x", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	snprintf(infobar, sizeof infobar,
+		 "PCI Bus Pos.   : %02x:%02x.%02x", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+    } else {
+
+	snprintf(buffer, sizeof buffer, "Manufacturer : %s",
+		 p->pci_device->dev_info->vendor_name);
+	snprintf(infobar, sizeof infobar, "Manufacturer : %s",
+		 p->pci_device->dev_info->vendor_name);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Product      : %s",
+		 p->pci_device->dev_info->product_name);
+	snprintf(infobar, sizeof infobar, "Product      : %s",
+		 p->pci_device->dev_info->product_name);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "MAC Address  : %s", p->mac_addr);
+    snprintf(infobar, sizeof infobar, "MAC Address  : %s", p->mac_addr);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IP Address   : %d.%d.%d.%d",
+	     p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+    snprintf(infobar, sizeof infobar, "IP Address   : %d.%d.%d.%d",
+	     p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (is_gpxe()) snprintf(gpxe,sizeof(gpxe),"%s","Yes");
+    else snprintf (gpxe, sizeof(gpxe), "%s", "No");
+
+    snprintf(buffer, sizeof buffer, "gPXE Detected: %s", gpxe);
+    snprintf(infobar, sizeof infobar, "gPXE Detected: %s", gpxe);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: PXE menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+/* Computing Summary menu */
+void compute_summarymenu(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    snprintf(buffer, sizeof(buffer), " Summary (%d CPU) ", hardware->physical_cpu_count);
+    menu->menu = add_menu(buffer, -1);
+    menu->items_count = 0;
+
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "CPU Vendor    : %s", hardware->cpu.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "CPU Vendor: %s",
+	     hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "CPU Model     : %s", hardware->cpu.model);
+    snprintf(statbuffer, sizeof statbuffer, "CPU Model: %s",
+	     hardware->cpu.model);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    char features[255]={0};
+    if (hardware->dmi.processor.thread_count != 0)
+        sprintf(buffer, ", %d thread", hardware->dmi.processor.thread_count);
+    else
+        buffer[0] = 0x00;
+    sprintf(features, "%d core%s, %dK L2 Cache", hardware->cpu.num_cores,
+        buffer, hardware->cpu.l2_cache_size);
+    if (hardware->cpu.flags.lm)
+	strcat(features, ", 64bit");
+    else
+	strcat(features, ", 32bit");
+    if (hardware->cpu.flags.smp)
+	strcat(features, ", SMP");
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm)
+	strcat(features, ", HwVIRT");
+    snprintf(buffer, sizeof buffer, "%s", features);
+    snprintf(statbuffer, sizeof statbuffer, "Features : %s", features);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+    if (hardware->is_dmi_valid == true) {
+
+	snprintf(buffer, sizeof buffer, "System Vendor : %s",
+		 hardware->dmi.system.manufacturer);
+	snprintf(statbuffer, sizeof statbuffer, "System Vendor: %s",
+		 hardware->dmi.system.manufacturer);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "System Product: %s",
+		 hardware->dmi.system.product_name);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "System Product Name: %s", hardware->dmi.system.product_name);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "System Serial : %s",
+		 hardware->dmi.system.serial);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "System Serial Number: %s", hardware->dmi.system.serial);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	add_item("", "", OPT_SEP, "", 0);
+
+	snprintf(buffer, sizeof buffer, "Bios Version  : %s",
+		 hardware->dmi.bios.version);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Version: %s",
+		 hardware->dmi.bios.version);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Bios Release  : %s",
+		 hardware->dmi.bios.release_date);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Release Date: %s",
+		 hardware->dmi.bios.release_date);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Memory Size   : %lu MiB (%lu KiB)",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10,
+	     hardware->detected_memory_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Detected Memory Size: %lu MiB (%lu KiB)",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10,
+	     hardware->detected_memory_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Nb PCI Devices: %d",
+	     hardware->nb_pci_devices);
+    snprintf(statbuffer, sizeof statbuffer, "Number of PCI Devices: %d",
+	     hardware->nb_pci_devices);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_pxe_valid == true) {
+	add_item("", "", OPT_SEP, "", 0);
+
+	struct s_pxe *p = &hardware->pxe;
+
+	snprintf(buffer, sizeof buffer, "PXE MAC Address: %s", p->mac_addr);
+	snprintf(statbuffer, sizeof statbuffer, "PXE MAC Address: %s",
+		 p->mac_addr);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PXE IP Address : %d.%d.%d.%d",
+		 p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "PXE IP Address: %d.%d.%d.%d", p->ip_addr[0],
+		 p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (hardware->modules_pcimap_return_code != -ENOMODULESPCIMAP) {
+	add_item("", "", OPT_SEP, "", 0);
+
+	struct pci_device *pci_device;
+	char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			    MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+	/*
+	 * For every detected pci device, grab its kernel module to compute
+	 * this submenu
+	 */
+	for_each_pci_func(pci_device, hardware->pci_domain) {
+	    memset(kernel_modules, 0, sizeof kernel_modules);
+	    for (int i = 0;
+		 i < pci_device->dev_info->linux_kernel_module_count; i++) {
+		if (i > 0) {
+		    strncat(kernel_modules, " | ", 3);
+		}
+		strncat(kernel_modules,
+			pci_device->dev_info->linux_kernel_module[i],
+			LINUX_KERNEL_MODULE_SIZE - 1);
+	    }
+	    /* No need to add unknown kernel modules */
+	    if (strlen(kernel_modules) > 0) {
+		snprintf(buffer, sizeof buffer, "%s (%s)",
+			 kernel_modules, pci_device->dev_info->class_name);
+		snprintf(statbuffer, sizeof statbuffer,
+			 "%04x:%04x %s : %s",
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->dev_info->vendor_name,
+			 pci_device->dev_info->product_name);
+
+		add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+		menu->items_count++;
+	    }
+	}
+    }
+
+    printf("MENU: Summary menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "syslinux/config.h"
+#include "hdt-menu.h"
+
+/* Computing Syslinux menu */
+void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char syslinux_fs_menu[24];
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    memset(syslinux_fs_menu, 0, sizeof syslinux_fs_menu);
+
+    snprintf(syslinux_fs_menu, sizeof syslinux_fs_menu, " %s ",
+	     hardware->syslinux_fs);
+    menu->menu = add_menu(syslinux_fs_menu, -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Bootloader : %s", hardware->syslinux_fs);
+    snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+	     hardware->syslinux_fs);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version    : %s",
+	     hardware->sv->version_string);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     hardware->sv->version_string);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version    : %u", hardware->sv->version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %u",
+	     hardware->sv->version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Max API    : %u", hardware->sv->max_api);
+    snprintf(statbuffer, sizeof statbuffer, "Max API: %u",
+	     hardware->sv->max_api);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "%s", hardware->sv->copyright_string);
+    /* Remove the trailing LF in the copyright string to avoid scrolling */
+    snprintf(statbuffer, sizeof statbuffer, "%s",
+	     remove_trailing_lf((char *)hardware->sv->copyright_string));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Syslinux menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+/* Submenu for the vesa card */
+static void compute_vesa_card(struct s_my_menu *menu,
+			      struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" VESA Bios ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "VESA Version: %d.%d",
+	     hardware->vesa.major_version, hardware->vesa.minor_version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %d.%d",
+	     hardware->vesa.major_version, hardware->vesa.minor_version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Vendor      : %s", hardware->vesa.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor Name: %s",
+	     hardware->vesa.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product     : %s", hardware->vesa.product);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     hardware->vesa.product);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product Rev.: %s",
+	     hardware->vesa.product_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Produt Revision: %s",
+	     hardware->vesa.product_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Software Rev: %d",
+	     hardware->vesa.software_rev);
+    snprintf(statbuffer, sizeof statbuffer, "Software Revision: %d",
+	     hardware->vesa.software_rev);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Memory (KB) : %d",
+	     hardware->vesa.total_memory * 64);
+    snprintf(statbuffer, sizeof statbuffer, "Memory (KB): %d",
+	     hardware->vesa.total_memory * 64);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+}
+
+/* Submenu for the vesa card */
+void compute_vesa_modes(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[56];
+    char statbuffer[STATLEN];
+
+    menu->menu = add_menu(" VESA Modes ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+	struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+	/* Sometimes, vesa bios reports 0x0 modes
+	 * We don't need to display that ones */
+	if ((mi->h_res == 0) || (mi->v_res == 0))
+	    continue;
+	snprintf(buffer, sizeof buffer, "%4u x %4u x %2ubits vga=%3d",
+		 mi->h_res, mi->v_res, mi->bpp,
+		 hardware->vesa.vmi[i].mode + 0x200);
+	snprintf(statbuffer, sizeof statbuffer, "%4ux%4ux%2ubits vga=%3d",
+		 mi->h_res, mi->v_res, mi->bpp,
+		 hardware->vesa.vmi[i].mode + 0x200);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+}
+
+/* Main VESA Menu*/
+int compute_VESA(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    char buffer[15];
+    compute_vesa_card(&hdt_menu->vesa_card_menu, hardware);
+    compute_vesa_modes(&hdt_menu->vesa_modes_menu, hardware);
+    hdt_menu->vesa_menu.menu = add_menu(" VESA ", -1);
+    hdt_menu->vesa_menu.items_count = 0;
+
+    add_item("VESA Bios", "VESA Bios", OPT_SUBMENU, NULL,
+	     hdt_menu->vesa_card_menu.menu);
+    hdt_menu->vesa_menu.items_count++;
+    snprintf(buffer, sizeof buffer, "%s (%d)", "Modes",
+	     hardware->vesa.vmi_count);
+    add_item(buffer, "VESA Modes", OPT_SUBMENU, NULL,
+	     hdt_menu->vesa_modes_menu.menu);
+    hdt_menu->vesa_menu.items_count++;
+    printf("MENU: VESA menu done (%d items)\n",
+	   hdt_menu->vesa_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/**
+ * compute_vpd - generate vpd menu
+ **/
+void compute_vpd(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];	/* Status bar */
+
+    menu->menu = add_menu(" VPD ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Address                  : %s",
+	     hardware->vpd.base_address);
+    snprintf(statbuffer, sizeof statbuffer, "Address: %s",
+	     hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (strlen(hardware->vpd.bios_build_id) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Build ID            : %s",
+		 hardware->vpd.bios_build_id);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Build ID: %s",
+		 hardware->vpd.bios_build_id);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.bios_release_date) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Release Date        : %s",
+		 hardware->vpd.bios_release_date);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Release Date: %s",
+		 hardware->vpd.bios_release_date);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.bios_version) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Version             : %s",
+		 hardware->vpd.bios_version);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Version: %s",
+		 hardware->vpd.bios_version);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.default_flash_filename) > 0) {
+	snprintf(buffer, sizeof buffer, "Default Flash Filename   : %s",
+		 hardware->vpd.default_flash_filename);
+	snprintf(statbuffer, sizeof statbuffer, "Default Flash Filename: %s",
+		 hardware->vpd.default_flash_filename);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.box_serial_number) > 0) {
+	snprintf(buffer, sizeof buffer, "Box Serial Number        : %s",
+		 hardware->vpd.box_serial_number);
+	snprintf(statbuffer, sizeof statbuffer, "Box Serial Number: %s",
+		 hardware->vpd.box_serial_number);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.motherboard_serial_number) > 0) {
+	snprintf(buffer, sizeof buffer, "Motherboard Serial Number: %s",
+		 hardware->vpd.motherboard_serial_number);
+	snprintf(statbuffer, sizeof statbuffer, "Motherboard Serial Number: %s",
+		 hardware->vpd.motherboard_serial_number);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.machine_type_model) > 0) {
+	snprintf(buffer, sizeof buffer, "Machine Type/Model       : %s",
+		 hardware->vpd.machine_type_model);
+	snprintf(statbuffer, sizeof statbuffer, "Machine Type/Model: %s",
+		 hardware->vpd.machine_type_model);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    printf("MENU: VPD menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,311 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <unistd.h>
+#include <memory.h>
+#include <syslinux/reboot.h>
+#include "hdt-menu.h"
+
+int start_menu_mode(struct s_hardware *hardware, char *version_string)
+{
+    struct s_hdt_menu hdt_menu;
+
+    memset(&hdt_menu, 0, sizeof(hdt_menu));
+
+    /* Setup the menu system */
+    setup_menu(version_string);
+
+    /* Compute all submenus */
+    compute_submenus(&hdt_menu, hardware);
+
+    /* Compute the main menu */
+    compute_main_menu(&hdt_menu, hardware);
+
+#ifdef WITH_MENU_DISPLAY
+    t_menuitem *curr;
+    char cmd[160];
+
+    if (!quiet)
+	more_printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
+    curr = showmenus(hdt_menu.main_menu.menu);
+    /* When we exit the menu, do we have something to do? */
+    if (curr) {
+	/* When want to execute something */
+	if (curr->action == OPT_RUN) {
+	    /* Tweak, we want to switch to the cli */
+	    if (!strncmp
+		(curr->data, HDT_SWITCH_TO_CLI, sizeof(HDT_SWITCH_TO_CLI))) {
+		return HDT_RETURN_TO_CLI;
+	    }
+	    /* Tweak, we want to start the dump mode */
+	    if (!strncmp
+		(curr->data, HDT_DUMP, sizeof(HDT_DUMP))) {
+		    dump(hardware);
+	        return 0;
+	    }
+	    if (!strncmp
+		(curr->data, HDT_REBOOT, sizeof(HDT_REBOOT))) {
+		syslinux_reboot(1);
+	    }
+	    strcpy(cmd, curr->data);
+
+	    /* Use specific syslinux call if needed */
+	    if (issyslinux())
+		runsyslinuxcmd(cmd);
+	    else
+		csprint(cmd, 0x07);
+	    return 1;		// Should not happen when run from SYSLINUX
+	}
+    }
+#endif
+    return 0;
+}
+
+/* In the menu system, what to do on keyboard timeout */
+TIMEOUTCODE ontimeout(void)
+{
+    // beep();
+    return CODE_WAIT;
+}
+
+/* Keyboard handler for the menu system */
+void keys_handler(t_menusystem * ms
+		  __attribute__ ((unused)), t_menuitem * mi, int scancode)
+{
+    int nr, nc;
+
+    /* 0xFFFF is an invalid helpid */
+    if (scancode == KEY_F1 && mi->helpid != 0xFFFF) {
+	runhelpsystem(mi->helpid);
+    }
+
+    /*
+     * If user hit TAB, and item is an "executable" item
+     * and user has privileges to edit it, edit it in place.
+     */
+    if ((scancode == KEY_TAB) && (mi->action == OPT_RUN)) {
+//(isallowed(username,"editcmd") || isallowed(username,"root"))) {
+	if (getscreensize(1, &nr, &nc)) {
+	    /* Unknown screen size? */
+	    nc = 80;
+	    nr = 24;
+	}
+	/* User typed TAB and has permissions to edit command line */
+	gotoxy(EDITPROMPT, 1);
+	csprint("Command line:", 0x07);
+	editstring(mi->data, ACTIONLEN);
+	gotoxy(EDITPROMPT, 1);
+	cprint(' ', 0x07, nc - 1);
+    }
+}
+
+/* Setup the Menu system */
+void setup_menu(char *version)
+{
+    /* Creating the menu */
+    init_menusystem(version);
+    set_window_size(0, 0, 25, 80);
+
+    /* Do not use inactive attributes - they make little sense for HDT */
+    set_normal_attr(-1, -1, 0x17, 0x1F);
+
+    /* Register the menusystem handler */
+    // reg_handler(HDLR_SCREEN,&msys_handler);
+    reg_handler(HDLR_KEYS, &keys_handler);
+
+    /* Register the ontimeout handler, with a time out of 10 seconds */
+    reg_ontimeout(ontimeout, 1000, 0);
+}
+
+/* Compute Main' submenus */
+void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+
+    /* Compute this menu if a DMI table exists */
+    if (hardware->is_dmi_valid) {
+	if (hardware->dmi.ipmi.filled == true)
+	    compute_ipmi(&hdt_menu->ipmi_menu, &hardware->dmi);
+	if (hardware->dmi.base_board.filled == true)
+	    compute_motherboard(&(hdt_menu->mobo_menu), &(hardware->dmi));
+	if (hardware->dmi.chassis.filled == true)
+	    compute_chassis(&(hdt_menu->chassis_menu), &(hardware->dmi));
+	if (hardware->dmi.system.filled == true)
+	    compute_system(&(hdt_menu->system_menu), &(hardware->dmi));
+	compute_memory(hdt_menu, &(hardware->dmi), hardware);
+	if (hardware->dmi.bios.filled == true)
+	    compute_bios(&(hdt_menu->bios_menu), &(hardware->dmi));
+	if (hardware->dmi.battery.filled == true)
+	    compute_battery(&(hdt_menu->battery_menu), &(hardware->dmi));
+    }
+
+    compute_processor(&(hdt_menu->cpu_menu), hardware);
+    compute_vpd(&(hdt_menu->vpd_menu), hardware);
+    compute_disks(hdt_menu, hardware);
+
+    compute_PCI(hdt_menu, hardware);
+    compute_PXE(&(hdt_menu->pxe_menu), hardware);
+    compute_kernel(&(hdt_menu->kernel_menu), hardware);
+    
+    compute_summarymenu(&(hdt_menu->summary_menu), hardware);
+    compute_syslinuxmenu(&(hdt_menu->syslinux_menu), hardware);
+    compute_VESA(hdt_menu, hardware);
+    compute_ACPI(hdt_menu, hardware);
+    compute_aboutmenu(&(hdt_menu->about_menu));
+}
+
+void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    char menu_item[64];
+    /* Let's count the number of menus we have */
+    hdt_menu->total_menu_count = 0;
+    hdt_menu->main_menu.items_count = 0;
+
+    hdt_menu->main_menu.menu = add_menu(" Main Menu ", -1);
+    set_item_options(-1, 24);
+
+    snprintf(menu_item, sizeof(menu_item), "PC<I> Devices(%2d)\n",
+	     hardware->nb_pci_devices);
+    add_item(menu_item, "PCI Devices Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->pci_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    hdt_menu->total_menu_count += hdt_menu->pci_menu.items_count;
+    
+    if (hdt_menu->disk_menu.items_count > 0) {
+	snprintf(menu_item, sizeof(menu_item), "<D>isks      (%2d)\n",
+		 hdt_menu->disk_menu.items_count);
+	add_item(menu_item, "Disks Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->disk_menu.menu);
+	hdt_menu->main_menu.items_count++;
+	hdt_menu->total_menu_count += hdt_menu->disk_menu.items_count;
+    }
+
+    snprintf(menu_item, sizeof(menu_item), "<M>emory\n");
+    add_item(menu_item, "Memory Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->memory_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    hdt_menu->total_menu_count += hdt_menu->memory_menu.items_count;
+
+    add_item("<P>rocessor", "Main Processor Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->cpu_menu.menu);
+    hdt_menu->main_menu.items_count++;
+
+    if (hardware->is_dmi_valid) {
+	if (hardware->dmi.base_board.filled == true) {
+	    add_item("M<o>therboard", "Motherboard Menu",
+		     OPT_SUBMENU, NULL, hdt_menu->mobo_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.bios.filled == true) {
+	    add_item("<B>ios", "Bios Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->bios_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.chassis.filled == true) {
+	    add_item("<C>hassis", "Chassis Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->chassis_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.system.filled == true) {
+	    add_item("<S>ystem", "System Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->system_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.battery.filled == true) {
+	    add_item("Ba<t>tery", "Battery Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->battery_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+	if (hardware->dmi.ipmi.filled == true) {
+	    add_item("I<P>MI", "IPMI Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->ipmi_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+    }
+
+    if (hardware->is_vpd_valid == true) {
+	add_item("<V>PD", "VPD Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->vpd_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_pxe_valid == true) {
+	add_item("P<X>E", "PXE Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->pxe_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_vesa_valid == true) {
+	add_item("<V>ESA", "VESA Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->vesa_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_acpi_valid == true) {
+	add_item("<A>CPI", "ACPI Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->acpi_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    add_item("", "", OPT_SEP, "", 0);
+    
+    if ((hardware->modules_pcimap_return_code != -ENOMODULESPCIMAP) ||
+	(hardware->modules_alias_return_code != -ENOMODULESALIAS)) {
+	add_item("<K>ernel Modules", "Kernel Modules Menu", OPT_SUBMENU,
+		 NULL, hdt_menu->kernel_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+    
+    add_item("S<y>slinux", "Syslinux Information Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->syslinux_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    add_item("S<u>mmary", "Summary Information Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->summary_menu.menu);
+    hdt_menu->main_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    add_item("S<w>itch to CLI", "Switch to Command Line", OPT_RUN,
+	     HDT_SWITCH_TO_CLI, 0);
+
+    if (hardware->is_pxe_valid == true) {
+    add_item("<D>ump to tftp", "Dump to tftp", OPT_RUN,
+	     HDT_DUMP, 0);
+    }
+
+    add_item("<A>bout", "About Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->about_menu.menu);
+    add_item("<R>eboot", "Reboot", OPT_RUN, HDT_REBOOT, 0);
+    add_item("E<x>it", "Exit", OPT_EXITMENU, NULL, 0);
+    hdt_menu->main_menu.items_count++;
+
+    hdt_menu->total_menu_count += hdt_menu->main_menu.items_count;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_MENU_H
+#define DEFINE_HDT_MENU_H
+#include <stdio.h>
+#include <getkey.h>
+
+#include "menu.h"
+#include "help.h"
+//#include "cpuid.h"
+#include "sys/pci.h"
+#include "hdt-common.h"
+#include "dmi/dmi.h"
+#include "hdt-ata.h"
+
+#define EDITPROMPT 21
+
+#define SUBMENULEN 46
+
+#define SUBMENU_Y 3
+#define SUBMENU_X 29
+
+#define MAX_PCI_SUB_MENU 128
+#define MAX_MEMORY_SUB_MENU 32
+#define MAX_DISK_SUB_MENU 32
+
+struct s_my_menu {
+    unsigned char menu;
+    int items_count;
+};
+
+struct s_hdt_menu {
+    struct s_my_menu main_menu;
+    struct s_my_menu cpu_menu;
+    struct s_my_menu mobo_menu;
+    struct s_my_menu chassis_menu;
+    struct s_my_menu bios_menu;
+    struct s_my_menu ipmi_menu;
+    struct s_my_menu system_menu;
+    struct s_my_menu pci_menu;
+    struct s_my_menu pci_sub_menu[MAX_PCI_SUB_MENU];
+    struct s_my_menu kernel_menu;
+    struct s_my_menu memory_menu;
+    struct s_my_menu memory_sub_menu[MAX_MEMORY_SUB_MENU];
+    struct s_my_menu disk_menu;
+    struct s_my_menu disk_sub_menu[MAX_DISK_SUB_MENU];
+    struct s_my_menu battery_menu;
+    struct s_my_menu syslinux_menu;
+    struct s_my_menu about_menu;
+    struct s_my_menu summary_menu;
+    struct s_my_menu pxe_menu;
+    struct s_my_menu vesa_menu;
+    struct s_my_menu vesa_card_menu;
+    struct s_my_menu vesa_modes_menu;
+    struct s_my_menu vpd_menu;
+    struct s_my_menu acpi_menu;
+    struct s_my_menu acpi_apic_menu;
+    struct s_my_menu acpi_tables_menu;
+    int total_menu_count;	// Sum of all menus we have
+};
+
+TIMEOUTCODE ontimeout(void);
+void keys_handler(t_menusystem * ms
+		  __attribute__ ((unused)), t_menuitem * mi, int scancode);
+
+// PCI Stuff
+int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+// KERNEL Stuff
+void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Disk Stuff
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware);
+
+// DMI Stuff
+void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi);
+void compute_battery(struct s_my_menu *menu, s_dmi * dmi);
+void compute_system(struct s_my_menu *menu, s_dmi * dmi);
+void compute_chassis(struct s_my_menu *menu, s_dmi * dmi);
+void compute_bios(struct s_my_menu *menu, s_dmi * dmi);
+void compute_memory(struct s_hdt_menu *menu, s_dmi * dmi,
+		    struct s_hardware *hardware);
+void compute_ipmi(struct s_my_menu *menu, s_dmi * dmi);
+
+// VPD Stuff
+void compute_vpd(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Processor Stuff
+void compute_processor(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Syslinux stuff
+void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// About menu
+void compute_aboutmenu(struct s_my_menu *menu);
+
+// Summary menu
+void compute_summarymenu(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// PXE menu
+void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware);
+
+//VESA menu
+int compute_VESA(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+// ACPI menu
+int compute_ACPI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+int start_menu_mode(struct s_hardware *hardware, char *version_string);
+void setup_menu(char *version);
+void compute_main_menu(struct s_hdt_menu *hdt_menu,
+		       struct s_hardware *hardware);
+void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+/* Computing div(x,y) */
+#define sub(val) (((val%1024)*100)>>10)
+#define sub_dec(val) (((val%1000)*100)/1000)
+
+void sectors_to_size(int sectors, char *buffer)
+{
+    int b = (sectors / 2);
+    int mib = b >> 10;
+    int gib = mib >> 10;
+    int tib = gib >> 10;
+
+    if (tib > 0)
+	sprintf(buffer, "%3d.%02d TiB", tib,sub(gib));
+    else if (gib > 0)
+	sprintf(buffer, "%3d.%02d GiB", gib,sub(mib));
+    else if (mib > 0)
+	sprintf(buffer, "%3d.%02d MiB", mib,sub(b));
+    else
+	sprintf(buffer, "%d B", b);
+}
+
+void sectors_to_size_dec(char *previous_unit, int *previous_size, char *unit,
+			 int *size, int sectors)
+{
+    *size = sectors / 2;	// Converting to bytes
+    strlcpy(unit, "KB", 2);
+    strlcpy(previous_unit, unit, 2);
+    *previous_size = *size;
+    if (*size > 1000) {
+	*size = *size / 1000;
+	strlcpy(unit, "MB", 2);
+	if (*size > 1000) {
+	    *previous_size = *size;
+	    *size = *size / 1000;
+	    strlcpy(previous_unit, unit, 2);
+	    strlcpy(unit, "GB", 2);
+	    if (*size > 1000) {
+		*previous_size = *size;
+		*size = *size / 1000;
+		strlcpy(previous_unit, unit, 2);
+		strlcpy(unit, "TB", 2);
+	    }
+	}
+    }
+}
+
+/* Return the human readable size of device
+ * This function avoid disk's size rounding while
+ * not using float as they aren't currently supported */
+void sectors_to_size_dec2(int sectors, char *buffer)
+{
+    int b = (sectors / 2);
+    int mib = b / 1000;
+    int gib = mib / 1000;
+    int tib = gib / 1000;
+
+    if (tib > 0)
+	sprintf(buffer, "%3d.%02d TB", tib,sub_dec(gib));
+    else if (gib > 0)
+	sprintf(buffer, "%3d.%02d GB", gib,sub_dec(mib));
+    else if (mib > 0)
+	sprintf(buffer, "%3d.%02d MB", mib,sub_dec(b));
+    else
+	sprintf(buffer, "%d B", b);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,34 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_UTIL_H
+#define DEFINE_HDT_UTIL_H
+void sectors_to_size(int, char *);
+void sectors_to_size_dec(char *, int *, char *, int *, int);
+void sectors_to_size_dec2(int sectors, char *buffer);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,94 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * hdt.c
+ *
+ * An Hardware Detection Tool
+ */
+
+#include <stdio.h>
+#include "hdt.h"
+#include "hdt-cli.h"
+#include "hdt-menu.h"
+#include "hdt-common.h"
+
+int display_line_nb = 0;
+bool disable_more_printf = false;
+
+/* Defines the number of lines in the console
+ * Default is 20 for a std console */
+int max_console_lines = MAX_CLI_LINES;
+
+int main(const int argc, const char *argv[])
+{
+    char version_string[256];
+    static struct s_hardware hardware;
+
+    snprintf(version_string, sizeof version_string, "%s %s (%s)",
+	     PRODUCT_NAME, VERSION, CODENAME);
+
+    /* Cleaning structures */
+    init_hardware(&hardware);
+
+    /* Detecting Syslinux version */
+    detect_syslinux(&hardware);
+
+    /* Detecting parameters */
+    detect_parameters(argc, argv, &hardware);
+
+    /* Opening the Syslinux console */
+    init_console(&hardware);
+
+    /* Detect hardware */
+    detect_hardware(&hardware);
+
+    /* Clear the screen and reset position of the cursor */
+    clear_screen();
+    printf("\033[1;1H");
+
+    more_printf("%s\n", version_string);
+
+    int return_code = 0;
+
+    if (!menumode || automode)
+	start_cli_mode(&hardware);
+    else {
+	return_code = start_menu_mode(&hardware, version_string);
+	if (return_code == HDT_RETURN_TO_CLI)
+	    start_cli_mode(&hardware);
+    }
+
+    /* Do we got request to do something at exit time ? */
+    if (strlen(hardware.postexec)>0) {
+	    more_printf("Executing postexec instructions : %s\n",hardware.postexec);
+	    runsyslinuxcmd(hardware.postexec);
+    }
+
+    return return_code;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_H
+#define DEFINE_HDT_H
+
+#define PRODUCT_NAME "Hardware Detection Tool"
+#define AUTHOR "Erwan Velu"
+#define CORE_DEVELOPER "Pierre-Alexandre Meyer"
+#define CONTACT "hdt@zytor.com"
+#define VERSION "0.5.2"
+#define CODENAME "Manon"
+#define NB_CONTRIBUTORS 3
+#define CONTRIBUTORS {"Sebastien Gonzalve (Patches)", "Gert Hulselmans (Tests)", "Alexander Andino (Design)"}
+#define WEBSITE_URL "http://hdt-project.org"
+#define IRC_CHANNEL "#hdt on freenode"
+
+#define ATTR_PACKED __attribute__((packed))
+
+#define WITH_MENU_DISPLAY 1
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/alloca.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/alloca.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/alloca.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,12 @@
+/*
+ * alloca.h
+ *
+ * Just call the builtin alloca() function
+ */
+
+#ifndef _ALLOCA_H
+#define _ALLOCA_H
+
+#define alloca(size) __builtin_alloca(size)
+
+#endif /* _ALLOCA_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/assert.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/assert.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/assert.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,7 @@
+#ifndef _ASSERT_H
+#define _ASSERT_H
+
+/* Assert not currently supported */
+#define assert(X) ((void)0)
+
+#endif /* _ASSERT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize/limits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * bits32/limits.h
+ */
+
+#ifndef _BITSIZE_LIMITS_H
+#define _BITSIZE_LIMITS_H
+
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/limits.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/limits.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
+#endif /* _BITSIZE_LIMITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stddef.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * Include stddef.h as appropriate for architecture
+ */
+
+#ifndef _BITSIZE_STDDEF_H
+#define _BITSIZE_STDDEF_H
+
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stddef.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stddef.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
+#endif /* _BITSIZE_STDDEF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdint.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * bits32/stdint.h
+ */
+
+#ifndef _BITSIZE_STDINT_H
+#define _BITSIZE_STDINT_H
+
+typedef signed char		int8_t;
+typedef short int		int16_t;
+typedef int			int32_t;
+
+typedef unsigned char		uint8_t;
+typedef unsigned short int	uint16_t;
+typedef unsigned int		uint32_t;
+
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdint.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdint.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+#endif				/* _BITSIZE_STDINT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintconst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * bitsize/stdintconst.h
+ */
+
+#ifndef _BITSIZE_STDINTCONST_H
+#define _BITSIZE_STDINTCONST_H
+
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdintconst.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdintconst.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
+#endif				/* _BITSIZE_STDINTCONST_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintlimits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * bitsize/stdintlimits.h
+ */
+
+#ifndef _BITSIZE_STDINTLIMITS_H
+#define _BITSIZE_STDINTLIMITS_H
+
+#if __SIZEOF_POINTER__ == 4
+#include <bitsize32/stdintlimits.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <bitsize64/stdintlimits.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
+#endif				/* _BITSIZE_STDINTLIMITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/limits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * bits32/limits.h
+ */
+
+#ifndef _BITSIZE32_LIMITS_H
+#define _BITSIZE32_LIMITS_H
+
+#define LONG_BIT	32
+
+#define LONG_MIN	(-2147483647L-1)
+#define LONG_MAX	2147483647L
+#define ULONG_MAX	4294967295UL
+
+#endif				/* _BITSIZE_LIMITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stddef.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+/*
+ * bits32/stddef.h
+ */
+
+#define _SIZE_T
+typedef unsigned int size_t;
+
+#define _PTRDIFF_T
+typedef signed long ptrdiff_t;
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdint.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * bits32/stdint.h
+ */
+
+
+typedef long long int		int64_t;
+
+typedef unsigned long long int	uint64_t;
+
+typedef int			int_fast16_t;
+typedef int			int_fast32_t;
+
+typedef unsigned int		uint_fast16_t;
+typedef unsigned int		uint_fast32_t;
+
+typedef int			intptr_t;
+typedef unsigned int		uintptr_t;
+
+#define __INT64_C(c)   c ## LL
+#define __UINT64_C(c)  c ## ULL
+
+#define __PRI64_RANK   "ll"
+#define __PRIFAST_RANK ""
+#define __PRIPTR_RANK  ""
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintconst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * bits32/stdintconst.h
+ */
+
+#define INT_FAST16_C(c)	 INT32_C(c)
+#define INT_FAST32_C(c)  INT32_C(c)
+
+#define UINT_FAST16_C(c) UINT32_C(c)
+#define UINT_FAST32_C(c) UINT32_C(c)
+
+#define INTPTR_C(c)	 INT32_C(c)
+#define UINTPTR_C(c)	 UINT32_C(c)
+#define PTRDIFF_C(c)     INT32_C(c)
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintlimits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize32/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * bits32/stdintlimits.h
+ */
+
+#define INT_FAST16_MIN	INT32_MIN
+#define INT_FAST32_MIN	INT32_MIN
+#define INT_FAST16_MAX	INT32_MAX
+#define INT_FAST32_MAX	INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN	INT32_MIN
+#define INTPTR_MAX	INT32_MAX
+#define UINTPTR_MAX	UINT32_MAX
+
+#define PTRDIFF_MIN	INT32_MIN
+#define PTRDIFF_MAX	INT32_MAX
+
+/* sig_atomic_t limit */
+# define SIG_ATOMIC_MIN         INT32_MIN //(-2147483647-1)
+# define SIG_ATOMIC_MAX         INT32_MAX //(2147483647)
+/* size_t limit */
+# define SIZE_MAX		UINT32_MAX //(4294967295U)
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/limits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * bits64/limits.h
+ */
+
+#ifndef _BITSIZE64_LIMITS_H
+#define _BITSIZE64_LIMITS_H
+
+#define LONG_BIT	64
+
+#define LONG_MIN	(-9223372036854775807L-1)
+#define LONG_MAX	9223372036854775807L
+#define ULONG_MAX	18446744073709551615UL
+
+#endif				/* _BITSIZE_LIMITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stddef.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+/*
+ * bits64/stddef.h
+ */
+
+#define _SIZE_T
+typedef unsigned long size_t;
+
+#define _PTRDIFF_T
+typedef signed long ptrdiff_t;
+
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdint.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * bits64/stdint.h
+ */
+
+
+typedef long int		int64_t;
+
+typedef unsigned long int	uint64_t;
+
+typedef long int		int_fast16_t;
+typedef long int		int_fast32_t;
+
+typedef unsigned long int	uint_fast16_t;
+typedef unsigned long int	uint_fast32_t;
+
+typedef long int		intptr_t;
+typedef unsigned long int	uintptr_t;
+
+#define __INT64_C(c)  c ## L
+#define __UINT64_C(c) c ## UL
+
+#define __PRI64_RANK	"l"
+#define __PRIFAST_RANK  "l"
+#define __PRIPTR_RANK	"l"
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintconst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * bits64/stdintconst.h
+ */
+
+#define INT_FAST16_C(c)	 INT64_C(c)
+#define INT_FAST32_C(c)  INT64_C(c)
+
+#define UINT_FAST16_C(c) UINT64_C(c)
+#define UINT_FAST32_C(c) UINT64_C(c)
+
+#define INTPTR_C(c)	 INT64_C(c)
+#define UINTPTR_C(c)	 UINT64_C(c)
+#define PTRDIFF_C(c)     INT64_C(c)
Index: bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintlimits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bitsize64/stdintlimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * bits64/stdintlimits.h
+ */
+
+#define INT_FAST16_MIN	INT64_MIN
+#define INT_FAST32_MIN	INT64_MIN
+#define INT_FAST16_MAX	INT64_MAX
+#define INT_FAST32_MAX	INT64_MAX
+#define UINT_FAST16_MAX UINT64_MAX
+#define UINT_FAST32_MAX UINT64_MAX
+
+#define INTPTR_MIN	INT64_MIN
+#define INTPTR_MAX	INT64_MAX
+#define UINTPTR_MAX	UINT64_MAX
+
+#define PTRDIFF_MIN	INT64_MIN
+#define PTRDIFF_MAX	INT64_MAX
+
+/* sig_atomic_t limit */
+# define SIG_ATOMIC_MAX         INT32_MAX //(2147483647)
+# define SIG_ATOMIC_MIN         (-SIG_ATOMIC_MAX-1) //(-2147483647-1)
+/* size_t limit */
+# define SIZE_MAX		UINT64_MAX
Index: bootcd/isolinux/syslinux-6.03/com32/include/bufprintf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/bufprintf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/bufprintf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+#define BUFPAD	4096
+
+struct print_buf {
+    char *buf;
+    size_t len;
+    size_t size;
+};
+
+int vbufprintf(struct print_buf *buf, const char *format, va_list ap);
+int bufprintf(struct print_buf *buf, const char *format, ...);
Index: bootcd/isolinux/syslinux-6.03/com32/include/byteswap.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/byteswap.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/byteswap.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,180 @@
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H
+
+#include <stdint.h>
+#include <klibc/endian.h>
+#include <klibc/compiler.h>
+
+/* This assumes an i386 platform */
+
+#define __bswap_16_macro(v) ((uint16_t)		  			\
+			     (((uint16_t)(v) << 8) | 			\
+			      ((uint16_t)(v) >> 8)))
+
+static inline __constfunc uint16_t __bswap_16(uint16_t v)
+{
+    return __bswap_16_macro(v);
+}
+
+#define bswap_16(x) (__builtin_constant_p(x) ?				\
+			__bswap_16_macro(x) : __bswap_16(x))
+
+#define __bswap_32_macro(v) ((uint32_t)					\
+			     ((((uint32_t)(v) & 0x000000ff) << 24) |	\
+			      (((uint32_t)(v) & 0x0000ff00) << 8)  |	\
+			     (((uint32_t)(v) & 0x00ff0000) >> 8)  |	\
+			      (((uint32_t)(v) & 0xff000000) >> 24)))
+
+static inline __constfunc uint32_t __bswap_32(uint32_t v)
+{
+#if defined(__x86_64__)
+    asm("bswap %0" : "+r" (v));
+#elif defined(__i386__)
+    asm("xchgb %h0,%b0 ; roll $16,%0 ; xchgb %h0,%b0"
+	: "+q" (v));
+#else
+    v = __bswap_32_macro(v);
+#endif
+    return v;
+}
+
+#define bswap_32(x) (__builtin_constant_p(x) ?				\
+			 __bswap_32_macro(x) : __bswap_32(x))
+
+
+#define __bswap_64_macro(v) ((uint64_t)					\
+    (((uint64_t)__bswap_32_macro((uint32_t)(v)) << 32) |		\
+     (__bswap_32_macro((uint32_t)((uint64_t)(v) >> 32)))))
+
+static inline __constfunc uint64_t __bswap_64(uint64_t v)
+{
+#if defined(__x86_64__)
+    asm("bswap %0" : "+r" (v));
+#else
+    v = ((uint64_t)__bswap_32(v) << 32) | __bswap_32(v >> 32);
+#endif
+    return v;
+}
+
+#define bswap_64(x) (__builtin_constant_p(x) ? 				\
+			__bswap_64_macro(x) :  __bswap_64(x))
+
+/* This is generic */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+#define be16_to_cpu(x) bswap_16(x)
+#define cpu_to_be16(x) bswap_16(x)
+#define be32_to_cpu(x) bswap_32(x)
+#define cpu_to_be32(x) bswap_32(x)
+#define be64_to_cpu(x) bswap_64(x)
+#define cpu_to_be64(x) bswap_64(x)
+
+#define le16_to_cpu(x) (x)
+#define cpu_to_le16(x) (x)
+#define le32_to_cpu(x) (x)
+#define cpu_to_le32(x) (x)
+#define le64_to_cpu(x) (x)
+#define cpu_to_le64(x) (x)
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+#define le16_to_cpu(x) bswap_16(x)
+#define cpu_to_le16(x) bswap_16(x)
+#define le32_to_cpu(x) bswap_32(x)
+#define cpu_to_le32(x) bswap_32(x)
+#define le64_to_cpu(x) bswap_64(x)
+#define cpu_to_le64(x) bswap_64(x)
+
+#define be16_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be32(x) (x)
+#define be64_to_cpu(x) (x)
+#define cpu_to_be64(x) (x)
+
+#else
+
+#error "Unknown byte order!"
+
+#endif
+
+typedef struct { uint16_t x; } __attribute__((packed)) __ua_uint16_t;
+typedef struct { uint32_t x; } __attribute__((packed)) __ua_uint32_t;
+typedef struct { uint64_t x; } __attribute__((packed)) __ua_uint64_t;
+
+/* These are guaranteed to support unaligned accesses */
+static inline uint16_t get_le16(const uint16_t *p)
+{
+    const __ua_uint16_t *up = (const __ua_uint16_t *)p;
+    return le16_to_cpu(up->x);
+}
+
+static inline uint32_t get_le32(const uint32_t *p)
+{
+    const __ua_uint32_t *up = (const __ua_uint32_t *)p;
+    return le32_to_cpu(up->x);
+}    
+
+static inline uint64_t get_le64(const uint64_t *p)
+{
+    const __ua_uint64_t *up = (const __ua_uint64_t *)p;
+    return le64_to_cpu(up->x);
+}
+
+static inline uint16_t get_be16(const uint16_t *p)
+{
+    const __ua_uint16_t *up = (const __ua_uint16_t *)p;
+    return be16_to_cpu(up->x);
+}
+
+static inline uint32_t get_be32(const uint32_t *p)
+{
+    const __ua_uint32_t *up = (const __ua_uint32_t *)p;
+    return be32_to_cpu(up->x);
+}    
+
+static inline uint64_t get_be64(const uint64_t *p)
+{
+    const __ua_uint64_t *up = (const __ua_uint64_t *)p;
+    return be64_to_cpu(up->x);
+}
+
+static inline void put_le16(uint16_t v, uint16_t *p)
+{
+    __ua_uint16_t *up = (__ua_uint16_t *)p;
+    up->x = cpu_to_le16(v);
+}
+
+static inline void put_le32(uint32_t v, uint32_t *p)
+{
+    __ua_uint32_t *up = (__ua_uint32_t *)p;
+    up->x = cpu_to_le32(v);
+}
+
+static inline void put_le64(uint64_t v, uint64_t *p)
+{
+    __ua_uint64_t *up = (__ua_uint64_t *)p;
+    up->x = cpu_to_le64(v);
+}
+
+static inline void put_be16(uint16_t v, uint16_t *p)
+{
+    __ua_uint16_t *up = (__ua_uint16_t *)p;
+    up->x = cpu_to_be16(v);
+}
+
+static inline void put_be32(uint32_t v, uint32_t *p)
+{
+    __ua_uint32_t *up = (__ua_uint32_t *)p;
+    up->x = cpu_to_be32(v);
+}
+
+static inline void put_be64(uint64_t v, uint64_t *p)
+{
+    __ua_uint64_t *up = (__ua_uint64_t *)p;
+    up->x = cpu_to_be64(v);
+}
+
+#endif /* _BYTESWAP_H */
+
Index: bootcd/isolinux/syslinux-6.03/com32/include/cli.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,20 @@
+#ifndef CLI_H
+#define CLI_H
+
+#define MAX_CMD_HISTORY 64
+#define COMMAND_DELIM		" \t\n"	// Whitespace delimiters
+#define MAX_COMMAND_ARGS	40
+
+struct cli_command {
+    struct list_head list;
+    char *command;
+};
+
+extern void clear_screen(void);
+extern int mygetkey(clock_t timeout);
+extern const char *edit_cmdline(const char *input, int top /*, int width */ ,
+				int (*pDraw_Menu) (int, int, int),
+				void (*show_fkey) (int), bool *);
+
+extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/colortbl.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/colortbl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/colortbl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _COLORTBL_H
+#define _COLORTBL_H
+
+/* Attribute/color table used by ansicon and vesacon to abstract
+   out the color selection. */
+
+/* Note: vesacon relies on the encoding of these numbers */
+enum color_table_shadow {
+    SHADOW_NONE = 0,
+    SHADOW_ALL = 1,
+    SHADOW_NORMAL = 2,
+    SHADOW_REVERSE = 3,
+};
+
+struct color_table {
+    const char *name;		/* Attribute name (used for customization) */
+    const char *ansi;		/* ANSI attribute */
+    unsigned int argb_fg;	/* ARGB for foreground */
+    unsigned int argb_bg;	/* ARGB for background */
+    enum color_table_shadow shadow;	/* Shadow mode */
+};
+
+extern struct color_table *console_color_table;
+extern int console_color_table_size;
+
+#endif /* _COLORTBL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/com32.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/com32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/com32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,211 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * com32.h
+ *
+ * Common declarations for com32 programs.
+ */
+
+#ifndef _COM32_H
+#define _COM32_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <klibc/compiler.h>	/* For __cdecl */
+
+/*
+ * This structure defines the register frame used by the
+ * system call interface.
+ *
+ * The syscall interface is:
+ *
+ * __intcall(interrupt_#, source_regs, return_regs)
+ * __farcall(seg, offs, source_regs, return_regs)
+ */
+typedef union {
+    uint32_t l;
+    uint16_t w[2];
+    uint8_t b[4];
+} reg32_t;
+
+typedef struct {
+    uint16_t gs;		/* Offset  0 */
+    uint16_t fs;		/* Offset  2 */
+    uint16_t es;		/* Offset  4 */
+    uint16_t ds;		/* Offset  6 */
+
+    reg32_t edi;		/* Offset  8 */
+    reg32_t esi;		/* Offset 12 */
+    reg32_t ebp;		/* Offset 16 */
+    reg32_t _unused_esp;	/* Offset 20 */
+    reg32_t ebx;		/* Offset 24 */
+    reg32_t edx;		/* Offset 28 */
+    reg32_t ecx;		/* Offset 32 */
+    reg32_t eax;		/* Offset 36 */
+
+    reg32_t eflags;		/* Offset 40 */
+} com32sys_t;
+
+/* EFLAGS definitions */
+#define EFLAGS_CF		0x00000001
+#define EFLAGS_PF		0x00000004
+#define EFLAGS_AF		0x00000010
+#define EFLAGS_ZF		0x00000040
+#define EFLAGS_SF		0x00000080
+#define EFLAGS_TF		0x00000100
+#define EFLAGS_IF		0x00000200
+#define EFLAGS_DF		0x00000400
+#define EFLAGS_OF		0x00000800
+#define EFLAGS_IOPL		0x00003000
+#define EFLAGS_NT		0x00004000
+#define EFLAGS_RF		0x00010000
+#define EFLAGS_VM		0x00020000
+#define EFLAGS_AC		0x00040000
+#define EFLAGS_VIF		0x00080000
+#define EFLAGS_VIP		0x00100000
+#define EFLAGS_ID		0x00200000
+
+struct com32_pmapi;
+
+extern struct com32_sys_args {
+    uint32_t cs_sysargs;
+    char *cs_cmdline;
+    void __cdecl (*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *);
+    void *cs_bounce;
+    uint32_t cs_bounce_size;
+    void __cdecl (*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *);
+    int __cdecl (*cs_cfarcall)(uint32_t, const void *, uint32_t);
+    uint32_t cs_memsize;
+    const char *cs_name;
+    const struct com32_pmapi *cs_pm;
+} __com32;
+
+/*
+ * System call wrapper functions
+ */
+void __intcall(uint8_t __i, const com32sys_t * __sr, com32sys_t * __dr);
+void __farcall(uint16_t __cs, uint16_t __ip,
+	       const com32sys_t * __sr, com32sys_t * __dr);
+int __cfarcall(uint16_t __cs, uint16_t __ip,
+	       const void *__stack, uint32_t __stack_size);
+extern const com32sys_t __com32_zero_regs;
+
+/*
+ * Lowmem allocation functions
+ */
+void *lmalloc(size_t);
+void *lzalloc(size_t);
+void lfree(void *);
+char *lstrdup(const char *);
+
+/*
+ * These functions convert between linear pointers in the range
+ * 0..0xFFFFF and real-mode style SEG:OFFS pointers.  Note that a
+ * 32-bit linear pointer is not compatible with a SEG:OFFS pointer
+ * stored in two consecutive 16-bit words.
+ *
+ * Use OFFS_WRT() if you want to compute an offset relative to a
+ * specific segment.  OFFS_VALID() will return whether or not the
+ * pointer is actually reachable from the target segment.
+ */
+#if defined(CORE_DEBUG) && (defined(__COM32__) || defined(__SYSLINUX_CORE__))
+__noreturn __bad_SEG(const volatile void *);
+
+static inline uint16_t SEG(const volatile void *__p)
+{
+    if (__unlikely((uintptr_t)__p > 0xfffff))
+	__bad_SEG(__p);
+
+    return (uint16_t) (((uintptr_t) __p) >> 4);
+}
+#else
+static inline uint16_t SEG(const volatile void *__p)
+{
+    return (uint16_t) (((uintptr_t) __p) >> 4);
+}
+#endif
+
+static inline uint16_t OFFS(const volatile void *__p)
+{
+    /* The double cast here is to shut up gcc */
+    return (uint16_t) (uintptr_t) __p & 0x000F;
+}
+
+static inline uint16_t OFFS_WRT(const volatile void *__p, uint16_t __seg)
+{
+    return (uint16_t) ((uintptr_t) __p - ((uintptr_t) __seg << 4));
+}
+
+#define OFFS_VALID(p,s) _OFFS_VALID((p), sizeof *(p), (s))
+
+static inline bool _OFFS_VALID(const volatile void *__p, size_t __s,
+			       uint16_t __seg)
+{
+    uintptr_t __segstart = (uintptr_t)__seg << 4;
+    uintptr_t __offs  = (uintptr_t)__p - __segstart;
+
+    return __offs <= 0x10000-__s;
+}
+
+static inline void *MK_PTR(uint16_t __seg, uint16_t __offs)
+{
+    return (void *)(unsigned long)((__seg << 4) + __offs);
+}
+
+/* Some tools to handle 16:16 far pointers in memory */
+
+struct __far_ptr {
+    union {
+	uint32_t ptr;
+	struct {
+	    uint16_t offs, seg;
+	};
+    };
+} __attribute__ ((packed));
+
+typedef struct __far_ptr far_ptr_t;
+
+static inline void *GET_PTR(far_ptr_t __fptr)
+{
+    return MK_PTR(__fptr.seg, __fptr.offs);
+}
+
+static inline far_ptr_t FAR_PTR(void *__ptr)
+{
+    far_ptr_t __fptr;
+
+    __fptr.offs = OFFS(__ptr);
+    __fptr.seg  = SEG(__ptr);
+    return __fptr;
+}
+
+extern const char *com32_cmdline(void);
+
+#endif /* _COM32_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/console.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/console.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/console.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,64 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * console.h
+ *
+ * Alternative consoles
+ */
+
+#ifndef _CONSOLE_H
+#define _CONSOLE_H
+
+#include <klibc/extern.h>
+#include <inttypes.h>
+#include <dev.h>
+
+__extern int openconsole(const struct input_dev *, const struct output_dev *);
+
+/* Standard line-oriented console */
+extern const struct input_dev dev_stdcon_r;
+extern const struct output_dev dev_stdcon_w;
+/* Raw character-oriented console */
+extern const struct input_dev dev_rawcon_r;
+extern const struct output_dev dev_rawcon_w;
+
+/* These are output-only consoles; combine with one of the input methods */
+
+/* Serial port only */
+extern const struct output_dev dev_serial_w;
+/* ANSI console (output only; combine with one of the input methods) */
+extern const struct output_dev dev_ansicon_w;
+/* ANSI plus serial port */
+extern const struct output_dev dev_ansiserial_w;
+
+/* VESA graphics console (output only) */
+extern const struct output_dev dev_vesacon_w;
+/* VESA plus serial port */
+extern const struct output_dev dev_vesaserial_w;
+
+#endif /* _CONSOLE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/cpufeature.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/cpufeature.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/cpufeature.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,152 @@
+/*
+ * cpufeature.h
+ *
+ * Defines x86 CPU feature bits
+ */
+
+#ifndef __ASM_I386_CPUFEATURE_H
+#define __ASM_I386_CPUFEATURE_H
+
+#define NCAPINTS	9	/* N 32-bit words worth of info */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
+#define X86_FEATURE_FPU		(0*32+ 0)	/* Onboard FPU */
+#define X86_FEATURE_VME		(0*32+ 1)	/* Virtual Mode Extensions */
+#define X86_FEATURE_DE		(0*32+ 2)	/* Debugging Extensions */
+#define X86_FEATURE_PSE 	(0*32+ 3)	/* Page Size Extensions */
+#define X86_FEATURE_TSC		(0*32+ 4)	/* Time Stamp Counter */
+#define X86_FEATURE_MSR		(0*32+ 5)	/* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE		(0*32+ 6)	/* Physical Address Extensions */
+#define X86_FEATURE_MCE		(0*32+ 7)	/* Machine Check Architecture */
+#define X86_FEATURE_CX8		(0*32+ 8)	/* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC	(0*32+ 9)	/* Onboard APIC */
+#define X86_FEATURE_SEP		(0*32+11)	/* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR	(0*32+12)	/* Memory Type Range Registers */
+#define X86_FEATURE_PGE		(0*32+13)	/* Page Global Enable */
+#define X86_FEATURE_MCA		(0*32+14)	/* Machine Check Architecture */
+#define X86_FEATURE_CMOV	(0*32+15)	/* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
+#define X86_FEATURE_PAT		(0*32+16)	/* Page Attribute Table */
+#define X86_FEATURE_PSE36	(0*32+17)	/* 36-bit PSEs */
+#define X86_FEATURE_PN		(0*32+18)	/* Processor serial number */
+#define X86_FEATURE_CLFLSH	(0*32+19)	/* Supports the CLFLUSH instruction */
+#define X86_FEATURE_DTES	(0*32+21)	/* Debug Trace Store */
+#define X86_FEATURE_ACPI	(0*32+22)	/* ACPI via MSR */
+#define X86_FEATURE_MMX		(0*32+23)	/* Multimedia Extensions */
+#define X86_FEATURE_FXSR	(0*32+24)	/* FXSAVE and FXRSTOR instructions (fast save and restore */
+					  /* of FPU context), and CR4.OSFXSR available */
+#define X86_FEATURE_XMM		(0*32+25)	/* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2	(0*32+26)	/* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP	(0*32+27)	/* CPU self snoop */
+#define X86_FEATURE_HT		(0*32+28)	/* Hyper-Threading */
+#define X86_FEATURE_ACC		(0*32+29)	/* Automatic clock control */
+#define X86_FEATURE_IA64	(0*32+30)	/* IA-64 processor */
+#define X86_FEATURE_PBE         (0*32+31)	/* Pending Break Enable */
+
+/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* Don't duplicate feature flags which are redundant with Intel! */
+#define X86_FEATURE_SYSCALL	(1*32+11)	/* SYSCALL/SYSRET */
+#define X86_FEATURE_MP		(1*32+19)	/* MP Capable. */
+#define X86_FEATURE_NX		(1*32+20)	/* Execute Disable */
+#define X86_FEATURE_MMXEXT	(1*32+22)	/* AMD MMX extensions */
+#define X86_FEATURE_FXSR_OPT    (1*32+25)	/* FXSAVE/FXRSTOR optimizations */
+#define X86_FEATURE_GBPAGES     (1*32+26)	/* "pdpe1gb" GB pages */
+#define X86_FEATURE_RDTSCP      (1*32+27)	/* RDTSCP */
+#define X86_FEATURE_LM		(1*32+29)	/* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT	(1*32+30)	/* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW	(1*32+31)	/* 3DNow! */
+
+/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+#define X86_FEATURE_RECOVERY	(2*32+ 0)	/* CPU in recovery mode */
+#define X86_FEATURE_LONGRUN	(2*32+ 1)	/* Longrun power control */
+#define X86_FEATURE_LRTI	(2*32+ 3)	/* LongRun table interface */
+
+/* Other features, Linux-defined mapping, word 3 */
+/* This range is used for feature bits which conflict or are synthesized */
+#define X86_FEATURE_CXMMX	(3*32+ 0)	/* Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR	(3*32+ 1)	/* AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR	(3*32+ 2)	/* Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR	(3*32+ 3)	/* Centaur MCRs (= MTRRs) */
+/* cpu types for specific tunings: */
+#define X86_FEATURE_K8		(3*32+ 4)	/* Opteron, Athlon64 */
+#define X86_FEATURE_K7		(3*32+ 5)	/* Athlon */
+#define X86_FEATURE_P3		(3*32+ 6)	/* P3 */
+#define X86_FEATURE_P4		(3*32+ 7)	/* P4 */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+#define X86_FEATURE_XMM3	(4*32+ 0)	/* Streaming SIMD Extensions-3 */
+#define X86_FEATURE_PCLMULQDQ   (4*32+ 1)	/* PCLMULQDQ instruction */
+#define X86_FEATURE_DTES64      (4*32+ 2)	/* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT	(4*32+ 3)	/* Monitor/Mwait support */
+#define X86_FEATURE_DSCPL	(4*32+ 4)	/* CPL Qualified Debug Store */
+#define X86_FEATURE_VMX		(4*32+ 5)	/* Hardware virtualization */
+#define X86_FEATURE_SMX         (4*32+ 6)	/* Safer mode */
+#define X86_FEATURE_EST		(4*32+ 7)	/* Enhanced SpeedStep */
+#define X86_FEATURE_TM2		(4*32+ 8)	/* Thermal Monitor 2 */
+#define X86_FEATURE_SSE3        (4*32+ 9)	/* Supplemental SSE-3 */
+#define X86_FEATURE_CID		(4*32+10)	/* Context ID */
+#define X86_FEATURE_FMA         (4*32+12)	/* Fused multiply-add */
+#define X86_FEATURE_CX16        (4*32+13)	/* CMPXCHG16B */
+#define X86_FEATURE_XTPR	(4*32+14)	/* Send Task Priority Messages */
+#define X86_FEATURE_PDCM        (4*32+15)	/* Performance Capabilities */
+#define X86_FEATURE_DCA         (4*32+18)	/* Direct Cache Access */
+#define X86_FEATURE_XMM4_1      (4*32+19)	/* "sse4_1" SSE-4.1 */
+#define X86_FEATURE_XMM4_2      (4*32+20)	/* "sse4_2" SSE-4.2 */
+#define X86_FEATURE_X2APIC      (4*32+21)	/* x2APIC */
+#define X86_FEATURE_MOVBE       (4*32+22)	/* MOVBE instruction */
+#define X86_FEATURE_POPCNT      (4*32+23)	/* POPCNT instruction */
+#define X86_FEATURE_AES         (4*32+25)	/* AES instructions */
+#define X86_FEATURE_XSAVE       (4*32+26)	/* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_OSXSAVE     (4*32+27)	/* "" XSAVE enabled in the OS */
+#define X86_FEATURE_AVX         (4*32+28)	/* Advanced Vector Extensions */
+#define X86_FEATURE_HYPERVISOR  (4*32+31)	/* Running on a hypervisor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_XSTORE	(5*32+ 2)	/* on-CPU RNG present (xstore insn) */
+#define X86_FEATURE_XSTORE_EN	(5*32+ 3)	/* on-CPU RNG enabled */
+#define X86_FEATURE_XCRYPT	(5*32+ 6)	/* on-CPU crypto (xcrypt insn) */
+#define X86_FEATURE_XCRYPT_EN	(5*32+ 7)	/* on-CPU crypto enabled */
+#define X86_FEATURE_ACE2        (5*32+ 8)	/* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN     (5*32+ 9)	/* ACE v2 enabled */
+#define X86_FEATURE_PHE         (5*32+10)	/* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN      (5*32+11)	/* PHE enabled */
+#define X86_FEATURE_PMM         (5*32+12)	/* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN      (5*32+13)	/* PMM enabled */
+
+/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+#define X86_FEATURE_LAHF_LM	(6*32+ 0)	/* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY	(6*32+ 1)	/* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM		(6*32+ 2)	/* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC     (6*32+ 3)	/* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY  (6*32+ 4)	/* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM         (6*32+ 5)	/* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A       (6*32+ 6)	/* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE (6*32+ 7)	/* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8)	/* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW        (6*32+ 9)	/* OS Visible Workaround */
+#define X86_FEATURE_IBS         (6*32+10)	/* Instruction Based Sampling */
+#define X86_FEATURE_SSE5        (6*32+11)	/* SSE-5 */
+#define X86_FEATURE_SKINIT      (6*32+12)	/* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT         (6*32+13)	/* Watchdog timer */
+
+/*
+ *  * Auxiliary flags: Linux defined - For features scattered in various
+ *   * CPUID levels like 0x6, 0xA etc
+ *    */
+#define X86_FEATURE_IDA         (7*32+ 0)	/* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT        (7*32+ 1)	/* Always Running APIC Timer */
+
+/* Virtualization flags: Linux defined */
+#define X86_FEATURE_TPR_SHADOW  (8*32+ 0)	/* Intel TPR Shadow */
+#define X86_FEATURE_VNMI        (8*32+ 1)	/* Intel Virtual NMI */
+#define X86_FEATURE_FLEXPRIORITY (8*32+ 2)	/* Intel FlexPriority */
+#define X86_FEATURE_EPT         (8*32+ 3)	/* Intel Extended Page Table */
+#define X86_FEATURE_VPID        (8*32+ 4)	/* Intel Virtual Processor ID */
+
+#endif /* __ASM_I386_CPUFEATURE_H */
+
+/*
+ * Local Variables:
+ * mode:c
+ * comment-column:42
+ * End:
+ */
Index: bootcd/isolinux/syslinux-6.03/com32/include/ctype.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/ctype.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/ctype.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,122 @@
+/*
+ * ctype.h
+ *
+ * This assumes ISO 8859-1, being a reasonable superset of ASCII.
+ */
+
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+#include <klibc/extern.h>
+
+#ifndef __CTYPE_NO_INLINE
+# define __ctype_inline static __inline__
+#else
+# define __ctype_inline
+#endif
+
+/*
+ * This relies on the following definitions:
+ *
+ * cntrl = !print
+ * alpha = upper|lower
+ * graph = punct|alpha|digit
+ * blank = '\t' || ' ' (per POSIX requirement)
+ */
+enum {
+    __ctype_upper = (1 << 0),
+    __ctype_lower = (1 << 1),
+    __ctype_digit = (1 << 2),
+    __ctype_xdigit = (1 << 3),
+    __ctype_space = (1 << 4),
+    __ctype_print = (1 << 5),
+    __ctype_punct = (1 << 6),
+    __ctype_cntrl = (1 << 7),
+};
+
+extern const unsigned char __ctypes[];
+
+__ctype_inline int isalnum(int __c)
+{
+    return __ctypes[__c + 1] & (__ctype_upper | __ctype_lower | __ctype_digit);
+}
+
+__ctype_inline int isalpha(int __c)
+{
+    return __ctypes[__c + 1] & (__ctype_upper | __ctype_lower);
+}
+
+__ctype_inline int isascii(int __c)
+{
+    return !(__c & ~0x7f);
+}
+
+__ctype_inline int isblank(int __c)
+{
+    return (__c == '\t') || (__c == ' ');
+}
+
+__ctype_inline int iscntrl(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_cntrl;
+}
+
+__ctype_inline int isdigit(int __c)
+{
+    return ((unsigned)__c - '0') <= 9;
+}
+
+__ctype_inline int isgraph(int __c)
+{
+    return __ctypes[__c + 1] &
+	(__ctype_upper | __ctype_lower | __ctype_digit | __ctype_punct);
+}
+
+__ctype_inline int islower(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_lower;
+}
+
+__ctype_inline int isprint(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_print;
+}
+
+__ctype_inline int ispunct(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_punct;
+}
+
+__ctype_inline int isspace(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_space;
+}
+
+__ctype_inline int isupper(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_upper;
+}
+
+__ctype_inline int isxdigit(int __c)
+{
+    return __ctypes[__c + 1] & __ctype_xdigit;
+}
+
+/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */
+#define _toupper(__c) ((__c) & ~32)
+#define _tolower(__c) ((__c) | 32)
+
+__ctype_inline int toupper(int __c)
+{
+    return islower(__c) ? _toupper(__c) : __c;
+}
+
+__ctype_inline int tolower(int __c)
+{
+    return isupper(__c) ? _tolower(__c) : __c;
+}
+
+__extern char *skipspace(const char *p);
+__extern void chrreplace(char *source, char old, char new);
+
+#endif /* _CTYPE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/dev.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/dev.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/dev.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * console.h
+ *
+ * Alternative consoles
+ */
+
+#ifndef _DEV_H
+#define _DEV_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <stddef.h>
+
+struct input_dev;
+struct output_dev;
+
+__extern int opendev(const struct input_dev *, const struct output_dev *, int);
+__extern int openmem(const void *, size_t, int);
+
+/* Common generic devices */
+
+/* Null device */
+extern const struct input_dev dev_null_r;
+extern const struct output_dev dev_null_w;
+
+/* Error device */
+extern const struct input_dev dev_error_r;
+extern const struct output_dev dev_error_w;
+
+#endif /* _DEV_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/dhcp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/dhcp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/dhcp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+#ifndef DHCP_H
+#define DHCP_H
+
+#include <inttypes.h>
+
+struct dhcp_option {
+	void *data;
+	int len;
+};
+
+struct dhcp_packet {
+	uint8_t op;		/*   0 */
+	uint8_t htype;		/*   1 */
+	uint8_t hlen;		/*   2 */
+	uint8_t hops;		/*   3 */
+	uint32_t xid;		/*   4 */
+	uint16_t secs;		/*   8 */
+	uint16_t flags;		/*  10 */
+	uint32_t ciaddr;	/*  12 */
+	uint32_t yiaddr;	/*  16 */
+	uint32_t siaddr;	/*  20 */
+	uint32_t giaddr;	/*  24 */
+	uint8_t chaddr[16];	/*  28 */
+	uint8_t sname[64];	/*  44 */
+	uint8_t file[128];	/* 108 */
+	uint32_t magic;		/* 236 */
+	uint8_t options[4];	/* 240 */
+};
+
+#define DHCP_VENDOR_MAGIC	0x63825363
+
+int dhcp_pack_packet(void *packet, size_t *len,
+		     const struct dhcp_option opt[256]);
+
+int dhcp_unpack_packet(const void *packet, size_t len,
+		       struct dhcp_option opt[256]);
+
+#endif /* DHCP_H */
+  
+
Index: bootcd/isolinux/syslinux-6.03/com32/include/dirent.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/dirent.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/dirent.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,20 @@
+/*
+ * dirent.h
+ */
+
+#ifndef _DIRENT_H
+#define _DIRENT_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <sys/dirent.h>
+
+__extern DIR *opendir(const char *);
+__extern struct dirent *readdir(DIR *);
+__extern int closedir(DIR *);
+__extern DIR *fdopendir(int);
+
+#endif /* Not _DIRENT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/dprintf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/dprintf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/dprintf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/*
+ * dprintf.h
+ */
+
+#ifndef _DPRINTF_H
+#define _DPRINTF_H
+
+#include <syslinux/debug.h>
+
+#if !defined(DEBUG_PORT) && !defined(DEBUG_STDIO)
+# undef CORE_DEBUG
+#endif
+
+#ifdef CORE_DEBUG
+
+# include <stdio.h>
+
+# ifdef DEBUG_STDIO
+#  define dprintf  printf
+#  define vdprintf vprintf
+#  define ddprintf dprintf
+# else
+void dprintf(const char *, ...);
+void vdprintf(const char *, va_list);
+#  define ddprintf(...)	{ printf(__VA_ARGS__); dprintf(__VA_ARGS__); }
+# endif
+
+#else
+
+#define dprintf(...) \
+    if (syslinux_debug_enabled) \
+        printf(__VA_ARGS__)
+#define vdprintf(fmt, ap) \
+    if (syslinux_debug_enabled) \
+        vprintf(fmt, ap)
+#define ddprintf	printf
+
+#endif /* CORE_DEBUG */
+
+# if CORE_DEBUG >= 2
+/* Really verbose debugging... */
+#  define dprintf2  dprintf
+#  define vdprintf2 vdprintf
+# else
+#  define dprintf2(fmt, ...)	((void)(0))
+#  define vdprintf2(fmt, ap)	((void)(0))
+# endif
+
+#endif /* _DPRINTF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/elf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/elf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/elf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * elf.h
+ */
+
+#ifndef _ELF_H
+#define _ELF_H
+
+#include <sys/elf32.h>
+#include <sys/elf64.h>
+
+#endif /* _ELF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/endian.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/endian.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/endian.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * endian.h
+ */
+
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <klibc/endian.h>
+
+#define LITTLE_ENDIAN	__LITTLE_ENDIAN
+#define BIG_ENDIAN	__BIG_ENDIAN
+#define PDP_ENDIAN	__PDP_ENDIAN
+#define BYTE_ORDER	__BYTE_ORDER
+
+#endif /* _ENDIAN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/errno.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/errno.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/errno.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,155 @@
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+extern int errno;
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+
+#define	EDEADLOCK	EDEADLK
+
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+/* lwIP nameserver query return codes */
+#define ENSROK    0 /* DNS server returned answer with no data */
+#define ENSRNODATA  160 /* DNS server returned answer with no data */
+#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
+#define ENSRSERVFAIL 162  /* DNS server returned general failure */
+#define ENSRNOTFOUND 163  /* Domain name not found */
+#define ENSRNOTIMP  164 /* DNS server does not implement requested operation */
+#define ENSRREFUSED 165 /* DNS server refused query */
+#define ENSRBADQUERY 166  /* Misformatted DNS query */
+#define ENSRBADNAME 167 /* Misformatted domain name */
+#define ENSRBADFAMILY 168 /* Unsupported address family */
+#define ENSRBADRESP 169 /* Misformatted DNS reply */
+#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
+#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
+#define ENSROF    172 /* End of file */
+#define ENSRFILE  173 /* Error reading file */
+#define ENSRNOMEM 174 /* Out of memory */
+#define ENSRDESTRUCTION 175 /* Application terminated lookup */
+#define ENSRQUERYDOMAINTOOLONG  176 /* Domain name is too long */
+#define ENSRCNAMELOOP 177 /* Domain name is too long */
+
+#endif /* _ERRNO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/fcntl.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/fcntl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/fcntl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+/*
+ * fcntl.h
+ */
+
+#ifndef _FCNTL_H
+#define _FCNTL_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <sys/types.h>
+
+/* None of these are actually supported, although O_RDONLY works */
+/* Note this is different from the classical Unix way of doing it */
+#define	O_RDONLY	1
+#define O_WRONLY	2
+#define O_RDWR		3
+#define O_DIRECTORY	010
+#define O_CREAT		0100
+#define O_EXCL		0200
+#define O_TRUNC		01000
+#define O_APPEND	02000
+
+__extern int open(const char *, int, ...);
+
+#endif /* _FCNTL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/getopt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/getopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/getopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,22 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#include <klibc/extern.h>
+
+struct option {
+	const char *name;
+	int has_arg;
+	int *flag;
+	int val;
+};
+
+enum {
+	no_argument	  = 0,
+	required_argument = 1,
+	optional_argument = 2,
+};
+
+__extern int getopt_long(int, char *const *, const char *,
+			 const struct option *, int *);
+
+#endif /* _GETOPT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/hw/vga.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/hw/vga.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/hw/vga.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,104 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2012 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _HW_VGA_H
+#define _HW_VGA_H 1
+
+#include <sys/io.h>
+
+/* These are relative to the CRTC base address */
+#define VGA_CRTC_ADDR			0x4
+#define VGA_CRTC_DATA			0x5
+#define VGA_CRTC_IX_HORIZ_TOTAL		0x00
+#define VGA_CRTC_IX_END_HORIZ_DISPLAY	0x01
+#define VGA_CRTC_IX_START_HORIZ_BLANK	0x02
+#define VGA_CRTC_IX_END_HORIZ_BLANK	0x03
+#define VGA_CRTC_IX_START_HORIZ_RETR	0x04
+#define VGA_CRTC_IX_END_HORIZ_RETR	0x05
+#define VGA_CRTC_IX_VERT_TOTAL		0x06
+#define VGA_CRTC_IX_OVERFLOW		0x07
+#define VGA_CRTC_IX_PRESET_ROW_SCAN	0x08
+#define VGA_CRTC_IX_MAX_SCAN_LINE	0x09
+#define VGA_CRTC_IX_CURSOR_START	0x0a
+#define VGA_CRTC_IX_CURSOR_END		0x0b
+#define VGA_CRTC_IX_START_ADDR_HIGH	0x0c
+#define VGA_CRTC_IX_START_ADDR_LOW	0x0d
+#define VGA_CRTC_IX_CURSOR_POS_HIGH	0x0e
+#define VGA_CRTC_IX_CURSOR_POS_LOW	0x0f
+#define VGA_CRTC_IX_START_VERT_RETR	0x10
+#define VGA_CRTC_IX_END_VERT_RETR	0x11
+#define VGA_CRTC_IX_END_VERT_DISPLAY	0x12
+#define VGA_CRTC_IX_OFFSET		0x13
+#define VGA_CRTC_IX_UNDERLINE		0x14
+#define VGA_CRTC_IX_START_VERT_BLANK	0x15
+#define VGA_CRTC_IX_END_VERT_BLANK	0x16
+#define VGA_CRTC_IX_MODE_CONTROL	0x17
+#define VGA_CRTC_IX_LINE_COMPARE	0x18
+#define VGA_CRTC_INPUT_STATUS_1		0xa
+#define VGA_CRTC_FEATURE_CONTROL_WRITE	0xa
+
+#define VGA_ATTR_ADDR_DATA		0x3c0
+#define VGA_ATTR_DATA_READ		0x3c1
+/* 0x00-0x0f are 16->64 palette registers */
+#define VGA_ATTR_IX_MODE_CONTROL	0x10
+#define VGA_ATTR_IX_OVERSCAN		0x11
+#define VGA_ATTR_IX_COLOR_PLANE_ENABLE	0x12
+#define VGA_ATTR_IX_HORIZ_PIXEL_PAN	0x13
+#define VGA_ADDR_IX_COLOR_SELECT	0x14
+#define VGA_INPUT_STATUS_0		0x3c2
+#define VGA_MISC_OUTPUT_WRITE		0x3c2
+#define VGA_SEQ_ADDR			0x3c4
+#define VGA_SEQ_DATA			0x3c5
+#define VGA_SEQ_IX_RESET		0
+#define VGA_SEQ_IX_CLOCKMODE		1
+#define VGA_SEQ_IX_MAP_MASK		2
+#define VGA_SEQ_IX_CHAR_MAP		3
+#define VGA_SEQ_IX_SEQ_MEM_MODE		4
+#define VGA_DAC_STATE			0x3c7
+#define VGA_DAC_ADDR_READ_MODE		0x3c7
+#define VGA_DAC_ADDR_WRITE_MODE		0x3c8
+#define VGA_DAC_DATA			0x3c9
+#define VGA_FEATURE_CONTROL_READ	0x3ca
+#define VGA_MISC_OUTPUT_READ		0x3cc
+#define VGA_GC_ADDR			0x3ce
+#define VGA_GC_DATA			0x3cf
+#define VGA_GC_IX_SET_RESET		0
+#define VGA_GC_IX_ENABLE_SET_RESET	1
+#define VGA_GC_IX_COLOR_COMPARE		2
+#define VGA_GC_IX_DATA_ROTATE		3
+#define VGA_GC_IX_READ_MAP_SELECT	4
+#define VGA_GC_IX_GRAPHICS_MODE		5
+#define VGA_GC_IX_MISC_GRAPHICS		6
+#define VGA_GC_IX_COLOR_DONT_CARE	7
+#define VGA_GC_IX_BIT_MASK		8
+
+static inline uint16_t vga_crtc_base(void)
+{
+    return 0x3b0 + ((inb(VGA_MISC_OUTPUT_READ) & 1) << 5);
+}
+
+#endif /* _HW_VGA_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/ilog2.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/ilog2.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/ilog2.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _ILOG2_H
+#define _ILOG2_H
+
+/*
+ * Computes floor(log2(x)) -- undefined for x = 0.
+ */
+
+#include <klibc/compiler.h>
+#include <stdint.h>
+
+static inline __constfunc uint32_t ilog2(uint32_t __v)
+{
+# if __GNUC__ >= 4
+    return __builtin_clz(__v) ^ 31;
+# else
+    asm("bsrl %1,%0" : "=r" (__v) : "rm" (__v));
+    return __v;
+# endif
+}
+
+#endif /* _ILOG2_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/inttypes.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/inttypes.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/inttypes.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,226 @@
+/*
+ * inttypes.h
+ */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <stddef.h>
+
+static __inline__ intmax_t imaxabs(intmax_t __n)
+{
+    return (__n < (intmax_t) 0) ? -__n : __n;
+}
+
+__extern intmax_t strtoimax(const char *, char **, int);
+__extern uintmax_t strtoumax(const char *, char **, int);
+
+/* extensions */
+__extern intmax_t strntoimax(const char *, char **, int, size_t);
+__extern uintmax_t strntoumax(const char *, char **, int, size_t);
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+
+#define PRId8	"d"
+#define PRId16	"d"
+#define PRId32	"d"
+#define PRId64	__PRI64_RANK "d"
+
+#define PRIdLEAST8	"d"
+#define PRIdLEAST16	"d"
+#define PRIdLEAST32	"d"
+#define PRIdLEAST64	__PRI64_RANK "d"
+
+#define PRIdFAST8	"d"
+#define PRIdFAST16	__PRIFAST_RANK "d"
+#define PRIdFAST32	__PRIFAST_RANK "d"
+#define PRIdFAST64	__PRI64_RANK "d"
+
+#define PRIdMAX	 __PRI64_RANK "d"
+#define PRIdPTR  __PRIPTR_RANK "d"
+
+#define PRIi8	"i"
+#define PRIi16	"i"
+#define PRIi32	"i"
+#define PRIi64	__PRI64_RANK "i"
+
+#define PRIiLEAST8	"i"
+#define PRIiLEAST16	"i"
+#define PRIiLEAST32	"i"
+#define PRIiLEAST64	__PRI64_RANK "i"
+
+#define PRIiFAST8	"i"
+#define PRIiFAST16	__PRIFAST_RANK "i"
+#define PRIiFAST32	__PRIFAST_RANK "i"
+#define PRIiFAST64	__PRI64_RANK "i"
+
+#define PRIiMAX	 __PRI64_RANK "i"
+#define PRIiPTR  __PRIPTR_RANK "i"
+
+#define PRIo8	"o"
+#define PRIo16	"o"
+#define PRIo32	"o"
+#define PRIo64	__PRI64_RANK "o"
+
+#define PRIoLEAST8	"o"
+#define PRIoLEAST16	"o"
+#define PRIoLEAST32	"o"
+#define PRIoLEAST64	__PRI64_RANK "o"
+
+#define PRIoFAST8	"o"
+#define PRIoFAST16	__PRIFAST_RANK "o"
+#define PRIoFAST32	__PRIFAST_RANK "o"
+#define PRIoFAST64	__PRI64_RANK "o"
+
+#define PRIoMAX	 __PRI64_RANK "o"
+#define PRIoPTR  __PRIPTR_RANK "o"
+
+#define PRIu8	"u"
+#define PRIu16	"u"
+#define PRIu32	"u"
+#define PRIu64	__PRI64_RANK "u"
+
+#define PRIuLEAST8	"u"
+#define PRIuLEAST16	"u"
+#define PRIuLEAST32	"u"
+#define PRIuLEAST64	__PRI64_RANK "u"
+
+#define PRIuFAST8	"u"
+#define PRIuFAST16	__PRIFAST_RANK "u"
+#define PRIuFAST32	__PRIFAST_RANK "u"
+#define PRIuFAST64	__PRI64_RANK "u"
+
+#define PRIuMAX	 __PRI64_RANK "u"
+#define PRIuPTR  __PRIPTR_RANK "u"
+
+#define PRIx8	"x"
+#define PRIx16	"x"
+#define PRIx32	"x"
+#define PRIx64	__PRI64_RANK "x"
+
+#define PRIxLEAST8	"x"
+#define PRIxLEAST16	"x"
+#define PRIxLEAST32	"x"
+#define PRIxLEAST64	__PRI64_RANK "x"
+
+#define PRIxFAST8	"x"
+#define PRIxFAST16	__PRIFAST_RANK "x"
+#define PRIxFAST32	__PRIFAST_RANK "x"
+#define PRIxFAST64	__PRI64_RANK "x"
+
+#define PRIxMAX	 __PRI64_RANK "x"
+#define PRIxPTR  __PRIPTR_RANK "x"
+
+#define PRIX8	"X"
+#define PRIX16	"X"
+#define PRIX32	"X"
+#define PRIX64	__PRI64_RANK "X"
+
+#define PRIXLEAST8	"X"
+#define PRIXLEAST16	"X"
+#define PRIXLEAST32	"X"
+#define PRIXLEAST64	__PRI64_RANK "X"
+
+#define PRIXFAST8	"X"
+#define PRIXFAST16	__PRIFAST_RANK "X"
+#define PRIXFAST32	__PRIFAST_RANK "X"
+#define PRIXFAST64	__PRI64_RANK "X"
+
+#define PRIXMAX	 __PRI64_RANK "X"
+#define PRIXPTR  __PRIPTR_RANK "X"
+
+#define SCNd8	"hhd"
+#define SCNd16	"hd"
+#define SCNd32	"d"
+#define SCNd64	__PRI64_RANK "d"
+
+#define SCNdLEAST8	"hhd"
+#define SCNdLEAST16	"hd"
+#define SCNdLEAST32	"d"
+#define SCNdLEAST64	__PRI64_RANK "d"
+
+#define SCNdFAST8	"hhd"
+#define SCNdFAST16	__PRIFAST_RANK "d"
+#define SCNdFAST32	__PRIFAST_RANK "d"
+#define SCNdFAST64	__PRI64_RANK "d"
+
+#define SCNdMAX	 __PRI64_RANK "d"
+#define SCNdPTR  __PRIPTR_RANK "d"
+
+#define SCNi8	"hhi"
+#define SCNi16	"hi"
+#define SCNi32	"i"
+#define SCNi64	__PRI64_RANK "i"
+
+#define SCNiLEAST8	"hhi"
+#define SCNiLEAST16	"hi"
+#define SCNiLEAST32	"i"
+#define SCNiLEAST64	__PRI64_RANK "i"
+
+#define SCNiFAST8	"hhi"
+#define SCNiFAST16	__PRIFAST_RANK "i"
+#define SCNiFAST32	__PRIFAST_RANK "i"
+#define SCNiFAST64	__PRI64_RANK "i"
+
+#define SCNiMAX	 __PRI64_RANK "i"
+#define SCNiPTR  __PRIPTR_RANK "i"
+
+#define SCNo8	"hho"
+#define SCNo16	"ho"
+#define SCNo32	"o"
+#define SCNo64	__PRI64_RANK "o"
+
+#define SCNoLEAST8	"hho"
+#define SCNoLEAST16	"ho"
+#define SCNoLEAST32	"o"
+#define SCNoLEAST64	__PRI64_RANK "o"
+
+#define SCNoFAST8	"hho"
+#define SCNoFAST16	__PRIFAST_RANK "o"
+#define SCNoFAST32	__PRIFAST_RANK "o"
+#define SCNoFAST64	__PRI64_RANK "o"
+
+#define SCNoMAX	 __PRI64_RANK "o"
+#define SCNoPTR  __PRIPTR_RANK "o"
+
+#define SCNu8	"hhu"
+#define SCNu16	"hu"
+#define SCNu32	"u"
+#define SCNu64	__PRI64_RANK "u"
+
+#define SCNuLEAST8	"hhu"
+#define SCNuLEAST16	"hu"
+#define SCNuLEAST32	"u"
+#define SCNuLEAST64	__PRI64_RANK "u"
+
+#define SCNuFAST8	"hhu"
+#define SCNuFAST16	__PRIFAST_RANK "u"
+#define SCNuFAST32	__PRIFAST_RANK "u"
+#define SCNuFAST64	__PRI64_RANK "u"
+
+#define SCNuMAX	 __PRI64_RANK "u"
+#define SCNuPTR  __PRIPTR_RANK "u"
+
+#define SCNx8	"hhx"
+#define SCNx16	"hx"
+#define SCNx32	"x"
+#define SCNx64	__PRI64_RANK "x"
+
+#define SCNxLEAST8	"hhx"
+#define SCNxLEAST16	"hx"
+#define SCNxLEAST32	"x"
+#define SCNxLEAST64	__PRI64_RANK "x"
+
+#define SCNxFAST8	"hhx"
+#define SCNxFAST16	__PRIFAST_RANK "x"
+#define SCNxFAST32	__PRIFAST_RANK "x"
+#define SCNxFAST64	__PRI64_RANK "x"
+
+#define SCNxMAX	 __PRI64_RANK "x"
+#define SCNxPTR  __PRIPTR_RANK "x"
+
+#endif
+
+#endif /* _INTTYPES_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/archsetjmp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+    unsigned int __ebx;
+    unsigned int __esp;
+    unsigned int __ebp;
+    unsigned int __esi;
+    unsigned int __edi;
+    unsigned int __eip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/compiler.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/compiler.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/compiler.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,144 @@
+/*
+ * klibc/compiler.h
+ *
+ * Various compiler features
+ */
+
+#ifndef _KLIBC_COMPILER_H
+#define _KLIBC_COMPILER_H
+
+#define __user
+
+/* Specific calling conventions */
+/* __cdecl is used when we want varadic and non-varadic functions to have
+   the same binary calling convention. */
+#ifdef __i386__
+# ifdef __GNUC__
+#  define __cdecl __attribute__((cdecl,regparm(0)))
+# else
+  /* Most other C compilers have __cdecl as a keyword */
+# endif
+#else
+# define __cdecl		/* Meaningless on non-i386 */
+#endif
+
+/* How to declare a function that *must* be inlined */
+#ifdef __GNUC__
+# if __GNUC_MAJOR__ >= 3
+#  define __must_inline static __inline__ __attribute__((always_inline))
+# else
+#  define __must_inline extern __inline__
+# endif
+#else
+# define __must_inline inline	/* Just hope this works... */
+#endif
+
+/* How to declare a function that does not return */
+#ifdef __GNUC__
+# define __noreturn void __attribute__((noreturn))
+#else
+# define __noreturn void
+#endif
+
+/* "const" function:
+
+     Many functions do not examine any values except their arguments,
+     and have no effects except the return value.  Basically this is
+     just slightly more strict class than the `pure' attribute above,
+     since function is not allowed to read global memory.
+
+     Note that a function that has pointer arguments and examines the
+     data pointed to must _not_ be declared `const'.  Likewise, a
+     function that calls a non-`const' function usually must not be
+     `const'.  It does not make sense for a `const' function to return
+     `void'.
+*/
+#ifdef __GNUC__
+# define __constfunc __attribute__((const))
+#else
+# define __constfunc
+#endif
+#undef __attribute_const__
+#define __attribute_const__ __constfunc
+
+/* "pure" function:
+
+     Many functions have no effects except the return value and their
+     return value depends only on the parameters and/or global
+     variables.  Such a function can be subject to common subexpression
+     elimination and loop optimization just as an arithmetic operator
+     would be.  These functions should be declared with the attribute
+     `pure'.
+*/
+#ifdef __GNUC__
+# define __purefunc __attribute__((pure))
+#else
+# define __purefunc
+#endif
+#undef __attribute_pure__
+#define __attribute_pure__ __purefunc
+
+/* Format attribute */
+#ifdef __GNUC__
+# define __formatfunc(t,f,a) __attribute__((format(t,f,a)))
+#else
+# define __formatfunc(t,f,a)
+#endif
+
+/* malloc() function (returns unaliased pointer) */
+#if defined(__GNUC__) && (__GNUC_MAJOR__ >= 3)
+# define __mallocfunc __attribute__((malloc))
+#else
+# define __mallocfunc
+#endif
+
+/* likely/unlikely */
+#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95))
+# define __likely(x)   __builtin_expect(!!(x), 1)
+# define __unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define __likely(x)   (!!(x))
+# define __unlikely(x) (!!(x))
+#endif
+
+/* Possibly unused function */
+#ifdef __GNUC__
+# define __unusedfunc	__attribute__((unused))
+#else
+# define __unusedfunc
+#endif
+
+/* Declare a variable or data structure as unused. */
+#ifdef __GNUC__
+# define __unused	__attribute__((unused))
+#else
+# define __unused
+#endif
+
+/* Used symbol */
+#define __used				__attribute__((used))
+
+/* Constructors and destructors */
+#define __constructor	__attribute__((constructor))
+#define __destructor	__attribute__((destructor))
+
+/* Packed structures */
+#define __packed	__attribute__((packed))
+
+/* Weak symbols */
+#define __weak          __attribute__((weak))
+
+/* Alignment */
+#define __aligned(x)	__attribute__((aligned(x)))
+#define __alignas(x)	__attribute__((aligned(__alignof__(x))))
+
+/* Handling of common (affect constructors/destructors) */
+#define __common	__attribute__((common))
+#define __nocommon	__attribute__((nocommon))
+
+/* Weak symbols */
+#define __weak			__attribute__((weak))
+
+#define __export		__attribute__((visibility("default")))
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/diverr.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/diverr.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/diverr.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+static inline void __divide_error(void)
+{
+    asm volatile ("int $0");	/* Divide by zero */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/endian.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/endian.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/endian.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/*
+ * klibc/endian.h
+ *
+ * Like <endian.h>, but export only double-underscore symbols
+ */
+
+#ifndef _KLIBC_ENDIAN_H
+#define _KLIBC_ENDIAN_H
+
+#define __LITTLE_ENDIAN		/* we're on i386, littleendian */
+
+/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or
+   __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be
+   defined with __BYTE_ORDER defining which is actually used... */
+
+#if defined(__LITTLE_ENDIAN)
+# undef  __LITTLE_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN    4321
+# define __PDP_ENDIAN    3412
+# define __BYTE_ORDER    __LITTLE_ENDIAN
+#elif defined(__BIG_ENDIAN)
+# undef  __BIG_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN    4321
+# define __PDP_ENDIAN    3412
+# define __BYTE_ORDER    __BIG_ENDIAN
+#elif defined(__PDP_ENDIAN)
+# undef  __PDP_ENDIAN
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN    4321
+# define __PDP_ENDIAN    3412
+# define __BYTE_ORDER    __PDP_ENDIAN
+#else
+# error "Unknown byte order!"
+#endif
+
+#endif /* _KLIBC_ENDIAN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/extern.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/extern.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/extern.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * klibc/extern.h
+ */
+
+#ifndef _KLIBC_EXTERN_H
+#define _KLIBC_EXTERN_H
+
+#ifdef __cplusplus
+#define __extern extern "C"
+#else
+#define __extern extern
+#endif
+
+#endif /* _KLIBC_EXTERN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/i386/archsetjmp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/i386/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/i386/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+    unsigned int __ebx;
+    unsigned int __esp;
+    unsigned int __ebp;
+    unsigned int __esi;
+    unsigned int __edi;
+    unsigned int __eip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/sysconfig.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/sysconfig.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/sysconfig.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,34 @@
+/*
+ * klibc/sysconfig.h
+ *
+ * Allows for definitions of some things which may be system-dependent
+ */
+
+#ifndef _KLIBC_SYSCONFIG_H
+#define _KLIBC_SYSCONFIG_H
+
+/*
+ * Define this to obtain memory using sbrk() instead
+ * of mmap().  This should make it friendlier on
+ * non-MMU architectures.  This should become a
+ * per-architecture configurable.
+ */
+#define MALLOC_USING_SBRK
+
+/*
+ * This is the minimum chunk size we will ask the kernel for using
+ * malloc(); this should be a multiple of the page size on all
+ * architectures.
+ */
+#define MALLOC_CHUNK_SIZE	4096
+#define MALLOC_CHUNK_MASK       (MALLOC_CHUNK_SIZE-1)
+
+/*
+ * This is the minimum alignment for the memory returned by sbrk().
+ * It must be a power of 2.  If MALLOC_USING_SBRK is defined it should
+ * be no smaller than the size of struct arena_header in malloc.h (4
+ * pointers.)
+ */
+#define SBRK_ALIGNMENT		32
+
+#endif /* _KLIBC_SYSCONFIG_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/klibc/x86_64/archsetjmp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/klibc/x86_64/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/klibc/x86_64/archsetjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * arch/x86_64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+	unsigned long __rbx;
+	unsigned long __rsp;
+	unsigned long __rbp;
+	unsigned long __r12;
+	unsigned long __r13;
+	unsigned long __r14;
+	unsigned long __r15;
+	unsigned long __rip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif				/* _SETJMP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/libansi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/libansi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/libansi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,103 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_LIB_ANSI_H
+#define DEFINE_LIB_ANSI_H
+
+#define CSI "\e["
+
+void display_cursor(bool status);
+void clear_end_of_line(void);
+void move_cursor_left(int count);
+void move_cursor_right(int count);
+void clear_line(void);
+void clear_beginning_of_line(void);
+void move_cursor_to_column(int count);
+void move_cursor_to_next_line(void);
+void disable_utf8(void);
+void set_g1_special_char(void);
+void set_us_g0_charset(void);
+void clear_entire_screen(void);
+void set_cursor_blink(bool status);
+void move_cursor_to_next_line(void);
+void disable_utf8(void);
+void set_g1_special_char(void);
+void set_us_g0_charset(void);
+void clear_entire_screen(void);
+void clearwindow(const char top, const char left, const char bot,
+		 const char right, const char fillchar, const char fillattr);
+
+static inline void beep(void)
+{
+	fputs("\007", stdout);
+}
+
+void reset_colors(void);
+
+/* Print a string */
+void csprint(const char *, const char);
+
+/* Print one character, one or more times */
+void cprint(const char, const char, unsigned int);
+
+/* Print one character, once */
+static inline void putch(const char x, char attr)
+{
+	cprint(x, attr, 1);
+}
+
+void cls(void);
+
+static inline void cursoroff(void)
+{
+  display_cursor(false);
+}
+
+static inline void cursoron(void)
+{
+  display_cursor(true);
+}
+
+static inline void scrollup(int times)
+{
+    if (times > 0)
+        printf(CSI "%dS", times);
+}
+
+/* Scroll up display screen by one line */
+static inline void scrollup_once(void)
+{
+	printf(CSI "S");
+}
+
+static inline void gotoxy(const char row, const char col)
+{
+	printf(CSI "%d;%dH", row + 1, col + 1);
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/limits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/limits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,39 @@
+/*
+ * limits.h
+ */
+
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#define CHAR_BIT	8
+#define SHRT_BIT	16
+#define INT_BIT		32
+#define LONGLONG_BIT	64
+
+#define SCHAR_MIN	(-128)
+#define SCHAR_MAX	127
+#define UCHAR_MAX	255
+
+#ifdef __CHAR_UNSIGNED__
+# define CHAR_MIN 0
+# define CHAR_MAX UCHAR_MAX
+#else
+# define CHAR_MIN SCHAR_MIN
+# define CHAR_MAX SCHAR_MAX
+#endif
+
+#define SHRT_MIN	(-32768)
+#define SHRT_MAX	32767
+#define USHRT_MAX	65535
+
+#define INT_MIN		(-2147483647-1)
+#define INT_MAX		2147483647
+#define UINT_MAX	4294967295U
+
+#define LONGLONG_MIN	(-9223372036854775807LL-1)
+#define LONGLONG_MAX	9223372036854775807LL
+#define ULONGLONG_MAX	18446744073709551615ULL
+
+#include <bitsize/limits.h>
+
+#endif /* _LIMITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/linux/list.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/linux/list.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/linux/list.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,464 @@
+// This list structure implementation is adapted from the list implementation
+// on the Linux kernel.
+
+// Original source:
+// http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.25.y.git;a=blob_plain;f=include/linux/list.h;hb=HEAD
+
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head->prev, head);
+}
+
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = NULL;
+	entry->prev = NULL;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+				struct list_head *new)
+{
+	new->next = old->next;
+	new->next->prev = new;
+	new->prev = old->prev;
+	new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+					struct list_head *new)
+{
+	list_replace(old, new);
+	INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+				  struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+				const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(struct list_head *list,
+				 struct list_head *head)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+	struct list_head *at = head->next;
+
+	first->prev = head;
+	head->next = first;
+
+	last->next = at;
+	at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); \
+        	pos = pos->next)
+
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev	-	iterate over a list backwards
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+	for (pos = (head)->prev; pos != (head); \
+        	pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+	for (pos = (head)->prev, n = pos->prev; \
+	     pos != (head); \
+	     pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+* @pos:        the type * to use as a loop cursor.
+* @n:          another type * to use as temporary storage
+* @head:       the head for your list.
+* @member:     the name of the list_struct within the struct.
+*/
+#define list_for_each_entry_safe(pos, n, head, member)                  \
+	for (pos = list_entry((head)->next, typeof(*pos), member),      \
+		n = list_entry(pos->member.next, typeof(*pos), member); \
+             &pos->member != (head);					\
+             pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:	the type * to use as a start point
+ * @head:	the head of the list
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+	((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member)		\
+	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head);	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) 			\
+	for (; &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
+		n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) 			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		n = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/math.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/math.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/math.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#ifndef _MATH_H
+#define _MATH_H
+
+#ifndef __DBL_MIN_EXP__
+# define __DBL_MIN_EXP__ (-1021)
+#endif
+#ifndef __DBL_MAX_EXP__
+# define __DBL_MAX_EXP__ 1024
+#endif
+
+double pow(double, double);
+double fabs(double);
+double strtod(const char *, char **);
+
+#endif /* _MATH_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/menu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,234 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * menu.h
+ *
+ * Header file for the simple menu system
+ */
+
+#ifndef MENU_H
+#define MENU_H
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <colortbl.h>
+#include <stdbool.h>
+#include <getkey.h>
+#include "refstr.h"
+
+/* #define DEBUG 1 */
+#include <dprintf.h>
+
+#ifndef CLK_TCK
+# define CLK_TCK sysconf(_SC_CLK_TCK)
+#endif
+
+struct menu;
+
+/* Note: the _UNRES variants must always be immediately after their
+   "normal" versions. */
+enum menu_action {
+    MA_NONE,			/* Undefined value */
+    MA_CMD,			/* Execute a command */
+    MA_DISABLED,		/* Disabled menu entry */
+    MA_SUBMENU,			/* This is a submenu entry */
+    MA_GOTO,			/* Go to another menu */
+    MA_GOTO_UNRES,		/* Unresolved go to */
+    MA_QUIT,			/* Quit to CLI */
+    MA_EXIT,			/* Exit to higher-level menu */
+    MA_EXIT_UNRES,		/* Unresolved exit */
+    MA_HELP,			/* Show help text */
+};
+
+struct menu_entry {
+    struct menu *menu;		/* Parent menu */
+    const char *displayname;
+    const char *label;
+    const char *passwd;
+    char *helptext;
+    const char *cmdline;
+    const char *background;
+    struct menu *submenu;
+    struct menu_entry *next;	/* Linked list of all labels across menus */
+    int entry;			/* Entry number inside menu */
+    enum menu_action action;
+    unsigned char hotkey;
+    bool immediate;		/* Hotkey action does not require Enter */
+    bool save;			/* Save this entry if selected */
+};
+
+static inline bool is_disabled(struct menu_entry *me)
+{
+    return me->action == MA_DISABLED;
+}
+
+enum kernel_type {
+    /* Meta-types for internal use */
+    KT_NONE,
+    KT_LOCALBOOT,
+
+    /* The ones we can pass off to SYSLINUX, in order */
+    KT_KERNEL,			/* Undefined type */
+    KT_LINUX,			/* Linux kernel */
+    KT_BOOT,			/* Bootstrap program */
+    KT_BSS,			/* Boot sector with patch */
+    KT_PXE,			/* PXE NBP */
+    KT_FDIMAGE,			/* Floppy disk image */
+    KT_COM32,			/* COM32 image */
+    KT_CONFIG,			/* Configuration file */
+};
+
+/* Configurable integer parameters */
+enum parameter_number {
+    P_WIDTH,
+    P_MARGIN,
+    P_PASSWD_MARGIN,
+    P_MENU_ROWS,
+    P_TABMSG_ROW,
+    P_CMDLINE_ROW,
+    P_END_ROW,
+    P_PASSWD_ROW,
+    P_TIMEOUT_ROW,
+    P_HELPMSG_ROW,
+    P_HELPMSGEND_ROW,
+    P_HSHIFT,
+    P_VSHIFT,
+    P_HIDDEN_ROW,
+
+    NPARAMS
+};
+
+/* Configurable messages */
+enum message_number {
+    MSG_TITLE,
+    MSG_AUTOBOOT,
+    MSG_TAB,
+    MSG_NOTAB,
+    MSG_PASSPROMPT,
+
+    MSG_COUNT
+};
+
+struct messages {
+    const char *name;		/* Message configuration name */
+    const char *defmsg;		/* Default message text */
+};
+
+struct menu_parameter {
+    const char *name;
+    int value;
+};
+
+extern const struct menu_parameter mparm[NPARAMS];
+
+struct fkey_help {
+    const char *textname;
+    const char *background;
+};
+
+struct menu {
+    struct menu *next;		/* Linked list of all menus */
+    const char *label;		/* Goto label for this menu */
+    struct menu *parent;
+    struct menu_entry *parent_entry;	/* Entry for self in parent */
+
+    struct menu_entry **menu_entries;
+    struct menu_entry *menu_hotkeys[256];
+
+    const char *messages[MSG_COUNT];
+    int mparm[NPARAMS];
+
+    int nentries;
+    int nentries_space;
+    int defentry;
+    int timeout;
+
+    bool allowedit;
+    bool immediate;		/* MENU IMMEDIATE default for this menu */
+    bool save;			/* MENU SAVE default for this menu */
+
+    int curentry;
+    int curtop;
+
+    const char *title;
+    const char *ontimeout;
+    const char *onerror;
+    const char *menu_master_passwd;
+    const char *menu_background;
+
+    struct color_table *color_table;
+
+    struct fkey_help fkeyhelp[12];
+};
+
+extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
+
+/* 2048 is the current definition inside syslinux */
+#define MAX_CMDLINE_LEN	 2048
+
+/* These are global parameters regardless of which menu we're displaying */
+extern int shiftkey;
+extern int hiddenmenu;
+extern int clearmenu;
+extern long long totaltimeout;
+extern clock_t kbdtimeout;
+extern const char *hide_key[KEY_MAX];
+
+void parse_configs(char **argv);
+int draw_background(const char *filename);
+void set_resolution(int x, int y);
+void start_console(void);
+void local_cursor_enable(bool);
+
+static inline int my_isspace(char c)
+{
+    return (unsigned char)c <= ' ';
+}
+
+int my_isxdigit(char c);
+unsigned int hexval(char c);
+unsigned int hexval2(const char *p);
+uint32_t parse_argb(char **p);
+
+extern const int message_base_color, menu_color_table_size;
+int mygetkey(clock_t timeout);
+int show_message_file(const char *filename, const char *background);
+
+/* passwd.c */
+int passwd_compare(const char *passwd, const char *entry);
+
+/* colors.c */
+#define MSG_COLORS_DEF_FG	0x90ffffff
+#define MSG_COLORS_DEF_BG	0x80ffffff
+#define MSG_COLORS_DEF_SHADOW	SHADOW_NORMAL
+void set_msg_colors_global(struct color_table *tbl,
+			   unsigned int fg, unsigned int bg,
+			   enum color_table_shadow shadow);
+struct color_table *default_color_table(void);
+struct color_table *copy_color_table(const struct color_table *master);
+extern const int message_base_color;
+
+/* background.c */
+extern const char *current_background;
+void set_background(const char *new_background);
+
+/* drain.c */
+void drain_keyboard(void);
+
+/* chainboot.c */
+void chainboot_file(const char *file, enum kernel_type type);
+
+#endif /* MENU_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/minmax.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/minmax.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/minmax.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _MINMAX_H
+#define _MINMAX_H
+
+/*
+ * minmax.h: Type-independent safe min/max macros
+ */
+
+#define min(x,y) ({ __typeof(x) xx = (x); \
+                    __typeof(y) yy = (y); \
+                    xx < yy ? xx : yy; })
+#define max(x,y) ({ __typeof(x) xx = (x); \
+                    __typeof(y) yy = (y); \
+                    xx > yy ? xx : yy; })
+
+#endif /* _MINMAX_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/netinet/in.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/netinet/in.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/netinet/in.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,27 @@
+#ifndef _NETINET_IN_H
+#define _NETINET_IN_H
+
+/* COM32 will be running on an i386 platform */
+
+#include <klibc/compiler.h>
+#include <klibc/extern.h>
+#include <stdint.h>
+#include <byteswap.h>
+
+#define htons(x) cpu_to_be16(x)
+#define ntohs(x) be16_to_cpu(x)
+#define htonl(x) cpu_to_be32(x)
+#define ntohl(x) be32_to_cpu(x)
+#define htonq(x) cpu_to_be64(x)
+#define ntohq(x) be64_to_cpu(x)
+
+typedef uint32_t in_addr_t;
+typedef uint16_t in_port_t;
+
+struct in_addr {
+    in_addr_t s_addr;
+};
+
+__extern char *inet_ntoa(struct in_addr);
+
+#endif /* _NETINET_IN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/png.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/png.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/png.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3788 @@
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.2.44 - June 26, 2010
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license (See LICENSE, below)
+ *
+ * Authors and maintainers:
+ *  libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ *  libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ *  libpng versions 0.97, January 1998, through 1.2.44 - June 26, 2010: Glenn
+ *  See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ *    Due to various miscommunications, unforeseen code incompatibilities
+ *    and occasional factors outside the authors' control, version numbering
+ *    on the library has not always been consistent and straightforward.
+ *    The following table summarizes matters since version 0.89c, which was
+ *    the first widely used release:
+ *
+ *    source                 png.h  png.h  shared-lib
+ *    version                string   int  version
+ *    -------                ------ -----  ----------
+ *    0.89c "1.0 beta 3"     0.89      89  1.0.89
+ *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
+ *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
+ *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
+ *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
+ *    0.97c                  0.97      97  2.0.97
+ *    0.98                   0.98      98  2.0.98
+ *    0.99                   0.99      98  2.0.99
+ *    0.99a-m                0.99      99  2.0.99
+ *    1.00                   1.00     100  2.1.0 [100 should be 10000]
+ *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
+ *    1.0.1       png.h string is   10001  2.1.0
+ *    1.0.1a-e    identical to the  10002  from here on, the shared library
+ *    1.0.2       source version)   10002  is 2.V where V is the source code
+ *    1.0.2a-b                      10003  version, except as noted.
+ *    1.0.3                         10003
+ *    1.0.3a-d                      10004
+ *    1.0.4                         10004
+ *    1.0.4a-f                      10005
+ *    1.0.5 (+ 2 patches)           10005
+ *    1.0.5a-d                      10006
+ *    1.0.5e-r                      10100 (not source compatible)
+ *    1.0.5s-v                      10006 (not binary compatible)
+ *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
+ *    1.0.6d-f                      10007 (still binary incompatible)
+ *    1.0.6g                        10007
+ *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
+ *    1.0.6i                        10007  10.6i
+ *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
+ *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
+ *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
+ *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
+ *    1.0.7                    1    10007  (still compatible)
+ *    1.0.8beta1-4             1    10008  2.1.0.8beta1-4
+ *    1.0.8rc1                 1    10008  2.1.0.8rc1
+ *    1.0.8                    1    10008  2.1.0.8
+ *    1.0.9beta1-6             1    10009  2.1.0.9beta1-6
+ *    1.0.9rc1                 1    10009  2.1.0.9rc1
+ *    1.0.9beta7-10            1    10009  2.1.0.9beta7-10
+ *    1.0.9rc2                 1    10009  2.1.0.9rc2
+ *    1.0.9                    1    10009  2.1.0.9
+ *    1.0.10beta1              1    10010  2.1.0.10beta1
+ *    1.0.10rc1                1    10010  2.1.0.10rc1
+ *    1.0.10                   1    10010  2.1.0.10
+ *    1.0.11beta1-3            1    10011  2.1.0.11beta1-3
+ *    1.0.11rc1                1    10011  2.1.0.11rc1
+ *    1.0.11                   1    10011  2.1.0.11
+ *    1.0.12beta1-2            2    10012  2.1.0.12beta1-2
+ *    1.0.12rc1                2    10012  2.1.0.12rc1
+ *    1.0.12                   2    10012  2.1.0.12
+ *    1.1.0a-f                 -    10100  2.1.1.0a-f (branch abandoned)
+ *    1.2.0beta1-2             2    10200  2.1.2.0beta1-2
+ *    1.2.0beta3-5             3    10200  3.1.2.0beta3-5
+ *    1.2.0rc1                 3    10200  3.1.2.0rc1
+ *    1.2.0                    3    10200  3.1.2.0
+ *    1.2.1beta1-4             3    10201  3.1.2.1beta1-4
+ *    1.2.1rc1-2               3    10201  3.1.2.1rc1-2
+ *    1.2.1                    3    10201  3.1.2.1
+ *    1.2.2beta1-6            12    10202  12.so.0.1.2.2beta1-6
+ *    1.0.13beta1             10    10013  10.so.0.1.0.13beta1
+ *    1.0.13rc1               10    10013  10.so.0.1.0.13rc1
+ *    1.2.2rc1                12    10202  12.so.0.1.2.2rc1
+ *    1.0.13                  10    10013  10.so.0.1.0.13
+ *    1.2.2                   12    10202  12.so.0.1.2.2
+ *    1.2.3rc1-6              12    10203  12.so.0.1.2.3rc1-6
+ *    1.2.3                   12    10203  12.so.0.1.2.3
+ *    1.2.4beta1-3            13    10204  12.so.0.1.2.4beta1-3
+ *    1.0.14rc1               13    10014  10.so.0.1.0.14rc1
+ *    1.2.4rc1                13    10204  12.so.0.1.2.4rc1
+ *    1.0.14                  10    10014  10.so.0.1.0.14
+ *    1.2.4                   13    10204  12.so.0.1.2.4
+ *    1.2.5beta1-2            13    10205  12.so.0.1.2.5beta1-2
+ *    1.0.15rc1-3             10    10015  10.so.0.1.0.15rc1-3
+ *    1.2.5rc1-3              13    10205  12.so.0.1.2.5rc1-3
+ *    1.0.15                  10    10015  10.so.0.1.0.15
+ *    1.2.5                   13    10205  12.so.0.1.2.5
+ *    1.2.6beta1-4            13    10206  12.so.0.1.2.6beta1-4
+ *    1.0.16                  10    10016  10.so.0.1.0.16
+ *    1.2.6                   13    10206  12.so.0.1.2.6
+ *    1.2.7beta1-2            13    10207  12.so.0.1.2.7beta1-2
+ *    1.0.17rc1               10    10017  10.so.0.1.0.17rc1
+ *    1.2.7rc1                13    10207  12.so.0.1.2.7rc1
+ *    1.0.17                  10    10017  10.so.0.1.0.17
+ *    1.2.7                   13    10207  12.so.0.1.2.7
+ *    1.2.8beta1-5            13    10208  12.so.0.1.2.8beta1-5
+ *    1.0.18rc1-5             10    10018  10.so.0.1.0.18rc1-5
+ *    1.2.8rc1-5              13    10208  12.so.0.1.2.8rc1-5
+ *    1.0.18                  10    10018  10.so.0.1.0.18
+ *    1.2.8                   13    10208  12.so.0.1.2.8
+ *    1.2.9beta1-3            13    10209  12.so.0.1.2.9beta1-3
+ *    1.2.9beta4-11           13    10209  12.so.0.9[.0]
+ *    1.2.9rc1                13    10209  12.so.0.9[.0]
+ *    1.2.9                   13    10209  12.so.0.9[.0]
+ *    1.2.10beta1-8           13    10210  12.so.0.10[.0]
+ *    1.2.10rc1-3             13    10210  12.so.0.10[.0]
+ *    1.2.10                  13    10210  12.so.0.10[.0]
+ *    1.2.11beta1-4           13    10211  12.so.0.11[.0]
+ *    1.0.19rc1-5             10    10019  10.so.0.19[.0]
+ *    1.2.11rc1-5             13    10211  12.so.0.11[.0]
+ *    1.0.19                  10    10019  10.so.0.19[.0]
+ *    1.2.11                  13    10211  12.so.0.11[.0]
+ *    1.0.20                  10    10020  10.so.0.20[.0]
+ *    1.2.12                  13    10212  12.so.0.12[.0]
+ *    1.2.13beta1             13    10213  12.so.0.13[.0]
+ *    1.0.21                  10    10021  10.so.0.21[.0]
+ *    1.2.13                  13    10213  12.so.0.13[.0]
+ *    1.2.14beta1-2           13    10214  12.so.0.14[.0]
+ *    1.0.22rc1               10    10022  10.so.0.22[.0]
+ *    1.2.14rc1               13    10214  12.so.0.14[.0]
+ *    1.0.22                  10    10022  10.so.0.22[.0]
+ *    1.2.14                  13    10214  12.so.0.14[.0]
+ *    1.2.15beta1-6           13    10215  12.so.0.15[.0]
+ *    1.0.23rc1-5             10    10023  10.so.0.23[.0]
+ *    1.2.15rc1-5             13    10215  12.so.0.15[.0]
+ *    1.0.23                  10    10023  10.so.0.23[.0]
+ *    1.2.15                  13    10215  12.so.0.15[.0]
+ *    1.2.16beta1-2           13    10216  12.so.0.16[.0]
+ *    1.2.16rc1               13    10216  12.so.0.16[.0]
+ *    1.0.24                  10    10024  10.so.0.24[.0]
+ *    1.2.16                  13    10216  12.so.0.16[.0]
+ *    1.2.17beta1-2           13    10217  12.so.0.17[.0]
+ *    1.0.25rc1               10    10025  10.so.0.25[.0]
+ *    1.2.17rc1-3             13    10217  12.so.0.17[.0]
+ *    1.0.25                  10    10025  10.so.0.25[.0]
+ *    1.2.17                  13    10217  12.so.0.17[.0]
+ *    1.0.26                  10    10026  10.so.0.26[.0]
+ *    1.2.18                  13    10218  12.so.0.18[.0]
+ *    1.2.19beta1-31          13    10219  12.so.0.19[.0]
+ *    1.0.27rc1-6             10    10027  10.so.0.27[.0]
+ *    1.2.19rc1-6             13    10219  12.so.0.19[.0]
+ *    1.0.27                  10    10027  10.so.0.27[.0]
+ *    1.2.19                  13    10219  12.so.0.19[.0]
+ *    1.2.20beta01-04         13    10220  12.so.0.20[.0]
+ *    1.0.28rc1-6             10    10028  10.so.0.28[.0]
+ *    1.2.20rc1-6             13    10220  12.so.0.20[.0]
+ *    1.0.28                  10    10028  10.so.0.28[.0]
+ *    1.2.20                  13    10220  12.so.0.20[.0]
+ *    1.2.21beta1-2           13    10221  12.so.0.21[.0]
+ *    1.2.21rc1-3             13    10221  12.so.0.21[.0]
+ *    1.0.29                  10    10029  10.so.0.29[.0]
+ *    1.2.21                  13    10221  12.so.0.21[.0]
+ *    1.2.22beta1-4           13    10222  12.so.0.22[.0]
+ *    1.0.30rc1               10    10030  10.so.0.30[.0]
+ *    1.2.22rc1               13    10222  12.so.0.22[.0]
+ *    1.0.30                  10    10030  10.so.0.30[.0]
+ *    1.2.22                  13    10222  12.so.0.22[.0]
+ *    1.2.23beta01-05         13    10223  12.so.0.23[.0]
+ *    1.2.23rc01              13    10223  12.so.0.23[.0]
+ *    1.2.23                  13    10223  12.so.0.23[.0]
+ *    1.2.24beta01-02         13    10224  12.so.0.24[.0]
+ *    1.2.24rc01              13    10224  12.so.0.24[.0]
+ *    1.2.24                  13    10224  12.so.0.24[.0]
+ *    1.2.25beta01-06         13    10225  12.so.0.25[.0]
+ *    1.2.25rc01-02           13    10225  12.so.0.25[.0]
+ *    1.0.31                  10    10031  10.so.0.31[.0]
+ *    1.2.25                  13    10225  12.so.0.25[.0]
+ *    1.2.26beta01-06         13    10226  12.so.0.26[.0]
+ *    1.2.26rc01              13    10226  12.so.0.26[.0]
+ *    1.2.26                  13    10226  12.so.0.26[.0]
+ *    1.0.32                  10    10032  10.so.0.32[.0]
+ *    1.2.27beta01-06         13    10227  12.so.0.27[.0]
+ *    1.2.27rc01              13    10227  12.so.0.27[.0]
+ *    1.0.33                  10    10033  10.so.0.33[.0]
+ *    1.2.27                  13    10227  12.so.0.27[.0]
+ *    1.0.34                  10    10034  10.so.0.34[.0]
+ *    1.2.28                  13    10228  12.so.0.28[.0]
+ *    1.2.29beta01-03         13    10229  12.so.0.29[.0]
+ *    1.2.29rc01              13    10229  12.so.0.29[.0]
+ *    1.0.35                  10    10035  10.so.0.35[.0]
+ *    1.2.29                  13    10229  12.so.0.29[.0]
+ *    1.0.37                  10    10037  10.so.0.37[.0]
+ *    1.2.30beta01-04         13    10230  12.so.0.30[.0]
+ *    1.0.38rc01-08           10    10038  10.so.0.38[.0]
+ *    1.2.30rc01-08           13    10230  12.so.0.30[.0]
+ *    1.0.38                  10    10038  10.so.0.38[.0]
+ *    1.2.30                  13    10230  12.so.0.30[.0]
+ *    1.0.39rc01-03           10    10039  10.so.0.39[.0]
+ *    1.2.31rc01-03           13    10231  12.so.0.31[.0]
+ *    1.0.39                  10    10039  10.so.0.39[.0]
+ *    1.2.31                  13    10231  12.so.0.31[.0]
+ *    1.2.32beta01-02         13    10232  12.so.0.32[.0]
+ *    1.0.40rc01              10    10040  10.so.0.40[.0]
+ *    1.2.32rc01              13    10232  12.so.0.32[.0]
+ *    1.0.40                  10    10040  10.so.0.40[.0]
+ *    1.2.32                  13    10232  12.so.0.32[.0]
+ *    1.2.33beta01-02         13    10233  12.so.0.33[.0]
+ *    1.2.33rc01-02           13    10233  12.so.0.33[.0]
+ *    1.0.41rc01              10    10041  10.so.0.41[.0]
+ *    1.2.33                  13    10233  12.so.0.33[.0]
+ *    1.0.41                  10    10041  10.so.0.41[.0]
+ *    1.2.34beta01-07         13    10234  12.so.0.34[.0]
+ *    1.0.42rc01              10    10042  10.so.0.42[.0]
+ *    1.2.34rc01              13    10234  12.so.0.34[.0]
+ *    1.0.42                  10    10042  10.so.0.42[.0]
+ *    1.2.34                  13    10234  12.so.0.34[.0]
+ *    1.2.35beta01-03         13    10235  12.so.0.35[.0]
+ *    1.0.43rc01-02           10    10043  10.so.0.43[.0]
+ *    1.2.35rc01-02           13    10235  12.so.0.35[.0]
+ *    1.0.43                  10    10043  10.so.0.43[.0]
+ *    1.2.35                  13    10235  12.so.0.35[.0]
+ *    1.2.36beta01-05         13    10236  12.so.0.36[.0]
+ *    1.2.36rc01              13    10236  12.so.0.36[.0]
+ *    1.0.44                  10    10044  10.so.0.44[.0]
+ *    1.2.36                  13    10236  12.so.0.36[.0]
+ *    1.2.37beta01-03         13    10237  12.so.0.37[.0]
+ *    1.2.37rc01              13    10237  12.so.0.37[.0]
+ *    1.2.37                  13    10237  12.so.0.37[.0]
+ *    1.2.45                  10    10045  12.so.0.45[.0]
+ *    1.0.46                  10    10046  10.so.0.46[.0]
+ *    1.2.38beta01            13    10238  12.so.0.38[.0]
+ *    1.2.38rc01-03           13    10238  12.so.0.38[.0]
+ *    1.0.47                  10    10047  10.so.0.47[.0]
+ *    1.2.38                  13    10238  12.so.0.38[.0]
+ *    1.2.39beta01-05         13    10239  12.so.0.39[.0]
+ *    1.2.39rc01              13    10239  12.so.0.39[.0]
+ *    1.0.48                  10    10048  10.so.0.48[.0]
+ *    1.2.39                  13    10239  12.so.0.39[.0]
+ *    1.2.40beta01            13    10240  12.so.0.40[.0]
+ *    1.2.40rc01              13    10240  12.so.0.40[.0]
+ *    1.0.49                  10    10049  10.so.0.49[.0]
+ *    1.2.40                  13    10240  12.so.0.40[.0]
+ *    1.2.41beta01-18         13    10241  12.so.0.41[.0]
+ *    1.0.51rc01              10    10051  10.so.0.51[.0]
+ *    1.2.41rc01-03           13    10241  12.so.0.41[.0]
+ *    1.0.51                  10    10051  10.so.0.51[.0]
+ *    1.2.41                  13    10241  12.so.0.41[.0]
+ *    1.2.42beta01-02         13    10242  12.so.0.42[.0]
+ *    1.2.42rc01-05           13    10242  12.so.0.42[.0]
+ *    1.0.52                  10    10052  10.so.0.52[.0]
+ *    1.2.42                  13    10242  12.so.0.42[.0]
+ *    1.2.43beta01-05         13    10243  12.so.0.43[.0]
+ *    1.0.53rc01-02           10    10053  10.so.0.53[.0]
+ *    1.2.43rc01-02           13    10243  12.so.0.43[.0]
+ *    1.0.53                  10    10053  10.so.0.53[.0]
+ *    1.2.43                  13    10243  12.so.0.43[.0]
+ *    1.2.44beta01-03         13    10244  12.so.0.44[.0]
+ *    1.2.44rc01-03           13    10244  12.so.0.44[.0]
+ *    1.2.44                  13    10244  12.so.0.44[.0]
+ *
+ *    Henceforth the source version will match the shared-library major
+ *    and minor numbers; the shared-library major version number will be
+ *    used for changes in backward compatibility, as it is intended.  The
+ *    PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ *    for applications, is an unsigned integer of the form xyyzz corresponding
+ *    to the source version x.y.z (leading zeros in y and z).  Beta versions
+ *    were given the previous public release number plus a letter, until
+ *    version 1.0.6j; from then on they were given the upcoming public
+ *    release number plus "betaNN" or "rcNN".
+ *
+ *    Binary incompatibility exists only when applications make direct access
+ *    to the info_ptr or png_ptr members through png.h, and the compiled
+ *    application is loaded with a different version of the library.
+ *
+ *    DLLNUM will change each time there are forward or backward changes
+ *    in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information.  The PNG specification
+ * is available as a W3C Recommendation and as an ISO Specification,
+ * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * This code is released under the libpng license.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.2.44, June 26, 2010, are
+ * Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ *    Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Simon-Pierre Cadieux
+ *    Eric S. Raymond
+ *    Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ *    There is no warranty against interference with your enjoyment of the
+ *    library or against infringement.  There is no warranty that our
+ *    efforts or the library will fulfill any of your particular purposes
+ *    or needs.  This library is provided with all faults, and the entire
+ *    risk of satisfactory quality, performance, accuracy, and effort is with
+ *    the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    Tom Lane
+ *    Glenn Randers-Pehrson
+ *    Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ *    John Bowler
+ *    Kevin Bracey
+ *    Sam Bushell
+ *    Magnus Holmgren
+ *    Greg Roelofs
+ *    Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ *    Andreas Dilger
+ *    Dave Martindale
+ *    Guy Eric Schalnat
+ *    Paul Schmidt
+ *    Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and
+ * must not be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ *    any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products.  If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software.  OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience.  This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ *    June 26, 2010
+ *
+ *    Since the PNG Development group is an ad-hoc body, we can't make
+ *    an official declaration.
+ *
+ *    This is your unofficial assurance that libpng from version 0.71 and
+ *    upward through 1.2.44 are Y2K compliant.  It is my belief that earlier
+ *    versions were also Y2K compliant.
+ *
+ *    Libpng only has three year fields.  One is a 2-byte unsigned integer
+ *    that will hold years up to 65535.  The other two hold the date in text
+ *    format, and will hold years up to 9999.
+ *
+ *    The integer is
+ *        "png_uint_16 year" in png_time_struct.
+ *
+ *    The strings are
+ *        "png_charp time_buffer" in png_struct and
+ *        "near_time_buffer", which is a local character string in png.c.
+ *
+ *    There are seven time-related functions:
+ *        png.c: png_convert_to_rfc_1123() in png.c
+ *          (formerly png_convert_to_rfc_1152() in error)
+ *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ *        png_convert_from_time_t() in pngwrite.c
+ *        png_get_tIME() in pngget.c
+ *        png_handle_tIME() in pngrutil.c, called in pngread.c
+ *        png_set_tIME() in pngset.c
+ *        png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ *    All handle dates properly in a Y2K environment.  The
+ *    png_convert_from_time_t() function calls gmtime() to convert from system
+ *    clock time, which returns (year - 1900), which we properly convert to
+ *    the full 4-digit year.  There is a possibility that applications using
+ *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ *    function, or that they are incorrectly passing only a 2-digit year
+ *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ *    but this is not under our control.  The libpng documentation has always
+ *    stated that it works with 4-digit years, and the APIs have been
+ *    documented as such.
+ *
+ *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+ *    integer to hold the year, and can hold years as large as 65535.
+ *
+ *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
+ *    no date-related code.
+ *
+ *       Glenn Randers-Pehrson
+ *       libpng maintainer
+ *       PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng.  The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build.  This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.2.44"
+#define PNG_HEADER_VERSION_STRING \
+   " libpng version 1.2.44 - June 26, 2010\n"
+
+#define PNG_LIBPNG_VER_SONUM   0
+#define PNG_LIBPNG_VER_DLLNUM  13
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR   1
+#define PNG_LIBPNG_VER_MINOR   2
+#define PNG_LIBPNG_VER_RELEASE 44
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
+ */
+
+#define PNG_LIBPNG_VER_BUILD  0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA    1
+#define PNG_LIBPNG_BUILD_BETA     2
+#define PNG_LIBPNG_BUILD_RC       3
+#define PNG_LIBPNG_BUILD_STABLE   4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
+                                       PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+                                       PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+                                       PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000).  From
+ * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
+ */
+#define PNG_LIBPNG_VER 10244 /* 1.2.44 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Include the compression library's header */
+#include "zlib.h"
+#endif
+
+/* Include all user configurable info, including optional assembler routines */
+#include "pngconf.h"
+
+/*
+ * Added at libpng-1.2.8 */
+/* Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#ifdef PNG_USER_PRIVATEBUILD
+#  define PNG_LIBPNG_BUILD_TYPE \
+          (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+#  ifdef PNG_LIBPNG_SPECIALBUILD
+#    define PNG_LIBPNG_BUILD_TYPE \
+            (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+#  else
+#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+#  endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This file is arranged in several sections.  The first section contains
+ * structure and type definitions.  The second section contains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+#ifndef PNG_NO_TYPECAST_NULL
+#define int_p_NULL                (int *)NULL
+#define png_bytep_NULL            (png_bytep)NULL
+#define png_bytepp_NULL           (png_bytepp)NULL
+#define png_doublep_NULL          (png_doublep)NULL
+#define png_error_ptr_NULL        (png_error_ptr)NULL
+#define png_flush_ptr_NULL        (png_flush_ptr)NULL
+#define png_free_ptr_NULL         (png_free_ptr)NULL
+#define png_infopp_NULL           (png_infopp)NULL
+#define png_malloc_ptr_NULL       (png_malloc_ptr)NULL
+#define png_read_status_ptr_NULL  (png_read_status_ptr)NULL
+#define png_rw_ptr_NULL           (png_rw_ptr)NULL
+#define png_structp_NULL          (png_structp)NULL
+#define png_uint_16p_NULL         (png_uint_16p)NULL
+#define png_voidp_NULL            (png_voidp)NULL
+#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
+#else
+#define int_p_NULL                NULL
+#define png_bytep_NULL            NULL
+#define png_bytepp_NULL           NULL
+#define png_doublep_NULL          NULL
+#define png_error_ptr_NULL        NULL
+#define png_flush_ptr_NULL        NULL
+#define png_free_ptr_NULL         NULL
+#define png_infopp_NULL           NULL
+#define png_malloc_ptr_NULL       NULL
+#define png_read_status_ptr_NULL  NULL
+#define png_rw_ptr_NULL           NULL
+#define png_structp_NULL          NULL
+#define png_uint_16p_NULL         NULL
+#define png_voidp_NULL            NULL
+#define png_write_status_ptr_NULL NULL
+#endif
+
+/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c.  This had better match
+ * the version above.
+ */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
+  /* Need room for 99.99.99beta99z */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
+/* Structures to facilitate easy interlacing.  See png.c for more details */
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
+/* This isn't currently used.  If you need it, see png.c for more details.
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
+*/
+#endif
+
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions.  The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+   png_byte red;
+   png_byte green;
+   png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+   png_byte index;    /* used for palette files */
+   png_uint_16 red;   /* for use in red green blue files */
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 gray;  /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+   png_byte red;   /* for use in red green blue files */
+   png_byte green;
+   png_byte blue;
+   png_byte gray;  /* for use in grayscale files */
+   png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+   png_uint_16 red;
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 alpha;
+   png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ *  occupy the LSB of their respective members, and the MSB of each member
+ *  is zero-filled.  The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+   png_charp name;           /* palette name */
+   png_byte depth;           /* depth of palette samples */
+   png_sPLT_entryp entries;  /* palette entries */
+   png_int_32 nentries;      /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not.  The "key" field
+ * points to a regular zero-terminated C string.  The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
+typedef struct png_text_struct
+{
+   int  compression;       /* compression value:
+                             -1: tEXt, none
+                              0: zTXt, deflate
+                              1: iTXt, none
+                              2: iTXt, deflate  */
+   png_charp key;          /* keyword, 1-79 character description of "text" */
+   png_charp text;         /* comment, may be an empty string (ie "")
+                              or a NULL pointer */
+   png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+   png_size_t itxt_length; /* length of the itxt string */
+   png_charp lang;         /* language code, 0-79 characters
+                              or a NULL pointer */
+   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
+                              chars or a NULL pointer */
+#endif
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed.
+ */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE    -1
+#define PNG_TEXT_COMPRESSION_zTXt     0
+#define PNG_ITXT_COMPRESSION_NONE     1
+#define PNG_ITXT_COMPRESSION_zTXt     2
+#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm.  There
+ * is no portable way to convert to either of these structures, as far
+ * as I know.  If you know of a portable way, send it to me.  As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+   png_uint_16 year; /* full year, as in, 1995 */
+   png_byte month;   /* month of year, 1 - 12 */
+   png_byte day;     /* day of month, 1 - 31 */
+   png_byte hour;    /* hour of day, 0 - 23 */
+   png_byte minute;  /* minute of hour, 0 - 59 */
+   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support.  The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+#define PNG_CHUNK_NAME_LENGTH 5
+typedef struct png_unknown_chunk_t
+{
+    png_byte name[PNG_CHUNK_NAME_LENGTH];
+    png_byte *data;
+    png_size_t size;
+
+    /* libpng-using applications should NOT directly modify this byte. */
+    png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file.  If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed.  With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng.  This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions.  A function to clear these members is available: see
+ * png_free_data().  The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+typedef struct png_info_struct
+{
+   /* The following are necessary for every PNG file */
+   png_uint_32 width PNG_DEPSTRUCT;       /* width of image in pixels (from IHDR) */
+   png_uint_32 height PNG_DEPSTRUCT;      /* height of image in pixels (from IHDR) */
+   png_uint_32 valid PNG_DEPSTRUCT;       /* valid chunk data (see PNG_INFO_ below) */
+   png_uint_32 rowbytes PNG_DEPSTRUCT;    /* bytes needed to hold an untransformed row */
+   png_colorp palette PNG_DEPSTRUCT;      /* array of color values (valid & PNG_INFO_PLTE) */
+   png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in "palette" (PLTE) */
+   png_uint_16 num_trans PNG_DEPSTRUCT;   /* number of transparent palette color (tRNS) */
+   png_byte bit_depth PNG_DEPSTRUCT;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+   png_byte color_type PNG_DEPSTRUCT;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
+   /* The following three should have been named *_method not *_type */
+   png_byte compression_type PNG_DEPSTRUCT; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+   png_byte filter_type PNG_DEPSTRUCT;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+   png_byte interlace_type PNG_DEPSTRUCT; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+   /* The following is informational only on read, and not used on writes. */
+   png_byte channels PNG_DEPSTRUCT;       /* number of data channels per pixel (1, 2, 3, 4) */
+   png_byte pixel_depth PNG_DEPSTRUCT;    /* number of bits per pixel */
+   png_byte spare_byte PNG_DEPSTRUCT;     /* to align the data, and for future use */
+   png_byte signature[8] PNG_DEPSTRUCT;   /* magic bytes read by libpng from start of file */
+
+   /* The rest of the data is optional.  If you are reading, check the
+    * valid field to see if the information in these are valid.  If you
+    * are writing, set the valid field to those chunks you want written,
+    * and initialize the appropriate fields below.
+    */
+
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+   /* The gAMA chunk describes the gamma characteristics of the system
+    * on which the image was created, normally in the range [1.0, 2.5].
+    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+    */
+   float gamma PNG_DEPSTRUCT; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+    /* GR-P, 0.96a */
+    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+   png_byte srgb_intent PNG_DEPSTRUCT; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+   /* The tEXt, and zTXt chunks contain human-readable textual data in
+    * uncompressed, compressed, and optionally compressed forms, respectively.
+    * The data in "text" is an array of pointers to uncompressed,
+    * null-terminated C strings. Each chunk has a keyword that describes the
+    * textual data contained in that chunk.  Keywords are not required to be
+    * unique, and the text string may be empty.  Any number of text chunks may
+    * be in an image.
+    */
+   int num_text PNG_DEPSTRUCT; /* number of comments read/to write */
+   int max_text PNG_DEPSTRUCT; /* current size of text array */
+   png_textp text PNG_DEPSTRUCT; /* array of comments read/to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#ifdef PNG_tIME_SUPPORTED
+   /* The tIME chunk holds the last time the displayed image data was
+    * modified.  See the png_time struct for the contents of this struct.
+    */
+   png_time mod_time PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+   /* The sBIT chunk specifies the number of significant high-order bits
+    * in the pixel data.  Values are in the range [1, bit_depth], and are
+    * only specified for the channels in the pixel data.  The contents of
+    * the low-order bits is not specified.  Data is valid if
+    * (valid & PNG_INFO_sBIT) is non-zero.
+    */
+   png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The tRNS chunk supplies transparency data for paletted images and
+    * other image types that don't need a full alpha channel.  There are
+    * "num_trans" transparency values for a paletted image, stored in the
+    * same order as the palette colors, starting from index 0.  Values
+    * for the data are in the range [0, 255], ranging from fully transparent
+    * to fully opaque, respectively.  For non-paletted images, there is a
+    * single color specified that should be treated as fully transparent.
+    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+    */
+   png_bytep trans PNG_DEPSTRUCT; /* transparent values for paletted image */
+   png_color_16 trans_values PNG_DEPSTRUCT; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The bKGD chunk gives the suggested image background color if the
+    * display program does not have its own background color and the image
+    * is needs to composited onto a background before display.  The colors
+    * in "background" are normally in the same color space/depth as the
+    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+    */
+   png_color_16 background PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+    * and downwards from the top-left corner of the display, page, or other
+    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
+    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
+    */
+   png_int_32 x_offset PNG_DEPSTRUCT; /* x offset on page */
+   png_int_32 y_offset PNG_DEPSTRUCT; /* y offset on page */
+   png_byte offset_unit_type PNG_DEPSTRUCT; /* offset units type */
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+   /* The pHYs chunk gives the physical pixel density of the image for
+    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+    */
+   png_uint_32 x_pixels_per_unit PNG_DEPSTRUCT; /* horizontal pixel density */
+   png_uint_32 y_pixels_per_unit PNG_DEPSTRUCT; /* vertical pixel density */
+   png_byte phys_unit_type PNG_DEPSTRUCT; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+   /* The hIST chunk contains the relative frequency or importance of the
+    * various palette entries, so that a viewer can intelligently select a
+    * reduced-color palette, if required.  Data is an array of "num_palette"
+    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+    * is non-zero.
+    */
+   png_uint_16p hist PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+   /* The cHRM chunk describes the CIE color characteristics of the monitor
+    * on which the PNG was created.  This data allows the viewer to do gamut
+    * mapping of the input image to ensure that the viewer sees the same
+    * colors in the image as the creator.  Values are in the range
+    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
+    */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float x_white PNG_DEPSTRUCT;
+   float y_white PNG_DEPSTRUCT;
+   float x_red PNG_DEPSTRUCT;
+   float y_red PNG_DEPSTRUCT;
+   float x_green PNG_DEPSTRUCT;
+   float y_green PNG_DEPSTRUCT;
+   float x_blue PNG_DEPSTRUCT;
+   float y_blue PNG_DEPSTRUCT;
+#endif
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+   /* The pCAL chunk describes a transformation between the stored pixel
+    * values and original physical data values used to create the image.
+    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+    * range given by [pcal_X0, pcal_X1], and are further transformed by a
+    * (possibly non-linear) transformation function given by "pcal_type"
+    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
+    * defines below, and the PNG-Group's PNG extensions document for a
+    * complete description of the transformations and how they should be
+    * implemented, and for a description of the ASCII parameter strings.
+    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+    */
+   png_charp pcal_purpose PNG_DEPSTRUCT;  /* pCAL chunk description string */
+   png_int_32 pcal_X0 PNG_DEPSTRUCT;      /* minimum value */
+   png_int_32 pcal_X1 PNG_DEPSTRUCT;      /* maximum value */
+   png_charp pcal_units PNG_DEPSTRUCT;    /* Latin-1 string giving physical units */
+   png_charpp pcal_params PNG_DEPSTRUCT;  /* ASCII strings containing parameter values */
+   png_byte pcal_type PNG_DEPSTRUCT;      /* equation type (see PNG_EQUATION_ below) */
+   png_byte pcal_nparams PNG_DEPSTRUCT;   /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me PNG_DEPSTRUCT;     /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+   /* Storage for unknown chunks that the library doesn't recognize. */
+   png_unknown_chunkp unknown_chunks PNG_DEPSTRUCT;
+   png_size_t unknown_chunks_num PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+   /* iCCP chunk data. */
+   png_charp iccp_name PNG_DEPSTRUCT;     /* profile name */
+   png_charp iccp_profile PNG_DEPSTRUCT;  /* International Color Consortium profile data */
+                            /* Note to maintainer: should be png_bytep */
+   png_uint_32 iccp_proflen PNG_DEPSTRUCT;  /* ICC profile data length */
+   png_byte iccp_compression PNG_DEPSTRUCT; /* Always zero */
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+   /* Data on sPLT chunks (there may be more than one). */
+   png_sPLT_tp splt_palettes PNG_DEPSTRUCT;
+   png_uint_32 splt_palettes_num PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+   /* The sCAL chunk describes the actual physical dimensions of the
+    * subject matter of the graphic.  The chunk contains a unit specification
+    * a byte value, and two ASCII strings representing floating-point
+    * values.  The values are width and height corresponsing to one pixel
+    * in the image.  This external representation is converted to double
+    * here.  Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+    */
+   png_byte scal_unit PNG_DEPSTRUCT;         /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double scal_pixel_width PNG_DEPSTRUCT;    /* width of one pixel */
+   double scal_pixel_height PNG_DEPSTRUCT;   /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp scal_s_width PNG_DEPSTRUCT;     /* string containing height */
+   png_charp scal_s_height PNG_DEPSTRUCT;    /* string containing width */
+#endif
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+   png_bytepp row_pointers PNG_DEPSTRUCT;        /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+   png_fixed_point int_gamma PNG_DEPSTRUCT; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+   png_fixed_point int_x_white PNG_DEPSTRUCT;
+   png_fixed_point int_y_white PNG_DEPSTRUCT;
+   png_fixed_point int_x_red PNG_DEPSTRUCT;
+   png_fixed_point int_y_red PNG_DEPSTRUCT;
+   png_fixed_point int_x_green PNG_DEPSTRUCT;
+   png_fixed_point int_y_green PNG_DEPSTRUCT;
+   png_fixed_point int_x_blue PNG_DEPSTRUCT;
+   png_fixed_point int_y_blue PNG_DEPSTRUCT;
+#endif
+
+} png_info;
+
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
+#define PNG_MAX_UINT PNG_UINT_31_MAX
+#endif
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE    1
+#define PNG_COLOR_MASK_COLOR      2
+#define PNG_COLOR_MASK_ALPHA      4
+
+/* color types.  Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type.  These values should NOT be changed. */
+#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST        2 /* Not a valid value */
+
+/* These are for the oFFs chunk.  These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST           2 /* Not a valid value */
+
+/* These are for the pCAL chunk.  These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST         4 /* Not a valid value */
+
+/* These are for the sCAL chunk.  These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER           1 /* meters per pixel */
+#define PNG_SCALE_RADIAN          2 /* radians per pixel */
+#define PNG_SCALE_LAST            3 /* Not a valid value */
+
+/* These are for the pHYs chunk.  These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER      1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
+
+/* These are for the sRGB chunk.  These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE   1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE   3
+#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH     79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH    256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file.  The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L  /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row.  It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+   png_uint_32 width; /* width of row */
+   png_uint_32 rowbytes; /* number of bytes in row */
+   png_byte color_type; /* color type of row */
+   png_byte bit_depth; /* bit depth of row */
+   png_byte channels; /* number of channels (1, 2, 3, or 4) */
+   png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own.  The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+   int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+   png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
+    png_row_infop, png_bytep));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
+#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
+#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
+#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
+#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
+#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
+#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
+#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only, deprecated */
+/* Added to libpng-1.2.34 */
+#define PNG_TRANSFORM_STRIP_FILLER_BEFORE 0x0800  /* write only */
+#define PNG_TRANSFORM_STRIP_FILLER_AFTER  0x1000  /* write only */
+/* Added to libpng-1.2.41 */
+#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
+#define PNG_FLAG_MNG_FILTER_64      0x04
+#define PNG_ALL_MNG_FEATURES        0x05
+
+typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf jmpbuf;            /* used in png_error */
+#endif
+   png_error_ptr error_fn PNG_DEPSTRUCT;    /* function for printing errors and aborting */
+   png_error_ptr warning_fn PNG_DEPSTRUCT;  /* function for printing warnings */
+   png_voidp error_ptr PNG_DEPSTRUCT;       /* user supplied struct for error functions */
+   png_rw_ptr write_data_fn PNG_DEPSTRUCT;  /* function for writing output data */
+   png_rw_ptr read_data_fn PNG_DEPSTRUCT;   /* function for reading input data */
+   png_voidp io_ptr PNG_DEPSTRUCT;          /* ptr to application struct for I/O functions */
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   png_user_transform_ptr read_user_transform_fn PNG_DEPSTRUCT; /* user read transform */
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   png_user_transform_ptr write_user_transform_fn PNG_DEPSTRUCT; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp user_transform_ptr PNG_DEPSTRUCT; /* user supplied struct for user transform */
+   png_byte user_transform_depth PNG_DEPSTRUCT;    /* bit depth of user transformed pixels */
+   png_byte user_transform_channels PNG_DEPSTRUCT; /* channels in user transformed pixels */
+#endif
+#endif
+
+   png_uint_32 mode PNG_DEPSTRUCT;          /* tells us where we are in the PNG file */
+   png_uint_32 flags PNG_DEPSTRUCT;         /* flags indicating various things to libpng */
+   png_uint_32 transformations PNG_DEPSTRUCT; /* which transformations to perform */
+
+   z_stream zstream PNG_DEPSTRUCT;          /* pointer to decompression structure (below) */
+   png_bytep zbuf PNG_DEPSTRUCT;            /* buffer for zlib */
+   png_size_t zbuf_size PNG_DEPSTRUCT;      /* size of zbuf */
+   int zlib_level PNG_DEPSTRUCT;            /* holds zlib compression level */
+   int zlib_method PNG_DEPSTRUCT;           /* holds zlib compression method */
+   int zlib_window_bits PNG_DEPSTRUCT;      /* holds zlib compression window bits */
+   int zlib_mem_level PNG_DEPSTRUCT;        /* holds zlib compression memory level */
+   int zlib_strategy PNG_DEPSTRUCT;         /* holds zlib compression strategy */
+
+   png_uint_32 width PNG_DEPSTRUCT;         /* width of image in pixels */
+   png_uint_32 height PNG_DEPSTRUCT;        /* height of image in pixels */
+   png_uint_32 num_rows PNG_DEPSTRUCT;      /* number of rows in current pass */
+   png_uint_32 usr_width PNG_DEPSTRUCT;     /* width of row at start of write */
+   png_uint_32 rowbytes PNG_DEPSTRUCT;      /* size of row in bytes */
+#if 0 /* Replaced with the following in libpng-1.2.43 */
+   png_size_t irowbytes PNG_DEPSTRUCT;
+#endif
+/* Added in libpng-1.2.43 */
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
+    * chunks that can be stored (0 means unlimited).
+    */
+   png_uint_32 user_chunk_cache_max PNG_DEPSTRUCT;
+#endif
+   png_uint_32 iwidth PNG_DEPSTRUCT;        /* width of current interlaced row in pixels */
+   png_uint_32 row_number PNG_DEPSTRUCT;    /* current row in interlace pass */
+   png_bytep prev_row PNG_DEPSTRUCT;        /* buffer to save previous (unfiltered) row */
+   png_bytep row_buf PNG_DEPSTRUCT;         /* buffer to save current (unfiltered) row */
+#ifndef PNG_NO_WRITE_FILTER
+   png_bytep sub_row PNG_DEPSTRUCT;         /* buffer to save "sub" row when filtering */
+   png_bytep up_row PNG_DEPSTRUCT;          /* buffer to save "up" row when filtering */
+   png_bytep avg_row PNG_DEPSTRUCT;         /* buffer to save "avg" row when filtering */
+   png_bytep paeth_row PNG_DEPSTRUCT;       /* buffer to save "Paeth" row when filtering */
+#endif
+   png_row_info row_info PNG_DEPSTRUCT;     /* used for transformation routines */
+
+   png_uint_32 idat_size PNG_DEPSTRUCT;     /* current IDAT size for read */
+   png_uint_32 crc PNG_DEPSTRUCT;           /* current chunk CRC value */
+   png_colorp palette PNG_DEPSTRUCT;        /* palette from the input file */
+   png_uint_16 num_palette PNG_DEPSTRUCT;   /* number of color entries in palette */
+   png_uint_16 num_trans PNG_DEPSTRUCT;     /* number of transparency values */
+   png_byte chunk_name[5] PNG_DEPSTRUCT;    /* null-terminated name of current chunk */
+   png_byte compression PNG_DEPSTRUCT;      /* file compression type (always 0) */
+   png_byte filter PNG_DEPSTRUCT;           /* file filter type (always 0) */
+   png_byte interlaced PNG_DEPSTRUCT;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+   png_byte pass PNG_DEPSTRUCT;             /* current interlace pass (0 - 6) */
+   png_byte do_filter PNG_DEPSTRUCT;        /* row filter flags (see PNG_FILTER_ below ) */
+   png_byte color_type PNG_DEPSTRUCT;       /* color type of file */
+   png_byte bit_depth PNG_DEPSTRUCT;        /* bit depth of file */
+   png_byte usr_bit_depth PNG_DEPSTRUCT;    /* bit depth of users row */
+   png_byte pixel_depth PNG_DEPSTRUCT;      /* number of bits per pixel */
+   png_byte channels PNG_DEPSTRUCT;         /* number of channels in file */
+   png_byte usr_channels PNG_DEPSTRUCT;     /* channels at start of write */
+   png_byte sig_bytes PNG_DEPSTRUCT;        /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+   png_byte filler PNG_DEPSTRUCT;           /* filler byte for pixel expansion */
+#else
+   png_uint_16 filler PNG_DEPSTRUCT;           /* filler bytes for pixel expansion */
+#endif
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+   png_byte background_gamma_type PNG_DEPSTRUCT;
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+   float background_gamma PNG_DEPSTRUCT;
+#  endif
+   png_color_16 background PNG_DEPSTRUCT;   /* background color in screen gamma space */
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_color_16 background_1 PNG_DEPSTRUCT; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_flush_ptr output_flush_fn PNG_DEPSTRUCT; /* Function for flushing output */
+   png_uint_32 flush_dist PNG_DEPSTRUCT;    /* how many rows apart to flush, 0 - no flush */
+   png_uint_32 flush_rows PNG_DEPSTRUCT;    /* number of rows written since last flush */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   int gamma_shift PNG_DEPSTRUCT;      /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float gamma PNG_DEPSTRUCT;          /* file gamma value */
+   float screen_gamma PNG_DEPSTRUCT;   /* screen gamma value (display_exponent) */
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep gamma_table PNG_DEPSTRUCT;     /* gamma table for 8-bit depth files */
+   png_bytep gamma_from_1 PNG_DEPSTRUCT;    /* converts from 1.0 to screen */
+   png_bytep gamma_to_1 PNG_DEPSTRUCT;      /* converts from file to 1.0 */
+   png_uint_16pp gamma_16_table PNG_DEPSTRUCT; /* gamma table for 16-bit depth files */
+   png_uint_16pp gamma_16_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */
+   png_uint_16pp gamma_16_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+   png_color_8 sig_bit PNG_DEPSTRUCT;       /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+   png_color_8 shift PNG_DEPSTRUCT;         /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep trans PNG_DEPSTRUCT;           /* transparency values for paletted files */
+   png_color_16 trans_values PNG_DEPSTRUCT; /* transparency values for non-paletted files */
+#endif
+
+   png_read_status_ptr read_row_fn PNG_DEPSTRUCT;   /* called after each row is decoded */
+   png_write_status_ptr write_row_fn PNG_DEPSTRUCT; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_progressive_info_ptr info_fn PNG_DEPSTRUCT; /* called after header data fully read */
+   png_progressive_row_ptr row_fn PNG_DEPSTRUCT;   /* called after each prog. row is decoded */
+   png_progressive_end_ptr end_fn PNG_DEPSTRUCT;   /* called after image is complete */
+   png_bytep save_buffer_ptr PNG_DEPSTRUCT;        /* current location in save_buffer */
+   png_bytep save_buffer PNG_DEPSTRUCT;            /* buffer for previously read data */
+   png_bytep current_buffer_ptr PNG_DEPSTRUCT;     /* current location in current_buffer */
+   png_bytep current_buffer PNG_DEPSTRUCT;         /* buffer for recently used data */
+   png_uint_32 push_length PNG_DEPSTRUCT;          /* size of current input chunk */
+   png_uint_32 skip_length PNG_DEPSTRUCT;          /* bytes to skip in input data */
+   png_size_t save_buffer_size PNG_DEPSTRUCT;      /* amount of data now in save_buffer */
+   png_size_t save_buffer_max PNG_DEPSTRUCT;       /* total size of save_buffer */
+   png_size_t buffer_size PNG_DEPSTRUCT;           /* total amount of available input data */
+   png_size_t current_buffer_size PNG_DEPSTRUCT;   /* amount of data now in current_buffer */
+   int process_mode PNG_DEPSTRUCT;                 /* what push library is currently doing */
+   int cur_palette PNG_DEPSTRUCT;                  /* current push library palette index */
+
+#  ifdef PNG_TEXT_SUPPORTED
+     png_size_t current_text_size PNG_DEPSTRUCT;   /* current size of text input data */
+     png_size_t current_text_left PNG_DEPSTRUCT;   /* how much text left to read in input */
+     png_charp current_text PNG_DEPSTRUCT;         /* current text chunk buffer */
+     png_charp current_text_ptr PNG_DEPSTRUCT;     /* current location in current_text */
+#  endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+   png_bytepp offset_table_ptr PNG_DEPSTRUCT;
+   png_bytep offset_table PNG_DEPSTRUCT;
+   png_uint_16 offset_table_number PNG_DEPSTRUCT;
+   png_uint_16 offset_table_count PNG_DEPSTRUCT;
+   png_uint_16 offset_table_count_free PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+   png_bytep palette_lookup PNG_DEPSTRUCT;         /* lookup table for dithering */
+   png_bytep dither_index PNG_DEPSTRUCT;           /* index translation for palette files */
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
+   png_uint_16p hist PNG_DEPSTRUCT;                /* histogram */
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   png_byte heuristic_method PNG_DEPSTRUCT;        /* heuristic for row filter selection */
+   png_byte num_prev_filters PNG_DEPSTRUCT;        /* number of weights for previous rows */
+   png_bytep prev_filters PNG_DEPSTRUCT;           /* filter type(s) of previous row(s) */
+   png_uint_16p filter_weights PNG_DEPSTRUCT;      /* weight(s) for previous line(s) */
+   png_uint_16p inv_filter_weights PNG_DEPSTRUCT;  /* 1/weight(s) for previous line(s) */
+   png_uint_16p filter_costs PNG_DEPSTRUCT;        /* relative filter calculation cost */
+   png_uint_16p inv_filter_costs PNG_DEPSTRUCT;    /* 1/relative filter calculation cost */
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+   png_charp time_buffer PNG_DEPSTRUCT;            /* String to hold RFC 1123 time text */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_uint_32 free_me PNG_DEPSTRUCT;   /* flags items libpng is responsible for freeing */
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+   png_voidp user_chunk_ptr PNG_DEPSTRUCT;
+   png_user_chunk_ptr read_user_chunk_fn PNG_DEPSTRUCT; /* user read chunk handler */
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   int num_chunk_list PNG_DEPSTRUCT;
+   png_bytep chunk_list PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.0.3 */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   png_byte rgb_to_gray_status PNG_DEPSTRUCT;
+   /* These were changed from png_byte in libpng-1.0.6 */
+   png_uint_16 rgb_to_gray_red_coeff PNG_DEPSTRUCT;
+   png_uint_16 rgb_to_gray_green_coeff PNG_DEPSTRUCT;
+   png_uint_16 rgb_to_gray_blue_coeff PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+    defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Changed from png_byte to png_uint_32 at version 1.2.0 */
+#ifdef PNG_1_0_X
+   png_byte mng_features_permitted PNG_DEPSTRUCT;
+#else
+   png_uint_32 mng_features_permitted PNG_DEPSTRUCT;
+#endif /* PNG_1_0_X */
+#endif
+
+/* New member added in libpng-1.0.7 */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_fixed_point int_gamma PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_byte filter_type PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_1_0_X
+/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
+   png_uint_32 row_buf_size PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.2.0 */
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#  ifndef PNG_1_0_X
+#    ifdef PNG_MMX_CODE_SUPPORTED
+   png_byte     mmx_bitdepth_threshold PNG_DEPSTRUCT;
+   png_uint_32  mmx_rowbytes_threshold PNG_DEPSTRUCT;
+#    endif
+   png_uint_32  asm_flags PNG_DEPSTRUCT;
+#  endif
+#endif
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_voidp mem_ptr PNG_DEPSTRUCT;            /* user supplied struct for mem functions */
+   png_malloc_ptr malloc_fn PNG_DEPSTRUCT;     /* function for allocating memory */
+   png_free_ptr free_fn PNG_DEPSTRUCT;         /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+   png_bytep big_row_buf PNG_DEPSTRUCT;        /* buffer to save current (unfiltered) row */
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+   png_bytep dither_sort PNG_DEPSTRUCT;        /* working sort array */
+   png_bytep index_to_palette PNG_DEPSTRUCT;   /* where the original index currently is */
+                                 /* in the palette */
+   png_bytep palette_to_index PNG_DEPSTRUCT;   /* which original index points to this */
+                                 /* palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+   png_byte compression_type PNG_DEPSTRUCT;
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   png_uint_32 user_width_max PNG_DEPSTRUCT;
+   png_uint_32 user_height_max PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+   /* Storage for unknown chunk that the library doesn't recognize. */
+   png_unknown_chunk unknown_chunk PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.2.26 */
+  png_uint_32 old_big_row_buf_size PNG_DEPSTRUCT;
+  png_uint_32 old_prev_row_size PNG_DEPSTRUCT;
+
+/* New member added in libpng-1.2.30 */
+  png_charp chunkdata PNG_DEPSTRUCT;  /* buffer for reading chunk data */
+
+
+};
+
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef png_structp version_1_2_44;
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used.  This is not
+ * the place to find out how to use libpng.  See libpng.txt for the
+ * full explanation, see example.c for the summary.  This just provides
+ * a simple one line description of the use of each function.
+ */
+
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+   int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise.  Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+   png_size_t num_to_check));
+
+/* Simple signature checking function.  This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)) PNG_DEPRECATED;
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED;
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED;
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+   PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+   PNGARG((png_structp png_ptr, png_uint_32 size));
+#endif
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_structp,png_create_read_struct_2)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED;
+extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+   PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED;
+#endif
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+   PNGARG((png_structp png_ptr)) PNG_ALLOCATED;
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize the info structure (old interface - DEPRECATED) */
+extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr))
+    PNG_DEPRECATED;
+#undef png_info_init
+#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
+    png_sizeof(png_info));
+#endif
+
+extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+    png_size_t png_info_struct_size));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+   PNGARG((png_structp png_ptr, png_timep ptime));
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* Convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+   struct tm FAR * ttime));
+
+/* Convert from time_t to png_time.  Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+   time_t ttime));
+#endif /* PNG_CONVERT_tIME_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+#ifndef PNG_1_0_X
+extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
+  png_ptr));
+#endif
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated */
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp
+    png_ptr)) PNG_DEPRECATED;
+#endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand the grayscale to 24-bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
+   int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+   int error_action, png_fixed_point red, png_fixed_point green ));
+extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
+   png_ptr));
+#endif
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+   png_colorp palette));
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+   png_uint_32 filler, int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+#ifndef PNG_1_0_X
+extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
+   png_uint_32 filler, int flags));
+#endif
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+   png_color_8p true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing.  Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma));
+#endif
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN  1
+#define PNG_BACKGROUND_GAMMA_FILE    2
+#define PNG_BACKGROUND_GAMMA_UNIQUE  3
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Strip the second byte of information from a 16-bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette, int maximum_colors,
+   png_uint_16p histogram, int full_dither));
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+   double screen_gamma, double default_file_gamma));
+#endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed.  Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+   int empty_plte_permitted)) PNG_DEPRECATED;
+#endif
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif
+
+/* Optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* Optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. */
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read a row of data. */
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+   png_bytep row,
+   png_bytep display_row));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+#endif
+
+/* Write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+   png_bytep row));
+
+/* Write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_uint_32 num_rows));
+
+/* Write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+
+/* Writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+/* Free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+   png_infopp info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+   png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* Free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_infop end_info_ptr)) PNG_DEPRECATED;
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+   PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr)) PNG_DEPRECATED;
+
+/* Set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+   int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein.  Note that it is impossible to "discard" data in a critical
+ * chunk.  For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard.  These values should NOT be changed.
+ *
+ *      value                       action:critical     action:ancillary
+ */
+#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
+#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
+#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
+#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
+#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
+#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib.  These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them.  See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* Set the filtering method(s) used by libpng.  Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+   int filters));
+
+/* Flags for png_set_filter() to say which filters to use.  The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS     0x00
+#define PNG_FILTER_NONE    0x08
+#define PNG_FILTER_SUB     0x10
+#define PNG_FILTER_UP      0x20
+#define PNG_FILTER_AVG     0x40
+#define PNG_FILTER_PAETH   0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE  0
+#define PNG_FILTER_VALUE_SUB   1
+#define PNG_FILTER_VALUE_UP    2
+#define PNG_FILTER_VALUE_AVG   3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST  5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows.  Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters.  This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified.  Weights have no influence on
+ * the selection of the first row filter.  Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type.  Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs.  There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs.  Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found.  If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+   int heuristic_method, int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs));
+#endif
+#endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection.  These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
+
+/* Set the library compression level.  Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression).  Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations.  In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+   int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+   PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+   PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+   PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+   int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf().  These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn().  See libpng.txt for
+ * more information.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions.  If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling.  If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+   png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ * It is probably a mistake to use NULL for output_flush_fn if
+ * write_data_fn is not also NULL unless you have built libpng with
+ * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
+ * default flush function, which uses the standard *FILE structure, will
+ * be used.
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+   png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+   png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
+   png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+   png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+   int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+   PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+   png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+   png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn));
+
+/* Returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+   PNGARG((png_structp png_ptr));
+
+/* Function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* Function that combines rows.  Not very much different than the
+ * png_combine_row() call.  Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+   png_uint_32 size)) PNG_ALLOCATED;
+
+#ifdef PNG_1_0_X
+#  define png_malloc_warn png_malloc
+#else
+/* Added at libpng version 1.2.4 */
+extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+   png_uint_32 size)) PNG_ALLOCATED;
+#endif
+
+/* Frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+#ifdef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
+   uInt size));
+
+/* Function to free memory for zlib */
+extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
+#endif
+
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application
+ */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int freer, png_uint_32 mask));
+#endif
+/* Assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL  0x7fff
+#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
+   png_uint_32 size)) PNG_ALLOCATED;
+extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+   png_voidp ptr));
+#endif
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, png_voidp s2, png_uint_32 size)) PNG_DEPRECATED;
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, int value, png_uint_32 size)) PNG_DEPRECATED;
+
+#if defined(USE_FAR_KEYWORD)  /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+   int check));
+#endif /* USE_FAR_KEYWORD */
+
+#ifndef PNG_NO_ERROR_TEXT
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+   png_const_charp error_message)) PNG_NORETURN;
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+   png_const_charp error_message)) PNG_NORETURN;
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN;
+#endif
+
+#ifndef PNG_NO_WARNINGS
+/* Non-fatal error in libpng.  Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+   png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+   png_const_charp warning_message));
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_NO_WARNINGS */
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored.  The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+ * returned from png_read_png().
+ */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+ * by png_write_png().
+ */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+#endif
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_bKGD_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p *background));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p background));
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+   double *red_y, double *green_x, double *green_y, double *blue_x,
+   double *blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+   *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+   png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+   *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double white_x, double white_y, double red_x,
+   double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y));
+#endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *file_gamma));
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double file_gamma));
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p *hist));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p hist));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+   int *bit_depth, int *color_type, int *interlace_method,
+   int *compression_method, int *filter_method));
+
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_method, int compression_method,
+   int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+   int *unit_type));
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+   int unit_type));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+   int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+   int type, int nparams, png_charp units, png_charpp params));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp palette, int num_palette));
+
+#ifdef PNG_sBIT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p *sig_bit));
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p sig_bit));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *intent));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charpp name, int *compression_type,
+   png_charpp profile, png_uint_32 *proflen));
+   /* Note to maintainer: profile should be png_bytepp */
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp name, int compression_type,
+   png_charp profile, png_uint_32 proflen));
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_get_text also returns the number of text chunks in *num_text */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/*
+ *  Note while png_set_text() will accept a structure whose text,
+ *  language, and  translated keywords are NULL pointers, the structure
+ *  returned by png_get_text will always contain regular
+ *  zero-terminated C strings.  They might be empty strings but
+ *  they will never be NULL pointers.
+ */
+
+#ifdef PNG_TEXT_SUPPORTED
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep *mod_time));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep mod_time));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep *trans, int *num_trans,
+   png_color_16p *trans_values));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep trans, int num_trans,
+   png_color_16p trans_values));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED */
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+/* Provide a list of chunks and how they are to be handled, if the built-in
+   handling or default unknown chunk handling is not desired.  Any chunks not
+   listed will be handled in the default manner.  The IHDR and IEND chunks
+   must not be listed.
+      keep = 0: follow default behaviour
+           = 1: do not keep
+           = 2: keep only if safe-to-copy
+           = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+   png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
+   chunk_name));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+   PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+   png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ * If you need to turn it off for a chunk that your application has freed,
+ * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+ */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int mask));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+                        png_infop info_ptr,
+                        int transforms,
+                        png_voidp params));
+#endif
+
+/* Define PNG_DEBUG at compile time for debugging information.  Higher
+ * numbers for PNG_DEBUG mean more debugging information.  This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#ifdef PNG_DEBUG
+#if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#ifndef _DEBUG
+#  define _DEBUG
+#endif
+#ifndef png_debug
+#define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
+#endif
+#ifndef png_debug1
+#define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
+#endif
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+
+#if (PNG_DEBUG > 1)
+/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on non-ISO
+ * compilers.
+ */
+#  ifdef __STDC__
+#    ifndef png_debug
+#      define png_debug(l,m) \
+       { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+       }
+#    endif
+#    ifndef png_debug1
+#      define png_debug1(l,m,p1) \
+       { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+       }
+#    endif
+#    ifndef png_debug2
+#      define png_debug2(l,m,p1,p2) \
+       { \
+       int num_tabs=l; \
+       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+       }
+#    endif
+#  else /* __STDC __ */
+#    ifndef png_debug
+#      define png_debug(l,m) \
+       { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format); \
+       }
+#    endif
+#    ifndef png_debug1
+#      define png_debug1(l,m,p1) \
+       { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format,p1); \
+       }
+#    endif
+#    ifndef png_debug2
+#      define png_debug2(l,m,p1,p2) \
+       { \
+       int num_tabs=l; \
+       char format[256]; \
+       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+         m,PNG_STRING_NEWLINE); \
+       fprintf(PNG_DEBUG_FILE,format,p1,p2); \
+       }
+#    endif
+#  endif /* __STDC __ */
+#endif /* (PNG_DEBUG > 1) */
+
+#endif /* _MSC_VER */
+#endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#define png_debug(l, m)
+#endif
+#ifndef png_debug1
+#define png_debug1(l, m, p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l, m, p1, p2)
+#endif
+
+extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+   png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
+#define PNG_HANDLE_CHUNK_NEVER        1
+#define PNG_HANDLE_CHUNK_IF_SAFE      2
+#define PNG_HANDLE_CHUNK_ALWAYS       3
+
+/* Added to version 1.2.0 */
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifdef PNG_MMX_CODE_SUPPORTED
+#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED  0x01  /* not user-settable */
+#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU    0x02  /* not user-settable */
+#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  0x04
+#define PNG_ASM_FLAG_MMX_READ_INTERLACE    0x08
+#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB   0x10
+#define PNG_ASM_FLAG_MMX_READ_FILTER_UP    0x20
+#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG   0x40
+#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
+#define PNG_ASM_FLAGS_INITIALIZED          0x80000000  /* not user-settable */
+
+#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+                           | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+                           | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
+#define PNG_MMX_WRITE_FLAGS ( 0 )
+
+#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
+                      | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU   \
+                      | PNG_MMX_READ_FLAGS                \
+                      | PNG_MMX_WRITE_FLAGS )
+
+#define PNG_SELECT_READ   1
+#define PNG_SELECT_WRITE  2
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
+   PNGARG((int flag_select, int *compilerID));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
+   PNGARG((int flag_select));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
+   PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
+   PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
+   PNGARG((png_structp png_ptr));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_asm_flags)
+   PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_mmx_thresholds)
+   PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
+   png_uint_32 mmx_rowbytes_threshold));
+
+#endif /* PNG_1_0_X */
+
+#ifndef PNG_1_0_X
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
+#endif /* PNG_1_0_X */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler.
+ */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
+   png_ptr, png_uint_32 strip_mode));
+#endif
+
+/* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
+   png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
+extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
+   png_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
+   png_ptr));
+#endif
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and in
+ * project defs
+ */
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines.  However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems.  There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same!  128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity          */
+
+#  define png_composite(composite, fg, alpha, bg)                            \
+     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+                        +        (png_uint_16)(bg)*(png_uint_16)(255 -       \
+                        (png_uint_16)(alpha)) + (png_uint_16)128);           \
+       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+#  define png_composite_16(composite, fg, alpha, bg)                         \
+     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+                        + (png_uint_32)(bg)*(png_uint_32)(65535L -           \
+                        (png_uint_32)(alpha)) + (png_uint_32)32768L);        \
+       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else  /* Standard method using integer division */
+
+#  define png_composite(composite, fg, alpha, bg)                            \
+     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +    \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
+       (png_uint_16)127) / 255)
+
+#  define png_composite_16(composite, fg, alpha, bg)                         \
+     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) +      \
+       (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+/* Inline macros to do direct reads of bytes from the input buffer.  These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage.  I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not.  The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
+#  define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+#  define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+#  define png_get_int_32(buf)  ( *((png_int_32p)  (buf)))
+#else
+extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
+extern PNG_EXPORT(png_uint_32,png_get_uint_31)
+  PNGARG((png_structp png_ptr, png_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ */
+extern PNG_EXPORT(void,png_save_uint_32)
+   PNGARG((png_bytep buf, png_uint_32 i));
+extern PNG_EXPORT(void,png_save_int_32)
+   PNGARG((png_bytep buf, png_int_32 i));
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+extern PNG_EXPORT(void,png_save_uint_16)
+   PNGARG((png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+
+/* ************************************************************************* */
+
+/* These next functions are used internally in the code.  They generally
+ * shouldn't be used unless you are writing code to add or replace some
+ * functionality in libpng.  More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+
+/* Various modes of operation, that are visible to applications because
+ * they are used for unknown chunk location.
+ */
+#define PNG_HAVE_IHDR               0x01
+#define PNG_HAVE_PLTE               0x02
+#define PNG_HAVE_IDAT               0x04
+#define PNG_AFTER_IDAT              0x08 /* Have complete zlib datastream */
+#define PNG_HAVE_IEND               0x10
+
+#ifdef PNG_INTERNAL
+
+/* More modes of operation.  Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_HAVE_gAMA               0x20
+#define PNG_HAVE_cHRM               0x40
+#define PNG_HAVE_sRGB               0x80
+#define PNG_HAVE_CHUNK_HEADER      0x100
+#define PNG_WROTE_tIME             0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY     0x800
+#define PNG_HAVE_PNG_SIGNATURE    0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+
+/* Flags for the transformations the PNG library does on the image data */
+#define PNG_BGR                0x0001
+#define PNG_INTERLACE          0x0002
+#define PNG_PACK               0x0004
+#define PNG_SHIFT              0x0008
+#define PNG_SWAP_BYTES         0x0010
+#define PNG_INVERT_MONO        0x0020
+#define PNG_DITHER             0x0040
+#define PNG_BACKGROUND         0x0080
+#define PNG_BACKGROUND_EXPAND  0x0100
+                          /*   0x0200 unused */
+#define PNG_16_TO_8            0x0400
+#define PNG_RGBA               0x0800
+#define PNG_EXPAND             0x1000
+#define PNG_GAMMA              0x2000
+#define PNG_GRAY_TO_RGB        0x4000
+#define PNG_FILLER             0x8000L
+#define PNG_PACKSWAP          0x10000L
+#define PNG_SWAP_ALPHA        0x20000L
+#define PNG_STRIP_ALPHA       0x40000L
+#define PNG_INVERT_ALPHA      0x80000L
+#define PNG_USER_TRANSFORM   0x100000L
+#define PNG_RGB_TO_GRAY_ERR  0x200000L
+#define PNG_RGB_TO_GRAY_WARN 0x400000L
+#define PNG_RGB_TO_GRAY      0x600000L  /* two bits, RGB_TO_GRAY_ERR|WARN */
+                       /*    0x800000L     Unused */
+#define PNG_ADD_ALPHA       0x1000000L  /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS     0x2000000L  /* Added to libpng-1.2.9 */
+#define PNG_PREMULTIPLY_ALPHA 0x4000000L  /* Added to libpng-1.2.41 */
+                                          /* by volker */
+                       /*   0x8000000L  unused */
+                       /*  0x10000000L  unused */
+                       /*  0x20000000L  unused */
+                       /*  0x40000000L  unused */
+
+/* Flags for png_create_struct */
+#define PNG_STRUCT_PNG   0x0001
+#define PNG_STRUCT_INFO  0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* Flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL        0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL    0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS  0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD       0x0010
+#define PNG_FLAG_ZLIB_FINISHED            0x0020
+#define PNG_FLAG_ROW_INIT                 0x0040
+#define PNG_FLAG_FILLER_AFTER             0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
+#define PNG_FLAG_FREE_PLTE                0x1000
+#define PNG_FLAG_FREE_TRNS                0x2000
+#define PNG_FLAG_FREE_HIST                0x4000
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS       0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH         0x20000L
+#define PNG_FLAG_STRIP_ERROR_NUMBERS      0x40000L
+#define PNG_FLAG_STRIP_ERROR_TEXT         0x80000L
+#define PNG_FLAG_MALLOC_NULL_MEM_OK       0x100000L
+#define PNG_FLAG_ADD_ALPHA                0x200000L  /* Added to libpng-1.2.8 */
+#define PNG_FLAG_STRIP_ALPHA              0x400000L  /* Added to libpng-1.2.8 */
+                                  /*      0x800000L  unused */
+                                  /*     0x1000000L  unused */
+                                  /*     0x2000000L  unused */
+                                  /*     0x4000000L  unused */
+                                  /*     0x8000000L  unused */
+                                  /*    0x10000000L  unused */
+                                  /*    0x20000000L  unused */
+                                  /*    0x40000000L  unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
+                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
+                                     PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* Save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+   abs((int)((c1).green) - (int)((c2).green)) + \
+   abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+    ((pixel_bits) >= 8 ? \
+    ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
+    (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ * ideal-delta..ideal+delta.  Each argument is evaluated twice.
+ * "ideal" and "delta" should be constants, normally simple
+ * integers, "value" a variable. Added to libpng-1.2.6 JB
+ */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+        ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Place to hold the signature string for a PNG file. */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+   PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
+#else
+#endif
+#endif /* PNG_NO_EXTERN */
+
+/* Constant strings for known chunk types.  If you need to add a chunk,
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
+#define PNG_IDAT png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
+#define PNG_IEND png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
+#define PNG_PLTE png_byte png_PLTE[5] = { 80,  76,  84,  69, '\0'}
+#define PNG_bKGD png_byte png_bKGD[5] = { 98,  75,  71,  68, '\0'}
+#define PNG_cHRM png_byte png_cHRM[5] = { 99,  72,  82,  77, '\0'}
+#define PNG_gAMA png_byte png_gAMA[5] = {103,  65,  77,  65, '\0'}
+#define PNG_hIST png_byte png_hIST[5] = {104,  73,  83,  84, '\0'}
+#define PNG_iCCP png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
+#define PNG_iTXt png_byte png_iTXt[5] = {105,  84,  88, 116, '\0'}
+#define PNG_oFFs png_byte png_oFFs[5] = {111,  70,  70, 115, '\0'}
+#define PNG_pCAL png_byte png_pCAL[5] = {112,  67,  65,  76, '\0'}
+#define PNG_sCAL png_byte png_sCAL[5] = {115,  67,  65,  76, '\0'}
+#define PNG_pHYs png_byte png_pHYs[5] = {112,  72,  89, 115, '\0'}
+#define PNG_sBIT png_byte png_sBIT[5] = {115,  66,  73,  84, '\0'}
+#define PNG_sPLT png_byte png_sPLT[5] = {115,  80,  76,  84, '\0'}
+#define PNG_sRGB png_byte png_sRGB[5] = {115,  82,  71,  66, '\0'}
+#define PNG_tEXt png_byte png_tEXt[5] = {116,  69,  88, 116, '\0'}
+#define PNG_tIME png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
+#define PNG_tRNS png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
+#define PNG_zTXt png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize png_ptr struct for reading, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_read_struct instead).
+ */
+extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr))
+    PNG_DEPRECATED;
+#undef png_read_init
+#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
+    PNG_LIBPNG_VER_STRING,  png_sizeof(png_struct));
+#endif
+
+extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize png_ptr struct for writing, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_write_struct instead).
+ */
+extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr))
+    PNG_DEPRECATED;
+#undef png_write_init
+#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
+    PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
+#endif
+
+extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+    png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+    png_info_size));
+
+/* Allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type)) PNG_PRIVATE;
+
+/* Free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)) PNG_PRIVATE;
+
+PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
+  malloc_fn, png_voidp mem_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
+   png_free_ptr free_fn, png_voidp mem_ptr)) PNG_PRIVATE;
+
+/* Free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+
+#ifndef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items,
+   uInt size)) PNG_PRIVATE;
+
+/* Function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)) PNG_PRIVATE;
+
+#ifdef PNG_SIZE_T
+/* Function to convert a sizeof an item to png_sizeof item */
+   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size))
+      PNG_PRIVATE;
+#endif
+
+/* Next four functions are used internally as callbacks.  PNGAPI is required
+ * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3.
+ */
+
+PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t length)) PNG_PRIVATE;
+#endif
+
+PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr))
+   PNG_PRIVATE;
+#endif
+#endif
+#else /* PNG_1_0_X */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t length)) PNG_PRIVATE;
+#endif
+#endif /* PNG_1_0_X */
+
+/* Reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length)) PNG_PRIVATE;
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length)) PNG_PRIVATE;
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+   png_size_t length)) PNG_PRIVATE;
+
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
+    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
+   int comp_type, png_size_t chunklength,
+   png_size_t prefix_length, png_size_t *data_length)) PNG_PRIVATE;
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)
+   PNG_PRIVATE);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Calculate the CRC over a section of data.  Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+   png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* Simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+   png_uint_32 height,
+   int bit_depth, int color_type, int compression_method, int filter_method,
+   int interlace_method)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+   png_uint_32 num_pal)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma))
+    PNG_PRIVATE;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr,
+    png_fixed_point file_gamma)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+   int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+   double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y)) PNG_PRIVATE;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+   png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+   int intent)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+   png_charp name, int compression_type,
+   png_charp profile, int proflen)) PNG_PRIVATE;
+   /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+   png_sPLT_tp palette)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+   png_color_16p values, int number, int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+   png_color_16p values, int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+   int num_hist)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+   png_charp key, png_charpp new_key)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len, int compression)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+   int compression, png_charp key, png_charp lang, png_charp lang_key,
+   png_charp text)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
+PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp text_ptr, int num_text)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+   png_int_32 x_offset, png_int_32 y_offset, int unit_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+   png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+   png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+   int unit_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+   png_timep mod_time)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+   int unit, double width, double height)) PNG_PRIVATE;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+   int unit, png_charp width, png_charp height)) PNG_PRIVATE;
+#endif
+#endif
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Internal use only.   Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* Combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+   int mask)) PNG_PRIVATE;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Expand an interlaced row */
+/* OLD pre-1.0.9 interface:
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass, png_uint_32 transformations)) PNG_PRIVATE;
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass)) PNG_PRIVATE;
+#endif
+
+/* Unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+   png_row_infop row_info, png_bytep row, png_bytep prev_row,
+   int filter)) PNG_PRIVATE;
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
+   png_row_infop row_info)) PNG_PRIVATE;
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+   png_bytep filtered_row)) PNG_PRIVATE;
+/* Finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* Initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+/* Optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+
+/* These are the functions that do the transformations */
+#ifdef PNG_READ_FILLER_SUPPORTED
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 filler, png_uint_32 flags)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 flags)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
+   row_info, png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p sig_bits)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+   png_bytep row, png_bytep palette_lookup,
+    png_bytep dither_lookup)) PNG_PRIVATE;
+
+#  ifdef PNG_CORRECT_PALETTE_SUPPORTED
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette)) PNG_PRIVATE;
+#  endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info,
+    png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 bit_depth)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p bit_depth)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background,
+   png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift)) PNG_PRIVATE;
+#else
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+   png_bytep row, png_colorp palette, png_bytep trans,
+   int num_trans)) PNG_PRIVATE;
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+   png_bytep row, png_color_16p trans_value)) PNG_PRIVATE;
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* Decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+   png_bytep chunk_name)) PNG_PRIVATE;
+
+/* Handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations
+   PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_do_write_transformations
+   PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+PNG_EXTERN void png_init_read_transformations
+   PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+   png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr,
+   png_bytep row)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_read_push_finish_row
+   PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr)) PNG_PRIVATE;
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+   png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifdef PNG_MMX_CODE_SUPPORTED
+/* png.c */ /* PRIVATE */
+PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+#endif
+
+
+/* The following six functions will be exported in libpng-1.4.0. */
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif /* PNG_pHYs_SUPPORTED */
+#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* Read the chunk header (length + type name) */
+PNG_EXTERN png_uint_32 png_read_chunk_header
+   PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Added at libpng version 1.2.34 */
+#ifdef PNG_cHRM_SUPPORTED
+PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
+   png_fixed_point int_white_x, png_fixed_point int_white_y,
+   png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+   int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+   png_fixed_point int_blue_y)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+/* Added at libpng version 1.2.34 */
+PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
+   unsigned long *hi_product, unsigned long *lo_product)) PNG_PRIVATE;
+#endif
+#endif
+
+/* Added at libpng version 1.2.41 */
+PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)) PNG_PRIVATE;
+
+/* Added at libpng version 1.2.41 */
+PNG_EXTERN png_voidp png_calloc PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* Do not put anything past this line */
+#endif /* PNG_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/pngconf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/pngconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/pngconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1665 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.2.44 - June 26, 2010
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#define PNG_1_2_X
+
+/*
+ * PNG_USER_CONFIG has to be defined on the compiler command line. This
+ * includes the resource compiler for Windows DLL configurations.
+ */
+#ifdef PNG_USER_CONFIG
+#  ifndef PNG_USER_PRIVATEBUILD
+#    define PNG_USER_PRIVATEBUILD
+#  endif
+#include "pngusr.h"
+#endif
+
+/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
+#ifdef PNG_CONFIGURE_LIBPNG
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * If you create a private DLL you need to define in "pngusr.h" the followings:
+ * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
+ *        the DLL was built>
+ *  e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
+ * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
+ *        distinguish your DLL from those of the official release. These
+ *        correspond to the trailing letters that come after the version
+ *        number and must match your private DLL name>
+ *  e.g. // private DLL "libpng13gx.dll"
+ *       #define PNG_USER_DLLFNAME_POSTFIX "gx"
+ *
+ * The following macros are also at your disposal if you want to complete the
+ * DLL VERSIONINFO structure.
+ * - PNG_USER_VERSIONINFO_COMMENTS
+ * - PNG_USER_VERSIONINFO_COMPANYNAME
+ * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
+ */
+
+#ifdef __STDC__
+#ifdef SPECIALBUILD
+#  pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
+ are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
+#endif
+
+#ifdef PRIVATEBUILD
+# pragma message("PRIVATEBUILD is deprecated.\
+ Use PNG_USER_PRIVATEBUILD instead.")
+# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
+#endif
+#endif /* __STDC__ */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* End of material added to libpng-1.2.8 */
+
+/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble
+   Restored at libpng-1.2.21 */
+#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \
+    !defined(PNG_WARN_UNINITIALIZED_ROW)
+#  define PNG_WARN_UNINITIALIZED_ROW 1
+#endif
+/* End of material added at libpng-1.2.19/1.2.21 */
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk.  Make this whatever size you feel is best for your
+ * machine.  One of these will be allocated per png_struct.  When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations.  Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage.  Note that zlib allocates at least 32Kb also.  For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 8192
+#endif
+
+/* Enable if you want a write-only libpng */
+
+#ifndef PNG_NO_READ_SUPPORTED
+#  define PNG_READ_SUPPORTED
+#endif
+
+/* Enable if you want a read-only libpng */
+
+#ifndef PNG_NO_WRITE_SUPPORTED
+#  define PNG_WRITE_SUPPORTED
+#endif
+
+/* Enabled in 1.2.41. */
+#ifdef PNG_ALLOW_BENIGN_ERRORS
+#  define png_benign_error png_warning
+#  define png_chunk_benign_error png_chunk_warning
+#else
+#  ifndef PNG_BENIGN_ERRORS_SUPPORTED
+#    define png_benign_error png_error
+#    define png_chunk_benign_error png_chunk_error
+#  endif
+#endif
+
+/* Added in libpng-1.2.41 */
+#if !defined(PNG_NO_WARNINGS) && !defined(PNG_WARNINGS_SUPPORTED)
+#  define PNG_WARNINGS_SUPPORTED
+#endif
+
+#if !defined(PNG_NO_ERROR_TEXT) && !defined(PNG_ERROR_TEXT_SUPPORTED)
+#  define PNG_ERROR_TEXT_SUPPORTED
+#endif
+
+#if !defined(PNG_NO_CHECK_cHRM) && !defined(PNG_CHECK_cHRM_SUPPORTED)
+#  define PNG_CHECK_cHRM_SUPPORTED
+#endif
+
+/* Enabled by default in 1.2.0.  You can disable this if you don't need to
+ * support PNGs that are embedded in MNG datastreams
+ */
+#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
+#  ifndef PNG_MNG_FEATURES_SUPPORTED
+#    define PNG_MNG_FEATURES_SUPPORTED
+#  endif
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+#  ifndef PNG_FLOATING_POINT_SUPPORTED
+#    define PNG_FLOATING_POINT_SUPPORTED
+#  endif
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this.  While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+#  define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ *   PNG_BUILD_DLL -- building dll
+ *   PNG_USE_DLL   -- building an application, linking to dll
+ *   (no define)   -- building static library, or building an
+ *                    application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ *   PNG_BUILD_DLL -- (ignored) building the dll
+ *   (no define)   -- (ignored) building an application, linking to the dll
+ *   PNG_STATIC    -- (ignored) building the static lib, or building an
+ *                    application that links to the static lib.
+ *   ALL_STATIC    -- (ignored) building various static libs, or building an
+ *                    application that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ *
+ * Also, the precedence order is:
+ *   ALL_STATIC (since we can't #undef something outside our namespace)
+ *   PNG_BUILD_DLL
+ *   PNG_STATIC
+ *   (nothing) == PNG_USE_DLL
+ *
+ * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
+ *   of auto-import in binutils, we no longer need to worry about
+ *   __declspec(dllexport) / __declspec(dllimport) and friends.  Therefore,
+ *   we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
+ *   to __declspec() stuff.  However, we DO need to worry about
+ *   PNG_BUILD_DLL and PNG_STATIC because those change some defaults
+ *   such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
+ */
+#ifdef __CYGWIN__
+#  ifdef ALL_STATIC
+#    ifdef PNG_BUILD_DLL
+#      undef PNG_BUILD_DLL
+#    endif
+#    ifdef PNG_USE_DLL
+#      undef PNG_USE_DLL
+#    endif
+#    ifdef PNG_DLL
+#      undef PNG_DLL
+#    endif
+#    ifndef PNG_STATIC
+#      define PNG_STATIC
+#    endif
+#  else
+#    ifdef PNG_BUILD_DLL
+#      ifdef PNG_STATIC
+#        undef PNG_STATIC
+#      endif
+#      ifdef PNG_USE_DLL
+#        undef PNG_USE_DLL
+#      endif
+#      ifndef PNG_DLL
+#        define PNG_DLL
+#      endif
+#    else
+#      ifdef PNG_STATIC
+#        ifdef PNG_USE_DLL
+#          undef PNG_USE_DLL
+#        endif
+#        ifdef PNG_DLL
+#          undef PNG_DLL
+#        endif
+#      else
+#        ifndef PNG_USE_DLL
+#          define PNG_USE_DLL
+#        endif
+#        ifndef PNG_DLL
+#          define PNG_DLL
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* This protects us against compilers that run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr.  The only one currently used is stderr
+ * in png_error() and png_warning().  #defining PNG_NO_CONSOLE_IO will
+ * prevent these from being compiled and used. #defining PNG_NO_STDIO
+ * will also prevent these, plus will prevent the entire set of stdio
+ * macros and functions (FILE *, printf, etc.) from being compiled and used,
+ * unless (PNG_DEBUG > 0) has been #defined.
+ *
+ * #define PNG_NO_CONSOLE_IO
+ * #define PNG_NO_STDIO
+ */
+
+#if !defined(PNG_NO_STDIO) && !defined(PNG_STDIO_SUPPORTED)
+#  define PNG_STDIO_SUPPORTED
+#endif
+
+#ifdef _WIN32_WCE
+#  include <windows.h>
+   /* Console I/O functions are not supported on WindowsCE */
+#  define PNG_NO_CONSOLE_IO
+   /* abort() may not be supported on some/all Windows CE platforms */
+#  define PNG_ABORT() exit(-1)
+#  ifdef PNG_DEBUG
+#    undef PNG_DEBUG
+#  endif
+#endif
+
+#ifdef PNG_BUILD_DLL
+#  ifndef PNG_CONSOLE_IO_SUPPORTED
+#    ifndef PNG_NO_CONSOLE_IO
+#      define PNG_NO_CONSOLE_IO
+#    endif
+#  endif
+#endif
+
+#  ifdef PNG_NO_STDIO
+#    ifndef PNG_NO_CONSOLE_IO
+#      define PNG_NO_CONSOLE_IO
+#    endif
+#    ifdef PNG_DEBUG
+#      if (PNG_DEBUG > 0)
+#        include <stdio.h>
+#      endif
+#    endif
+#  else
+#    ifndef _WIN32_WCE
+/* "stdio.h" functions are not supported on WindowsCE */
+#      include <stdio.h>
+#    endif
+#  endif
+
+#if !(defined PNG_NO_CONSOLE_IO) && !defined(PNG_CONSOLE_IO_SUPPORTED)
+#  define PNG_CONSOLE_IO_SUPPORTED
+#endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers).  If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+#  define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+#  define PNGARG(arglist) ()
+#  ifndef PNG_TYPECAST_NULL
+#     define PNG_TYPECAST_NULL
+#  endif
+#else
+#  define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac.  Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+      defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+#    define MACOS
+#  endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+#  include <sys/types.h>
+#endif
+
+#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
+#  define PNG_SETJMP_SUPPORTED
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This is an attempt to force a single setjmp behaviour on Linux.  If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ *
+ * You can bypass this test if you know that your application uses exactly
+ * the same setjmp.h that was included when libpng was built.  Only define
+ * PNG_SKIP_SETJMP_CHECK while building your application, prior to the
+ * application's '#include "png.h"'. Don't define PNG_SKIP_SETJMP_CHECK
+ * while building a separate libpng library for general use.
+ */
+
+#  ifndef PNG_SKIP_SETJMP_CHECK
+#    ifdef __linux__
+#      ifdef _BSD_SOURCE
+#        define PNG_SAVE_BSD_SOURCE
+#        undef _BSD_SOURCE
+#      endif
+#      ifdef _SETJMP_H
+       /* If you encounter a compiler error here, see the explanation
+        * near the end of INSTALL.
+        */
+           __pngconf.h__ in libpng already includes setjmp.h;
+           __dont__ include it again.;
+#      endif
+#    endif /* __linux__ */
+#  endif /* PNG_SKIP_SETJMP_CHECK */
+
+   /* include setjmp.h for error handling */
+#  include <setjmp.h>
+
+#  ifdef __linux__
+#    ifdef PNG_SAVE_BSD_SOURCE
+#      ifndef _BSD_SOURCE
+#        define _BSD_SOURCE
+#      endif
+#      undef PNG_SAVE_BSD_SOURCE
+#    endif
+#  endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef BSD
+#  include <strings.h>
+#else
+#  include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here.  */
+#ifdef PNG_INTERNAL
+
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all.  In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here.  Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#  ifdef MACOS
+     /* We need to check that <math.h> hasn't already been included earlier
+      * as it seems it doesn't agree with <fp.h>, yet we should really use
+      * <fp.h> if possible.
+      */
+#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+#      include <fp.h>
+#    endif
+#  else
+#    include <math.h>
+#  endif
+#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+      * MATH=68881
+      */
+#    include <m68881.h>
+#  endif
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+#  define PNG_ALWAYS_EXTERN
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+#  include <mem.h>
+#  include <alloc.h>
+#endif
+
+/* I have no idea why is this necessary... */
+#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
+    defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
+#  include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets.  As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+#  define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+#  define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+#  define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway.  Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables.  Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+#  define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+#  define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+#  define PNG_CONST const
+#else
+#  define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using.  I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users.  So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled.  If
+ * your linker can't find a function, you may want to make sure the
+ * ability is defined here.  Some of these depend upon some others being
+ * defined.  I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile.  If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any features you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations.  This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt support was added.  iTXt support was turned off by default through
+ * libpng-1.2.x, to support old apps that malloc the png_text structure
+ * instead of calling png_set_text() and letting libpng malloc it.  It
+ * will be turned on by default in libpng-1.4.0.
+ */
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+#  ifndef PNG_NO_iTXt_SUPPORTED
+#    define PNG_NO_iTXt_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_iTXt
+#    define PNG_NO_READ_iTXt
+#  endif
+#  ifndef PNG_NO_WRITE_iTXt
+#    define PNG_NO_WRITE_iTXt
+#  endif
+#endif
+
+#if !defined(PNG_NO_iTXt_SUPPORTED)
+#  if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
+#    define PNG_READ_iTXt
+#  endif
+#  if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
+#    define PNG_WRITE_iTXt
+#  endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+#  define PNG_NO_FREE_ME
+#  define PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_NO_HANDLE_AS_UNKNOWN
+#  define PNG_NO_READ_USER_CHUNKS
+#  define PNG_NO_READ_iCCP
+#  define PNG_NO_WRITE_iCCP
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_READ_sCAL
+#  define PNG_NO_WRITE_sCAL
+#  define PNG_NO_READ_sPLT
+#  define PNG_NO_WRITE_sPLT
+#  define PNG_NO_INFO_IMAGE
+#  define PNG_NO_READ_RGB_TO_GRAY
+#  define PNG_NO_READ_USER_TRANSFORM
+#  define PNG_NO_WRITE_USER_TRANSFORM
+#  define PNG_NO_USER_MEM
+#  define PNG_NO_READ_EMPTY_PLTE
+#  define PNG_NO_MNG_FEATURES
+#  define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+    !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+#  define PNG_FIXED_POINT_SUPPORTED
+#endif
+
+#ifndef PNG_NO_FREE_ME
+#  define PNG_FREE_ME_SUPPORTED
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
+      !defined(PNG_NO_READ_TRANSFORMS)
+#  define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#  ifndef PNG_NO_READ_EXPAND
+#    define PNG_READ_EXPAND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SHIFT
+#    define PNG_READ_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACK
+#    define PNG_READ_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BGR
+#    define PNG_READ_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP
+#    define PNG_READ_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_PACKSWAP
+#    define PNG_READ_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT
+#    define PNG_READ_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_DITHER
+#    define PNG_READ_DITHER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_BACKGROUND
+#    define PNG_READ_BACKGROUND_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_16_TO_8
+#    define PNG_READ_16_TO_8_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_FILLER
+#    define PNG_READ_FILLER_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GAMMA
+#    define PNG_READ_GAMMA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_GRAY_TO_RGB
+#    define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_SWAP_ALPHA
+#    define PNG_READ_SWAP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_INVERT_ALPHA
+#    define PNG_READ_INVERT_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_STRIP_ALPHA
+#    define PNG_READ_STRIP_ALPHA_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_USER_TRANSFORM
+#    define PNG_READ_USER_TRANSFORM_SUPPORTED
+#  endif
+#  ifndef PNG_NO_READ_RGB_TO_GRAY
+#    define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#  endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+/* PNG_PROGRESSIVE_READ_NOT_SUPPORTED is deprecated. */
+#if !defined(PNG_NO_PROGRESSIVE_READ) && \
+ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED)  /* if you don't do progressive */
+#  define PNG_PROGRESSIVE_READ_SUPPORTED     /* reading.  This is not talking */
+#endif                               /* about interlacing capability!  You'll */
+            /* still have interlacing unless you change the following define: */
+#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
+
+/* PNG_NO_SEQUENTIAL_READ_SUPPORTED is deprecated. */
+#if !defined(PNG_NO_SEQUENTIAL_READ) && \
+    !defined(PNG_SEQUENTIAL_READ_SUPPORTED) && \
+    !defined(PNG_NO_SEQUENTIAL_READ_SUPPORTED)
+#  define PNG_SEQUENTIAL_READ_SUPPORTED
+#endif
+
+#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
+
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+#  ifndef PNG_NO_READ_COMPOSITED_NODIV  /* libpng-1.0.x misspelling */
+#    define PNG_READ_COMPOSITE_NODIV_SUPPORTED  /* well tested on Intel, SGI */
+#  endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, will be removed from version 2.0.0.
+   Use PNG_MNG_FEATURES_SUPPORTED instead. */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+#  define PNG_READ_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_READ_SUPPORTED */
+
+#ifdef PNG_WRITE_SUPPORTED
+
+# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_WRITE_TRANSFORMS)
+#  define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+#  ifndef PNG_NO_WRITE_SHIFT
+#    define PNG_WRITE_SHIFT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACK
+#    define PNG_WRITE_PACK_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_BGR
+#    define PNG_WRITE_BGR_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP
+#    define PNG_WRITE_SWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_PACKSWAP
+#    define PNG_WRITE_PACKSWAP_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_INVERT
+#    define PNG_WRITE_INVERT_SUPPORTED
+#  endif
+#  ifndef PNG_NO_WRITE_FILLER
+#    define PNG_WRITE_FILLER_SUPPORTED   /* same as WRITE_STRIP_ALPHA */
+#  endif
+#  ifndef PNG_NO_WRITE_SWAP_ALPHA
+#    define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#  endif
+#ifndef PNG_1_0_X
+#  ifndef PNG_NO_WRITE_INVERT_ALPHA
+#    define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#  endif
+#endif
+#  ifndef PNG_NO_WRITE_USER_TRANSFORM
+#    define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#  endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
+    !defined(PNG_WRITE_INTERLACING_SUPPORTED)
+#define PNG_WRITE_INTERLACING_SUPPORTED  /* not required for PNG-compliant
+                                            encoders, but can cause trouble
+                                            if left undefined */
+#endif
+
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+    !defined(PNG_WRITE_WEIGHTED_FILTER) && \
+     defined(PNG_FLOATING_POINT_SUPPORTED)
+#  define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_FLUSH
+#  define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+#  define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+#  ifndef PNG_NO_ERROR_NUMBERS
+#    define PNG_ERROR_NUMBERS_SUPPORTED
+#  endif
+#endif /* PNG_1_0_X */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#  ifndef PNG_NO_USER_TRANSFORM_PTR
+#    define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#  endif
+#endif
+
+#ifndef PNG_NO_STDIO
+#  define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
+#  define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
+ * and removed from version 1.2.20.  The following will be removed
+ * from libpng-1.4.0
+*/
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
+#  ifndef PNG_OPTIMIZED_CODE_SUPPORTED
+#    define PNG_OPTIMIZED_CODE_SUPPORTED
+#  endif
+#endif
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
+#  ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+#    define PNG_ASSEMBLER_CODE_SUPPORTED
+#  endif
+
+#  if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4)
+     /* work around 64-bit gcc compiler bugs in gcc-3.x */
+#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+#      define PNG_NO_MMX_CODE
+#    endif
+#  endif
+
+#  ifdef __APPLE__
+#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+#      define PNG_NO_MMX_CODE
+#    endif
+#  endif
+
+#  if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh))
+#    if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+#      define PNG_NO_MMX_CODE
+#    endif
+#  endif
+
+#  if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+#    define PNG_MMX_CODE_SUPPORTED
+#  endif
+
+#endif
+/* end of obsolete code to be removed from libpng-1.4.0 */
+
+/* Added at libpng-1.2.0 */
+#ifndef PNG_1_0_X
+#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
+#  define PNG_USER_MEM_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#ifndef PNG_1_0_X
+#  ifndef PNG_SET_USER_LIMITS_SUPPORTED
+#    ifndef PNG_NO_SET_USER_LIMITS
+#      define PNG_SET_USER_LIMITS_SUPPORTED
+#    endif
+#  endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.0.53 and 1.2.43 */
+#ifndef PNG_USER_LIMITS_SUPPORTED
+#  ifndef PNG_NO_USER_LIMITS
+#    define PNG_USER_LIMITS_SUPPORTED
+#  endif
+#endif
+
+/* Added at libpng-1.0.16 and 1.2.6.  To accept all valid PNGS no matter
+ * how large, set these limits to 0x7fffffffL
+ */
+#ifndef PNG_USER_WIDTH_MAX
+#  define PNG_USER_WIDTH_MAX 1000000L
+#endif
+#ifndef PNG_USER_HEIGHT_MAX
+#  define PNG_USER_HEIGHT_MAX 1000000L
+#endif
+
+/* Added at libpng-1.2.43.  To accept all valid PNGs no matter
+ * how large, set these two limits to 0.
+ */
+#ifndef PNG_USER_CHUNK_CACHE_MAX
+#  define PNG_USER_CHUNK_CACHE_MAX 0
+#endif
+
+/* Added at libpng-1.2.43 */
+#ifndef PNG_USER_CHUNK_MALLOC_MAX
+#  define PNG_USER_CHUNK_MALLOC_MAX 0
+#endif
+
+#ifndef PNG_LITERAL_SHARP
+#  define PNG_LITERAL_SHARP 0x23
+#endif
+#ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
+#  define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
+#endif
+#ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
+#  define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
+#endif
+
+/* Added at libpng-1.2.34 */
+#ifndef PNG_STRING_NEWLINE
+#define PNG_STRING_NEWLINE "\n"
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+#  ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+#    define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+#  endif
+#endif
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+#  define PNG_READ_BIG_ENDIAN_SUPPORTED
+#endif
+*/
+
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
+#if !defined(PNG_NO_POINTER_INDEXING) && \
+    !defined(PNG_POINTER_INDEXING_SUPPORTED)
+#  define PNG_POINTER_INDEXING_SUPPORTED
+#endif
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define  PNG_USELESS_TESTS_SUPPORTED
+#define  PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here.  The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#if defined(PNG_READ_SUPPORTED) && \
+    !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
+#  define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#if defined(PNG_WRITE_SUPPORTED) && \
+    !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+    !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
+#  define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+#  define PNG_NO_READ_iTXt
+#  define PNG_NO_READ_tEXt
+#  define PNG_NO_READ_zTXt
+#endif
+#ifndef PNG_NO_READ_bKGD
+#  define PNG_READ_bKGD_SUPPORTED
+#  define PNG_bKGD_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_cHRM
+#  define PNG_READ_cHRM_SUPPORTED
+#  define PNG_cHRM_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_gAMA
+#  define PNG_READ_gAMA_SUPPORTED
+#  define PNG_gAMA_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_hIST
+#  define PNG_READ_hIST_SUPPORTED
+#  define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+#  define PNG_READ_iCCP_SUPPORTED
+#  define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+#  ifndef PNG_READ_iTXt_SUPPORTED
+#    define PNG_READ_iTXt_SUPPORTED
+#  endif
+#  ifndef PNG_iTXt_SUPPORTED
+#    define PNG_iTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_READ_oFFs
+#  define PNG_READ_oFFs_SUPPORTED
+#  define PNG_oFFs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pCAL
+#  define PNG_READ_pCAL_SUPPORTED
+#  define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+#  define PNG_READ_sCAL_SUPPORTED
+#  define PNG_sCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pHYs
+#  define PNG_READ_pHYs_SUPPORTED
+#  define PNG_pHYs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sBIT
+#  define PNG_READ_sBIT_SUPPORTED
+#  define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+#  define PNG_READ_sPLT_SUPPORTED
+#  define PNG_sPLT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sRGB
+#  define PNG_READ_sRGB_SUPPORTED
+#  define PNG_sRGB_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tEXt
+#  define PNG_READ_tEXt_SUPPORTED
+#  define PNG_tEXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tIME
+#  define PNG_READ_tIME_SUPPORTED
+#  define PNG_tIME_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tRNS
+#  define PNG_READ_tRNS_SUPPORTED
+#  define PNG_tRNS_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_zTXt
+#  define PNG_READ_zTXt_SUPPORTED
+#  define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_OPT_PLTE
+#  define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif                      /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED)
+#  define PNG_READ_TEXT_SUPPORTED
+#  define PNG_TEXT_SUPPORTED
+#endif
+
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+#  define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+     defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+#  define PNG_READ_USER_CHUNKS_SUPPORTED
+#  define PNG_USER_CHUNKS_SUPPORTED
+#  ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+#    undef PNG_NO_READ_UNKNOWN_CHUNKS
+#  endif
+#  ifdef PNG_NO_HANDLE_AS_UNKNOWN
+#    undef PNG_NO_HANDLE_AS_UNKNOWN
+#  endif
+#endif
+
+#ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#    define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#  endif
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+#  define PNG_NO_WRITE_iTXt
+#  define PNG_NO_WRITE_tEXt
+#  define PNG_NO_WRITE_zTXt
+#endif
+#ifndef PNG_NO_WRITE_bKGD
+#  define PNG_WRITE_bKGD_SUPPORTED
+#  ifndef PNG_bKGD_SUPPORTED
+#    define PNG_bKGD_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_cHRM
+#  define PNG_WRITE_cHRM_SUPPORTED
+#  ifndef PNG_cHRM_SUPPORTED
+#    define PNG_cHRM_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_gAMA
+#  define PNG_WRITE_gAMA_SUPPORTED
+#  ifndef PNG_gAMA_SUPPORTED
+#    define PNG_gAMA_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_hIST
+#  define PNG_WRITE_hIST_SUPPORTED
+#  ifndef PNG_hIST_SUPPORTED
+#    define PNG_hIST_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+#  define PNG_WRITE_iCCP_SUPPORTED
+#  ifndef PNG_iCCP_SUPPORTED
+#    define PNG_iCCP_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+#  ifndef PNG_WRITE_iTXt_SUPPORTED
+#    define PNG_WRITE_iTXt_SUPPORTED
+#  endif
+#  ifndef PNG_iTXt_SUPPORTED
+#    define PNG_iTXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_oFFs
+#  define PNG_WRITE_oFFs_SUPPORTED
+#  ifndef PNG_oFFs_SUPPORTED
+#    define PNG_oFFs_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_pCAL
+#  define PNG_WRITE_pCAL_SUPPORTED
+#  ifndef PNG_pCAL_SUPPORTED
+#    define PNG_pCAL_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+#  define PNG_WRITE_sCAL_SUPPORTED
+#  ifndef PNG_sCAL_SUPPORTED
+#    define PNG_sCAL_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_pHYs
+#  define PNG_WRITE_pHYs_SUPPORTED
+#  ifndef PNG_pHYs_SUPPORTED
+#    define PNG_pHYs_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sBIT
+#  define PNG_WRITE_sBIT_SUPPORTED
+#  ifndef PNG_sBIT_SUPPORTED
+#    define PNG_sBIT_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+#  define PNG_WRITE_sPLT_SUPPORTED
+#  ifndef PNG_sPLT_SUPPORTED
+#    define PNG_sPLT_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_sRGB
+#  define PNG_WRITE_sRGB_SUPPORTED
+#  ifndef PNG_sRGB_SUPPORTED
+#    define PNG_sRGB_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tEXt
+#  define PNG_WRITE_tEXt_SUPPORTED
+#  ifndef PNG_tEXt_SUPPORTED
+#    define PNG_tEXt_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tIME
+#  define PNG_WRITE_tIME_SUPPORTED
+#  ifndef PNG_tIME_SUPPORTED
+#    define PNG_tIME_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_tRNS
+#  define PNG_WRITE_tRNS_SUPPORTED
+#  ifndef PNG_tRNS_SUPPORTED
+#    define PNG_tRNS_SUPPORTED
+#  endif
+#endif
+#ifndef PNG_NO_WRITE_zTXt
+#  define PNG_WRITE_zTXt_SUPPORTED
+#  ifndef PNG_zTXt_SUPPORTED
+#    define PNG_zTXt_SUPPORTED
+#  endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_WRITE_zTXt_SUPPORTED)
+#  define PNG_WRITE_TEXT_SUPPORTED
+#  ifndef PNG_TEXT_SUPPORTED
+#    define PNG_TEXT_SUPPORTED
+#  endif
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+#  ifndef PNG_NO_CONVERT_tIME
+#    ifndef _WIN32_WCE
+/*   The "tm" structure is not supported on WindowsCE */
+#      ifndef PNG_CONVERT_tIME_SUPPORTED
+#        define PNG_CONVERT_tIME_SUPPORTED
+#      endif
+#   endif
+#  endif
+#endif
+
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+#if !defined(PNG_NO_WRITE_FILTER) && !defined(PNG_WRITE_FILTER_SUPPORTED)
+#  define PNG_WRITE_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+#  define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+#    define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#  endif
+#endif
+
+#ifndef PNG_NO_HANDLE_AS_UNKNOWN
+#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#    define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#  endif
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
+
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+#  define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
+/* Need the time information for converting tIME chunks */
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+     /* "time.h" functions are not supported on WindowsCE */
+#    include <time.h>
+#endif
+
+/* Some typedefs to get us started.  These should be safe on most of the
+ * common platforms.  The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size.  Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16.  Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t.  It is typedef'ed just in case you need it to
+   change (I'm not sure if you will or not, so I thought I'd be safe) */
+#ifdef PNG_SIZE_T
+   typedef PNG_SIZE_T png_size_t;
+#  define png_sizeof(x) png_convert_size(sizeof(x))
+#else
+   typedef size_t png_size_t;
+#  define png_sizeof(x) sizeof(x)
+#endif
+
+/* The following is needed for medium model support.  It cannot be in the
+ * PNG_INTERNAL section.  Needs modification for other compilers besides
+ * MSC.  Model independent support declares all arrays and pointers to be
+ * large using the far keyword.  The zlib version used must also support
+ * model independent data.  As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+   defines FAR. (SJT) */
+#ifdef __BORLANDC__
+#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+#    define LDATA 1
+#  else
+#    define LDATA 0
+#  endif
+   /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
+#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+#    define PNG_MAX_MALLOC_64K
+#    if (LDATA != 1)
+#      ifndef FAR
+#        define FAR __far
+#      endif
+#      define USE_FAR_KEYWORD
+#    endif   /* LDATA != 1 */
+     /* Possibly useful for moving data out of default segment.
+      * Uncomment it if you want. Could also define FARDATA as
+      * const if your compiler supports it. (SJT)
+#    define FARDATA FAR
+      */
+#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
+#endif   /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#ifdef FAR
+#  ifdef M_I86MM
+#    define USE_FAR_KEYWORD
+#    define FARDATA FAR
+#    include <dos.h>
+#  endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+#  define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+#  define FARDATA
+#endif
+
+/* Typedef for floating-point numbers that are converted
+   to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void            FAR * png_voidp;
+typedef png_byte        FAR * png_bytep;
+typedef png_uint_32     FAR * png_uint_32p;
+typedef png_int_32      FAR * png_int_32p;
+typedef png_uint_16     FAR * png_uint_16p;
+typedef png_int_16      FAR * png_int_16p;
+typedef PNG_CONST char  FAR * png_const_charp;
+typedef char            FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#ifdef _WIN32_WCE
+typedef HANDLE                png_FILE_p;
+#else
+typedef FILE                * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double          FAR * png_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte        FAR * FAR * png_bytepp;
+typedef png_uint_32     FAR * FAR * png_uint_32pp;
+typedef png_int_32      FAR * FAR * png_int_32pp;
+typedef png_uint_16     FAR * FAR * png_uint_16pp;
+typedef png_int_16      FAR * FAR * png_int_16pp;
+typedef PNG_CONST char  FAR * FAR * png_const_charpp;
+typedef char            FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double          FAR * FAR * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char            FAR * FAR * FAR * png_charppp;
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* SPC -  Is this stuff deprecated? */
+/* It'll be removed as of libpng-1.4.0 - GR-P */
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf *         png_zcharp;
+typedef charf * FAR *   png_zcharpp;
+typedef z_stream FAR *  png_zstreamp;
+#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
+
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ *   -or- if you are building an application that you want to link to the
+ *   static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ *   the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+#  define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#ifdef __CYGWIN__
+#  ifndef PNG_STATIC
+#    ifdef PNG_USE_GLOBAL_ARRAYS
+#      undef PNG_USE_GLOBAL_ARRAYS
+#    endif
+#    ifndef PNG_USE_LOCAL_ARRAYS
+#      define PNG_USE_LOCAL_ARRAYS
+#    endif
+#  else
+#    if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+#      ifdef PNG_USE_GLOBAL_ARRAYS
+#        undef PNG_USE_GLOBAL_ARRAYS
+#      endif
+#    endif
+#  endif
+#  if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#    define PNG_USE_LOCAL_ARRAYS
+#  endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+#  if defined(PNG_NO_GLOBAL_ARRAYS) || \
+      (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
+#    define PNG_USE_LOCAL_ARRAYS
+#  else
+#    define PNG_USE_GLOBAL_ARRAYS
+#  endif
+#endif
+
+#ifdef __CYGWIN__
+#  undef PNGAPI
+#  define PNGAPI __cdecl
+#  undef PNG_IMPEXP
+#  define PNG_IMPEXP
+#endif
+
+/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
+ * you may get warnings regarding the linkage of png_zalloc and png_zfree.
+ * Don't ignore those warnings; you must also reset the default calling
+ * convention in your compiler to match your PNGAPI, and you must build
+ * zlib and your applications the same way you build libpng.
+ */
+
+#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
+#  ifndef PNG_NO_MODULEDEF
+#    define PNG_NO_MODULEDEF
+#  endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+#  define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+    (( defined(_Windows) || defined(_WINDOWS) || \
+       defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
+
+#  ifndef PNGAPI
+#     if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+#        define PNGAPI __cdecl
+#     else
+#        define PNGAPI _cdecl
+#     endif
+#  endif
+
+#  if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+       0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+#     define PNG_IMPEXP
+#  endif
+
+#  ifndef PNG_IMPEXP
+
+#     define PNG_EXPORT_TYPE1(type,symbol)  PNG_IMPEXP type PNGAPI symbol
+#     define PNG_EXPORT_TYPE2(type,symbol)  type PNG_IMPEXP PNGAPI symbol
+
+      /* Borland/Microsoft */
+#     if defined(_MSC_VER) || defined(__BORLANDC__)
+#        if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+#           define PNG_EXPORT PNG_EXPORT_TYPE1
+#        else
+#           define PNG_EXPORT PNG_EXPORT_TYPE2
+#           ifdef PNG_BUILD_DLL
+#              define PNG_IMPEXP __export
+#           else
+#              define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
+                                                 VC++ */
+#           endif                             /* Exists in Borland C++ for
+                                                 C++ classes (== huge) */
+#        endif
+#     endif
+
+#     ifndef PNG_IMPEXP
+#        ifdef PNG_BUILD_DLL
+#           define PNG_IMPEXP __declspec(dllexport)
+#        else
+#           define PNG_IMPEXP __declspec(dllimport)
+#        endif
+#     endif
+#  endif  /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+#   if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+#      ifndef PNGAPI
+#         define PNGAPI _System
+#      endif
+#   else
+#      if 0 /* ... other platforms, with other meanings */
+#      endif
+#   endif
+#endif
+
+#ifndef PNGAPI
+#  define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+#  define PNG_IMPEXP
+#endif
+
+#ifdef PNG_BUILDSYMS
+#  ifndef PNG_EXPORT
+#    define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
+#  endif
+#  ifdef PNG_USE_GLOBAL_ARRAYS
+#    ifndef PNG_EXPORT_VAR
+#      define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
+#    endif
+#  endif
+#endif
+
+#ifndef PNG_EXPORT
+#  define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+#  ifndef PNG_EXPORT_VAR
+#    define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+#  endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS
+#  ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
+#    define PNG_PEDANTIC_WARNINGS_SUPPORTED
+#  endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
+/* Support for compiler specific function attributes.  These are used
+ * so that where compiler support is available incorrect use of API
+ * functions in png.h will generate compiler warnings.  Added at libpng
+ * version 1.2.41.
+ */
+#  ifdef __GNUC__
+#    ifndef PNG_USE_RESULT
+#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+#    endif
+#    ifndef PNG_NORETURN
+#      define PNG_NORETURN   __attribute__((__noreturn__))
+#    endif
+#    ifndef PNG_ALLOCATED
+#      define PNG_ALLOCATED  __attribute__((__malloc__))
+#    endif
+
+    /* This specifically protects structure members that should only be
+     * accessed from within the library, therefore should be empty during
+     * a library build.
+     */
+#    ifndef PNG_DEPRECATED
+#      define PNG_DEPRECATED __attribute__((__deprecated__))
+#    endif
+#    ifndef PNG_DEPSTRUCT
+#      define PNG_DEPSTRUCT  __attribute__((__deprecated__))
+#    endif
+#    ifndef PNG_PRIVATE
+#      if 0 /* Doesn't work so we use deprecated instead*/
+#        define PNG_PRIVATE \
+          __attribute__((warning("This function is not exported by libpng.")))
+#      else
+#        define PNG_PRIVATE \
+          __attribute__((__deprecated__))
+#      endif
+#    endif /* PNG_PRIVATE */
+#  endif /* __GNUC__ */
+#endif /* PNG_PEDANTIC_WARNINGS */
+
+#ifndef PNG_DEPRECATED
+#  define PNG_DEPRECATED  /* Use of this function is deprecated */
+#endif
+#ifndef PNG_USE_RESULT
+#  define PNG_USE_RESULT  /* The result of this function must be checked */
+#endif
+#ifndef PNG_NORETURN
+#  define PNG_NORETURN    /* This function does not return */
+#endif
+#ifndef PNG_ALLOCATED
+#  define PNG_ALLOCATED   /* The result of the function is new memory */
+#endif
+#ifndef PNG_DEPSTRUCT
+#  define PNG_DEPSTRUCT   /* Access to this struct member is deprecated */
+#endif
+#ifndef PNG_PRIVATE
+#  define PNG_PRIVATE     /* This is a private libpng function */
+#endif
+
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
+ */
+
+#ifndef PNG_ABORT
+#  define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+#  define png_jmpbuf(png_ptr) \
+   (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
+#ifdef USE_FAR_KEYWORD  /* memory model independent fns */
+/* Use this to make far-to-near assignments */
+#  define CHECK   1
+#  define NOCHECK 0
+#  define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+#  define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+#  define png_snprintf _fsnprintf   /* Added to v 1.2.19 */
+#  define png_strlen  _fstrlen
+#  define png_memcmp  _fmemcmp    /* SJT: added */
+#  define png_memcpy  _fmemcpy
+#  define png_memset  _fmemset
+#else /* Use the usual functions */
+#  define CVT_PTR(ptr)         (ptr)
+#  define CVT_PTR_NOCHECK(ptr) (ptr)
+#  ifndef PNG_NO_SNPRINTF
+#    ifdef _MSC_VER
+#      define png_snprintf _snprintf   /* Added to v 1.2.19 */
+#      define png_snprintf2 _snprintf
+#      define png_snprintf6 _snprintf
+#    else
+#      define png_snprintf snprintf   /* Added to v 1.2.19 */
+#      define png_snprintf2 snprintf
+#      define png_snprintf6 snprintf
+#    endif
+#  else
+     /* You don't have or don't want to use snprintf().  Caution: Using
+      * sprintf instead of snprintf exposes your application to accidental
+      * or malevolent buffer overflows.  If you don't have snprintf()
+      * as a general rule you should provide one (you can get one from
+      * Portable OpenSSH).
+      */
+#    define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
+#    define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
+#    define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
+        sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
+#  endif
+#  define png_strlen  strlen
+#  define png_memcmp  memcmp      /* SJT: added */
+#  define png_memcpy  memcpy
+#  define png_memset  memset
+#endif
+/* End of memory model independent support */
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+#  undef PNG_ZBUF_SIZE
+#  define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* Added at libpng-1.2.8 */
+#endif /* PNG_VERSION_INFO_ONLY */
+
+#endif /* PNGCONF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/refstr.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/refstr.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/refstr.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * refstr.h
+ *
+ * Simple reference-counted strings
+ */
+
+#ifndef REFSTR_H
+#define REFSTR_H
+
+#include <stddef.h>
+#include <stdarg.h>
+
+static inline __attribute__ ((always_inline))
+const char *refstr_get(const char *r)
+{
+    if (r)
+	((unsigned int *)r)[-1]++;
+    return r;
+}
+
+void refstr_put(const char *);
+char *refstr_alloc(size_t);
+const char *refstrdup(const char *);
+const char *refstrndup(const char *, size_t);
+int rsprintf(const char **, const char *, ...);
+int vrsprintf(const char **, const char *, va_list);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/setjmp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/setjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/setjmp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,28 @@
+/*
+ * setjmp.h
+ */
+
+#ifndef _SETJMP_H
+#define _SETJMP_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+
+#if __SIZEOF_POINTER__ == 4
+#include <klibc/i386/archsetjmp.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <klibc/x86_64/archsetjmp.h>
+#else
+#error "unsupported architecture"
+#endif
+
+__extern int setjmp(jmp_buf);
+__extern __noreturn longjmp(jmp_buf, int);
+
+typedef jmp_buf sigjmp_buf;
+
+#define sigsetjmp(__env, __save) setjmp(__env)
+#define siglongjmp(__env, __val) longjmp(__env, __val)
+
+#endif /* _SETJMP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sort.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sort.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sort.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * sort.h - Quick sort module API definitions
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#ifndef SORT_H_
+#define SORT_H_
+
+/**
+ * quick_sort - In place sort of an array of numbers.
+ * @nums: Pointer to the array
+ * @count: The number count in the array
+ */
+extern void quick_sort(int *nums, int count);
+
+#endif /* SORT_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/include/stdarg.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stdarg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stdarg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * stdarg.h
+ *
+ * This is just a wrapper for the gcc one, but defines va_copy()
+ * even if gcc doesn't.
+ */
+
+/* Note: the _STDARG_H macro belongs to the gcc header... */
+#include_next <stdarg.h>
+
+/* Older gcc considers this an extension, so it's double underbar only */
+#ifndef va_copy
+#define va_copy(d,s) __va_copy(d,s)
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/stdbool.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stdbool.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stdbool.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ *
+ * stdbool.h
+ */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
+# if !defined(__GNUC__) ||(__GNUC__ < 3)
+typedef char _Bool;		/* For C compilers without _Bool */
+# endif
+#endif
+
+#define bool  _Bool
+#define true  1
+#define false 0
+
+#else
+
+/* C++ */
+#define bool  bool
+#define true  true
+#define false false
+
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/stddef.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stddef.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ * stddef.h
+ */
+
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#ifndef __KLIBC__
+# define __KLIBC__ 1
+#endif
+
+#include <bitsize/stddef.h>
+
+#undef NULL
+#ifdef __cplusplus
+# define NULL 0
+#else
+# define NULL ((void *)0)
+#endif
+
+#undef offsetof
+#define offsetof(t,m) ((size_t)&((t *)0)->m)
+
+#undef container_of
+/*
+ * The container_of construct: if p is a pointer to member m of
+ * container class c, then return a pointer to the container of which
+ * *p is a member.
+ */
+#define container_of(p, c, m) ((c *)((char *)(p) - offsetof(c,m)))
+
+#endif /* _STDDEF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/stdint.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stdint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+/*
+ * stdint.h
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#include <bitsize/stdint.h>
+
+typedef int8_t		int_least8_t;
+typedef int16_t		int_least16_t;
+typedef int32_t		int_least32_t;
+typedef int64_t		int_least64_t;
+
+typedef uint8_t		uint_least8_t;
+typedef uint16_t	uint_least16_t;
+typedef uint32_t	uint_least32_t;
+typedef uint64_t	uint_least64_t;
+
+typedef int8_t		int_fast8_t;
+typedef int64_t		int_fast64_t;
+
+typedef uint8_t		uint_fast8_t;
+typedef uint64_t	uint_fast64_t;
+
+typedef int64_t		intmax_t;
+typedef uint64_t	uintmax_t;
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+#define INT8_MIN	(-128)
+#define INT16_MIN	(-32768)
+#define INT32_MIN	(-2147483647-1)
+#define INT64_MIN	(__INT64_C(-9223372036854775807)-1)
+
+#define INT8_MAX	(127)
+#define INT16_MAX	(32767)
+#define INT32_MAX	(2147483647)
+#define INT64_MAX	(__INT64_C(9223372036854775807))
+
+#define UINT8_MAX	(255U)
+#define UINT16_MAX	(65535U)
+#define UINT32_MAX	(4294967295U)
+#define UINT64_MAX	(__UINT64_C(18446744073709551615))
+
+#define INT_LEAST8_MIN	INT8_MIN
+#define INT_LEAST16_MIN	INT16_MIN
+#define INT_LEAST32_MIN	INT32_MIN
+#define INT_LEAST64_MIN	INT64_MIN
+
+#define INT_LEAST8_MAX	INT8_MAX
+#define INT_LEAST16_MAX	INT16_MAX
+#define INT_LEAST32_MAX	INT32_MAX
+#define INT_LEAST64_MAX	INT64_MAX
+
+#define UINT_LEAST8_MAX	 UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN	INT8_MIN
+#define INT_FAST64_MIN	INT64_MIN
+
+#define INT_FAST8_MAX	INT8_MAX
+#define INT_FAST64_MAX	INT64_MAX
+
+#define UINT_FAST8_MAX	UINT8_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTMAX_MIN	INT64_MIN
+#define INTMAX_MAX	INT64_MAX
+#define UINTMAX_MAX	UINT64_MAX
+
+#include <bitsize/stdintlimits.h>
+
+#endif
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define INT8_C(c)	c
+#define INT16_C(c)	c
+#define INT32_C(c)	c
+#define INT64_C(c)	__INT64_C(c)
+
+#define UINT8_C(c)	c ## U
+#define UINT16_C(c)	c ## U
+#define UINT32_C(c)	c ## U
+#define UINT64_C(c)	__UINT64_C(c)
+
+#define INT_LEAST8_C(c)	 INT8_C(c)
+#define INT_LEAST16_C(c) INT16_C(c)
+#define INT_LEAST32_C(c) INT32_C(c)
+#define INT_LEAST64_C(c) INT64_C(c)
+
+#define UINT_LEAST8_C(c)  UINT8_C(c)
+#define UINT_LEAST16_C(c) UINT16_C(c)
+#define UINT_LEAST32_C(c) UINT32_C(c)
+#define UINT_LEAST64_C(c) UINT64_C(c)
+
+#define INT_FAST8_C(c)	INT8_C(c)
+#define INT_FAST64_C(c) INT64_C(c)
+
+#define UINT_FAST8_C(c)  UINT8_C(c)
+#define UINT_FAST64_C(c) UINT64_C(c)
+
+#define INTMAX_C(c)	INT64_C(c)
+#define UINTMAX_C(c)	UINT64_C(c)
+
+#include <bitsize/stdintconst.h>
+
+#endif
+
+/* Keep the kernel from trying to define these types... */
+#define __BIT_TYPES_DEFINED__
+
+#endif				/* _STDINT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/stdio.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stdio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stdio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/*
+ * stdio.h
+ */
+
+#ifndef _STDIO_H
+#define _STDIO_H
+
+#include <klibc/extern.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+/* This structure doesn't really exist, but it gives us something
+   to define FILE * with */
+struct _IO_file;
+typedef struct _IO_file FILE;
+
+#ifndef EOF
+# define EOF (-1)
+#endif
+
+#ifndef BUFSIZ
+# define BUFSIZ 4096
+#endif
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+/*
+ * Convert between a FILE * and a file descriptor.  We don't actually
+ * have any in-memory data, so we just abuse the pointer itself to
+ * hold the data.  Note, however, that for file descriptors, -1 is
+ * error and 0 is a valid value; for FILE *, NULL (0) is error and
+ * non-NULL are valid.
+ */
+static __inline__ int fileno(FILE * __f)
+{
+    /* This should really be intptr_t, but size_t should be the same size */
+    return (int)(size_t) __f - 1;
+}
+
+/* This is a macro so it can be used as initializer */
+#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1))
+
+#define stdin  __create_file(0)
+#define stdout __create_file(1)
+#define stderr __create_file(2)
+
+__extern FILE *fopen(const char *, const char *);
+struct dev_info;
+__extern FILE *fopendev(const struct dev_info *, const char *);
+
+static __inline__ FILE *fdopen(int __fd, const char *__m)
+{
+    (void)__m;
+    return __create_file(__fd);
+}
+
+__extern int fclose(FILE * __f);
+__extern int fputs(const char *, FILE *);
+__extern int puts(const char *);
+__extern int fputc(int, FILE *);
+#define putc(c,f)  fputc((c),(f))
+#define putchar(c) fputc((c),stdout)
+
+__extern int fgetc(FILE *);
+__extern char *fgets(char *, int, FILE *);
+#define getc(f) fgetc(f)
+
+__extern size_t _fread(void *, size_t, FILE *);
+__extern size_t _fwrite(const void *, size_t, FILE *);
+
+__extern size_t fread(void *, size_t, size_t, FILE *);
+__extern size_t fwrite(const void *, size_t, size_t, FILE *);
+
+#ifndef __NO_FREAD_FWRITE_INLINES
+#define fread(__p, __s, __n, __f)					\
+  ( (__builtin_constant_p(__s) && __s == 1)				\
+    ? _fread(__p, __n, __f)						\
+    : fread(__p,__s,__n,__f) )
+
+#define fwrite(__p, __s, __n, __f)					\
+  ( (__builtin_constant_p(__s) && __s == 1)				\
+    ? _fwrite(__p, __n, __f)						\
+    : fwrite(__p,__s,__n,__f) )
+#endif
+
+/* No seek, but we can tell */
+__extern long ftell(FILE *);
+
+__extern int printf(const char *, ...);
+__extern int vprintf(const char *, va_list);
+__extern int fprintf(FILE *, const char *, ...);
+__extern int vfprintf(FILE *, const char *, va_list);
+__extern int sprintf(char *, const char *, ...);
+__extern int vsprintf(char *, const char *, va_list);
+__extern int snprintf(char *, size_t n, const char *, ...);
+__extern int vsnprintf(char *, size_t n, const char *, va_list);
+
+__extern int asprintf(char **, const char *, ...);
+__extern int vasprintf(char **, const char *, va_list);
+
+#define mp(f, x...) \
+        printf("[%s()]: " f "\n", __func__,##x)
+#define mpi()	mp("enter")
+#define mpo()	mp("exit")
+
+/* No buffering, so no flushing needed */
+static __inline__ int fflush(FILE * __f)
+{
+    (void)__f;
+    return 0;
+}
+
+__extern int sscanf(const char *, const char *, ...);
+__extern int vsscanf(const char *, const char *, va_list);
+
+__extern void perror(const char *);
+
+__extern int rename(const char *, const char *);
+
+/*
+ * unhexchar: Convert a hexadecimal digit to the equivalent number
+ *
+ * Returns 0 if 'data' was converted succesfully, -1 otherwise.
+ */
+static inline int unhexchar(unsigned char *data)
+{
+	unsigned char num = *data;
+
+	if (num >= '0' && num <= '9') {
+		*data = num - '0';
+		return 0;
+	} else {
+		num |= 0x20;	/* upper case -> lower case */
+		if (num >= 'a' && num <= 'f') {
+			*data = num - 'a' + 10;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+#endif /* _STDIO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/stdlib.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/stdlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/stdlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,101 @@
+/*
+ * stdlib.h
+ */
+
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+__extern __noreturn abort(void);
+static __inline__ int abs(int __n)
+{
+    return (__n < 0) ? -__n : __n;
+}
+
+__extern int atexit(void (*)(void));
+__extern int on_exit(void (*)(int, void *), void *);
+__extern int atoi(const char *);
+__extern long atol(const char *);
+__extern long long atoll(const char *);
+__extern __noreturn exit(int);
+__extern __noreturn _Exit(int);
+__extern void free(void *);
+static __inline__ long labs(long __n)
+{
+    return (__n < 0L) ? -__n : __n;
+}
+
+static __inline__ long long llabs(long long __n)
+{
+    return (__n < 0LL) ? -__n : __n;
+}
+
+__extern __mallocfunc void *malloc(size_t);
+__extern __mallocfunc void *zalloc(size_t);
+__extern __mallocfunc void *calloc(size_t, size_t);
+__extern __mallocfunc void *realloc(void *, size_t);
+__extern long strtol(const char *, char **, int);
+__extern long long strtoll(const char *, char **, int);
+__extern unsigned long strtoul(const char *, char **, int);
+__extern unsigned long long strtoull(const char *, char **, int);
+
+static __inline__ char *getenv(const char *name)
+{
+    (void)name;
+    return NULL;
+}
+
+__extern int putenv(const char *);
+__extern int setenv(const char *, const char *, int);
+__extern int unsetenv(const char *);
+
+__extern void qsort(void *, size_t, size_t,
+		    int (*)(const void *, const void *));
+
+__extern long jrand48(unsigned short *);
+__extern long mrand48(void);
+__extern long nrand48(unsigned short *);
+__extern long lrand48(void);
+__extern unsigned short *seed48(const unsigned short *);
+__extern void srand48(long);
+
+#define RAND_MAX 0x7fffffff
+static __inline__ int rand(void)
+{
+    return (int)lrand48();
+}
+
+static __inline__ void srand(unsigned int __s)
+{
+    srand48(__s);
+}
+
+static __inline__ long random(void)
+{
+    return lrand48();
+}
+
+static __inline__ void srandom(unsigned int __s)
+{
+    srand48(__s);
+}
+
+/* Basic PTY functions.  These only work if devpts is mounted! */
+
+__extern int unlockpt(int);
+__extern char *ptsname(int);
+__extern int getpt(void);
+
+static __inline__ int grantpt(int __fd)
+{
+    (void)__fd;
+    return 0;			/* devpts does this all for us! */
+}
+
+#endif /* _STDLIB_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/string.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/string.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/string.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/*
+ * string.h
+ */
+
+#ifndef _STRING_H
+#define _STRING_H
+
+#include <klibc/extern.h>
+#include <stddef.h>
+
+__extern void *memccpy(void *, const void *, int, size_t);
+__extern void *memchr(const void *, int, size_t);
+__extern int memcmp(const void *, const void *, size_t);
+__extern void *memcpy(void *, const void *, size_t);
+__extern void *mempcpy(void *, const void *, size_t);
+__extern void *memmove(void *, const void *, size_t);
+__extern void *memset(void *, int, size_t);
+__extern void *memmem(const void *, size_t, const void *, size_t);
+__extern void memswap(void *, void *, size_t);
+__extern int strcasecmp(const char *, const char *);
+__extern int strncasecmp(const char *, const char *, size_t);
+__extern char *strcat(char *, const char *);
+__extern char *strchr(const char *, int);
+__extern int strcmp(const char *, const char *);
+__extern char *strcpy(char *, const char *);
+__extern size_t strcspn(const char *, const char *);
+__extern char *strdup(const char *);
+__extern char *strndup(const char *, size_t);
+__extern char *strerror(int);
+__extern size_t strlen(const char *);
+__extern size_t strnlen(const char *, size_t);
+__extern char *strncat(char *, const char *, size_t);
+__extern size_t strlcat(char *, const char *, size_t);
+__extern int strncmp(const char *, const char *, size_t);
+__extern char *strncpy(char *, const char *, size_t);
+__extern char *stpcpy(char *, const char *);
+__extern char *stpncpy(char *, const char *, size_t);
+__extern size_t strlcpy(char *, const char *, size_t);
+__extern char *strpbrk(const char *, const char *);
+__extern char *strrchr(const char *, int);
+__extern char *strsep(char **, const char *);
+__extern size_t strspn(const char *, const char *);
+__extern char *strstr(const char *, const char *);
+__extern char *strtok(char *, const char *);
+__extern char *strreplace(const char *, const char *, const char *);
+
+#endif /* _STRING_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/suffix_number.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/suffix_number.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/suffix_number.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * suffix_number.h
+ *
+ * Definitions used to convert a string of a number with potential SI suffix
+ * to int-type.
+ */
+
+#ifndef LIBUTIL_SUFFIX_NUMBER_H
+#define LIBUTIL_SUFFIX_NUMBER_H
+
+unsigned long long suffix_number(const char *);
+
+#endif /* LIBUTIL_SUFFIX_NUMBER_H */
+
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/bitops.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2010-2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bitops.h
+ *
+ * Simple bitwise operations
+ */
+
+#ifndef _BITOPS_H
+#define _BITOPS_H
+
+#include <klibc/compiler.h>
+
+#if __SIZEOF_POINTER__ == 4
+#include <i386/bitops.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/bitops.h>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+#endif /* _BITOPS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/cpu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+#ifndef _CPU_H
+#define _CPU_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <klibc/compiler.h>
+
+#if __SIZEOF_POINTER__ == 4
+#include <i386/cpu.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/cpu.h>
+#else 
+#error "unsupported architecture"
+#endif
+
+typedef unsigned long irq_state_t;
+
+static inline irq_state_t irq_state(void)
+{
+    irq_state_t __st;
+
+    asm volatile("pushf ; pop %0" : "=rm" (__st) : : "memory");
+    return __st;
+}
+
+static inline irq_state_t irq_save(void)
+{
+    irq_state_t __st = irq_state();
+    cli();
+    return __st;
+}
+
+static inline void irq_restore(irq_state_t __st)
+{
+    asm volatile("push %0 ; popf" : : "rm" (__st) : "memory");
+}
+
+/* Standard macro to see if a specific flag is changeable */
+static inline __constfunc bool cpu_has_eflag(unsigned long flag)
+{
+	unsigned long f0, f1;
+	asm("pushf ; "
+	    "pushf ; "
+	    "pop %0 ; "
+	    "mov %0,%1 ; "
+	    "xor %2,%1 ; "
+	    "push %1 ; "
+	    "popf ; "
+	    "pushf ; "
+	    "pop %1 ; "
+	    "popf"
+	    : "=&r" (f0), "=&r" (f1)
+	    : "ri" (flag));
+	return !!((f0^f1) & flag);
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/dirent.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/dirent.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/dirent.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/*
+ * sys/dirent.h
+ */
+
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifndef NAME_MAX
+#define NAME_MAX 255
+#endif
+
+struct dirent {
+    uint32_t d_ino;
+    uint32_t d_off;
+    uint16_t d_reclen;
+    uint16_t d_type;
+    char d_name[NAME_MAX + 1];
+};
+
+enum dirent_type {
+    DT_UNKNOWN	=  0,
+    DT_FIFO	=  1,
+    DT_CHR	=  2,
+    DT_DIR	=  4,
+    DT_BLK	=  6,
+    DT_REG	=  8,
+    DT_LNK	= 10,
+    DT_SOCK	= 12,
+    DT_WHT	= 14,
+};
+
+/*
+ * Convert between stat structure mode types and directory types.
+ * The stat structure mode types are the same as in Linux.
+ */
+#define IFTODT(mode)	(((mode) & 0170000) >> 12)
+#define DTTOIF(dt)	((dt) << 12)
+
+struct _DIR_;
+typedef struct _DIR_ DIR;
+
+#endif /* sys/dirent.h */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/elf32.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/elf32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/elf32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,113 @@
+/*
+ * sys/elf32.h
+ */
+
+#ifndef _SYS_ELF32_H
+#define _SYS_ELF32_H
+
+#include <sys/elfcommon.h>
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+typedef uint16_t Elf32_Half;
+typedef int16_t Elf32_SHalf;
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+
+typedef uint32_t Elf32_Off;
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Section;
+
+/* Dynamic header */
+
+typedef struct elf32_dyn {
+    Elf32_Sword d_tag;
+    union {
+	Elf32_Sword d_val;
+	Elf32_Addr d_ptr;
+    } d_un;
+} Elf32_Dyn;
+
+/* Relocations */
+
+#define ELF32_R_SYM(x)	((x) >> 8)
+#define ELF32_R_TYPE(x)	((x) & 0xff)
+
+typedef struct elf32_rel {
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf32_rela {
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+    Elf32_Sword r_addend;
+} Elf32_Rela;
+
+/* Symbol */
+
+typedef struct elf32_sym {
+    Elf32_Word st_name;
+    Elf32_Addr st_value;
+    Elf32_Word st_size;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf32_Half st_shndx;
+} Elf32_Sym;
+
+/* Main file header */
+
+typedef struct elf32_hdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;
+    Elf32_Off e_phoff;
+    Elf32_Off e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+/* Program header */
+
+typedef struct elf32_phdr {
+    Elf32_Word p_type;
+    Elf32_Off p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
+} Elf32_Phdr;
+
+/* Section header */
+
+typedef struct elf32_shdr {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+/* Note header */
+typedef struct elf32_note {
+    Elf32_Word n_namesz;	/* Name size */
+    Elf32_Word n_descsz;	/* Content size */
+    Elf32_Word n_type;		/* Content type */
+} Elf32_Nhdr;
+
+#endif /* _SYS_ELF32_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/elf64.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/elf64.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/elf64.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,113 @@
+/*
+ * sys/elf64.h
+ */
+
+#ifndef _SYS_ELF64_H
+#define _SYS_ELF64_H
+
+#include <sys/elfcommon.h>
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+typedef uint16_t Elf64_Half;
+typedef int16_t Elf64_SHalf;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef uint64_t Elf64_Off;
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Section;
+
+/* Dynamic header */
+
+typedef struct elf64_dyn {
+    Elf64_Sxword d_tag;
+    union {
+	Elf64_Xword d_val;
+	Elf64_Addr d_ptr;
+    } d_un;
+} Elf64_Dyn;
+
+/* Relocations */
+
+#define ELF64_R_SYM(x)	((x) >> 32)
+#define ELF64_R_TYPE(x)	((x) & 0xffffffff)
+
+typedef struct elf64_rel {
+    Elf64_Addr r_offset;
+    Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct elf64_rela {
+    Elf64_Addr r_offset;
+    Elf64_Xword r_info;
+    Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+/* Symbol */
+
+typedef struct elf64_sym {
+    Elf64_Word st_name;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf64_Half st_shndx;
+    Elf64_Addr st_value;
+    Elf64_Xword st_size;
+} Elf64_Sym;
+
+/* Main file header */
+
+typedef struct elf64_hdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf64_Half e_type;
+    Elf64_Half e_machine;
+    Elf64_Word e_version;
+    Elf64_Addr e_entry;
+    Elf64_Off e_phoff;
+    Elf64_Off e_shoff;
+    Elf64_Word e_flags;
+    Elf64_Half e_ehsize;
+    Elf64_Half e_phentsize;
+    Elf64_Half e_phnum;
+    Elf64_Half e_shentsize;
+    Elf64_Half e_shnum;
+    Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* Program header */
+
+typedef struct elf64_phdr {
+    Elf64_Word p_type;
+    Elf64_Word p_flags;
+    Elf64_Off p_offset;
+    Elf64_Addr p_vaddr;
+    Elf64_Addr p_paddr;
+    Elf64_Xword p_filesz;
+    Elf64_Xword p_memsz;
+    Elf64_Xword p_align;
+} Elf64_Phdr;
+
+/* Section header */
+
+typedef struct elf64_shdr {
+    Elf64_Word sh_name;
+    Elf64_Word sh_type;
+    Elf64_Xword sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off sh_offset;
+    Elf64_Xword sh_size;
+    Elf64_Word sh_link;
+    Elf64_Word sh_info;
+    Elf64_Xword sh_addralign;
+    Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+/* Note header */
+typedef struct elf64_note {
+    Elf64_Word n_namesz;	/* Name size */
+    Elf64_Word n_descsz;	/* Content size */
+    Elf64_Word n_type;		/* Content type */
+} Elf64_Nhdr;
+
+#endif /* _SYS_ELF64_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/elfcommon.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/elfcommon.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/elfcommon.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,414 @@
+/*
+ * sys/elfcommon.h
+ */
+
+#ifndef _SYS_ELFCOMMON_H
+#define _SYS_ELFCOMMON_H
+
+#include <stdint.h>
+
+/* Segment types */
+#define PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_LOOS		0x60000000
+#define PT_HIOS		0x6fffffff
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+#define PT_GNU_EH_FRAME	0x6474e550	/* Extension, eh? */
+
+/* ELF file types */
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+/* ELF machine types */
+#define EM_NONE		0
+#define EM_M32		1
+#define EM_SPARC	2
+#define EM_386		3
+#define EM_68K		4
+#define EM_88K		5
+#define EM_486		6	/* Not used in Linux at least */
+#define EM_860		7
+#define EM_MIPS         8	/* R3k, bigendian(?) */
+#define EM_MIPS_RS4_BE	10	/* R4k BE */
+#define EM_PARISC	15
+#define EM_SPARC32PLUS	18
+#define EM_PPC		20
+#define EM_PPC64	21
+#define EM_S390         22
+#define EM_SH		42
+#define EM_SPARCV9	43	/* v9 = SPARC64 */
+#define EM_H8_300H      47
+#define EM_H8S          48
+#define EM_IA_64        50	/* Itanic */
+#define EM_X86_64       62
+#define EM_CRIS         76
+#define EM_V850         87
+#define EM_ALPHA        0x9026	/* Interrim Alpha that stuck around */
+#define EM_CYGNUS_V850  0x9080	/* Old v850 ID used by Cygnus */
+#define EM_S390_OLD     0xA390	/* Obsolete interrim value for S/390 */
+
+/* Dynamic type values */
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Auxilliary table entries */
+#define AT_NULL		0	/* end of vector */
+#define AT_IGNORE	1	/* entry should be ignored */
+#define AT_EXECFD	2	/* file descriptor of program */
+#define AT_PHDR		3	/* program headers for program */
+#define AT_PHENT	4	/* size of program header entry */
+#define AT_PHNUM	5	/* number of program headers */
+#define AT_PAGESZ	6	/* system page size */
+#define AT_BASE		7	/* base address of interpreter */
+#define AT_FLAGS	8	/* flags */
+#define AT_ENTRY	9	/* entry point of program */
+#define AT_NOTELF	10	/* program is not ELF */
+#define AT_UID		11	/* real uid */
+#define AT_EUID		12	/* effective uid */
+#define AT_GID		13	/* real gid */
+#define AT_EGID		14	/* effective gid */
+#define AT_PLATFORM	15	/* string identifying CPU for optimizations */
+#define AT_HWCAP	16	/* arch dependent hints at CPU capabilities */
+#define AT_CLKTCK	17	/* frequency at which times() increments */
+/* 18..22 = ? */
+#define AT_SECURE	23	/* secure mode boolean */
+
+/* Program header permission flags */
+#define PF_X            0x1
+#define PF_W            0x2
+#define PF_R            0x4
+
+/* Section header types */
+#define SHT_NULL        0
+#define SHT_PROGBITS    1
+#define SHT_SYMTAB      2
+#define SHT_STRTAB      3
+#define SHT_RELA        4
+#define SHT_HASH        5
+#define SHT_DYNAMIC     6
+#define SHT_NOTE        7
+#define SHT_NOBITS      8
+#define SHT_REL         9
+#define SHT_SHLIB       10
+#define SHT_DYNSYM      11
+#define SHT_NUM         12
+#define SHT_LOPROC      0x70000000
+#define SHT_HIPROC      0x7fffffff
+#define SHT_LOUSER      0x80000000
+#define SHT_HIUSER      0xffffffff
+
+/* Section header flags */
+#define SHF_WRITE       0x1
+#define SHF_ALLOC       0x2
+#define SHF_EXECINSTR   0x4
+#define SHF_MASKPROC    0xf0000000
+
+/* Special section numbers */
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+
+/* Symbol table definitions */
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+
+/* Lenght of magic at the start of a file */
+#define EI_NIDENT	16
+
+/* Magic number constants... */
+#define EI_MAG0         0	/* e_ident[] indexes */
+#define EI_MAG1         1
+#define EI_MAG2         2
+#define EI_MAG3         3
+#define EI_CLASS        4
+#define EI_DATA         5
+#define EI_VERSION      6
+#define EI_OSABI        7
+#define EI_PAD          8
+
+#define ELFMAG0         0x7f	/* EI_MAG */
+#define ELFMAG1         'E'
+#define ELFMAG2         'L'
+#define ELFMAG3         'F'
+#define ELFMAG          "\177ELF"
+#define SELFMAG         4
+
+#define ELFCLASSNONE    0	/* EI_CLASS */
+#define ELFCLASS32      1
+#define ELFCLASS64      2
+#define ELFCLASSNUM     3
+
+#define ELFDATANONE     0	/* e_ident[EI_DATA] */
+#define ELFDATA2LSB     1
+#define ELFDATA2MSB     2
+
+#define EV_NONE         0	/* e_version, EI_VERSION */
+#define EV_CURRENT      1
+#define EV_NUM          2
+
+#define ELFOSABI_NONE   0
+#define ELFOSABI_LINUX  3
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* Keep this the last entry.  */
+#define R_386_NUM	   38
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+#define R_X86_64_PC64		24	/* PC relative 64 bit */
+#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
+					   offset to GOT */
+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
+					   to GOT entry */
+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
+					   to PLT entry */
+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
+					   descriptor.  */
+#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+
+#define R_X86_64_NUM		38
+
+#endif				/* _SYS_ELFCOMMON_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/exec.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/exec.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/exec.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,79 @@
+/*
+ * exec.h
+ *
+ *  Created on: Aug 14, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#ifndef EXEC_H_
+#define EXEC_H_
+
+#include <sys/module.h>
+#include <stdlib.h>
+
+/**
+ * EXEC_ROOT_NAME - The name of the ELF module associated with the COM32 module.
+ *
+ * This is a shallow ELF module, that contains only the symbol table for
+ * the code and data sections of the loaded COM32 root module.
+ */
+#define EXEC_ROOT_NAME			"_root_.c32"
+
+/**
+ * spawn_load - Load a library module or executes an executable one
+ * @name	the name of the library/executable to use, including the extension
+ * 			(e.g. 'sort.c32')
+ * @argc:	the number of string arguments in @argv
+ * @argv:	a NULL-terminated vector of string arguments, starting with
+ * 			the program name.
+ *
+ * This procedure in essence loads takes the name of a module and checks to see what
+ * kind of module it is ( executable or library ), after which is performs the
+ * appropriate action, either spawning or simply loading the module into memory.
+ */
+extern int spawn_load(const char *name, int argc, char **argv);
+
+/**
+ * spawnv - Executes a program in the current environment.
+ * @name:	the name of the program to spawn, including the extension
+ * 			(e.g. 'hello.c32')
+ * @argv:	a NULL-terminated vector of string arguments, starting with
+ * 			the program name.
+ *
+ * A program is an ELF module that contains a main routine. A program is
+ * loaded into memory, executed, then unloaded, thus remaining in memory only
+ * while the main() function is executing. A program also defines a
+ * memory allocation context, and a simple garbage collection mechanism
+ * it thus provided. This is done by internally associating with the program
+ * module each pointer returned by malloc(). After the program finishes
+ * its execution, all the unallocated memory pertaining to the program
+ * is automatically cleaned up.
+ *
+ * Note that this association takes place both for the allocations happening
+ * directly in the program, or indirectly through a library function. Libraries
+ * do not create allocation contexts, thus each allocation they made belong
+ * to the innermost calling program.
+ */
+extern int spawnv(const char *name, const char **argv);
+
+/**
+ * spawnl - Executes a program in the current environment.
+ * @name:	the name of the program to spawn, including the extension
+ * 			(e.g. 'hello.c32')
+ * @arg:	the first argument (argv[0]) to be passed to the main function
+ * 			of the program
+ * @...:	optional subsequent arguments that are passed o the main function
+ * 			of the program
+ *
+ * This is another version of the spawn routine. Please see 'spawnv' for
+ * a full presentation.
+ */
+extern int spawnl(const char *name, const char *arg, ...);
+
+/**
+ * exec_term - Releases the resources of the execution environment.
+ */
+extern void exec_term(void);
+
+
+#endif /* EXEC_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/fpu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/fpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/fpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,6 @@
+#ifndef _SYS_FPU_H
+#define _SYS_FPU_H
+
+extern int x86_init_fpu(void);
+
+#endif /* _SYS_FPU_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/gpxe.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/gpxe.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/gpxe.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+#ifndef _GPXE_H
+#define _GPXE_H
+
+#include <com32.h>
+
+struct s_PXENV_FILE_CHECK_API {
+    uint16_t Status;
+    uint16_t Size;
+    uint32_t Magic;
+    uint32_t Provider;
+    uint32_t APIMask;
+    uint32_t Flags;
+};
+
+bool is_gpxe(void);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/bitops.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2010-2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * i386 bitops.h
+ *
+ * Simple bitwise operations
+ */
+static inline void set_bit(long __bit, void *__bitmap)
+{
+    asm volatile("btsl %1,%0"
+		 : "+m" (*(unsigned char *)__bitmap)
+		 : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+    asm volatile("btcl %1,%0"
+		 : "+m" (*(unsigned char *)__bitmap)
+		 : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+    unsigned char __r;
+    asm("btl %2,%1; setc %0"
+	: "=qm" (__r)
+	: "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
+    return __r;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/cpu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,114 @@
+/* i386 cpu.h */
+
+static inline uint64_t rdtsc(void)
+{
+    uint64_t v;
+    asm volatile("rdtsc" : "=A" (v));
+    return v;
+}
+
+static inline uint32_t rdtscl(void)
+{
+    uint32_t v;
+    asm volatile("rdtsc" : "=a" (v) : : "edx");
+    return v;
+}
+
+static inline void cpuid_count(uint32_t op, uint32_t cnt,
+			       uint32_t * eax, uint32_t * ebx,
+			       uint32_t * ecx, uint32_t * edx)
+{
+    asm volatile("movl %%ebx,%1 ; "
+		 "cpuid ; "
+		 "xchgl %1,%%ebx"
+		 : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
+		 : "a"(op), "c"(cnt));
+}
+
+static inline void cpuid(uint32_t op, uint32_t * eax, uint32_t * ebx,
+			 uint32_t * ecx, uint32_t * edx)
+{
+    cpuid_count(op, 0, eax, ebx, ecx, edx);
+}
+
+static inline __constfunc uint32_t cpuid_eax(uint32_t level)
+{
+    uint32_t v;
+
+    asm volatile("pushl %%ebx ; "
+		 "cpuid ; "
+		 "popl %%ebx"
+		 : "=a" (v)
+		 : "a"(level)
+		 : "ecx", "edx");
+    return v;
+}
+
+static inline __constfunc uint32_t cpuid_ebx(uint32_t level)
+{
+    uint32_t v;
+
+    asm volatile("movl %%ebx,%0 ; "
+		 "cpuid ; "
+		 "xchgl %0,%%ebx"
+		 : "=SD" (v), "+a" (level)
+		 : : "ecx", "edx");
+    return v;
+}
+
+static inline __constfunc uint32_t cpuid_ecx(uint32_t level)
+{
+    uint32_t v;
+
+    asm volatile("pushl %%ebx ; "
+		 "cpuid ; "
+		 "popl %%ebx"
+		 : "=c" (v), "+a" (level)
+		 : : "edx");
+    return v;
+}
+
+static inline __constfunc uint32_t cpuid_edx(uint32_t level)
+{
+    uint32_t v;
+
+    asm volatile("pushl %%ebx ; "
+		 "cpuid ; "
+		 "popl %%ebx"
+		 : "=d" (v), "+a" (level)
+		 : : "ecx");
+    return v;
+}
+
+static inline uint64_t rdmsr(uint32_t msr)
+{
+    uint64_t v;
+
+    asm volatile("rdmsr" : "=A" (v) : "c"(msr));
+    return v;
+}
+
+static inline void wrmsr(uint64_t v, uint32_t msr)
+{
+    asm volatile("wrmsr" : : "A" (v), "c" (msr));
+}
+
+static inline void cpu_relax(void)
+{
+    asm volatile("rep ; nop" : : : "memory");
+}
+
+static inline void hlt(void)
+{
+    asm volatile("hlt" : : : "memory");
+}
+
+static inline void cli(void)
+{
+    asm volatile("cli" : : : "memory");
+}
+
+static inline void sti(void)
+{
+    asm volatile("sti" : : : "memory");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/module.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/i386/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,35 @@
+/**
+ * syslinux/module.h
+ *
+ * Dynamic ELF modules definitions and services.
+ */
+
+#ifndef I386_MODULE_H_
+#define I386_MODULE_H_
+
+#include <elf.h>
+
+/*
+ * Accepted values for various ELF header parameters found in an ELF dynamic
+ * object.
+ */
+#define MODULE_ELF_CLASS		ELFCLASS32		// 32-bit modules
+#define MODULE_ELF_CLASS_SIZE		32			// Size of a word value
+#define MODULE_ELF_DATA			ELFDATA2LSB		// Word endianess
+#define MODULE_ELF_VERSION		EV_CURRENT		// Object version
+#define MODULE_ELF_TYPE			ET_DYN			// Executable type (shared object - .so)
+#define MODULE_ELF_MACHINE		EM_386			// Target architecture
+
+#define ELF_MOD_SYS		"32 bit"
+
+typedef Elf32_Addr		Elf_Addr;
+typedef Elf32_Dyn		Elf_Dyn;
+typedef Elf32_Word		Elf_Word;
+typedef Elf32_Off		Elf_Off;
+typedef Elf32_Sym		Elf_Sym;
+typedef Elf32_Ehdr		Elf_Ehdr;
+typedef Elf32_Phdr		Elf_Phdr;
+typedef Elf32_Rel		Elf_Rel;
+typedef Elf32_Word		Elf_Bword;
+
+#endif // I386_MODULE_H_
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/io.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+#ifndef _SYS_IO_H
+#define _SYS_IO_H
+
+#include <inttypes.h>
+
+static inline uint8_t inb(uint16_t p)
+{
+    uint8_t v;
+    asm volatile ("inb %1,%0":"=a" (v):"Nd"(p));
+    return v;
+}
+
+static inline uint16_t inw(uint16_t p)
+{
+    uint16_t v;
+    asm volatile ("inw %1,%0":"=a" (v):"Nd"(p));
+    return v;
+}
+
+static inline uint32_t inl(uint16_t p)
+{
+    uint32_t v;
+    asm volatile ("inl %1,%0":"=a" (v):"Nd"(p));
+    return v;
+}
+
+static inline void outb(uint8_t v, uint16_t p)
+{
+    asm volatile ("outb %0,%1"::"a" (v), "Nd"(p));
+}
+
+static inline void outw(uint16_t v, uint16_t p)
+{
+    asm volatile ("outw %0,%1"::"a" (v), "Nd"(p));
+}
+
+static inline void outl(uint32_t v, uint16_t p)
+{
+    asm volatile ("outl %0,%1"::"a" (v), "Nd"(p));
+}
+
+#endif /* _SYS_IO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/module.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,351 @@
+/**
+ * syslinux/module.h
+ *
+ * Dynamic ELF modules definitions and services.
+ */
+
+#ifndef MODULE_H_
+#define MODULE_H_
+
+#include <stdio.h>
+#include <elf.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <stdbool.h>
+#include <linux/list.h>
+
+#if __SIZEOF_POINTER__ == 4
+#include <i386/module.h>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/module.h>
+#else
+#error "unsupported architecture"
+#endif
+
+/*
+ * The maximum length of the module file name (including path), stored
+ * in the struct module descriptor.
+ */
+#define MODULE_NAME_SIZE		256
+
+/*
+ * Some common information about what kind of modules we're dealing with
+ */
+#define EXEC_MODULE			0		
+#define LIB_MODULE			1
+
+#define MAX_NR_DEPS			64
+
+/*
+ * Initialization and finalization function signatures
+ */
+
+/**
+ * module_main_t - pointer to an entry routine
+ *
+ * The entry routine is present only in executable modules, and represents
+ * the entry point for the program.
+ */
+typedef int (*module_main_t)(int, char**);
+
+/**
+ * module_ctor_t - pointer to a constructor or destructor routine
+ *
+ * A module may have multiple routines that need to be executed before
+ * or after the main routine. These are the constructors and
+ * destructors, respectively.
+ */
+typedef void (*module_ctor_t) (void);
+
+/**
+ * struct elf_module - structure encapsulating a module loaded in memory.
+ *
+ * Each SYSLINUX ELF module must have an associated struct elf_module descriptor
+ * that keeps track of memory allocations, symbol information, and various other
+ * resources needed by the module itself or by other modules that depend on it.
+ *
+ * There are two types of modules:
+ *  - regular modules, which are actual memory images of a loaded & linked shared
+ *  object (ELF file). Memory is reserved for the struct elf_module structure itself
+ *  and for the object loadable sections read from the file.
+ *  - shallow modules, which are not associated with an ELF shared object, but contain
+ *  metainformation about a memory region already present and containing the
+ *  actual code and data. One particular usage of shallow modules is to access
+ *  symbol information from the root COM32 module loaded by the SYSLINUX core.
+ *  As their name suggests, memory is reserved only for the elf_module structure
+ *  itself and optionally for a usually small memory region containing metainformation
+ *  (symbol information).
+ *
+ *  Module descriptors are related to each other through dependency information. A module
+ *  can depend on symbols from other modules, and in turn it can provide symbols used
+ *  by other dependant modules. This relationship can be described as a directed
+ *  acyclic graph (DAG). The graph is stored using double linked lists of
+ *  predecessors and successors. There is also a global linked list containing all
+ *  the modules currently loaded.
+ */
+struct atexit;
+struct elf_module {
+	char				name[MODULE_NAME_SIZE]; 		// The module name
+
+	bool			shallow;	// Whether the module contains any code
+
+	struct list_head	required;		// Head of the required modules list
+	struct list_head	dependants;		// Head of module dependants list
+	struct list_head	list;		// The list entry in the module list
+
+	module_ctor_t		*ctors;		// module constructors
+	module_ctor_t		*dtors;		// module destructors
+	module_main_t		main_func; // The main function (for executable modules)
+
+	void				*module_addr; // The module location in the memory
+	Elf_Addr			base_addr;	// The base address of the module
+	Elf_Word			module_size; // The module size in memory
+
+	Elf_Word			*hash_table;	// The symbol hash table
+	Elf_Word			*ghash_table;	// The GNU style hash table
+	char				*str_table;		// The string table
+	void 				*sym_table;		// The symbol table
+	void				*got;			// The Global Offset Table
+	Elf_Dyn			*dyn_table;		// Dynamic loading information table
+
+	Elf_Word			strtable_size;	// The size of the string table
+	Elf_Word			syment_size;	// The size of a symbol entry
+	Elf_Word			symtable_size;	// The size of the symbol table
+
+
+	union {
+		// Transient - Data available while the module is loading
+		struct {
+			FILE		*_file;		// The file object of the open file
+			Elf_Off	_cr_offset;	// The current offset in the open file
+		} l;
+
+		// Process execution data
+		struct {
+			jmp_buf		process_exit;	// Exit state
+			struct atexit  *atexit_list;	// atexit() chain
+		} x;
+	} u;
+
+	// ELF DT_NEEDED entries for this module
+	int				nr_needed;
+	Elf_Word			needed[MAX_NR_DEPS];
+};
+
+/**
+ * struct module_dep - structure encapsulating a module dependency need
+ *
+ * This structure represents an item in a double linked list of predecessors or
+ * successors. The item contents is a pointer to the corresponding module descriptor.
+ */
+struct module_dep {
+	struct list_head	list;		// The list entry in the dependency list
+
+	struct elf_module	*module;	// The target module descriptor
+};
+
+
+/**
+ * Unload all modules that have been loaded since @name.
+ *
+ * Returns the struct elf_module * for @name or %NULL if no modules
+ * have been loaded since @name.
+ */
+extern struct elf_module *unload_modules_since(const char *name);
+
+extern FILE *findpath(char *name);
+
+
+/**
+ * Names of symbols with special meaning (treated as special cases at linking)
+ */
+#define MODULE_ELF_INIT_PTR		"__module_init_ptr"	// Initialization pointer symbol name
+#define MODULE_ELF_EXIT_PTR		"__module_exit_ptr"	// Finalization pointer symbol name
+#define MODULE_ELF_MAIN_PTR		"__module_main_ptr" // Entry pointer symbol name
+
+/**
+ * modules_head - A global linked list containing all the loaded modules.
+ */
+extern struct list_head modules_head;
+
+
+/**
+ * for_each_module - iterator loop through the list of loaded modules.
+ */
+#define for_each_module(m)	list_for_each_entry(m, &modules_head, list)
+
+/**
+ * for_each_module_safe - iterator loop through the list of loaded modules safe against removal.
+ */
+#define for_each_module_safe(m, n)				\
+	list_for_each_entry_safe(m, n, &modules_head, list)
+
+/**
+ * module_current - return the module at the head of the module list.
+ */
+static inline struct elf_module *module_current(void)
+{
+	struct elf_module *head;
+
+	head = list_entry((&modules_head)->next, typeof(*head), list);
+	return head;
+}
+
+/**
+ * modules_init - initialize the module subsystem.
+ *
+ * This function must be called before any module operation is to be performed.
+ */
+extern int modules_init(void);
+
+
+/**
+ * modules_term - releases all resources pertaining to the module subsystem.
+ *
+ * This function should be called after all module operations.
+ */
+extern void modules_term(void);
+
+
+/**
+ * module_alloc - reserves space for a new module descriptor.
+ * @name: 	the file name of the module to be loaded.
+ *
+ * The function simply allocates a new module descriptor and initializes its fields
+ * in order to be used by subsequent loading operations.
+ */
+extern struct elf_module *module_alloc(const char *name);
+
+
+/**
+ * module_load - loads a regular ELF module into memory.
+ * @module:	the module descriptor returned by module_alloc.
+ *
+ * The function reads the module file, checks whether the file has a
+ * valid structure, then loads into memory the code and the data and performs
+ * any symbol relocations. A module dependency is created automatically when the
+ * relocated symbol is defined in a different module.
+ *
+ * The function returns 0 if the operation is completed successfully, and
+ * a non-zero value if an error occurs. Possible errors include invalid module
+ * structure, missing symbol definitions (unsatisfied dependencies) and memory
+ * allocation issues.
+ */
+extern int module_load(struct elf_module *module);
+
+
+/**
+ * module_unload - unloads the module from the system.
+ * @module: the module descriptor structure.
+ *
+ * The function checks to see whether the module can be safely
+ * removed, then it executes any destructors and releases all the
+ * associated memory. This function can be applied both for standard
+ * modules and for shallow modules.
+ *
+ * A module can be safely removed from the system when no other modules reference
+ * symbols from it.
+ */
+extern int module_unload(struct elf_module *module);
+
+/**
+ * _module_unload - unloads the module without running destructors
+ * @module: the module descriptor structure.
+ *
+ * This function is the same as module_unload(), except that the
+ * module's destructors are not executed.
+ */
+extern int _module_unload(struct elf_module *module);
+
+/**
+ * get_module_type - get type of the module
+ * @module: the module descriptor structure.
+ *
+ * This function returns the type of module we're dealing with
+ * either a library module ( LIB_MODULE ), executable module ( EXEC_MODULE ),
+ * or an error ( UNKNOWN_MODULE ). The way it checks teh type is by checking to see
+ * if the module has its main_func set ( in which case it's an executable ). In case
+ * it doesn't it then checks to see if init_func is set ( in which case it's a
+ * library module. If this isn't the case either we don't know what it is so bail out
+ */
+extern int get_module_type(struct elf_module *module);
+
+/**
+ * module_unloadable - checks whether the given module can be unloaded.
+ * @module: the module descriptor structure
+ *
+ * A module can be unloaded from the system when no other modules depend on it,
+ * that is, no symbols are referenced from it.
+ */
+extern int module_unloadable(struct elf_module *module);
+
+/**
+ * module_find - searches for a module by its name.
+ * @name: the name of the module, as it was specified in module_alloc.
+ *
+ * The function returns a pointer to the module descriptor, if found, or
+ * NULL otherwise.
+ */
+extern struct elf_module *module_find(const char *name);
+
+/**
+ * module_find_symbol - searches for a symbol definition in a given module.
+ * @name: the name of the symbol to be found.
+ * @module: the module descriptor structure.
+ *
+ * The function searches the module symbol table for a symbol matching exactly
+ * the name provided. The operation uses the following search algorithms, in this
+ * order:
+ *  - If a GNU hash table is present in the module, it is used to find the symbol.
+ *  - If the symbol cannot be found with the first method (either the hash table
+ *  is not present or the symbol is not found) and if a regular (SysV) hash table
+ *  is present, a search is performed on the SysV hash table. If the symbol is not
+ *  found, NULL is returned.
+ *  - If the second method cannot be applied, a linear search is performed by
+ *  inspecting every symbol in the symbol table.
+ *
+ *  If the symbol is found, a pointer to its descriptor structure is returned, and
+ *  NULL otherwise.
+ */
+extern Elf_Sym *module_find_symbol(const char *name, struct elf_module *module);
+
+/**
+ * global_find_symbol - searches for a symbol definition in the entire module namespace.
+ * @name: the name of the symbol to be found.
+ * @module: an optional (may be NULL) pointer to a module descriptor variable that
+ * will hold the module where the symbol was found.
+ *
+ * The function search for the given symbol name in all the modules currently
+ * loaded in the system, in the reverse module loading order. That is, the most
+ * recently loaded module is searched first, followed by the previous one, until
+ * the first loaded module is reached.
+ *
+ * If no module contains the symbol, NULL is returned, otherwise the return value is
+ * a pointer to the symbol descriptor structure. If the module parameter is not NULL,
+ * it is filled with the address of the module descriptor where the symbol is defined.
+ */
+extern Elf_Sym *global_find_symbol(const char *name, struct elf_module **module);
+
+/**
+ * module_get_absolute - converts an memory address relative to a module base address
+ * to its absolute value in RAM.
+ * @addr: the relative address to convert.
+ * @module: the module whose base address is used for the conversion.
+ *
+ * The function returns a pointer to the absolute memory address.
+ */
+static inline void *module_get_absolute(Elf_Addr addr, struct elf_module *module) {
+	return (void*)(module->base_addr + addr);
+}
+
+/**
+ * syslinux_current - get the current module process
+ */
+extern struct elf_module *__syslinux_current;
+static inline const struct elf_module *syslinux_current(void)
+{
+	return __syslinux_current;
+}
+
+
+#endif // MODULE_H_
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/pci.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/pci.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/pci.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,153 @@
+#ifndef _SYS_PCI_H
+#define _SYS_PCI_H
+
+#include <inttypes.h>
+#include <sys/io.h>
+
+#define MAX_PCI_FUNC		  8
+#define MAX_PCI_DEVICES		 32
+#define MAX_PCI_BUSES		256
+#define LINUX_KERNEL_MODULE_SIZE 64
+#define PCI_VENDOR_NAME_SIZE	256
+#define PCI_PRODUCT_NAME_SIZE	256
+#define PCI_CLASS_NAME_SIZE	256
+#define MAX_KERNEL_MODULES_PER_PCI_DEVICE 10
+#define MAX_PCI_CLASSES		256
+
+typedef uint32_t pciaddr_t;
+
+enum {
+	ENOPCIIDS = 100,
+	ENOMODULESPCIMAP,
+	ENOMODULESALIAS
+};
+
+/* a structure for extended pci information */
+/* XXX: use pointers for these? */
+struct pci_dev_info {
+    char vendor_name[PCI_VENDOR_NAME_SIZE];
+    char product_name[PCI_PRODUCT_NAME_SIZE];
+    char linux_kernel_module[LINUX_KERNEL_MODULE_SIZE]
+	[MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    int linux_kernel_module_count;
+    char class_name[PCI_CLASS_NAME_SIZE];	/* The most precise class name */
+    char category_name[PCI_CLASS_NAME_SIZE];	/*The general category */
+    uint8_t irq;
+    uint8_t latency;
+};
+
+/* PCI device (really, function) */
+struct pci_device {
+    union {
+	struct {
+	    uint16_t vendor;
+	    uint16_t product;
+	    uint16_t sub_vendor;
+	    uint16_t sub_product;
+	    uint8_t revision;
+	    uint8_t class[3];
+	};
+	struct {
+	    uint32_t vid_did;
+	    uint32_t svid_sdid;
+	    uint32_t rid_class;
+	};
+    };
+    struct pci_dev_info *dev_info;
+    struct pci_device *next;
+};
+
+/* PCI device ("slot") structure */
+struct pci_slot {
+    struct pci_device *func[MAX_PCI_FUNC];
+};
+
+/* PCI bus structure */
+struct pci_bus {
+    struct pci_slot *slot[MAX_PCI_DEVICES];
+};
+
+/* PCI domain structure */
+struct pci_domain {
+    struct pci_bus *bus[MAX_PCI_BUSES];
+};
+
+/* Iterate over a PCI domain */
+#define for_each_pci_func(funcp, domain) \
+  for (int __pci_bus = 0; __pci_bus < MAX_PCI_BUSES; __pci_bus++) \
+    if ((domain)->bus[__pci_bus]) \
+      for (int __pci_slot = 0; __pci_slot < MAX_PCI_DEVICES; __pci_slot++) \
+	if ((domain)->bus[__pci_bus]->slot[__pci_slot]) \
+	  for (int __pci_func = 0; __pci_func < MAX_PCI_FUNC; __pci_func++) \
+	    if (((funcp) = (domain)->bus[__pci_bus]->slot[__pci_slot]-> \
+		 func[__pci_func]))
+
+#define for_each_pci_func3(funcp, domain, addr) \
+  for (int __pci_bus = 0; __pci_bus < MAX_PCI_BUSES; __pci_bus++) \
+    if ((domain)->bus[__pci_bus]) \
+      for (int __pci_slot = 0; __pci_slot < MAX_PCI_DEVICES; __pci_slot++) \
+	if ((domain)->bus[__pci_bus]->slot[__pci_slot]) \
+	  for (int __pci_func = 0; __pci_func < MAX_PCI_FUNC; __pci_func++) \
+	    if (((addr) = pci_mkaddr(__pci_bus, __pci_slot, __pci_func, 0)), \
+		((funcp) = (domain)->bus[__pci_bus]->slot[__pci_slot]-> \
+		 func[__pci_func]))
+
+struct match {
+    struct match *next;
+    uint32_t did;
+    uint32_t did_mask;
+    uint32_t sid;
+    uint32_t sid_mask;
+    uint8_t rid_min, rid_max;
+    char *filename;
+};
+
+static inline pciaddr_t pci_mkaddr(uint32_t bus, uint32_t dev,
+				   uint32_t func, uint32_t reg)
+{
+    return 0x80000000 | ((bus & 0xff) << 16) | ((dev & 0x1f) << 11) |
+	((func & 0x07) << 8) | (reg & 0xff);
+}
+
+static inline int pci_bus(pciaddr_t addr)
+{
+    return (addr >> 16) & 0xff;
+}
+
+static inline int pci_dev(pciaddr_t addr)
+{
+    return (addr >> 11) & 0x1f;
+}
+
+static inline int pci_func(pciaddr_t addr)
+{
+    return (addr >> 8) & 0x07;
+}
+
+enum pci_config_type {
+    PCI_CFG_NONE = -1,		/* badness */
+    PCI_CFG_AUTO = 0,		/* autodetect */
+    PCI_CFG_TYPE1 = 1,
+    PCI_CFG_TYPE2 = 2,
+    PCI_CFG_BIOS = 3,
+};
+
+enum pci_config_type pci_set_config_type(enum pci_config_type);
+
+uint8_t pci_readb(pciaddr_t);
+uint16_t pci_readw(pciaddr_t);
+uint32_t pci_readl(pciaddr_t);
+void pci_writeb(uint8_t, pciaddr_t);
+void pci_writew(uint16_t, pciaddr_t);
+void pci_writel(uint32_t, pciaddr_t);
+
+struct pci_domain *pci_scan(void);
+void free_pci_domain(struct pci_domain *domain);
+struct match *find_pci_device(const struct pci_domain *pci_domain,
+			      struct match *list);
+int get_name_from_pci_ids(struct pci_domain *pci_domain, char *pciids_path);
+int get_module_name_from_pcimap(struct pci_domain *pci_domain, char *modules_pcimap_path);
+int get_module_name_from_alias(struct pci_domain *pci_domain, char *modules_alias_path);
+int get_class_name_from_pci_ids(struct pci_domain *pci_domain, char *pciids_path);
+void gather_additional_pci_config(struct pci_domain *domain);
+#endif /* _SYS_PCI_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/stat.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/stat.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/stat.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/*
+ * sys/stat.h
+ */
+
+#ifndef _SYS_STAT_H
+#define _SYS_STAT_H
+
+#include <sys/types.h>
+
+/* We don't use this, but it's there for compatibility */
+
+#define S_IFMT  00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK  0120000
+#define S_IFREG  0100000
+#define S_IFBLK  0060000
+#define S_IFDIR  0040000
+#define S_IFCHR  0020000
+#define S_IFIFO  0010000
+#define S_ISUID  0004000
+#define S_ISGID  0002000
+#define S_ISVTX  0001000
+#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+/* These are the only fields in struct stat we emulate */
+struct stat {
+    mode_t st_mode;
+    off_t st_size;
+};
+
+/* Only fstat() supported */
+int fstat(int, struct stat *);
+
+#endif /* _SYS_STAT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/time.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/time.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/time.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,6 @@
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+
+/* empty */
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/times.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/times.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/times.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,27 @@
+/*
+ * sys/times.h
+ */
+
+#ifndef _SYS_TIMES_H
+#define _SYS_TIMES_H
+
+#include <stdint.h>
+
+struct tms {
+    /* Empty */
+};
+
+#define HZ		1000
+#define CLK_TCK		HZ
+
+typedef uint32_t clock_t;
+
+extern volatile uint32_t __ms_timer;
+
+static inline clock_t times(struct tms *buf)
+{
+    (void)buf;
+    return __ms_timer;
+}
+
+#endif /* _SYS_TIMES_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/types.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/types.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/types.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * sys/types.h
+ */
+
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <stdint.h>
+
+typedef ptrdiff_t ssize_t;
+typedef int mode_t;
+typedef size_t off_t;
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/bitops.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/bitops.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2010-2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bitops.h - i386
+ *
+ * Simple bitwise operations
+ */
+
+static inline void set_bit(long __bit, void *__bitmap)
+{
+    asm volatile("bts %1,%0"
+		 : "+m" (*(unsigned char *)__bitmap)
+		 : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+    asm volatile("btcl %1,%0"
+		 : "+m" (*(unsigned char *)__bitmap)
+		 : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+    unsigned char __r;
+    asm("bt %2,%1; setc %0"
+	: "=qm" (__r)
+	: "m" (*(const unsigned char *)__bitmap), "Ir" (__bit));
+    return __r;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/cpu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/cpu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,128 @@
+#ifndef _CPU_X86_64_H
+#define _CPU_X86_64_H
+
+/* x86_64 cpu.h  */
+
+static inline uint64_t rdtsc(void)
+{
+    uint64_t v;
+    asm volatile("rdtsc" : "=A" (v));
+    return v;
+}
+
+static inline uint32_t rdtscl(void)
+{
+    uint32_t v;
+    asm volatile("rdtsc" : "=a" (v) : : "edx");
+    return v;
+}
+
+static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
+                                unsigned int *ecx, unsigned int *edx)
+{
+        /* ecx is often an input as well as an output. */
+        asm volatile("cpuid"
+            : "=a" (*eax),
+              "=b" (*ebx),
+              "=c" (*ecx),
+              "=d" (*edx)
+            : "0" (*eax), "2" (*ecx)
+            : "memory");
+}
+/*
+ * Generic CPUID function
+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+ * resulting in stale register contents being returned.
+ */
+static inline void cpuid(uint32_t op,
+                         uint32_t *eax, uint32_t *ebx,
+                         uint32_t *ecx, uint32_t *edx)
+{
+        *eax = op;
+        *ecx = 0;
+        native_cpuid(eax, ebx, ecx, edx);
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline uint32_t cpuid_eax(uint32_t op)
+{
+        uint32_t eax, ebx, ecx, edx;
+
+        cpuid(op, &eax, &ebx, &ecx, &edx);
+
+        return eax;
+}
+
+static inline uint32_t cpuid_ebx(uint32_t op)
+{
+        uint32_t eax, ebx, ecx, edx;
+
+        cpuid(op, &eax, &ebx, &ecx, &edx);
+
+        return ebx;
+}
+
+static inline uint32_t cpuid_ecx(uint32_t op)
+{
+        uint32_t eax, ebx, ecx, edx;
+
+        cpuid(op, &eax, &ebx, &ecx, &edx);
+
+        return ecx;
+}
+
+static inline uint32_t cpuid_edx(uint32_t op)
+{
+        uint32_t eax, ebx, ecx, edx;
+
+        cpuid(op, &eax, &ebx, &ecx, &edx);
+
+        return edx;
+}
+
+static inline void cpuid_count(uint32_t op, uint32_t cnt,
+			       uint32_t * eax, uint32_t * ebx,
+			       uint32_t * ecx, uint32_t * edx)
+{
+    asm volatile("movl %%ebx,%1 ; "
+		 "cpuid ; "
+		 "xchgl %1,%%ebx"
+		 : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
+		 : "a"(op), "c"(cnt));
+}
+
+static inline uint64_t rdmsr(uint32_t msr)
+{
+    uint64_t v;
+
+    asm volatile("rdmsr" : "=A" (v) : "c"(msr));
+    return v;
+}
+
+static inline void wrmsr(uint64_t v, uint32_t msr)
+{
+    asm volatile("wrmsr" : : "A" (v), "c" (msr));
+}
+
+static inline void cpu_relax(void)
+{
+    asm volatile("rep ; nop" : : : "memory");
+}
+
+static inline void hlt(void)
+{
+    asm volatile("hlt" : : : "memory");
+}
+
+static inline void cli(void)
+{
+    asm volatile("cli" : : : "memory");
+}
+
+static inline void sti(void)
+{
+    asm volatile("sti" : : : "memory");
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/module.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/sys/x86_64/module.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,35 @@
+/**
+ * syslinux/module.h
+ *
+ * Dynamic ELF64 modules definitions and services.
+ */
+
+#ifndef _X86_64_MODULE_H_
+#define _X86_64_MODULE_H_
+
+#include <elf.h>
+
+/*
+ * Accepted values for various ELF header parameters found in an ELF dynamic
+ * object.
+ */
+#define MODULE_ELF_CLASS		ELFCLASS64		// 64-bit modules
+#define MODULE_ELF_CLASS_SIZE		64			// Size of a word value
+#define MODULE_ELF_DATA			ELFDATA2LSB		// Word endianess
+#define MODULE_ELF_VERSION		EV_CURRENT		// Object version
+#define MODULE_ELF_TYPE			ET_DYN			// Executable type (shared object - .so)
+#define MODULE_ELF_MACHINE		EM_X86_64		// Target architecture
+
+#define ELF_MOD_SYS		"64 bit"
+
+typedef Elf64_Addr		Elf_Addr;
+typedef Elf64_Dyn		Elf_Dyn;
+typedef Elf64_Word		Elf_Word;
+typedef Elf64_Off		Elf_Off;
+typedef Elf64_Sym		Elf_Sym;
+typedef Elf64_Ehdr		Elf_Ehdr;
+typedef Elf64_Phdr		Elf_Phdr;
+typedef Elf64_Rel		Elf_Rel;
+typedef Elf64_Xword		Elf_Bword;
+
+#endif // _X86_64_MODULE_H_
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/adv.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/adv.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/adv.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/adv.h
+ */
+
+#ifndef _SYSLINUX_ADV_H
+#define _SYSLINUX_ADV_H
+
+#include <klibc/extern.h>
+#include <stddef.h>
+#include <syslinux/advconst.h>
+
+__extern void *__syslinux_adv_ptr;
+__extern size_t __syslinux_adv_size;
+
+static inline void *syslinux_adv_ptr(void)
+{
+    return __syslinux_adv_ptr;
+}
+
+static inline size_t syslinux_adv_size(void)
+{
+    return __syslinux_adv_size;
+}
+
+__extern int syslinux_adv_write(void);
+
+__extern int syslinux_setadv(int, size_t, const void *);
+__extern const void *syslinux_getadv(int, size_t *);
+
+#endif /* _SYSLINUX_ADV_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/advconst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/advconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/advconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/advconst.h
+ *
+ * ADV defined constants
+ *
+ * Defined in a separate file so it can be used by non-COM32 code.
+ * Some of these constants are also defined in adv.inc, they better match...
+ */
+
+#ifndef _SYSLINUX_ADVCONST_H
+#define _SYSLINUX_ADVCONST_H
+
+#define ADV_END		0
+#define ADV_BOOTONCE	1
+#define ADV_MENUSAVE	2
+
+#endif /* _SYSLINUX_ADVCONST_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/align.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/align.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/align.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _SYSLINUX_ALIGN_H
+#define _SYSLINUX_ALIGN_H
+
+#include <stdint.h>
+
+static inline uintptr_t __align_down(uintptr_t __p, uintptr_t __a)
+{
+    return __p & ~(__a - 1);
+}
+
+static inline uintptr_t __align_up(uintptr_t __p, uintptr_t __a)
+{
+    return (__p + __a - 1) & ~(__a - 1);
+}
+
+#define ALIGN_UP(p,a) ((__typeof__(p))__align_up((uintptr_t)(p), (a)))
+#define ALIGN_DOWN(p,a) ((__typeof__(p))__align_down((uintptr_t)(p), (a)))
+#define ALIGN_UP_FOR(p,t) ALIGN_UP(p,sizeof(t))
+#define ALIGN_DOWN_FOR(p,t) ALIGN_DOWN(p,sizeof(t))
+
+#endif /* _SYSLINUX_ALIGN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/boot.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/boot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/boot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/boot.h
+ *
+ * SYSLINUX boot API invocation
+ */
+
+#ifndef _SYSLINUX_BOOT_H
+#define _SYSLINUX_BOOT_H
+
+#include <stdint.h>
+#include <klibc/compiler.h>
+
+int syslinux_run_command(const char *);
+__noreturn syslinux_run_default(void);
+
+void syslinux_local_boot(int16_t flags);
+
+void syslinux_final_cleanup(uint16_t flags);
+
+void syslinux_chain_bootstrap(uint16_t flags, const void *bootstrap,
+			      uint32_t bootstrap_len, uint32_t edx,
+			      uint32_t esi, uint16_t ds);
+
+void bios_do_shuffle_and_boot(uint16_t bootflags, uint32_t descaddr,
+			      const void *descbuf, uint32_t dsize);
+
+struct image_types {
+    const char *name;
+    uint32_t type;
+};
+
+extern const struct image_types image_boot_types[];
+
+#define IMAGE_TYPE_KERNEL	0
+#define IMAGE_TYPE_LINUX	1
+#define IMAGE_TYPE_BOOT		2
+#define IMAGE_TYPE_BSS		3
+#define IMAGE_TYPE_PXE		4
+#define IMAGE_TYPE_FDIMAGE	5
+#define IMAGE_TYPE_COM32	7
+#define IMAGE_TYPE_CONFIG	8
+#define IMAGE_TYPE_LOCALBOOT	9
+
+uint32_t parse_image_type(const char *cmdline);
+void syslinux_run_kernel_image(const char *filename, const char *cmdline,
+			       uint32_t ipappend_flags, uint32_t type);
+
+#endif /* _SYSLINUX_BOOT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootpm.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootpm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootpm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/bootpm.h
+ *
+ * Data structures for shuffle and boot to protected mode
+ */
+
+#ifndef _SYSLINUX_BOOTPM_H
+#define _SYSLINUX_BOOTPM_H
+
+#include <stdint.h>
+#include <syslinux/movebits.h>
+
+struct syslinux_pm_regs {
+    uint32_t eax;		/* Offset  0 */
+    uint32_t ecx;		/* Offset  4 */
+    uint32_t edx;		/* Offset  8 */
+    uint32_t ebx;		/* Offset 12 */
+    uint32_t esp;		/* Offset 16 */
+    uint32_t ebp;		/* Offset 20 */
+    uint32_t esi;		/* Offset 24 */
+    uint32_t edi;		/* Offset 28 */
+
+    uint32_t eip;		/* Offset 32 */
+};
+
+int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist,
+			     struct syslinux_memmap *memmap,
+			     uint16_t bootflags, struct syslinux_pm_regs *regs);
+
+#endif /* _SYSLINUX_BOOTPM_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootrm.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootrm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/bootrm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,73 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/bootrm.h
+ *
+ * Data structures for shuffle and boot to protected mode
+ */
+
+#ifndef _SYSLINUX_BOOTRM_H
+#define _SYSLINUX_BOOTRM_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <com32.h>
+#include <syslinux/movebits.h>
+
+/* This register set is used by the shuffle and boot interface.  It is
+   a completely different structure from what the __intcall() and
+   __farcall() interfaces use! */
+struct syslinux_rm_regs {
+    uint16_t es;		/* Offset  0 */
+    uint16_t _unused_cs;	/* Offset  2 */
+    uint16_t ss;		/* Offset  4 */
+    uint16_t ds;		/* Offset  6 */
+    uint16_t fs;		/* Offset  8 */
+    uint16_t gs;		/* Offset 10 */
+
+    reg32_t eax;		/* Offset 12 */
+    reg32_t ecx;		/* Offset 16 */
+    reg32_t edx;		/* Offset 20 */
+    reg32_t ebx;		/* Offset 24 */
+    reg32_t esp;		/* Offset 28 */
+    reg32_t ebp;		/* Offset 32 */
+    reg32_t esi;		/* Offset 36 */
+    reg32_t edi;		/* Offset 40 */
+
+    uint16_t ip;		/* Offset 44 */
+    uint16_t cs;		/* Offset 46 */
+
+    bool sti;			/* Offset 48 */
+};
+
+int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist,
+			     struct syslinux_memmap *memmap,
+			     uint16_t bootflags, struct syslinux_rm_regs *regs);
+
+#endif /* _SYSLINUX_BOOTRM_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/config.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,193 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/config.h
+ *
+ * Query syslinux configuration information.
+ */
+
+#ifndef _SYSLINUX_CONFIG_H
+#define _SYSLINUX_CONFIG_H
+
+#include <stdint.h>
+#include <com32.h>
+
+enum syslinux_filesystem {
+    SYSLINUX_FS_UNKNOWN  = 0x30,
+    SYSLINUX_FS_SYSLINUX = 0x31,
+    SYSLINUX_FS_PXELINUX = 0x32,
+    SYSLINUX_FS_ISOLINUX = 0x33,
+    SYSLINUX_FS_EXTLINUX = 0x34,
+};
+
+struct syslinux_version {
+    uint16_t version;		/* (major << 8)+minor */
+    uint16_t max_api;
+    enum syslinux_filesystem filesystem;
+    const char *version_string;
+    const char *copyright_string;
+};
+
+struct syslinux_ipinfo {
+    uint32_t ipver;
+    uint32_t myip;
+    uint32_t serverip;
+    uint32_t gateway;
+    uint32_t netmask;
+};
+
+extern __nocommon struct syslinux_version __syslinux_version;
+static inline const struct syslinux_version *syslinux_version(void)
+{
+    return &__syslinux_version;
+}
+
+union syslinux_derivative_info {
+    struct {
+	com32sys_t r;
+	const void *esbx;
+	const void *fssi;
+	const void *gsdi;
+    } rr;			/* real raw */
+    struct {
+	uint16_t _pad1[4];
+	uint32_t _pad2[7];
+	uint8_t filesystem;
+	uint8_t ah;
+	uint16_t axh;
+    } c;			/* common */
+    struct {
+	uint16_t gs;
+	uint16_t fs;
+	uint16_t es;
+	uint16_t ds;
+	uint16_t di, dih;
+	uint16_t si, sih;
+	uint16_t bp, bph;
+	uint16_t sp, sph;
+	uint16_t bx, bxh;
+	uint16_t dx, dxh;
+	uint16_t cx, cxh;
+	uint16_t ax, axh;
+	uint32_t eflags;
+	const void *esbx;
+	const void *fssi;
+	const void *gsdi;
+    } r;			/* raw */
+    struct {
+	uint16_t _gs, _fs, _es, _ds;
+	uint32_t _edi, _esi, _ebp, _esp, _ebx;
+	uint8_t drive_number, dh;
+	uint16_t _dxh;
+	uint8_t sector_shift, ch;
+	uint16_t _cxh;
+	uint8_t filesystem, ah;
+	uint16_t _axh;
+	uint32_t _eflags;
+	const void *ptab_ptr;
+	const uint32_t *esdi_ptr;
+	const uint64_t *partoffset;
+    } disk;			/* syslinux/extlinux */
+    struct {
+	uint16_t _gs, stack_seg, pxenv_seg, _ds;
+	uint32_t _edi, stack_offs, _ebp, _esp, pxenv_offs;
+	uint16_t apiver;
+	uint16_t _dxh;
+	uint32_t myip;
+	uint8_t filesystem, ah;
+	uint16_t _axh;
+	uint32_t _eflags;
+	const void *pxenvptr;
+	const void *stack;
+	const struct syslinux_ipinfo *ipinfo;
+    } pxe;			/* pxelinux */
+    struct {
+	uint16_t _gs, _fs, _es, _ds;
+	uint32_t _edi, _esi, _ebp, _esp, _ebx;
+	uint8_t drive_number, dh;
+	uint16_t _dxh;
+	uint8_t sector_shift, cd_mode;
+	uint16_t _cxh;
+	uint8_t filesystem, ah;
+	uint16_t _axh;
+	uint32_t _eflags;
+	const void *spec_packet;
+	const uint32_t *esdi_ptr;
+	const uint64_t *partoffset;
+    } iso;			/* isolinux */
+};
+
+extern __nocommon union syslinux_derivative_info __syslinux_derivative_info;
+static inline const union syslinux_derivative_info
+    *syslinux_derivative_info(void)
+{
+    return &__syslinux_derivative_info;
+}
+
+struct syslinux_serial_console_info {
+    uint16_t iobase;
+    uint16_t divisor;
+    uint16_t flowctl;
+};
+
+extern void __syslinux_set_serial_console_info(void);
+
+extern __nocommon struct syslinux_serial_console_info
+    __syslinux_serial_console_info;
+static inline const struct syslinux_serial_console_info
+    *syslinux_serial_console_info(void)
+{
+    return &__syslinux_serial_console_info;
+}
+
+extern char ConfigName[];
+static inline const char *syslinux_config_file(void)
+{
+    return ConfigName;
+}
+
+struct syslinux_ipappend_strings {
+    int count;
+    const char *const *ptr;
+};
+extern __nocommon struct syslinux_ipappend_strings __syslinux_ipappend_strings;
+static inline const struct syslinux_ipappend_strings
+    *syslinux_ipappend_strings(void)
+{
+    return &__syslinux_ipappend_strings;
+}
+
+static inline enum syslinux_filesystem syslinux_filesystem(void)
+{
+    return syslinux_derivative_info()->c.filesystem;
+}
+
+extern void get_derivative_info(union syslinux_derivative_info *di);
+
+#endif /* _SYSLINUX_CONFIG_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/debug.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/debug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/debug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdbool.h>
+
+#ifdef DYNAMIC_DEBUG
+#define syslinux_debug_enabled	__syslinux_debug_enabled(__func__)
+extern bool __syslinux_debug_enabled(const char *func);
+#else
+#define syslinux_debug_enabled	(0)
+#endif /* DYNAMIC_DEBUG */
+
+extern int syslinux_debug(const char *str, bool enable);
+
+#endif /* DEBUG_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/disk.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/disk.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/disk.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,187 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright (C) 2010 Shao Miller
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/**
+ * @file syslinux/disk.h
+ *
+ * Deal with disks and partitions
+ */
+
+#ifndef _SYSLINUX_DISK_H
+#define _SYSLINUX_DISK_H
+
+#include <com32.h>
+#include <stdint.h>
+
+#define SECTOR 512u		/* bytes/sector */
+
+enum disk_op_codes {
+    EBIOS_READ_CODE = 0x42, /* Extended read */
+    EBIOS_WRITE_CODE = 0x43, /* Extended write */
+    CHS_READ_CODE = 0x02,
+    CHS_WRITE_CODE = 0x03,
+};
+
+struct disk_info {
+    int disk;
+    int ebios;			/* EBIOS supported on this disk */
+    int cbios;			/* CHS geometry is valid */
+    uint32_t bps;		/* bytes per sector */
+    uint64_t lbacnt;		/* total amount of sectors */
+    uint32_t cyl;
+    uint32_t head;
+    uint32_t spt;
+};
+
+struct disk_ebios_dapa {
+    uint16_t len;
+    uint16_t count;
+    uint16_t off;
+    uint16_t seg;
+    uint64_t lba;
+} __attribute__ ((packed));
+
+struct disk_ebios_eparam {
+    uint16_t len;
+    uint16_t info;
+    uint32_t cyl;
+    uint32_t head;
+    uint32_t spt;
+    uint64_t lbacnt;
+    uint16_t bps;	/* bytes per sector */
+    uint32_t edd;
+    uint16_t dpi_sig;
+    uint8_t  dpi_len;
+    char     reserved1[3];
+    char     hostbus[4];
+    char     if_type[8];
+    char     if_path[8];
+    char     dev_path[8];
+    char     reserved2;
+    uint8_t  checksum;
+} __attribute__ ((packed));
+
+/**
+ * CHS (cylinder, head, sector) value extraction macros.
+ * Taken from WinVBlock.  None expand to an lvalue.
+*/
+#define     chs_head(chs) chs[0]
+#define   chs_sector(chs) (chs[1] & 0x3F)
+#define chs_cyl_high(chs) (((uint16_t)(chs[1] & 0xC0)) << 2)
+#define  chs_cyl_low(chs) ((uint16_t)chs[2])
+#define chs_cylinder(chs) (chs_cyl_high(chs) | chs_cyl_low(chs))
+typedef uint8_t disk_chs[3];
+
+/* A DOS partition table entry */
+struct disk_dos_part_entry {
+    uint8_t active_flag;	/* 0x80 if "active" */
+    disk_chs start;
+    uint8_t ostype;
+    disk_chs end;
+    uint32_t start_lba;
+    uint32_t length;
+} __attribute__ ((packed));
+
+/* A DOS MBR */
+struct disk_dos_mbr {
+    char code[440];
+    uint32_t disk_sig;
+    char pad[2];
+    struct disk_dos_part_entry table[4];
+    uint16_t sig;
+} __attribute__ ((packed));
+#define disk_mbr_sig_magic 0xAA55
+
+/**
+ * A GPT disk/partition GUID
+ *
+ * Be careful with endianness, you must adjust it yourself
+ * iff you are directly using the fourth data chunk.
+ * There might be a better header for this...
+ */
+struct guid {
+    uint32_t data1;
+    uint16_t data2;
+    uint16_t data3;
+    uint64_t data4;
+} __attribute__ ((packed));
+
+/* A GPT partition */
+struct disk_gpt_part_entry {
+    struct guid type;
+    struct guid uid;
+    uint64_t lba_first;
+    uint64_t lba_last;
+    uint64_t attribs;
+    char name[72];
+} __attribute__ ((packed));
+
+/* A GPT header */
+struct disk_gpt_header {
+    char sig[8];
+    union {
+	struct {
+	    uint16_t minor;
+	    uint16_t major;
+	} fields __attribute__ ((packed));
+	uint32_t uint32;
+	char raw[4];
+    } rev __attribute__ ((packed));
+    uint32_t hdr_size;
+    uint32_t chksum;
+    char reserved1[4];
+    uint64_t lba_cur;
+    uint64_t lba_alt;
+    uint64_t lba_first_usable;
+    uint64_t lba_last_usable;
+    struct guid disk_guid;
+    uint64_t lba_table;
+    uint32_t part_count;
+    uint32_t part_size;
+    uint32_t table_chksum;
+    char reserved2[1];
+} __attribute__ ((packed));
+static const char disk_gpt_sig_magic[] = "EFI PART";
+
+extern int disk_int13_retry(const com32sys_t * inreg, com32sys_t * outreg);
+extern int disk_get_params(int disk, struct disk_info *const diskinfo);
+extern void *disk_read_sectors(const struct disk_info *const diskinfo,
+			       uint64_t lba, uint8_t count);
+extern int disk_write_sectors(const struct disk_info *const diskinfo,
+			      uint64_t lba, const void *data, uint8_t count);
+extern int disk_write_verify_sectors(const struct disk_info *const diskinfo,
+				     uint64_t lba, const void *buf, uint8_t count);
+extern void disk_dos_part_dump(const struct disk_dos_part_entry *const part);
+extern void guid_to_str(char *buf, const struct guid *const id);
+extern int str_to_guid(const char *buf, struct guid *const id);
+extern void disk_gpt_part_dump(const struct disk_gpt_part_entry *const
+			       gpt_part);
+extern void disk_gpt_header_dump(const struct disk_gpt_header *const gpt);
+
+#endif /* _SYSLINUX_DISK_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/firmware.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/firmware.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/firmware.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+#ifndef _SYSLINUX_FIRMWARE_H
+#define _SYSLINUX_FIRMWARE_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+struct term_state;
+
+struct output_ops {
+	void (*erase) (int, int, int, int, uint8_t);
+	void (*write_char) (uint8_t, uint8_t);
+	void (*showcursor) (const struct term_state *);
+	void (*scroll_up) (uint8_t, uint8_t, uint8_t);
+	void (*set_cursor) (int, int, bool);
+	void (*beep) (void);
+	void (*get_mode)(int *, int *);
+	void (*text_mode)(void);
+	void (*get_cursor)(uint8_t *, uint8_t *);
+};
+
+struct input_ops {
+	char (*getchar)(char *);
+	int (*pollchar)(void);
+	uint8_t (*shiftflags)(void);
+};
+
+struct adv_ops {
+	void (*init)(void);
+	int (*write)(void);
+};
+
+struct vesa_info;
+enum vesa_pixel_format;
+struct win_info;
+
+struct vesa_ops {
+	int (*set_mode)(struct vesa_info *, int *, int *, enum vesa_pixel_format *);
+	void (*screencpy)(size_t, const uint32_t *, size_t, struct win_info *);
+	int (*font_query)(uint8_t **);
+};
+
+enum heap;
+struct mem_ops {
+	void *(*malloc)(size_t, enum heap, size_t);
+	void *(*realloc)(void *, size_t);
+	void (*free)(void *);
+};
+
+struct initramfs;
+struct setup_data;
+
+struct firmware {
+	void (*init)(void);
+	void (*adjust_screen)(void);
+	void (*cleanup)(void);
+	struct disk *(*disk_init)(void *);
+	struct output_ops *o_ops;
+	struct input_ops *i_ops;
+	void (*get_serial_console_info)(uint16_t *, uint16_t *, uint16_t *);
+	struct adv_ops *adv_ops;
+	int (*boot_linux)(void *, size_t, struct initramfs *,
+			  struct setup_data *, char *);
+	struct vesa_ops *vesa;
+	struct mem_ops *mem;
+};
+
+extern struct firmware *firmware;
+
+extern void syslinux_register_bios(void);
+extern void init(void);
+
+#endif /* _SYSLINUX_FIRMWARE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/idle.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/idle.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/idle.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/idle.h
+ */
+
+#ifndef _SYSLINUX_IDLE_H
+#define _SYSLINUX_IDLE_H
+
+void syslinux_idle(void);
+void syslinux_reset_idle(void);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/io.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/io.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/io.h
+ *
+ * SYSLINUX low-level I/O functions
+ */
+
+#ifndef _SYSLINUX_IO_H
+#define _SYSLINUX_IO_H
+
+int syslinux_read_disk(void *buf, uint32_t sector, uint16_t count);
+
+#endif /* _SYSLINUX_IO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/keyboard.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/keyboard.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/keyboard.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/keyboard.h
+ *
+ * Query syslinux keyboard map.
+ */
+
+#ifndef _SYSLINUX_KEYBOARD_H
+#define _SYSLINUX_KEYBOARD_H
+
+#include <stdint.h>
+
+struct syslinux_keyboard_map {
+    uint16_t version;
+    uint16_t length;
+    void *map;
+};
+
+extern struct syslinux_keyboard_map __syslinux_keyboard_map;
+static inline const struct syslinux_keyboard_map *syslinux_keyboard_map(void)
+{
+    return &__syslinux_keyboard_map;
+}
+
+#endif /* _SYSLINUX_KEYBOARD_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/linux.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/linux.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/linux.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,206 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2012 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/linux.h
+ *
+ * Definitions used to boot a Linux kernel
+ */
+
+#ifndef _SYSLINUX_LINUX_H
+#define _SYSLINUX_LINUX_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <klibc/compiler.h>
+
+/* A chunk of an initramfs.  These are kept as a doubly-linked
+   circular list with headnode; the headnode is distinguished by
+   having len == 0.  The data pointer can be NULL if data_len is zero;
+   if data_len < len then the balance of the region is zeroed. */
+
+struct initramfs {
+    struct initramfs *prev, *next;
+    size_t len;
+    size_t align;
+    const void *data;
+    size_t data_len;
+};
+#define INITRAMFS_MAX_ALIGN	4096
+
+struct setup_data_header {
+	uint64_t next;
+	uint32_t type;
+	uint32_t len;
+} __packed;
+
+struct setup_data {
+    struct setup_data *prev, *next;
+    const void *data;
+    struct setup_data_header hdr;
+};
+
+#define SETUP_NONE	0
+#define SETUP_E820_EXT	1
+#define SETUP_DTB	2
+
+#define XLF_KERNEL_64			(1 << 0)
+#define XLF_CAN_BE_LOADED_ABOVE_4G	(1 << 1)
+#define XLF_EFI_HANDOVER_32		(1 << 2)
+#define XLF_EFI_HANDOVER_64		(1 << 3)
+
+struct linux_header {
+    uint8_t boot_sector_1[0x0020];
+    uint16_t old_cmd_line_magic;
+    uint16_t old_cmd_line_offset;
+    uint8_t boot_sector_2[0x01f1 - 0x0024];
+    uint8_t setup_sects;
+    uint16_t root_flags;
+    uint32_t syssize;
+    uint16_t ram_size;
+    uint16_t vid_mode;
+    uint16_t root_dev;
+    uint16_t boot_flag;
+    uint16_t jump;
+    uint32_t header;
+    uint16_t version;
+    uint32_t realmode_swtch;
+    uint16_t start_sys;
+    uint16_t kernel_version;
+    uint8_t type_of_loader;
+    uint8_t loadflags;
+    uint16_t setup_move_size;
+    uint32_t code32_start;
+    uint32_t ramdisk_image;
+    uint32_t ramdisk_size;
+    uint32_t bootsect_kludge;
+    uint16_t heap_end_ptr;
+    uint16_t pad1;
+    uint32_t cmd_line_ptr;
+    uint32_t initrd_addr_max;
+    uint32_t kernel_alignment;
+    uint8_t relocatable_kernel;
+    uint8_t min_alignment;
+    uint16_t xloadflags;
+    uint32_t cmdline_max_len;
+    uint32_t hardware_subarch;
+    uint64_t hardware_subarch_data;
+    uint32_t payload_offset;
+    uint32_t payload_length;
+    uint64_t setup_data;
+    uint64_t pref_address;
+    uint32_t init_size;
+    uint32_t handover_offset;
+} __packed;
+
+struct screen_info {
+	uint8_t  orig_x;		/* 0x00 */
+	uint8_t  orig_y;		/* 0x01 */
+	uint16_t ext_mem_k;	/* 0x02 */
+	uint16_t orig_video_page;	/* 0x04 */
+	uint8_t  orig_video_mode;	/* 0x06 */
+	uint8_t  orig_video_cols;	/* 0x07 */
+	uint8_t  flags;		/* 0x08 */
+	uint8_t  unused2;		/* 0x09 */
+	uint16_t orig_video_ega_bx;/* 0x0a */
+	uint16_t unused3;		/* 0x0c */
+	uint8_t  orig_video_lines;	/* 0x0e */
+	uint8_t  orig_video_isVGA;	/* 0x0f */
+	uint16_t orig_video_points;/* 0x10 */
+
+	/* VESA graphic mode -- linear frame buffer */
+	uint16_t lfb_width;	/* 0x12 */
+	uint16_t lfb_height;	/* 0x14 */
+	uint16_t lfb_depth;	/* 0x16 */
+	uint32_t lfb_base;		/* 0x18 */
+	uint32_t lfb_size;		/* 0x1c */
+	uint16_t cl_magic, cl_offset; /* 0x20 */
+	uint16_t lfb_linelength;	/* 0x24 */
+	uint8_t  red_size;		/* 0x26 */
+	uint8_t  red_pos;		/* 0x27 */
+	uint8_t  green_size;	/* 0x28 */
+	uint8_t  green_pos;	/* 0x29 */
+	uint8_t  blue_size;	/* 0x2a */
+	uint8_t  blue_pos;		/* 0x2b */
+	uint8_t  rsvd_size;	/* 0x2c */
+	uint8_t  rsvd_pos;		/* 0x2d */
+	uint16_t vesapm_seg;	/* 0x2e */
+	uint16_t vesapm_off;	/* 0x30 */
+	uint16_t pages;		/* 0x32 */
+	uint16_t vesa_attributes;	/* 0x34 */
+	uint32_t capabilities;     /* 0x36 */
+	uint8_t  _reserved[6];	/* 0x3a */
+} __packed;
+
+int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
+			struct initramfs *initramfs,
+			struct setup_data *setup_data,
+			char *cmdline);
+
+/* Initramfs manipulation functions */
+
+struct initramfs *initramfs_init(void);
+int initramfs_add_data(struct initramfs *ihead, const void *data,
+		       size_t data_len, size_t len, size_t align);
+int initramfs_mknod(struct initramfs *ihead, const char *filename,
+		    int do_mkdir,
+		    uint16_t mode, size_t len, uint32_t major, uint32_t minor);
+int initramfs_add_file(struct initramfs *ihead, const void *data,
+		       size_t data_len, size_t len,
+		       const char *filename, int do_mkdir, uint32_t mode);
+int initramfs_load_file(struct initramfs *ihead, const char *src_filename,
+			const char *dst_filename, int do_mkdir, uint32_t mode);
+int initramfs_add_trailer(struct initramfs *ihead);
+int initramfs_load_archive(struct initramfs *ihead, const char *filename);
+
+/* Get the combined size of the initramfs */
+static inline uint32_t initramfs_size(struct initramfs *initramfs)
+{
+    struct initramfs *ip;
+    uint32_t size = 0;
+
+    if (!initramfs)
+	return 0;
+
+    for (ip = initramfs->next; ip->len; ip = ip->next) {
+	size = (size + ip->align - 1) & ~(ip->align - 1);	/* Alignment */
+	size += ip->len;
+    }
+
+    return size;
+}
+
+/* Setup data manipulation functions */
+
+struct setup_data *setup_data_init(void);
+int setup_data_add(struct setup_data *head, uint32_t type,
+		   const void *data, size_t data_len);
+int setup_data_load(struct setup_data *head, uint32_t type,
+		    const char *filename);
+
+#endif /* _SYSLINUX_LINUX_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/loadfile.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/loadfile.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/loadfile.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#ifndef LIBUTIL_LOADFILE_H
+#define LIBUTIL_LOADFILE_H
+
+#include <stddef.h>
+#include <stdio.h>
+
+/* loadfile() returns the true size of the file, but will guarantee valid,
+   zero-padded memory out to this boundary. */
+#define LOADFILE_ZERO_PAD	64
+
+int loadfile(const char *, void **, size_t *);
+int zloadfile(const char *, void **, size_t *);
+int floadfile(FILE *, void **, size_t *, const void *, size_t);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/memscan.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/memscan.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/memscan.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _SYSLINUX_MEMSCAN_H
+#define _SYSLINUX_MEMSCAN_H
+
+#include <linux/list.h>
+#include <syslinux/movebits.h>	/* addr_t */
+
+typedef int (*scan_memory_callback_t) (void *, addr_t, addr_t,
+				       enum syslinux_memmap_types type);
+
+struct syslinux_memscan {
+    int (*func)(scan_memory_callback_t callback, void *data);
+    struct list_head next;
+};
+
+void syslinux_memscan_add(struct syslinux_memscan *entry);
+int syslinux_memscan_new(int (*func)(scan_memory_callback_t cb, void *data));
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data);
+
+#endif /* _SYSLINUX_MEMSCAN_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/movebits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/movebits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/movebits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,110 @@
+#ifndef _SYSLINUX_MOVEBITS_H
+#define _SYSLINUX_MOVEBITS_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+typedef uint32_t addr_t;
+
+/*
+ * A syslinux_movelist is a linked list of move operations.  The ordering
+ * is important, so no sorting requirement can be imposed.
+ */
+struct syslinux_movelist {
+    addr_t dst;
+    addr_t src;
+    addr_t len;
+    struct syslinux_movelist *next;
+};
+
+/*
+ * A syslinux_memmap is a sorted, linked list of memory regions,
+ * guaranteed to satisfy the constraint that no adjacent zones have
+ * the same type.  Undefined memory ranges are represented with entries;
+ * they have type SMT_UNDEFINED.
+ *
+ * Note that there is no length field.  The length of a region is obtained
+ * by looking at the start of the next entry in the chain.
+ */
+enum syslinux_memmap_types {
+    SMT_ERROR = -2,		/* Internal error token */
+    SMT_END = -1,		/* End of list */
+    SMT_UNDEFINED = 0,		/* Unknown range */
+    SMT_FREE = 1,		/* Available memory */
+    SMT_RESERVED,		/* Unusable memory */
+    SMT_ALLOC,			/* Memory allocated by user */
+    SMT_ZERO,			/* Memory that should be zeroed */
+    SMT_TERMINAL,		/* Memory to be used as a last resort */
+};
+
+struct syslinux_memmap {
+    addr_t start;
+    enum syslinux_memmap_types type;
+    struct syslinux_memmap *next;
+};
+
+static inline bool valid_terminal_type(enum syslinux_memmap_types type)
+{
+    return (type == SMT_FREE) || (type == SMT_TERMINAL);
+}
+
+/*
+ * moves is computed from "fraglist" and "memmap".  Areas that are
+ * to be zeroed should be marked as such in the memmap, not in the
+ * fraglist.
+ */
+
+int syslinux_compute_movelist(struct syslinux_movelist **movelist,
+			      struct syslinux_movelist *fraglist,
+			      struct syslinux_memmap *memmap);
+
+struct syslinux_memmap *syslinux_memory_map(void);
+void syslinux_free_movelist(struct syslinux_movelist *);
+int syslinux_add_movelist(struct syslinux_movelist **,
+			  addr_t dst, addr_t src, addr_t len);
+int syslinux_allocate_from_list(struct syslinux_movelist **freelist,
+				addr_t dst, addr_t len);
+int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
+			struct syslinux_memmap *memmap,
+			addr_t entry_point, addr_t entry_type,
+			uint16_t bootflags);
+struct syslinux_memmap *syslinux_target_memmap(struct syslinux_movelist
+					       *fraglist,
+					       struct syslinux_memmap *memmap);
+
+/* Operatons on struct syslinux_memmap */
+struct syslinux_memmap *syslinux_init_memmap(void);
+int syslinux_add_memmap(struct syslinux_memmap **list,
+			addr_t start, addr_t len,
+			enum syslinux_memmap_types type);
+enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list,
+						addr_t start, addr_t len);
+int syslinux_memmap_largest(struct syslinux_memmap *list,
+			    enum syslinux_memmap_types type,
+			    addr_t * start, addr_t * len);
+int syslinux_memmap_highest(const struct syslinux_memmap *list,
+			    enum syslinux_memmap_types types,
+			    addr_t *start, addr_t len,
+			    addr_t ceiling, addr_t align);
+void syslinux_free_memmap(struct syslinux_memmap *list);
+struct syslinux_memmap *syslinux_dup_memmap(struct syslinux_memmap *list);
+int syslinux_memmap_find_type(struct syslinux_memmap *list,
+			      enum syslinux_memmap_types type,
+			      addr_t * start, addr_t * len, addr_t align);
+int syslinux_memmap_find(struct syslinux_memmap *mmap,
+			 addr_t *base, size_t size,
+			 bool relocate, size_t align,
+			 addr_t start_min, addr_t start_max,
+			 addr_t end_min, addr_t end_max);
+
+/* Debugging functions */
+#ifdef DEBUG
+void syslinux_dump_movelist(struct syslinux_movelist *ml);
+void syslinux_dump_memmap(struct syslinux_memmap *memmap);
+#else
+#define syslinux_dump_movelist(x) ((void)0)
+#define syslinux_dump_memmap(x)	  ((void)0)
+#endif
+
+#endif /* _SYSLINUX_MOVEBITS_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pmapi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pmapi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pmapi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pmapi.h
+ *
+ * Definitions for the Syslinux 4 protected-mode ABI
+ */
+
+#ifndef _SYSLINUX_PMAPI_H
+#define _SYSLINUX_PMAPI_H
+
+#include <stddef.h>
+#include <inttypes.h>
+
+/*
+ * Note: add new members to this structure only at the end.
+ * The position of elements in this structure is an ABI.
+ */
+struct _DIR_;
+struct dirent;
+
+struct com32_filedata {
+    size_t size;		/* File size */
+    int blocklg2;		/* log2(block size) */
+    uint16_t handle;		/* File handle */
+};
+
+struct com32_pmapi {
+    size_t __pmapi_size;
+
+    void *(*lmalloc)(size_t);
+    void (*lfree)(void *);
+
+    int (*open_file)(const char *, int, struct com32_filedata *);
+    size_t (*read_file)(uint16_t *, void *, size_t);
+    void (*close_file)(uint16_t);
+
+    struct _DIR_ *(*opendir)(const char *);
+    struct dirent *(*readdir)(struct _DIR_ *);
+    int (*closedir)(struct _DIR_ *);
+
+    void (*idle)(void);
+    void (*reset_idle)(void);
+
+    int (*chdir)(const char *);
+    char *(*getcwd)(char *, size_t);
+
+    /* Should be "const volatile", but gcc miscompiles that sometimes */
+    volatile uint32_t *jiffies;
+    volatile uint32_t *ms_timer;
+
+    const int sysappend_count;
+    const char * const *sysappend_strings;
+};
+
+#endif /* _SYSLINUX_PMAPI_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/pxe.h
+ *
+ * PXE definitions and function prototypes for SYSLINUX
+ */
+
+#ifndef _SYSLINUX_PXE_H
+#define _SYSLINUX_PXE_H
+
+#include <syslinux/pxe_api.h>
+
+/* SYSLINUX-defined PXE utility functions */
+int pxe_get_cached_info(int level, void **buf, size_t *len);
+int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE * gnt);
+uint32_t pxe_dns(const char *hostname);
+
+#endif /* _SYSLINUX_PXE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe_api.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe_api.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/pxe_api.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,595 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/pxe_api.h
+ *
+ * PXE type and constant definitions for SYSLINUX
+ */
+
+#ifndef _SYSLINUX_PXE_API_H
+#define _SYSLINUX_PXE_API_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+/* PXE spec structures and definitions.  These mostly follow the PXE
+   spec, except when the PXE spec is unnecessarily stupid.  Of course,
+   that is most of the time. */
+
+/* Basic types; use Unix-like _t convention instead of SCREAMING; also
+   re-use types we already have, like in_addr_t. */
+
+typedef uint16_t pxenv_status_t;
+
+#define MAC_ADDR_LEN	16
+typedef uint8_t mac_addr_t[MAC_ADDR_LEN];
+
+/* "Protected mode segment descriptor" according to PXE... */
+typedef struct {
+    uint16_t sel;
+    uint32_t base;
+    uint16_t size;
+} __packed pxe_segdesc_t;
+
+typedef far_ptr_t segoff16_t;
+
+typedef struct {
+    uint8_t opcode;
+#define BOOTP_REQ 1
+#define BOOTP_REP 2
+    uint8_t Hardware;
+    uint8_t Hardlen;
+    uint8_t Gatehops;
+    uint32_t ident;
+    uint16_t seconds;
+    uint16_t Flags;
+#define BOOTP_BCAST 0x8000
+    in_addr_t cip;		/* Client IP address */
+    in_addr_t yip;		/* You IP address */
+    in_addr_t sip;		/* next server IP address */
+    in_addr_t gip;		/*relay agent IP address */
+    mac_addr_t CAddr;
+    uint8_t Sname[64];
+    uint8_t bootfile[128];
+    union {
+#define BOOTP_DHCPVEND 1024
+	uint8_t d[BOOTP_DHCPVEND];
+	struct {
+	    uint8_t magic[4];
+#define VM_RFC1048 0x63825363L
+	    uint32_t flags;
+	    uint8_t pad[56];
+	} v;
+    } vendor;
+} __packed pxe_bootp_t;
+
+/* Function calling structures and constants */
+
+typedef struct s_PXENV_GET_CACHED_INFO {
+    pxenv_status_t Status;
+    uint16_t PacketType;
+#define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
+#define PXENV_PACKET_TYPE_DHCP_ACK 2
+#define PXENV_PACKET_TYPE_CACHED_REPLY 3
+    uint16_t BufferSize;
+    segoff16_t Buffer;
+    uint16_t BufferLimit;
+} __packed t_PXENV_GET_CACHED_INFO;
+
+typedef struct s_PXENV_START_UNDI {
+    pxenv_status_t Status;
+    uint16_t AX;
+    uint16_t BX;
+    uint16_t DX;
+    uint16_t DI;
+    uint16_t ES;
+} __packed t_PXENV_START_UNDI;
+
+typedef struct s_PXENV_STOP_UNDI {
+    pxenv_status_t Status;
+} __packed t_PXENV_STOP_UNDI;
+
+typedef struct s_PXENV_START_BASE {
+    pxenv_status_t Status;
+} __packed t_PXENV_START_BASE;
+
+typedef struct s_PXENV_STOP_BASE {
+    pxenv_status_t Status;
+} __packed t_PXENV_STOP_BASE;
+
+typedef struct s_PXENV_TFTP_OPEN {
+    pxenv_status_t Status;
+    in_addr_t ServerIPAddress;
+    in_addr_t GatewayIPAddress;
+    uint8_t FileName[128];
+    in_port_t TFTPPort;
+    uint16_t PacketSize;
+} __packed t_PXENV_TFTP_OPEN;
+
+typedef struct s_PXENV_TFTP_CLOSE {
+    pxenv_status_t Status;
+} __packed t_PXENV_TFTP_CLOSE;
+
+typedef struct s_PXENV_TFTP_READ {
+    pxenv_status_t Status;
+    uint16_t PacketNumber;
+    uint16_t BufferSize;
+    segoff16_t Buffer;
+} __packed t_PXENV_TFTP_READ;
+
+typedef struct s_PXENV_TFTP_READ_FILE {
+    pxenv_status_t Status;
+    uint8_t FileName[128];
+    uint32_t BufferSize;
+    void *Buffer;
+    in_addr_t ServerIPAddress;
+    in_addr_t GatewayIPAddress;
+    in_addr_t McastIPAddress;
+    in_port_t TFTPClntPort;
+    in_port_t TFTPSrvPort;
+    uint16_t TFTPOpenTimeOut;
+    uint16_t TFTPReopenDelay;
+} __packed t_PXENV_TFTP_READ_FILE;
+
+typedef struct s_PXENV_TFTP_GET_FSIZE {
+    pxenv_status_t Status;
+    in_addr_t ServerIPAddress;
+    in_addr_t GatewayIPAddress;
+    uint8_t FileName[128];
+    uint32_t FileSize;
+} __packed t_PXENV_TFTP_GET_FSIZE;
+
+typedef struct s_PXENV_UDP_OPEN {
+    pxenv_status_t status;
+    in_addr_t src_ip;
+} __packed t_PXENV_UDP_OPEN;
+
+typedef struct s_PXENV_UDP_CLOSE {
+    pxenv_status_t status;
+} __packed t_PXENV_UDP_CLOSE;
+
+typedef struct s_PXENV_UDP_WRITE {
+    pxenv_status_t status;
+    in_addr_t ip;
+    in_addr_t gw;
+    in_port_t src_port;
+    in_port_t dst_port;
+    uint16_t buffer_size;
+    segoff16_t buffer;
+} __packed t_PXENV_UDP_WRITE;
+
+typedef struct s_PXENV_UDP_READ {
+    pxenv_status_t status;
+    in_addr_t src_ip;
+    in_addr_t dest_ip;
+    in_port_t s_port;
+    in_port_t d_port;
+    uint16_t buffer_size;
+    segoff16_t buffer;
+} __packed t_PXENV_UDP_READ;
+
+typedef struct s_PXENV_UNDI_STARTUP {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_STARTUP;
+
+typedef struct s_PXENV_UNDI_CLEANUP {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_CLEANUP;
+
+typedef struct s_PXENV_UNDI_INITIALIZE {
+    pxenv_status_t Status;
+    void *ProtocolIni;
+    uint8_t reserved[8];
+} __packed t_PXENV_UNDI_INITIALIZE;
+
+#define MAXNUM_MCADDR 8
+typedef struct s_PXENV_UNDI_MCAST_ADDRESS {
+    uint16_t MCastAddrCount;
+    mac_addr_t McastAddr[MAXNUM_MCADDR];
+} __packed t_PXENV_UNDI_MCAST_ADDRESS;
+
+typedef struct s_PXENV_UNDI_RESET {
+    pxenv_status_t Status;
+    t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __packed t_PXENV_UNDI_RESET;
+
+typedef struct s_PXENV_UNDI_SHUTDOWN {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_SHUTDOWN;
+
+typedef struct s_PXENV_UNDI_OPEN {
+    pxenv_status_t Status;
+    uint16_t OpenFlag;
+    uint16_t PktFilter;
+#define FLTR_DIRECTED 0x0001
+#define FLTR_BRDCST 0x0002
+#define FLTR_PRMSCS 0x0004
+#define FLTR_SRC_RTG 0x0008
+     t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __packed t_PXENV_UNDI_OPEN;
+
+typedef struct s_PXENV_UNDI_CLOSE {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_CLOSE;
+
+typedef struct s_PXENV_UNDI_TRANSMIT {
+    pxenv_status_t Status;
+    uint8_t Protocol;
+#define P_UNKNOWN 0
+#define P_IP 1
+#define P_ARP 2
+#define P_RARP 3
+    uint8_t XmitFlag;
+#define XMT_DESTADDR 0x0000
+#define XMT_BROADCAST 0x0001
+    segoff16_t DestAddr;
+    segoff16_t TBD;
+    uint32_t Reserved[2];
+} __packed t_PXENV_UNDI_TRANSMIT;
+#define MAX_DATA_BLKS 8
+typedef struct s_PXENV_UNDI_TBD {
+    uint16_t ImmedLength;
+    segoff16_t Xmit;
+    uint16_t DataBlkCount;
+    struct DataBlk {
+	uint8_t TDPtrType;
+	uint8_t TDRsvdByte;
+	uint16_t TDDataLen;
+	segoff16_t TDDataPtr;
+    } DataBlock[MAX_DATA_BLKS];
+} __packed t_PXENV_UNDI_TBD;
+
+typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS {
+    pxenv_status_t Status;
+     t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __packed t_PXENV_UNDI_SET_MCAST_ADDR;
+
+typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS {
+    pxenv_status_t Status;
+    mac_addr_t StationAddress;
+} __packed t_PXENV_UNDI_SET_STATION_ADDR;
+
+typedef struct s_PXENV_UNDI_SET_PACKET_FILTER {
+    pxenv_status_t Status;
+    uint8_t filter;
+} __packed t_PXENV_UNDI_SET_PACKET_FILTER;
+
+typedef struct s_PXENV_UNDI_GET_INFORMATION {
+    pxenv_status_t Status;
+    uint16_t BaseIo;
+    uint16_t IntNumber;
+    uint16_t MaxTranUnit;
+    uint16_t HwType;
+#define ETHER_TYPE 1
+#define EXP_ETHER_TYPE 2
+#define IEEE_TYPE 6
+#define ARCNET_TYPE 7
+    uint16_t HwAddrLen;
+    mac_addr_t CurrentNodeAddress;
+    mac_addr_t PermNodeAddress;
+    uint16_t ROMAddress;
+    uint16_t RxBufCt;
+    uint16_t TxBufCt;
+} __packed t_PXENV_UNDI_GET_INFORMATION;
+
+typedef struct s_PXENV_UNDI_GET_STATISTICS {
+    pxenv_status_t Status;
+    uint32_t XmtGoodFrames;
+    uint32_t RcvGoodFrames;
+    uint32_t RcvCRCErrors;
+    uint32_t RcvResourceErrors;
+} __packed t_PXENV_UNDI_GET_STATISTICS;
+
+typedef struct s_PXENV_UNDI_CLEAR_STATISTICS {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_CLEAR_STATISTICS;
+
+typedef struct s_PXENV_UNDI_INITIATE_DIAGS {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_INITIATE_DIAGS;
+
+typedef struct s_PXENV_UNDI_FORCE_INTERRUPT {
+    pxenv_status_t Status;
+} __packed t_PXENV_UNDI_FORCE_INTERRUPT;
+
+typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS {
+    pxenv_status_t Status;
+    in_addr_t InetAddr;
+    mac_addr_t MediaAddr;
+} __packed t_PXENV_UNDI_GET_MCAST_ADDR;
+
+typedef struct s_PXENV_UNDI_GET_NIC_TYPE {
+    pxenv_status_t Status;
+    uint8_t NicType;
+#define PCI_NIC 2
+#define PnP_NIC 3
+#define CardBus_NIC 4
+    union {
+	struct {
+	    uint16_t Vendor_ID;
+	    uint16_t Dev_ID;
+	    uint8_t Base_Class;
+	    uint8_t Sub_Class;
+	    uint8_t Prog_Intf;
+	    uint8_t Rev;
+	    uint16_t BusDevFunc;
+	    uint16_t SubVendor_ID;
+	    uint16_t SubDevice_ID;
+	} pci, cardbus;
+	struct {
+	    uint32_t EISA_Dev_ID;
+	    uint8_t Base_Class;
+	    uint8_t Sub_Class;
+	    uint8_t Prog_Intf;
+	    uint16_t CardSelNum;
+	} __packed pnp;
+    } __packed info;
+} __packed t_PXENV_UNDI_GET_NIC_TYPE;
+
+typedef struct s_PXENV_UNDI_GET_IFACE_INFO {
+    pxenv_status_t Status;
+    uint8_t IfaceType[16];
+    uint32_t LinkSpeed;
+    uint32_t ServiceFlags;
+    uint32_t Reserved[4];
+} __packed t_PXENV_UNDI_GET_IFACE_INFO;
+#define PXE_UNDI_IFACE_FLAG_BCAST	0x00000001
+#define PXE_UNDI_IFACE_FLAG_MCAST	0x00000002
+#define PXE_UNDI_IFACE_FLAG_GROUP	0x00000004
+#define PXE_UNDI_IFACE_FLAG_PROMISC	0x00000008
+#define PXE_UNDI_IFACE_FLAG_SOFTMAC	0x00000010
+#define PXE_UNDI_IFACE_FLAG_STATS	0x00000020
+#define PXE_UNDI_IFACE_FLAG_DIAGS	0x00000040
+#define PXE_UNDI_IFACE_FLAG_LOOPBACK	0x00000080
+#define PXE_UNDI_IFACE_FLAG_RCVCHAIN	0x00000100
+#define PXE_UNDI_IFACE_FLAG_IBMSRCRT	0x00000200
+#define PXE_UNDI_IFACE_FLAG_RESET	0x00000400
+#define PXE_UNDI_IFACE_FLAG_OPEN	0x00000800
+#define PXE_UNDI_IFACE_FLAG_IRQ		0x00001000
+#define PXE_UNDI_IFACE_FLAG_SRCRT	0x00002000
+#define PXE_UNDI_IFACE_FLAG_GDTVIRT	0x00004000
+#define PXE_UNDI_IFACE_FLAG_MULTI	0x00008000
+#define PXE_UNDI_IFACE_FLAG_LKFISZ	0x00010000
+
+typedef struct s_PXENV_UNDI_GET_STATE {
+#define PXE_UNDI_GET_STATE_STARTED 1
+#define PXE_UNDI_GET_STATE_INITIALIZED 2
+#define PXE_UNDI_GET_STATE_OPENED 3
+    pxenv_status_t Status;
+    uint8_t UNDIstate;
+} __packed t_PXENV_UNDI_GET_STATE;
+
+typedef struct s_PXENV_UNDI_ISR {
+    pxenv_status_t Status;
+    uint16_t FuncFlag;
+    uint16_t BufferLength;
+    uint16_t FrameLength;
+    uint16_t FrameHeaderLength;
+    segoff16_t Frame;
+    uint8_t ProtType;
+    uint8_t PktType;
+} __packed t_PXENV_UNDI_ISR;
+
+typedef struct s_PXENV_FILE_API_CHECK {
+    pxenv_status_t Status;
+    uint16_t Size;
+    uint32_t Magic;
+    uint32_t Provider;
+    uint32_t APIMask;
+    uint32_t Flags;
+} __packed t_PXENV_FILE_API_CHECK;
+
+typedef struct s_PXENV_FILE_READ {
+    pxenv_status_t Status;
+    uint16_t FileHandle;
+    uint16_t BufferSize;
+    segoff16_t Buffer;
+} __packed t_PXENV_FILE_READ;
+
+typedef struct s_PXENV_FILE_OPEN {
+    pxenv_status_t Status;
+    uint16_t FileHandle;
+    segoff16_t FileName;
+    uint32_t Reserved;
+} __packed t_PXENV_FILE_OPEN;
+
+typedef struct s_PXENV_FILE_CLOSE {
+    pxenv_status_t Status;
+    uint16_t FileHandle;
+} __packed t_PXENV_FILE_CLOSE;
+
+typedef struct s_PXENV_GET_FILE_SIZE {
+    pxenv_status_t Status;
+    uint16_t FileHandle;
+    uint32_t FileSize;
+} __packed t_PXENV_GET_FILE_SIZE;
+
+typedef struct s_PXENV_UNLOAD_STACK {
+    pxenv_status_t Status;
+    uint8_t reserved[10];
+} __packed t_PXENV_UNLOAD_STACK;
+    
+#define PXENV_UNDI_ISR_IN_START 1
+#define PXENV_UNDI_ISR_IN_PROCESS 2
+#define PXENV_UNDI_ISR_IN_GET_NEXT 3
+/* One of these will be returned for
+   PXENV_UNDI_ISR_IN_START */
+#define PXENV_UNDI_ISR_OUT_OURS 0
+#define PXENV_UNDI_USR_OUT_NOT_OURS 1
+/* One of these will be returned for
+   PXENV_UNDI_ISR_IN_PROCESS and
+   PXENV_UNDI_ISR_IN_GET_NEXT */
+#define PXENV_UNDI_ISR_OUT_DONE 0
+#define PXENV_UNDI_ISR_OUT_TRANSMIT 2
+#define PXENV_UNDI_ISR_OUT_RECEIVE 3
+#define PXENV_UNDI_ISR_OUT_BUSY 4
+
+/* Function numbers and error codes */
+
+#define PXENV_TFTP_OPEN			0x0020
+#define PXENV_TFTP_CLOSE		0x0021
+#define PXENV_TFTP_READ			0x0022
+#define PXENV_TFTP_READ_FILE		0x0023
+#define PXENV_TFTP_READ_FILE_PMODE	0x0024
+#define PXENV_TFTP_GET_FSIZE		0x0025
+
+#define PXENV_UDP_OPEN			0x0030
+#define PXENV_UDP_CLOSE			0x0031
+#define PXENV_UDP_READ			0x0032
+#define PXENV_UDP_WRITE			0x0033
+
+#define PXENV_START_UNDI		0x0000
+#define PXENV_UNDI_STARTUP		0x0001
+#define PXENV_UNDI_CLEANUP		0x0002
+#define PXENV_UNDI_INITIALIZE		0x0003
+#define PXENV_UNDI_RESET_NIC		0x0004
+#define PXENV_UNDI_SHUTDOWN		0x0005
+#define PXENV_UNDI_OPEN			0x0006
+#define PXENV_UNDI_CLOSE		0x0007
+#define PXENV_UNDI_TRANSMIT		0x0008
+#define PXENV_UNDI_SET_MCAST_ADDR	0x0009
+#define PXENV_UNDI_SET_STATION_ADDR	0x000A
+#define PXENV_UNDI_SET_PACKET_FILTER	0x000B
+#define PXENV_UNDI_GET_INFORMATION	0x000C
+#define PXENV_UNDI_GET_STATISTICS	0x000D
+#define PXENV_UNDI_CLEAR_STATISTICS	0x000E
+#define PXENV_UNDI_INITIATE_DIAGS	0x000F
+#define PXENV_UNDI_FORCE_INTERRUPT	0x0010
+#define PXENV_UNDI_GET_MCAST_ADDR	0x0011
+#define PXENV_UNDI_GET_NIC_TYPE		0x0012
+#define PXENV_UNDI_GET_IFACE_INFO	0x0013
+#define PXENV_UNDI_ISR			0x0014
+#define	PXENV_STOP_UNDI			0x0015	/* Overlap...? */
+#define PXENV_UNDI_GET_STATE		0x0015	/* Overlap...? */
+
+#define PXENV_UNLOAD_STACK		0x0070
+#define PXENV_GET_CACHED_INFO		0x0071
+#define PXENV_RESTART_DHCP		0x0072
+#define PXENV_RESTART_TFTP		0x0073
+#define PXENV_MODE_SWITCH		0x0074
+#define PXENV_START_BASE		0x0075
+#define PXENV_STOP_BASE			0x0076
+
+/* gPXE extensions... */
+#define PXENV_FILE_OPEN			0x00e0
+#define PXENV_FILE_CLOSE		0x00e1
+#define PXENV_FILE_SELECT		0x00e2
+#define PXENV_FILE_READ			0x00e3
+#define PXENV_GET_FILE_SIZE		0x00e4
+#define PXENV_FILE_EXEC			0x00e5
+#define PXENV_FILE_API_CHECK		0x00e6
+
+/* Exit codes */
+#define PXENV_EXIT_SUCCESS				 0x0000
+#define PXENV_EXIT_FAILURE				 0x0001
+
+/* Status codes */
+#define PXENV_STATUS_SUCCESS				 0x00
+#define PXENV_STATUS_FAILURE				 0x01
+#define PXENV_STATUS_BAD_FUNC				 0x02
+#define PXENV_STATUS_UNSUPPORTED			 0x03
+#define PXENV_STATUS_KEEP_UNDI				 0x04
+#define PXENV_STATUS_KEEP_ALL				 0x05
+#define PXENV_STATUS_OUT_OF_RESOURCES			 0x06
+#define PXENV_STATUS_ARP_TIMEOUT			 0x11
+#define PXENV_STATUS_UDP_CLOSED				 0x18
+#define PXENV_STATUS_UDP_OPEN				 0x19
+#define PXENV_STATUS_TFTP_CLOSED			 0x1a
+#define PXENV_STATUS_TFTP_OPEN				 0x1b
+#define PXENV_STATUS_MCOPY_PROBLEM			 0x20
+#define PXENV_STATUS_BIS_INTEGRITY_FAILURE		 0x21
+#define PXENV_STATUS_BIS_VALIDATE_FAILURE		 0x22
+#define PXENV_STATUS_BIS_INIT_FAILURE			 0x23
+#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE		 0x24
+#define PXENV_STATUS_BIS_GBOA_FAILURE			 0x25
+#define PXENV_STATUS_BIS_FREE_FAILURE			 0x26
+#define PXENV_STATUS_BIS_GSI_FAILURE			 0x27
+#define PXENV_STATUS_BIS_BAD_CKSUM			 0x28
+#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS		 0x30
+#define PXENV_STATUS_TFTP_OPEN_TIMEOUT			 0x32
+
+#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE		 0x33
+#define PXENV_STATUS_TFTP_READ_TIMEOUT			 0x35
+#define PXENV_STATUS_TFTP_ERROR_OPCODE			 0x36
+#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION	 0x38
+#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION	 0x39
+#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES		 0x3a
+#define PXENV_STATUS_TFTP_FILE_NOT_FOUND		 0x3b
+#define PXENV_STATUS_TFTP_ACCESS_VIOLATION		 0x3c
+#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS		 0x3d
+#define PXENV_STATUS_TFTP_NO_FILESIZE			 0x3e
+#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE		 0x3f
+#define PXENV_STATUS_DHCP_TIMEOUT			 0x51
+#define PXENV_STATUS_DHCP_NO_IP_ADDRESS			 0x52
+#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME		 0x53
+#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS		 0x54
+#define PXENV_STATUS_UNDI_INVALID_FUNCTION		 0x60
+#define PXENV_STATUS_UNDI_MEDIATEST_FAILED		 0x61
+#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST	 0x62
+#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC		 0x63
+#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY		 0x64
+#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA	 0x65
+#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA		 0x66
+#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS		 0x67
+#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM		 0x68
+#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR		 0x69
+#define PXENV_STATUS_UNDI_INVALID_STATE			 0x6a
+#define PXENV_STATUS_UNDI_TRANSMIT_ERROR		 0x6b
+#define PXENV_STATUS_UNDI_INVALID_PARAMETER		 0x6c
+#define PXENV_STATUS_BSTRAP_PROMPT_MENU			 0x74
+#define PXENV_STATUS_BSTRAP_MCAST_ADDR			 0x76
+#define PXENV_STATUS_BSTRAP_MISSING_LIST		 0x77
+#define PXENV_STATUS_BSTRAP_NO_RESPONSE			 0x78
+#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG		 0x79
+#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE		 0xa0
+#define PXENV_STATUS_BINL_NO_PXE_SERVER			 0xa1
+#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE		 0xa2
+#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE		 0xa3
+#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED		 0xb0
+#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY		 0xc0
+#define PXENV_STATUS_LOADER_NO_BC_ROMID			 0xc1
+#define PXENV_STATUS_LOADER_BAD_BC_ROMID		 0xc2
+#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE	 0xc3
+#define PXENV_STATUS_LOADER_NO_UNDI_ROMID		 0xc4
+#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID		 0xc5
+#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE	 0xc6
+#define PXENV_STATUS_LOADER_NO_PXE_STRUCT		 0xc8
+#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT		 0xc9
+#define PXENV_STATUS_LOADER_UNDI_START			 0xca
+#define PXENV_STATUS_LOADER_BC_START			 0xcb
+
+int __weak pxe_call(int, void *);
+void __weak unload_pxe(uint16_t flags);
+uint32_t __weak dns_resolv(const char *);
+
+extern uint32_t __weak SendCookies;
+void __weak http_bake_cookies(void);
+
+#endif /* _SYSLINUX_PXE_API_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/reboot.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/reboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/reboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/reboot.h
+ *
+ * Reboot the system
+ */
+
+#ifndef _SYSLINUX_REBOOT_H
+#define _SYSLINUX_REBOOT_H
+
+#include <klibc/compiler.h>
+
+__noreturn syslinux_reboot(int warm);
+
+#endif /* _SYSLINUX_REBOOT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/resolve.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/resolve.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/resolve.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/resolve.h
+ *
+ * Interface to the syslinux DNS query API
+ */
+
+#ifndef _SYSLINUX_RESOLVE_H
+#define _SYSLINUX_RESOLVE_H
+
+#include <netinet/in.h>
+
+in_addr_t syslinux_resolve_hostname(const char *);
+
+#endif /* _SYSLINUX_RESOLVE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/sysappend.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/sysappend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/sysappend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/sysappend.h
+ *
+ * List of the Syslinux sysappend strings
+ */
+
+#ifndef _SYSLINUX_SYSAPPEND_H
+#define _SYSLINUX_SYSAPPEND_H
+
+enum syslinux_sysappend {
+    SYSAPPEND_IP,		/* PXELINUX: ip= address */
+    SYSAPPEND_BOOTIF,		/* PXELINUX: BOOTIF= address */
+    SYSAPPEND_SYSUUID,		/* System UUID from PXE or DMI */
+    SYSAPPEND_CPU,		/* CPU features */
+    SYSAPPEND_SYSVENDOR,	/* System or MB vendor from DMI */
+    SYSAPPEND_SYSPRODUCT,	/* System or MB product from DMI */
+    SYSAPPEND_SYSVERSION,	/* System or MB version from DMI */
+    SYSAPPEND_SYSSERIAL,	/* System or MB serial from DMI */
+    SYSAPPEND_SYSSKU,		/* System SKU from DMI */
+    SYSAPPEND_SYSFAMILY,	/* System family from DMI */
+    SYSAPPEND_MBVENDOR,		/* System or MB vendor from DMI */
+    SYSAPPEND_MBPRODUCT,	/* System or MB product from DMI */
+    SYSAPPEND_MBVERSION,	/* System or MB version from DMI */
+    SYSAPPEND_MBSERIAL,		/* System or MB serial from DMI */
+    SYSAPPEND_MBASSET,		/* MB asset tag from DMI */
+    SYSAPPEND_BIOSVENDOR,	/* BIOS vendor */
+    SYSAPPEND_BIOSVERSION,	/* BIOS version string */
+    SYSAPPEND_SYSFF,		/* System form factor */
+    SYSAPPEND_FSUUID,		/* Boot filesystem UUID */
+    SYSAPPEND_MAX		/* Total number of strings */
+};
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/version.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/version.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/version.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,6 @@
+#ifndef _SYSLINUX_VERSION_H
+#define _SYSLINUX_VERSION_H
+
+#define __STDC_VERSION__ 200000L
+
+#endif /* _SYSLINUX_VERSION_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/vesacon.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/vesacon.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/vesacon.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _SYSLINUX_VESACON_H
+#define _SYSLINUX_VESACON_H
+
+#include <stdbool.h>
+
+int vesacon_default_background(void);
+void vesacon_set_resolution(int, int);
+int vesacon_load_background(const char *);
+int vesacon_set_background(unsigned int);
+void vesacon_cursor_enable(bool);
+
+#endif /* _SYSLINUX_VESACON_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/video.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/video.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/video.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video.h
+ *
+ * SYSLINUX video API functions.
+ */
+
+#ifndef _SYSLINUX_VIDEO_H
+#define _SYSLINUX_VIDEO_H
+
+#include <stdint.h>
+
+void syslinux_force_text_mode(void);
+void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize);
+int syslinux_font_query(uint8_t **font);
+
+#endif /* _SYSLINUX_API_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/syslinux/zio.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/syslinux/zio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/syslinux/zio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * <syslinux/zio.h>
+ */
+
+#ifndef _SYSLINUX_ZIO_H
+#define _SYSLINUX_ZIO_H
+
+#include <stdio.h>
+
+int zopen(const char *, int, ...);
+FILE *zfopen(const char *, const char *);
+
+#endif /* _SYSLINUX_ZIO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/time.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/time.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/time.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,6 @@
+#ifndef _TIME_H
+#define _TIME_H
+
+/* empty */
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/tinyjpeg.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/tinyjpeg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/tinyjpeg.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/*
+ * Small jpeg decoder library (header file)
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef __JPEGDEC_H__
+#define __JPEGDEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct jdec_private;
+
+/* Flags that can be set by any applications */
+#define TINYJPEG_FLAGS_MJPEG_TABLE	(1<<1)
+
+/* Format accepted in outout */
+struct tinyjpeg_colorspace;
+typedef const struct tinyjpeg_colorspace *tinyjpeg_colorspace_t;
+
+extern const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY, TINYJPEG_FMT_BGR24,
+  TINYJPEG_FMT_RGB24, TINYJPEG_FMT_YUV420P, TINYJPEG_FMT_BGRA32,
+  TINYJPEG_FMT_RGBA32;
+
+struct jdec_private *tinyjpeg_init(void);
+void tinyjpeg_free(struct jdec_private *priv);
+
+int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size);
+int tinyjpeg_decode(struct jdec_private *priv, tinyjpeg_colorspace_t pixel_format);
+const char *tinyjpeg_get_errorstring(struct jdec_private *priv);
+void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height);
+int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents);
+int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents);
+int tinyjpeg_get_bytes_per_row(struct jdec_private *priv, unsigned int *bytes, unsigned int ncomponents);
+int tinyjpeg_set_bytes_per_row(struct jdec_private *priv, const unsigned int *bytes, unsigned int ncomponents);
+int tinyjpeg_set_flags(struct jdec_private *priv, int flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/include/unistd.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/unistd.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/unistd.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+/*
+ * unistd.h
+ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+__extern __noreturn _exit(int);
+
+__extern int open(const char *, int, ...);
+__extern int close(int);
+
+__extern ssize_t read(int, void *, size_t);
+__extern ssize_t write(int, const void *, size_t);
+
+__extern int isatty(int);
+
+__extern int getscreensize(int, int *, int *);
+
+__extern char *getcwd(char *, int);
+__extern int chdir(const char *);
+
+__extern unsigned int sleep(unsigned int);
+__extern unsigned int msleep(unsigned int);
+
+__extern int getopt(int, char *const *, const char *);
+__extern char *optarg;
+__extern int optind, opterr, optopt;
+
+/* Standard file descriptor numbers. */
+#define STDIN_FILENO	0
+#define STDOUT_FILENO	1
+#define STDERR_FILENO	2
+
+#endif /* _UNISTD_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/zconf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/zconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/zconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,428 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  define gz_error              z_gz_error
+#  define gz_intmax             z_gz_intmax
+#  define gz_strwinerror        z_gz_strwinerror
+#  define gzbuffer              z_gzbuffer
+#  define gzclearerr            z_gzclearerr
+#  define gzclose               z_gzclose
+#  define gzclose_r             z_gzclose_r
+#  define gzclose_w             z_gzclose_w
+#  define gzdirect              z_gzdirect
+#  define gzdopen               z_gzdopen
+#  define gzeof                 z_gzeof
+#  define gzerror               z_gzerror
+#  define gzflush               z_gzflush
+#  define gzgetc                z_gzgetc
+#  define gzgets                z_gzgets
+#  define gzoffset              z_gzoffset
+#  define gzoffset64            z_gzoffset64
+#  define gzopen                z_gzopen
+#  define gzopen64              z_gzopen64
+#  define gzprintf              z_gzprintf
+#  define gzputc                z_gzputc
+#  define gzputs                z_gzputs
+#  define gzread                z_gzread
+#  define gzrewind              z_gzrewind
+#  define gzseek                z_gzseek
+#  define gzseek64              z_gzseek64
+#  define gzsetparams           z_gzsetparams
+#  define gztell                z_gztell
+#  define gztell64              z_gztell64
+#  define gzungetc              z_gzungetc
+#  define gzwrite               z_gzwrite
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  define uncompress            z_uncompress
+#  define zError                z_zError
+#  define zcalloc               z_zcalloc
+#  define zcfree                z_zcfree
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  define gzFile                z_gzFile
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef STDC
+#  include <sys/types.h>    /* for off_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#  include <unistd.h>       /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>     /* for off_t */
+#  endif
+#  ifndef z_off_t
+#    define z_off_t off_t
+#  endif
+#endif
+
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define z_off64_t off64_t
+#else
+#  define z_off64_t z_off_t
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/include/zlib.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/include/zlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/include/zlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1613 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.5, April 19th, 2010
+
+  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.5"
+#define ZLIB_VERNUM 0x1250
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip streams in memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use in the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).  Some
+    output may be provided even if flush is not set.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed code
+  block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error.  After
+  deflate has returned Z_STREAM_END, the only possible operations on the stream
+  are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step.  In this case, avail_out must be at least the
+  value returned by deflateBound (see below).  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  In doubt, the data is considered
+  binary.  This field is only for information purposes and does not affect the
+  compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  If next_in is not Z_NULL and avail_in is large enough (the
+   exact value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit() does not process any header information -- that is deferred
+   until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing will
+    resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all the uncompressed data.  (The size
+  of the uncompressed data may have been saved by the compressor for this
+  purpose.) The next operation on this stream must be inflateEnd to deallocate
+  the decompression state.  The use of Z_FINISH is never required, but can be
+  used to inform inflate that a faster approach may be used for the single
+  inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK or Z_TREES is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained, so applications that need that information should
+  instead use raw inflate, see inflateInit2() below, or inflateBack() and
+  perform their own processing of the gzip header and trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent.  In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any call
+   of deflate.  The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort).  deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.  The
+   stream will keep the same compression level and any other attributes that
+   may have been set by deflateInit2.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression level is changed, the input available so far is
+   compressed with the old level (and may be flushed); the new level will take
+   effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to be
+   compressed and flushed.  In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+   strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a full flush point (see above the
+   description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+   if no more input was provided, Z_DATA_ERROR if no flush point has been
+   found, or Z_STREAM_ERROR if the stream structure was inconsistent.  In the
+   success case, the application may save the current current value of total_in
+   which indicates where valid compressed data was found.  In the error case,
+   the application may repeatedly call inflateSync, providing more input each
+   time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above or -1 << 16 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the normal
+   behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.) Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef voidp gzFile;       /* opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.) Also "a"
+   can be used instead of "w" to request that the gzip stream that will be
+   written be appended to the file.  "+" will result in an error, since reading
+   and writing to the same gzip file is not supported.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Two buffers are allocated, either both of the specified size when
+   writing, or one of the specified size and the other twice that size when
+   reading.  A larger buffer size of, for example, 64K or 128K bytes will
+   noticeably increase the speed of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.
+
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file was not in gzip format, gzread copies the given number of
+   bytes into the buffer.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream, or failing that, reading the rest
+   of the input file directly without decompression.  The entire input file
+   will be read if gzread is called until it returns less than the requested
+   len.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or 0 in case of error.  The number of
+   uncompressed bytes written is limited to 8191, or one less than the buffer
+   size given to gzbuffer().  The caller should assure that this limit is not
+   exceeded.  If it is exceeded, then gzprintf() will return an error (0) with
+   nothing written.  In this case, there may also be a buffer overflow with
+   unpredictable consequences, which is possible only if zlib was compiled with
+   the insecure functions sprintf() or vsprintf() because the secure snprintf()
+   or vsnprintf() functions were not available.  This can be determined using
+   zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatented gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.  This state can change from
+   false to true while reading the input file if the end of a gzip stream is
+   reached, but is followed by data that is not another gzip stream.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the for the crc.  Pre- and post-conditioning (one's
+   complement) is performed within this function so it shouldn't be done by the
+   application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+                                            ZLIB_VERSION, sizeof(z_stream))
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
+#  define gzopen gzopen64
+#  define gzseek gzseek64
+#  define gztell gztell64
+#  define gzoffset gzoffset64
+#  define adler32_combine adler32_combine64
+#  define crc32_combine crc32_combine64
+#  ifdef _LARGEFILE64_SOURCE
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,134 @@
+#
+# ONLY INCLUDE MIT OR 2/3-BSD-LICENSED CODE IN THIS LIBRARY
+#
+
+# Include configuration rules
+NOGPL := 1
+VPATH = $(SRC)
+include $(MAKEDIR)/lib.mk
+
+## OPTIONAL OBJECTS, AVAILABLE AS DYNAMIC LINKED MODULES
+# PNG library object files
+LIBPNG_OBJS = \
+	libpng/png.o libpng/pngset.o libpng/pngget.o libpng/pngrutil.o  \
+	libpng/pngtrans.o libpng/pngwutil.o libpng/pngread.o		\
+	libpng/pngrio.o libpng/pngwio.o libpng/pngwrite.o		\
+	libpng/pngrtran.o libpng/pngwtran.o libpng/pngmem.o		\
+	libpng/pngerror.o libpng/pngpread.o
+
+# JPG library object files
+LIBJPG_OBJS = \
+	jpeg/tinyjpeg.o jpeg/jidctflt.o	jpeg/decode1.o jpeg/decode3.o   \
+	jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o		\
+	jpeg/rgba32.o jpeg/bgra32.o					
+
+ifdef EFI_BUILD
+I915VESA_OBJ =
+else
+I915VESA_OBJ = sys/vesa/i915resolution.o
+endif
+
+LIBVESA_OBJS = \
+	sys/vesacon_write.o sys/vesaserial_write.o			\
+	sys/vesa/initvesa.o sys/vesa/drawtxt.o	sys/vesa/background.o	\
+	sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o	\
+	$(I915VESA_OBJ)
+
+LIBMISC_OBJS = \
+	sys/libansi.o sys/gpxe.o
+
+LIBPCI_OBJS = \
+	pci/cfgtype.o pci/scan.o pci/bios.o				\
+	pci/readb.o pci/readw.o pci/readl.o				\
+	pci/writeb.o pci/writew.o pci/writel.o
+
+LIBSYSLINUX_OBJS = \
+	syslinux/reboot.o syslinux/keyboard.o				\
+	syslinux/version.o						\
+	syslinux/pxe_get_cached.o syslinux/pxe_get_nic.o		\
+	syslinux/pxe_dns.o						\
+	syslinux/video/fontquery.o syslinux/video/reportmode.o
+
+DYNENTRY_OBJS = \
+	atexit.o onexit.o abort.o
+
+MINLIBOBJS = \
+	syslinux/ipappend.o \
+	syslinux/dsinfo.o \
+	$(LIBOTHER_OBJS) \
+	$(LIBGCC_OBJS) \
+	$(LIBCONSOLE_OBJS) \
+	$(LIBLOAD_OBJS) \
+	$(LIBZLIB_OBJS)
+#	$(LIBVESA_OBJS)
+
+DYNLIBOBJS = \
+	$(LIBZLIB_OBJS) \
+	$(LIBPNG_OBJS) \
+	$(LIBJPG_OBJS) \
+	$(LIBPCI_OBJS) \
+	$(LIBVESA_OBJS) \
+	$(LIBSYSLINUX_OBJS) \
+	$(LIBLOAD_OBJS) \
+	$(LIBMISC_OBJS) \
+	$(DYNENTRY_OBJS)
+
+
+LIBOBJS = $(DYNLIBOBJS)
+
+BINDIR   = /usr/bin
+LIBDIR   = /usr/lib
+DATADIR  = /usr/share
+AUXDIR   = $(DATADIR)/syslinux
+INCDIR   = /usr/include
+COM32DIR = $(AUXDIR)/com32
+
+all: makeoutputdirs libcom32.c32 libcom32min.a libcom32core.a
+
+makeoutputdirs:
+	@mkdir -p $(foreach b, \
+		$(addprefix $(OBJ)/,$(sort $(dir $(LIBOBJS) $(MINLIBOBJS) $(CORELIBOBJS)))),$(b))
+
+libcom32.elf : $(LIBOBJS)
+	rm -f $@
+	$(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
+
+libcom32min.a : $(MINLIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $^
+	$(RANLIB) $@
+
+libcom32core.a : $(CORELIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $^
+	$(RANLIB) $@
+
+tidy dist clean:
+	rm -f sys/vesa/alphatbl.c errlist.c
+	find . \( -name \*.o -o -name \*.a -o -name .\*.d -o -name \*.tmp \) -print0 | \
+		xargs -0r rm -f
+
+spotless: clean
+	rm -f *.a *.c32
+	rm -f *~ \#* */*~ */\#*
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+	install -m 644 $(SRC)/com32.ld $(INSTALLROOT)$(COM32DIR)
+	-rm -rf $(INSTALLROOT)$(COM32DIR)/include
+	cp -r $(SRC)/../include $(INSTALLROOT)$(COM32DIR)
+
+errlist.c: makeerrlist.pl $(SRC)/../include/errno.h
+	$(PERL) $<  $(CFLAGS) -errlist > $@ || rm -f $@
+
+# These files are performance critical, and doesn't compile well with -Os
+sys/vesa/drawtxt.o: sys/vesa/drawtxt.c
+	$(CC) $(MAKEDEPS) $(CFLAGS) -O3 -c -o $@ $<
+
+sys/vesa/alphatbl.c: sys/vesa/alphatbl.pl
+	$(PERL) $< > $@
+
+jpeg/jidctflt.o: jpeg/jidctflt.c
+	$(CC) $(MAKEDEPS) $(CFLAGS) -O3 -c -o $@ $<
+
+-include .*.d */.*.d */*/.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/lib/abort.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/abort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/abort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * abort.c
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+void abort(void)
+{
+    _exit(255);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/asprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/asprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/asprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+/*
+ * asprintf.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+int asprintf(char **bufp, const char *format, ...)
+{
+    va_list ap, ap1;
+    int rv;
+    int bytes;
+    char *p;
+
+    va_start(ap, format);
+    va_copy(ap1, ap);
+
+    bytes = vsnprintf(NULL, 0, format, ap1) + 1;
+    va_end(ap1);
+
+    *bufp = p = malloc(bytes);
+    if (!p)
+	rv = -1;
+    else
+	rv = vsnprintf(p, bytes, format, ap);
+
+    va_end(ap);
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atexit.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atexit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atexit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+/*
+ * atexit.c
+ */
+
+#include <stdlib.h>
+
+int atexit(void (*fctn) (void))
+{
+    return on_exit((void (*)(int, void *))fctn, NULL);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atexit.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atexit.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atexit.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * atexit.h
+ *
+ * atexit()/on_exit() internal definitions
+ */
+
+#ifndef ATEXIT_H
+#define ATEXIT_H
+
+struct atexit {
+    void (*fctn) (int, void *);
+    void *arg;			/* on_exit() parameter */
+    struct atexit *next;
+};
+
+#endif /* ATEXIT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atoi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atoi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atoi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE int
+#define NAME atoi
+#include "atox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atol.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atol.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atol.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE long
+#define NAME atol
+#include "atox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atoll.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atoll.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atoll.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE long long
+#define NAME atoll
+#include "atox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/atox.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/atox.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/atox.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * atox.c
+ *
+ * atoi(), atol(), atoll()
+ */
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+TYPE NAME(const char *nptr)
+{
+    return (TYPE) strntoumax(nptr, (char **)NULL, 10, ~(size_t) 0);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/bufprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/bufprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/bufprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <bufprintf.h>
+
+int vbufprintf(struct print_buf *buf, const char *format, va_list ap)
+{
+    va_list ap2;
+    int rv;
+
+    va_copy(ap2, ap);
+    rv = vsnprintf(NULL, 0, format, ap);
+
+    /* >= to make sure we have space for terminating null */
+    if (rv + buf->len >= buf->size) {
+	size_t newsize = rv + buf->len + BUFPAD;
+	char *newbuf;
+
+	newbuf = realloc(buf->buf, newsize);
+	if (!newbuf) {
+	    rv = -1;
+	    goto bail;
+	}
+
+	buf->buf = newbuf;
+	buf->size = newsize;
+    }
+
+    rv = vsnprintf(buf->buf + buf->len, buf->size - buf->len, format, ap2);
+    buf->len += rv;
+bail:
+    va_end(ap2);
+    return rv;
+}
+
+int bufprintf(struct print_buf *buf, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vbufprintf(buf, format, ap);
+    va_end(ap);
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/calloc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/calloc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/calloc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * calloc.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+/* FIXME: This should look for multiplication overflow */
+
+void *calloc(size_t nmemb, size_t size)
+{
+    return zalloc(size * nmemb);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/chrreplace.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/chrreplace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/chrreplace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+#include <ctype.h>
+
+/* Replace char 'old' by char 'new' in source */
+void chrreplace(char *source, char old, char new) 
+{
+    while (*source) { 
+	source++;
+	if (source[0] == old) source[0]=new;
+    }
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/com32.ld
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/com32.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/com32.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,128 @@
+/*
+ * Linker script for COM32 binaries using libcom32
+ */
+
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386",
+	      "elf32-i386")
+OUTPUT_ARCH(i386)
+EXTERN(_start)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0;
+  HIDDEN (__executable_start = .);
+  HIDDEN (_stext = .);
+
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0x90909090
+  .text           :
+  {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0x90909090
+  HIDDEN (_etext = .);
+
+  HIDDEN( __rodata_start = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  HIDDEN(__rodata_end = .);
+
+  /*
+   * The difference betwee .ctors/.dtors and .init_array/.fini_array
+   * is the ordering, but we don't use prioritization for libcom32, so
+   * just lump them all together and hope that's okay.
+   */
+  . = ALIGN(4);
+  .ctors          : {
+    HIDDEN(__ctors_start = .);
+    KEEP (*(SORT(.preinit_array*)))
+    KEEP (*(SORT(.init_array*)))
+    KEEP (*(SORT(.ctors*)))
+    HIDDEN(__ctors_end = .);
+  }
+  .dtors          : {
+    HIDDEN(__dtors_start = .);
+    KEEP (*(SORT(.fini_array*)))
+    KEEP (*(SORT(.dtors*)))
+    HIDDEN(__dtors_end = .);
+  }
+
+  .got            : {
+    HIDDEN(__got_start = .);
+    KEEP (*(.got.plt))
+    KEEP (*(.got))
+    HIDDEN(__got_end = .);
+  }
+
+  /* Adjust the address for the data segment.  Avoid mixing code and
+     data within same 128-byte chunk. */
+  . = ALIGN(128);
+
+  .data           :
+  {
+    HIDDEN(_sdata = .);
+    KEEP(*(.data .data.* .gnu.linkonce.d.*))
+    SORT(CONSTRUCTORS)
+    *(.data1)
+    . = ALIGN(4);
+    HIDDEN(_edata = .);
+  }
+
+  HIDDEN(__bss_start = .);
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(4);
+  }
+  . = ALIGN(4);
+  HIDDEN(_end = .);
+
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /DISCARD/ : { *(.note.GNU-stack) }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/creat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/creat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/creat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,12 @@
+/*
+ * creat.c
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int creat(const char *pathname, mode_t mode)
+{
+    return open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/ctypes.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/ctypes.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/ctypes.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,284 @@
+/*
+ * ctypes.c
+ *
+ * This is the array that defines <ctype.h> classes.
+ * This assumes ISO 8859-1.
+ */
+
+#include <ctype.h>
+
+const unsigned char __ctypes[257] = {
+    0,				/* EOF */
+
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl | __ctype_space,	/* BS */
+    __ctype_cntrl | __ctype_space,	/* TAB */
+    __ctype_cntrl | __ctype_space,	/* LF */
+    __ctype_cntrl | __ctype_space,	/* VT */
+    __ctype_cntrl | __ctype_space,	/* FF */
+    __ctype_cntrl | __ctype_space,	/* CR */
+    __ctype_cntrl,		/* control character */
+
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+
+    __ctype_print | __ctype_space,	/* space */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_digit | __ctype_xdigit,	/* digit */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper | __ctype_xdigit,	/* A-F */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_upper,	/* G-Z */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower | __ctype_xdigit,	/* a-f */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_lower,	/* g-z */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_cntrl,		/* control character */
+
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+    __ctype_cntrl,		/* control character */
+
+    __ctype_print | __ctype_space,	/* NBSP */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_punct,	/* punctuation */
+
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_upper,	/* upper accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_punct,	/* punctuation */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+    __ctype_print | __ctype_lower,	/* lower accented */
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/dhcppack.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/dhcppack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/dhcppack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,166 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+// #include <arpa/inet.h>
+#include <netinet/in.h>
+
+// #include "dhcp.h"
+#include <dhcp.h>
+
+/*
+ * Pack DHCP options into an option field, without overload support.
+ * On return, len contains the number of active bytes, and the full
+ * field is zero-padded.
+ *
+ * Options which are successfully placed have their length zeroed out.
+ */
+static int dhcp_pack_field_zero(void *field, size_t *len,
+				struct dhcp_option opt[256])
+{
+	int i;
+	size_t xlen, plen;
+	const uint8_t *p;
+	uint8_t *q = field;
+	size_t spc = *len;
+	int err = 0;
+
+	if (!*len)
+		return ENOSPC;
+
+	for (i = 1; i < 255; i++) {
+		if (opt[i].len < 0)
+			continue;
+
+		/* We need to handle the 0 case as well as > 255 */
+		if (opt[i].len <= 255)
+			xlen = opt[i].len + 2;
+		else
+			xlen = opt[i].len + 2*((opt[i].len+254)/255);
+
+		p = opt[i].data;
+
+		if (xlen >= spc) {
+			/* This option doesn't fit... */
+			err++;
+			continue;
+		}
+
+		xlen = opt[i].len;
+		do {
+			*q++ = i;
+			*q++ = plen = xlen > 255 ? 255 : xlen;
+			if (plen)
+				memcpy(q, p, plen);
+			q += plen;
+			p += plen;
+			spc -= plen+2;
+			xlen -= plen;
+		} while (xlen);
+
+		opt[i].len = -1;
+	}
+
+	*q++ = 255;		/* End marker */
+	memset(q, 0, spc);	/* Zero-pad the rest of the field */
+	
+	*len = xlen = q - (uint8_t *)field;
+	return err;
+}
+
+/*
+ * Pack DHCP options into an option field, without overload support.
+ * On return, len contains the number of active bytes, and the full
+ * field is zero-padded.
+ *
+ * Use this to encode encapsulated option fields.
+ */
+int dhcp_pack_field(void *field, size_t *len,
+		    struct dhcp_option opt[256])
+{
+	struct dhcp_option ox[256];
+	
+	memcpy(ox, opt, sizeof ox);
+	return dhcp_pack_field_zero(field, len, ox);
+}
+
+/*
+ * Pack DHCP options into a packet.
+ * Apply overloading if (and only if) the "file" or "sname" option
+ * doesn't fit in the respective dedicated fields.
+ */
+int dhcp_pack_packet(void *packet, size_t *len,
+		     const struct dhcp_option opt[256])
+{
+	struct dhcp_packet *pkt = packet;
+	size_t spc = *len;
+	uint8_t overload;
+	struct dhcp_option ox[256];
+	uint8_t *q;
+	int err;
+
+	if (spc < sizeof(struct dhcp_packet))
+		return ENOSPC;	/* Buffer impossibly small */
+	
+	pkt->magic = htonl(DHCP_VENDOR_MAGIC);
+
+	memcpy(ox, opt, sizeof ox);
+
+	/* Figure out if we should do overloading or not */
+	overload = 0;
+
+	if (opt[67].len > 128)
+		overload |= 1;
+	else
+		ox[67].len = -1;
+
+	if (opt[66].len > 64)
+		overload |= 2;
+	else
+		ox[66].len = -1;
+
+	/* Kill any passed-in overload option */
+	ox[52].len = -1;
+
+	q = pkt->options;
+	spc -= 240;
+
+	/* Force option 53 (DHCP packet type) first */
+	if (ox[53].len == 1) {
+		*q++ = 53;
+		*q++ = 1;
+		*q++ = *(uint8_t *)ox[53].data;
+		spc -= 3;
+		ox[53].len = -1;
+	}
+
+	/* Follow with the overload option, if applicable */
+	if (overload) {
+		*q++ = 52;
+		*q++ = 1;
+		*q++ = overload;
+		spc -= 3;
+	}
+
+	err = dhcp_pack_field_zero(q, &spc, ox);
+	*len = spc + (q-(uint8_t *)packet);
+
+	if (overload & 1) {
+		spc = 128;
+		err = dhcp_pack_field_zero(pkt->file, &spc, ox);
+	} else {
+		memset(pkt->file, 0, 128);
+		if (opt[67].len > 0)
+			memcpy(pkt->file, opt[67].data, opt[67].len);
+	}
+
+	if (overload & 2) {
+		spc = 64;
+		err = dhcp_pack_field_zero(pkt->sname, &spc, ox);
+	} else {
+		memset(pkt->sname, 0, 64);
+		if (opt[66].len > 0)
+			memcpy(pkt->sname, opt[66].data, opt[66].len);
+	}
+
+	return err;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/dhcpunpack.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/dhcpunpack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/dhcpunpack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+#define _GNU_SOURCE		/* For strnlen() */
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+// #include <arpa/inet.h>
+#include <netinet/in.h>
+
+// #include "dhcp.h"
+#include <dhcp.h>
+
+/*
+ * Unpack DHCP options from a field.  Assumes opt is pre-initalized
+ * (to all zero in the common case.)
+ */
+int dhcp_unpack_field(const void *field, size_t len,
+		      struct dhcp_option opt[256])
+{
+	const uint8_t *p = field;
+	int err = 0;
+
+	while (len > 1) {
+		uint8_t op;
+		size_t xlen;
+
+		op = *p++; len--;
+		if (op == 0)
+			continue;
+		else if (op == 255)
+			break;
+		
+		xlen = *p++; len--;
+		if (xlen > len)
+			break;
+		if (opt[op].len < 0)
+			opt[op].len = 0;
+		if (xlen) {
+			opt[op].data = realloc(opt[op].data,
+					       opt[op].len + xlen + 1);
+			if (!opt[op].data) {
+				err = ENOMEM;
+				continue;
+			}
+			memcpy((char *)opt[op].data + opt[op].len, p, xlen);
+			opt[op].len += xlen;
+			/* Null-terminate as a courtesy to users */
+			*((char *)opt[op].data + opt[op].len) = 0;
+			p += xlen;
+			len -= xlen;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * Unpack a DHCP packet, with overload support.  Do not use this
+ * to unpack an encapsulated option set.
+ */
+int dhcp_unpack_packet(const void *packet, size_t len,
+		       struct dhcp_option opt[256])
+{
+	const struct dhcp_packet *pkt = packet;
+	int err;
+	uint8_t overload;
+	int i;
+
+	if (len < 240 || pkt->magic != htonl(DHCP_VENDOR_MAGIC))
+		return EINVAL;	/* Bogus packet */
+	
+	for (i = 0; i < 256; i++) {
+		opt[i].len = -1; /* Option not present */
+		opt[i].data = NULL;
+	}
+	
+	err = dhcp_unpack_field(pkt->options, len-240, opt);
+
+	overload = 0;
+	if (opt[52].len == 1) {
+		overload = *(uint8_t *)opt[52].data;
+		free(opt[52].data);
+		opt[52].len = -1;
+		opt[52].data = NULL;
+	}
+
+	if (overload & 1) {
+		err |= dhcp_unpack_field(pkt->file, 128, opt);
+	} else {
+		opt[67].len  = strnlen((const char *)pkt->file, 128);
+		if (opt[67].len) {
+			opt[67].data = malloc(opt[67].len + 1);
+			if (opt[67].data) {
+				memcpy(opt[67].data, pkt->file, opt[67].len);
+				*((char *)opt[67].data + opt[67].len) = 0;
+			} else {
+				err |= ENOMEM;
+			}
+		}
+	}
+
+	if (overload & 2) {
+		err |= dhcp_unpack_field(pkt->sname, 64, opt);
+	} else {
+		opt[66].len  = strnlen((const char *)pkt->sname, 64);
+		if (opt[66].len) {
+			opt[66].data = malloc(opt[66].len + 1);
+			if (opt[66].data) {
+				memcpy(opt[66].data, pkt->file, opt[66].len);
+				*((char *)opt[66].data + opt[66].len) = 0;
+			} else {
+				err |= ENOMEM;
+			}
+		}
+	}
+
+	return err;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/dprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/dprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/dprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * dprintf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef DEBUG_PORT
+
+void vdprintf(const char *, va_list);
+
+void dprintf(const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    vdprintf(format, ap);
+    va_end(ap);
+}
+
+#endif /* DEBUG_PORT */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/exit.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/exit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/exit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * exit.c
+ *
+ * The regular exit
+ */
+
+#include <sys/module.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "atexit.h"
+
+__noreturn exit(int rv)
+{
+	struct atexit *ap;
+
+    for (ap = __syslinux_current->u.x.atexit_list; ap; ap = ap->next) {
+	ap->fctn(rv, ap->arg);	/* This assumes extra args are harmless */
+    }
+
+    _exit(rv);
+}    
+
+__noreturn _Exit(int rv)
+{
+    _exit(rv);
+}
+
+__noreturn _exit(int rv)
+{
+    longjmp(__syslinux_current->u.x.process_exit, (uint8_t)rv+1);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fclose.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fclose.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fclose.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * fclose.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int fclose(FILE * __f)
+{
+    return close(fileno(__f));
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fdopendir.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fdopendir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fdopendir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * fdopendir.c
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+
+DIR *fdopendir(int __fd)
+{
+    (void)__fd;
+
+    errno = ENOSYS;
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fgetc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fgetc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fgetc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/*
+ * fgetc.c
+ *
+ * Extremely slow fgetc implementation, using _fread().  If people
+ * actually need character-oriented input to be fast, we may actually
+ * have to implement buffering.  Sigh.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int fgetc(FILE * f)
+{
+    unsigned char ch;
+
+    return (_fread(&ch, 1, f) == 1) ? (int)ch : EOF;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fgets.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fgets.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fgets.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+/*
+ * fgets.c
+ *
+ * This will be very slow due to the implementation of getc(),
+ * but we can't afford to drain characters we don't need from
+ * the input.
+ */
+
+#include <stdio.h>
+
+char *fgets(char *s, int n, FILE * f)
+{
+    int ch;
+    char *p = s;
+
+    while (n > 1) {
+	ch = getc(f);
+	if (ch == EOF) {
+	    *p = '\0';
+	    return (p == s) ? NULL : s;
+	}
+	*p++ = ch;
+	if (ch == '\n')
+	    break;
+	n--;
+    }
+    if (n)
+	*p = '\0';
+
+    return s;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fopen.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fopen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fopen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/*
+ * fopen.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+FILE *fopen(const char *file, const char *mode)
+{
+    int flags = O_RDONLY;
+    int plus = 0;
+    int fd;
+
+    while (*mode) {
+	switch (*mode) {
+	case 'r':
+	    flags = O_RDONLY;
+	    break;
+	case 'w':
+	    flags = O_WRONLY | O_CREAT | O_TRUNC;
+	    break;
+	case 'a':
+	    flags = O_WRONLY | O_CREAT | O_APPEND;
+	    break;
+	case '+':
+	    plus = 1;
+	    break;
+	}
+	mode++;
+    }
+
+    if (plus) {
+	flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+    }
+
+    fd = open(file, flags, 0666);
+
+    if (fd < 0)
+	return NULL;
+    else
+	return fdopen(fd, mode);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fopendev.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fopendev.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fopendev.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/*
+ * fopendev.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+FILE *fopendev(const struct dev_info * dev, const char *mode)
+{
+    int flags = O_RDONLY;
+    int plus = 0;
+    int fd;
+
+    while (*mode) {
+	switch (*mode) {
+	case 'r':
+	    flags = O_RDONLY;
+	    break;
+	case 'w':
+	    flags = O_WRONLY | O_CREAT | O_TRUNC;
+	    break;
+	case 'a':
+	    flags = O_WRONLY | O_CREAT | O_APPEND;
+	    break;
+	case '+':
+	    plus = 1;
+	    break;
+	}
+	mode++;
+    }
+
+    if (plus) {
+	flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+    }
+
+    fd = opendev(file, flags);
+
+    if (fd < 0)
+	return NULL;
+    else
+	return fdopen(fd, mode);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+/*
+ * fprintf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int fprintf(FILE * file, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vfprintf(file, format, ap);
+    va_end(ap);
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fputc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fputc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fputc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * fputc.c
+ *
+ * gcc "printf decompilation" expects this to exist...
+ */
+
+#include <stdio.h>
+
+int fputc(int c, FILE * f)
+{
+    unsigned char ch = c;
+
+    return _fwrite(&ch, 1, f) == 1 ? ch : EOF;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fputs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fputs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fputs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * fputs.c
+ *
+ * This isn't quite fputs() in the stdio sense, since we don't
+ * have stdio, but it takes a file descriptor argument instead
+ * of the FILE *.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+int fputs(const char *s, FILE * file)
+{
+    return _fwrite(s, strlen(s), file);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fread.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ * fread.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+
+size_t _fread(void *buf, size_t count, FILE * f)
+{
+    size_t bytes = 0;
+    ssize_t rv;
+    char *p = buf;
+
+    while (count) {
+	rv = read(fileno(f), p, count);
+	if (rv == -1) {
+	    if (errno == EINTR || errno == EAGAIN)
+		continue;
+	    else
+		break;
+	} else if (rv == 0) {
+	    break;
+	}
+
+	p += rv;
+	bytes += rv;
+	count -= rv;
+    }
+
+    return bytes;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fread2.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fread2.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fread2.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * fread2.c
+ *
+ * The actual fread() function as a non-inline
+ */
+
+#define __NO_FREAD_FWRITE_INLINES
+#include <stdio.h>
+
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE * f)
+{
+    return _fread(ptr, size * nmemb, f) / size;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fwrite.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ * fwrite.c
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+
+size_t _fwrite(const void *buf, size_t count, FILE * f)
+{
+    size_t bytes = 0;
+    ssize_t rv;
+    const char *p = buf;
+
+    while (count) {
+	rv = write(fileno(f), p, count);
+	if (rv == -1) {
+	    if (errno == EINTR || errno == EAGAIN)
+		continue;
+	    else
+		break;
+	} else if (rv == 0) {
+	    break;
+	}
+
+	p += rv;
+	bytes += rv;
+	count -= rv;
+    }
+
+    return bytes;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/fwrite2.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/fwrite2.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/fwrite2.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * fwrite2.c
+ *
+ * The actual fwrite() function as a non-inline
+ */
+
+#define __NO_FREAD_FWRITE_INLINES
+#include <stdio.h>
+
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * f)
+{
+    return _fwrite(ptr, size * nmemb, f) / size;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/getcwd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/getcwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/getcwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,12 @@
+/*
+ * getcwd.c
+ */
+
+#include <com32.h>
+#include <syslinux/pmapi.h>
+#include <fs.h>
+
+char *getcwd(char *buf, size_t size)
+{
+    return core_getcwd(buf, size);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/getopt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/getopt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/getopt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,97 @@
+/*
+ * getopt.c
+ *
+ * Simple POSIX getopt(), no GNU extensions...
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+
+char *optarg;
+int optind, opterr, optopt;
+static struct getopt_private_state {
+	const char *optptr;
+	const char *last_optstring;
+	char *const *last_argv;
+} pvt;
+
+int getopt(int argc, char *const *argv, const char *optstring)
+{
+	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] == '-' && !carg[2]) {
+		optind++;
+		return -1;
+	}
+
+	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/com32/lib/getopt_long.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/getopt_long.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/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 <unistd.h>
+#include <string.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/com32/lib/i386/elf.ld
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/i386/elf.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/i386/elf.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,171 @@
+/*
+ * Linker script for ELF dynamic loaded modules.
+ */
+
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386",
+	      "elf32-i386")
+OUTPUT_ARCH(i386)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0 + SIZEOF_HEADERS;
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn        :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+    }
+  .rel.plt        : { *(.rel.plt) }
+  .rela.plt       : { *(.rela.plt) }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0x90909090
+  .plt            : { *(.plt) }
+  .text           :
+  {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0x90909090
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  . = ALIGN(4);
+  .preinit_array     :
+  {
+    KEEP (*(.preinit_array))
+  }
+  .ctors          :
+  {
+  	__ctors_start = .;
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*(.ctors_modinit))
+    KEEP (*(.ctors_modmain))
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+	__ctors_end = .;
+  }
+  
+  .dtors          :
+  {
+  	__dtors_start = .;
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    KEEP (*(.dtors_modexit))
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+	__dtors_end = .;
+  }
+  
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) }
+  /*. = DATA_SEGMENT_RELRO_END (12, .); -> This gives a "invalid assignment to location counter" error */
+  .got.plt        : { *(.got.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    KEEP (*(.gnu.linkonce.d.*personality*))
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  PROVIDE (edata = .);
+  PROVIDE (_edata = .); 
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 32 / 8 : 1);
+  }
+  . = ALIGN(32 / 8);
+  . = ALIGN(32 / 8);
+  PROVIDE (_end = .); 
+  PROVIDE (end = .);
+  /*. = DATA_SEGMENT_END (.); -> This gives a "invalid assignment to location counter" error */
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.eh_frame) }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/i386/setjmp.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/i386/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/i386/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/*
+ * arch/i386/setjmp.S
+ *
+ * setjmp/longjmp for the i386 architecture
+ *
+ *
+ *
+ * The jmp_buf is assumed to contain the following, in order:
+ *	%ebx
+ *	%esp
+ *	%ebp
+ *	%esi
+ *	%edi
+ *	<return address>
+ */
+
+	.text
+	.align 4
+
+	.globl _setjmp
+	.type _setjmp, @function
+_setjmp:				# gcc 4.0.1 wants this as an alias?
+
+	.globl setjmp
+	.type setjmp, @function
+setjmp:
+#ifdef REGPARM
+	movl %eax,%edx
+#else
+	movl 4(%esp),%edx
+#endif
+	popl %ecx			# Return address, and adjust the stack
+	xorl %eax,%eax			# Return value
+	movl %ebx,(%edx)
+	movl %esp,4(%edx)		# Post-return %esp!
+	pushl %ecx			# Make the call/return stack happy
+	movl %ebp,8(%edx)
+	movl %esi,12(%edx)
+	movl %edi,16(%edx)
+	movl %ecx,20(%edx)		# Return address
+	ret
+
+	.size setjmp,.-setjmp
+
+	.text
+	.align 4
+	.globl longjmp
+	.type longjmp, @function
+longjmp:
+#ifdef REGPARM
+	xchgl %eax,%edx
+#else
+	movl 4(%esp),%edx		# jmp_ptr address
+	movl 8(%esp),%eax		# Return value
+#endif
+	movl (%edx),%ebx
+	movl 4(%edx),%esp
+	movl 8(%edx),%ebp
+	movl 12(%edx),%esi
+	movl 16(%edx),%edi
+	jmp *20(%edx)
+
+	.size longjmp,.-longjmp
Index: bootcd/isolinux/syslinux-6.03/com32/lib/inet.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/inet.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/inet.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <netinet/in.h>
+
+char *inet_ntoa(struct in_addr addr)
+{
+    static char buf[16];
+    const uint8_t *bytes = (const uint8_t *)&addr.s_addr;
+
+    sprintf(buf, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2], bytes[3]);
+    return buf;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgr24.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgr24.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgr24.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,373 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+  if (i<0)
+    return 0;
+  else if (i>255)
+    return 255;
+  else
+    return i;
+}
+
+/**
+ *  YCrCb -> BGR24 (1x1)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_BGR24_1x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 8*3;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+
+       Y++;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ *  YCrCb -> BGR24 (2x1)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_BGR24_2x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 16*3;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+       }
+
+       Y += 2;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/*
+ *  YCrCb -> BGR24 (1x2)
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void YCrCB_to_BGR24_1x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0 ; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+
+       if (i > 1) {
+	   y  = Y[8] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+       }
+
+       Y++;
+    }
+    Y += 8;
+    p += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ *  YCrCb -> BGR24 (2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void YCrCB_to_BGR24_2x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+       }
+
+       if (i > 1) {
+	   y  = Y[16+0] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+
+	   if (j > 1) {
+	       y  = Y[16+1] << SCALEBITS;
+	       b = (y + add_b) >> SCALEBITS;
+	       *p2++ = clamp(b);
+	       g = (y + add_g) >> SCALEBITS;
+	       *p2++ = clamp(g);
+	       r = (y + add_r) >> SCALEBITS;
+	       *p2++ = clamp(r);
+	   }
+       }
+
+       Y += 2;
+    }
+    Y  += 16;
+    p  += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_bgr24(struct jdec_private *priv,
+			    unsigned int *bytes_per_blocklines,
+			    unsigned int *bytes_per_mcu)
+{
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width * 3;
+  if (!priv->components[0])
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+  bytes_per_mcu[0] = 3*8;
+
+  return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_bgr24 =
+  {
+    {
+      YCrCB_to_BGR24_1x1,
+      YCrCB_to_BGR24_1x2,
+      YCrCB_to_BGR24_2x1,
+      YCrCB_to_BGR24_2x2,
+    },
+    tinyjpeg_decode_mcu_3comp_table,
+    initialize_bgr24
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_BGR24 = &format_bgr24;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgra32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgra32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/bgra32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,390 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+  if (i<0)
+    return 0;
+  else if (i>255)
+    return 255;
+  else
+    return i;
+}
+
+/**
+ *  YCrCb -> BGRA32 (1x1)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 8*4;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       a = 255;
+       *p++ = a;
+
+       Y++;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ *  YCrCb -> BGRA32 (2x1)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 16*4;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j -= 2) {
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       a = 255;
+       *p++ = a;
+       
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   a = 255;
+	   *p++ = a;
+       }
+
+       Y += 2;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/*
+ *  YCrCb -> BGRA32 (1x2)
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       a = 255;
+       *p++ = a;
+
+       if (i > 1) {
+	   y  = Y[8] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   a = 255;
+	   *p2++ = a;
+       }
+
+       Y++;
+    }
+    Y += 8;
+    p += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ *  YCrCb -> BGRA32 (2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       a = 255;
+       *p++ = a;
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   a = 255;
+	   *p++ = a;
+       }
+
+       if (i > 1) {
+	   y  = Y[16+0] << SCALEBITS;
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   a = 255;
+	   *p2++ = a;
+	   
+	   if (j > 1) {
+	       y  = Y[16+1] << SCALEBITS;
+	       b = (y + add_b) >> SCALEBITS;
+	       *p2++ = clamp(b);
+	       g = (y + add_g) >> SCALEBITS;
+	       *p2++ = clamp(g);
+	       r = (y + add_r) >> SCALEBITS;
+	       *p2++ = clamp(r);
+	       a = 255;
+	       *p2++ = a;
+	   }
+       }
+
+       Y += 2;
+    }
+    Y  += 16;
+    p  += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_bgra32(struct jdec_private *priv,
+			     unsigned int *bytes_per_blocklines,
+			     unsigned int *bytes_per_mcu)
+{
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width * 4;
+  if (!priv->components[0])
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+  bytes_per_mcu[0] = 4*8;
+
+  return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_bgra32 =
+  {
+    {
+      YCrCB_to_BGRA32_1x1,
+      YCrCB_to_BGRA32_1x2,
+      YCrCB_to_BGRA32_2x1,
+      YCrCB_to_BGRA32_2x2,
+    },
+    tinyjpeg_decode_mcu_3comp_table,
+    initialize_bgra32
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_BGRA32 = &format_bgra32;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode1.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode1.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode1.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,138 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*
+ * Decode a 1x1 directly in 1 color
+ */
+static void decode_MCU_1x1_1plane(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 8);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+  IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+  IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+
+/*
+ * Decode a 2x1
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void decode_MCU_2x1_1plane(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+
+/*
+ * Decode a 2x2 directly in GREY format (8bits)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void decode_MCU_2x2_1plane(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+/*
+ * Decode a 1x2 mcu
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void decode_MCU_1x2_1plane(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 8);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64, 8);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4] = {
+   decode_MCU_1x1_1plane,
+   decode_MCU_1x2_1plane,
+   decode_MCU_2x1_1plane,
+   decode_MCU_2x2_1plane,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode3.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/decode3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,142 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*
+ * Decode all the 3 components for 1x1
+ */
+static void decode_MCU_1x1_3planes(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 8);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+  IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+  IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 2x1
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void decode_MCU_2x1_3planes(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+  IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+  IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 2x2
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void decode_MCU_2x2_3planes(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+  IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+  IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 1x2 mcu
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void decode_MCU_1x2_3planes(struct jdec_private *priv)
+{
+  // Y
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y, 8);
+  tinyjpeg_process_Huffman_data_unit(priv, cY);
+  IDCT(&priv->component_infos[cY], priv->Y+64, 8);
+
+  // Cb
+  tinyjpeg_process_Huffman_data_unit(priv, cCb);
+  IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+  // Cr
+  tinyjpeg_process_Huffman_data_unit(priv, cCr);
+  IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4] = {
+   decode_MCU_1x1_3planes,
+   decode_MCU_1x2_3planes,
+   decode_MCU_2x1_3planes,
+   decode_MCU_2x2_3planes,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/grey.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/grey.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/grey.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,117 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/**
+ *  YCrCb -> Grey (1x1, 1x2)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_Grey_1xN(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *y;
+  unsigned char *p;
+  unsigned int i;
+  int offset_to_next_row;
+
+  p = priv->plane[0];
+  y = priv->Y;
+  offset_to_next_row = priv->bytes_per_row[0];
+
+  for (i = sy; i > 0; i--) {
+     memcpy(p, y, sx);
+     y += 8;
+     p += offset_to_next_row;
+  }
+}
+
+/**
+ *  YCrCb -> Grey (2x1, 2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_Grey_2xN(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *y;
+  unsigned char *p;
+  unsigned int i;
+  int offset_to_next_row;
+
+  p = priv->plane[0];
+  y = priv->Y;
+  offset_to_next_row = priv->bytes_per_row[0];
+
+  for (i = sy; i > 0; i--) {
+     memcpy(p, y, sx);
+     y += 16;
+     p += offset_to_next_row;
+  }
+}
+
+static int initialize_grey(struct jdec_private *priv,
+			   unsigned int *bytes_per_blocklines,
+			   unsigned int *bytes_per_mcu)
+{
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width;
+  if (!priv->components[0])
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+  bytes_per_mcu[0] = 8;
+
+  return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_grey =
+  {
+    {
+      YCrCB_to_Grey_1xN,
+      YCrCB_to_Grey_1xN,
+      YCrCB_to_Grey_2xN,
+      YCrCB_to_Grey_2xN,
+    },
+    tinyjpeg_decode_mcu_1comp_table,
+    initialize_grey
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY = &format_grey;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/jidctflt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/jidctflt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/jidctflt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,285 @@
+/*
+ * jidctflt.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ *
+ * The authors make NO WARRANTY or representation, either express or implied,
+ * with respect to this software, its quality, accuracy, merchantability, or
+ * fitness for a particular purpose.  This software is provided "AS IS", and you,
+ * its user, assume the entire risk as to its quality and accuracy.
+ *
+ * This software is copyright (C) 1991-1998, Thomas G. Lane.
+ * All Rights Reserved except as specified below.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * software (or portions thereof) for any purpose, without fee, subject to these
+ * conditions:
+ * (1) If any part of the source code for this software is distributed, then this
+ * README file must be included, with this copyright and no-warranty notice
+ * unaltered; and any additions, deletions, or changes to the original files
+ * must be clearly indicated in accompanying documentation.
+ * (2) If only executable code is distributed, then the accompanying
+ * documentation must state that "this software is based in part on the work of
+ * the Independent JPEG Group".
+ * (3) Permission for use of this software is granted only if the user accepts
+ * full responsibility for any undesirable consequences; the authors accept
+ * NO LIABILITY for damages of any kind.
+ *
+ * These conditions apply to any software derived from or based on the IJG code,
+ * not just to the unmodified library.  If you use our work, you ought to
+ * acknowledge us.
+ *
+ * Permission is NOT granted for the use of any IJG author's name or company name
+ * in advertising or publicity relating to this software or products derived from
+ * it.  This software may be referred to only as "the Independent JPEG Group's
+ * software".
+ *
+ * We specifically permit and encourage the use of this software as the basis of
+ * commercial products, provided that all warranty or liability claims are
+ * assumed by the product vendor.
+ *
+ *
+ * This file contains a floating-point implementation of the
+ * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * This implementation should be more accurate than either of the integer
+ * IDCT implementations.  However, it may not give the same results on all
+ * machines because of differences in roundoff behavior.  Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time).  Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README).  The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs.  These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values.  However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#include <stdint.h>
+#include "tinyjpeg-internal.h"
+
+#define FAST_FLOAT float
+#define DCTSIZE	   8
+#define DCTSIZE2   (DCTSIZE*DCTSIZE)
+
+#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval))
+
+#if 1 && defined(__GNUC__) && (defined(__i686__) || defined(__x86_64__))
+
+static inline unsigned char descale_and_clamp(int x, int shift)
+{
+  __asm__ (
+      "add %3,%1\n"
+      "\tsar %2,%1\n"
+      "\tsub $-128,%1\n"
+      "\tcmovl %5,%1\n"	/* Use the sub to compare to 0 */
+      "\tcmpl %4,%1\n"
+      "\tcmovg %4,%1\n"
+      : "=r"(x)
+      : "0"(x), "Ir"(shift), "ir"(1UL<<(shift-1)), "r" (0xff), "r" (0)
+      );
+  return x;
+}
+
+#else
+static inline unsigned char descale_and_clamp(int x, int shift)
+{
+  x += (1UL<<(shift-1));
+  if (x<0)
+    x = (x >> shift) | ((~(0UL)) << (32-(shift)));
+  else
+    x >>= shift;
+  x += 128;
+  if (x>255)
+    return 255;
+  else if (x<0)
+    return 0;
+  else
+    return x;
+}
+#endif
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+void
+tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
+{
+  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+  FAST_FLOAT z5, z10, z11, z12, z13;
+  int16_t *inptr;
+  FAST_FLOAT *quantptr;
+  FAST_FLOAT *wsptr;
+  uint8_t *outptr;
+  int ctr;
+  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
+
+  /* Pass 1: process columns from input, store into work array. */
+
+  inptr = compptr->DCT;
+  quantptr = compptr->Q_table;
+  wsptr = workspace;
+  for (ctr = DCTSIZE; ctr > 0; ctr--) {
+    /* Due to quantization, we will usually find that many of the input
+     * coefficients are zero, especially the AC terms.  We can exploit this
+     * by short-circuiting the IDCT calculation for any column in which all
+     * the AC terms are zero.  In that case each output is equal to the
+     * DC coefficient (with scale factor as needed).
+     * With typical images and quantization tables, half or more of the
+     * column DCT calculations can be simplified this way.
+     */
+
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
+      /* AC terms all zero */
+      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+      wsptr[DCTSIZE*0] = dcval;
+      wsptr[DCTSIZE*1] = dcval;
+      wsptr[DCTSIZE*2] = dcval;
+      wsptr[DCTSIZE*3] = dcval;
+      wsptr[DCTSIZE*4] = dcval;
+      wsptr[DCTSIZE*5] = dcval;
+      wsptr[DCTSIZE*6] = dcval;
+      wsptr[DCTSIZE*7] = dcval;
+
+      inptr++;			/* advance pointers to next column */
+      quantptr++;
+      wsptr++;
+      continue;
+    }
+
+    /* Even part */
+
+    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+    tmp10 = tmp0 + tmp2;	/* phase 3 */
+    tmp11 = tmp0 - tmp2;
+
+    tmp13 = tmp1 + tmp3;	/* phases 5-3 */
+    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
+
+    tmp0 = tmp10 + tmp13;	/* phase 2 */
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+
+    /* Odd part */
+
+    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+    z13 = tmp6 + tmp5;		/* phase 6 */
+    z10 = tmp6 - tmp5;
+    z11 = tmp4 + tmp7;
+    z12 = tmp4 - tmp7;
+
+    tmp7 = z11 + z13;		/* phase 5 */
+    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
+
+    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;	/* phase 2 */
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    wsptr[DCTSIZE*0] = tmp0 + tmp7;
+    wsptr[DCTSIZE*7] = tmp0 - tmp7;
+    wsptr[DCTSIZE*1] = tmp1 + tmp6;
+    wsptr[DCTSIZE*6] = tmp1 - tmp6;
+    wsptr[DCTSIZE*2] = tmp2 + tmp5;
+    wsptr[DCTSIZE*5] = tmp2 - tmp5;
+    wsptr[DCTSIZE*4] = tmp3 + tmp4;
+    wsptr[DCTSIZE*3] = tmp3 - tmp4;
+
+    inptr++;			/* advance pointers to next column */
+    quantptr++;
+    wsptr++;
+  }
+
+  /* Pass 2: process rows from work array, store into output array. */
+  /* Note that we must descale the results by a factor of 8 == 2**3. */
+
+  wsptr = workspace;
+  outptr = output_buf;
+  for (ctr = 0; ctr < DCTSIZE; ctr++) {
+    /* Rows of zeroes can be exploited in the same way as we did with columns.
+     * However, the column calculation has created many nonzero AC terms, so
+     * the simplification applies less often (typically 5% to 10% of the time).
+     * And testing floats for zero is relatively expensive, so we don't bother.
+     */
+
+    /* Even part */
+
+    tmp10 = wsptr[0] + wsptr[4];
+    tmp11 = wsptr[0] - wsptr[4];
+
+    tmp13 = wsptr[2] + wsptr[6];
+    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
+
+    tmp0 = tmp10 + tmp13;
+    tmp3 = tmp10 - tmp13;
+    tmp1 = tmp11 + tmp12;
+    tmp2 = tmp11 - tmp12;
+
+    /* Odd part */
+
+    z13 = wsptr[5] + wsptr[3];
+    z10 = wsptr[5] - wsptr[3];
+    z11 = wsptr[1] + wsptr[7];
+    z12 = wsptr[1] - wsptr[7];
+
+    tmp7 = z11 + z13;
+    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
+
+    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+    tmp6 = tmp12 - tmp7;
+    tmp5 = tmp11 - tmp6;
+    tmp4 = tmp10 + tmp5;
+
+    /* Final output stage: scale down by a factor of 8 and range-limit */
+
+    outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3);
+    outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3);
+    outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3);
+    outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3);
+    outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3);
+    outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3);
+    outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3);
+    outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3);
+
+
+    wsptr += DCTSIZE;		/* advance pointer to next row */
+    outptr += stride;
+  }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgb24.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgb24.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgb24.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,372 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+  if (i<0)
+    return 0;
+  else if (i>255)
+    return 255;
+  else
+    return i;
+}
+
+/**
+ *  YCrCb -> RGB24 (1x1)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_RGB24_1x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 8*3;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j++) {
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+
+       Y++;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ *  YCrCb -> RGB24 (2x1)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_RGB24_2x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 16*3;
+  for (i = sy; i > 0; i--) {
+
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+       }
+
+       Y += 2;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/**
+ *  YCrCb -> RGB24 (1x2)
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void YCrCB_to_RGB24_1x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+
+       if (i > 1) {
+	   y  = Y[8] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+       }
+
+       Y++;
+    }
+    Y += 8;
+    p += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ *  YCrCb -> RGB24 (2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void YCrCB_to_RGB24_2x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+       }
+
+       if (i > 1) {
+	   y  = Y[16+0] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+
+	   if (j > 1) {
+	       y  = Y[16+1] << SCALEBITS;
+	       r = (y + add_r) >> SCALEBITS;
+	       *p2++ = clamp(r);
+	       g = (y + add_g) >> SCALEBITS;
+	       *p2++ = clamp(g);
+	       b = (y + add_b) >> SCALEBITS;
+	       *p2++ = clamp(b);
+	   }
+       }
+       
+       Y += 2;
+    }
+    Y  += 16;
+    p  += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_rgb24(struct jdec_private *priv,
+			    unsigned int *bytes_per_blocklines,
+			    unsigned int *bytes_per_mcu)
+{
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width * 3;
+  if (priv->components[0] == NULL)
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+  bytes_per_mcu[0] = 3*8;
+
+  return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_rgb24 =
+  {
+    {
+      YCrCB_to_RGB24_1x1,
+      YCrCB_to_RGB24_1x2,
+      YCrCB_to_RGB24_2x1,
+      YCrCB_to_RGB24_2x2,
+    },
+    tinyjpeg_decode_mcu_3comp_table,
+    initialize_rgb24
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_RGB24 = &format_rgb24;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgba32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgba32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/rgba32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,390 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+  if (i<0)
+    return 0;
+  else if (i>255)
+    return 255;
+  else
+    return i;
+}
+
+/**
+ *  YCrCb -> RGBA32 (1x1)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 8*4;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       a = 255;
+       *p++ = a;
+
+       Y++;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ *  YCrCb -> RGBA32 (2x1)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = priv->bytes_per_row[0] - 16*4;
+  for (i = sy; i > 0; i--) {
+    for (j = sx; j > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       y  = Y[0] << SCALEBITS;
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       a = 255;
+       *p++ = a;
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   a = 255;
+	   *p++ = a;
+       }
+
+       Y += 2;
+    }
+
+    p += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/**
+ *  YCrCb -> RGBA32 (1x2)
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; j > 0; j--) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       a = 255;
+       *p++ = a;
+
+       if (i > 1) {
+	   y  = Y[8] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   a = 255;
+	   *p2++ = a;
+       }
+
+       Y++;
+    }
+    Y += 8;
+    p += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ *  YCrCb -> RGBA32 (2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *Y, *Cb, *Cr;
+  unsigned char *p, *p2;
+  int i,j;
+  int offset_to_next_row;
+
+#define SCALEBITS       10
+#define ONE_HALF        (1UL << (SCALEBITS-1))
+#define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+  p = priv->plane[0];
+  p2 = priv->plane[0] + priv->bytes_per_row[0];
+  Y = priv->Y;
+  Cb = priv->Cb;
+  Cr = priv->Cr;
+  offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4;
+  for (i = sy; i > 0; i -= 2) {
+    for (j = sx; i > 0; j -= 2) {
+
+       int y, cb, cr;
+       int add_r, add_g, add_b;
+       int r, g , b, a;
+
+       cb = *Cb++ - 128;
+       cr = *Cr++ - 128;
+       add_r = FIX(1.40200) * cr + ONE_HALF;
+       add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+       add_b = FIX(1.77200) * cb + ONE_HALF;
+
+       y  = Y[0] << SCALEBITS;
+       r = (y + add_r) >> SCALEBITS;
+       *p++ = clamp(r);
+       g = (y + add_g) >> SCALEBITS;
+       *p++ = clamp(g);
+       b = (y + add_b) >> SCALEBITS;
+       *p++ = clamp(b);
+       a = 255;
+       *p++ = a;
+
+       if (j > 1) {
+	   y  = Y[1] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p++ = clamp(b);
+	   a = 255;
+	   *p++ = a;
+       }
+
+       if (i > 1) {
+	   y  = Y[16+0] << SCALEBITS;
+	   r = (y + add_r) >> SCALEBITS;
+	   *p2++ = clamp(r);
+	   g = (y + add_g) >> SCALEBITS;
+	   *p2++ = clamp(g);
+	   b = (y + add_b) >> SCALEBITS;
+	   *p2++ = clamp(b);
+	   a = 255;
+	   *p2++ = a;
+
+	   if (j > 1) {
+	       y  = Y[16+1] << SCALEBITS;
+	       r = (y + add_r) >> SCALEBITS;
+	       *p2++ = clamp(r);
+	       g = (y + add_g) >> SCALEBITS;
+	       *p2++ = clamp(g);
+	       b = (y + add_b) >> SCALEBITS;
+	       *p2++ = clamp(b);
+	       a = 255;
+	       *p2++ = a;
+	   }
+       }
+
+       Y += 2;
+    }
+    Y  += 16;
+    p  += offset_to_next_row;
+    p2 += offset_to_next_row;
+  }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_rgba32(struct jdec_private *priv,
+			     unsigned int *bytes_per_blocklines,
+			     unsigned int *bytes_per_mcu)
+{
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width * 4;
+  if (!priv->components[0])
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+  bytes_per_mcu[0] = 4*8;
+
+  return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_rgba32 =
+  {
+    {
+      YCrCB_to_RGBA32_1x1,
+      YCrCB_to_RGBA32_1x2,
+      YCrCB_to_RGBA32_2x1,
+      YCrCB_to_RGBA32_2x2,
+    },
+    tinyjpeg_decode_mcu_3comp_table,
+    initialize_rgba32
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_RGBA32 = &format_rgba32;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg-internal.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg-internal.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg-internal.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,213 @@
+/*
+ * Small jpeg decoder library (Internal header)
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef __TINYJPEG_INTERNAL_H_
+#define __TINYJPEG_INTERNAL_H_
+
+#include <setjmp.h>
+
+#define SANITY_CHECK 1
+
+struct jdec_private;
+
+#define HUFFMAN_BITS_SIZE  256
+#define HUFFMAN_HASH_NBITS 9
+#define HUFFMAN_HASH_SIZE  (1UL<<HUFFMAN_HASH_NBITS)
+#define HUFFMAN_HASH_MASK  (HUFFMAN_HASH_SIZE-1)
+
+#define HUFFMAN_TABLES	   4
+#define COMPONENTS	   3
+#define JPEG_MAX_WIDTH	   4096
+#define JPEG_MAX_HEIGHT	   4096
+
+struct huffman_table
+{
+  /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
+   * if the symbol is <0, then we need to look into the tree table */
+  short int lookup[HUFFMAN_HASH_SIZE];
+  /* code size: give the number of bits of a symbol is encoded */
+  unsigned char code_size[HUFFMAN_HASH_SIZE];
+  /* some place to store value that is not encoded in the lookup table
+   * FIXME: Calculate if 256 value is enough to store all values
+   */
+  uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
+};
+
+struct component
+{
+  unsigned int Hfactor;
+  unsigned int Vfactor;
+  float *Q_table;		/* Pointer to the quantisation table to use */
+  struct huffman_table *AC_table;
+  struct huffman_table *DC_table;
+  short int previous_DC;	/* Previous DC coefficient */
+  short int DCT[64];		/* DCT coef */
+#if SANITY_CHECK
+  unsigned int cid;
+#endif
+};
+
+
+typedef void (*decode_MCU_fct) (struct jdec_private *priv);
+typedef void (*convert_colorspace_fct) (struct jdec_private *priv, int, int);
+
+struct jdec_private
+{
+  /* Public variables */
+  uint8_t *components[COMPONENTS];
+  unsigned int bytes_per_row[COMPONENTS];
+  unsigned int width, height;	/* Size of the image */
+  unsigned int flags;
+
+  /* Private variables */
+  const unsigned char *stream_begin, *stream_end;
+  unsigned int stream_length;
+
+  const unsigned char *stream;	/* Pointer to the current stream */
+  unsigned int reservoir, nbits_in_reservoir;
+
+  struct component component_infos[COMPONENTS];
+  float Q_tables[COMPONENTS][64];		/* quantization tables */
+  struct huffman_table HTDC[HUFFMAN_TABLES];	/* DC huffman tables   */
+  struct huffman_table HTAC[HUFFMAN_TABLES];	/* AC huffman tables   */
+  int default_huffman_table_initialized;
+  int restart_interval;
+  int restarts_to_go;				/* MCUs left in this restart interval */
+  int last_rst_marker_seen;			/* Rst marker is incremented each time */
+
+  /* Temp space used after the IDCT to store each components */
+  uint8_t Y[64*4], Cr[64], Cb[64];
+
+  jmp_buf jump_state;
+  /* Internal Pointer use for colorspace conversion, do not modify it !!! */
+  uint8_t *plane[COMPONENTS];
+
+};
+
+#define IDCT tinyjpeg_idct_float
+void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
+
+struct tinyjpeg_colorspace {
+  convert_colorspace_fct convert_colorspace[4];
+  const decode_MCU_fct *decode_mcu_table;
+  int (*initialize)(struct jdec_private *, unsigned int *, unsigned int *);
+};
+
+void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component);
+
+extern const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4];
+extern const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4];
+
+enum std_markers {
+   DQT  = 0xDB, /* Define Quantization Table */
+   SOF  = 0xC0, /* Start of Frame (size information) */
+   DHT  = 0xC4, /* Huffman Table */
+   SOI  = 0xD8, /* Start of Image */
+   SOS  = 0xDA, /* Start of Scan */
+   RST  = 0xD0, /* Reset Marker d0 -> .. */
+   RST7 = 0xD7, /* Reset Marker .. -> d7 */
+   EOI  = 0xD9, /* End of Image */
+   DRI  = 0xDD, /* Define Restart Interval */
+   APP0 = 0xE0,
+};
+
+#define cY	0
+#define cCb	1
+#define cCr	2
+
+#define BLACK_Y 0
+#define BLACK_U 127
+#define BLACK_V 127
+
+#define SANITY_CHECK 1
+
+#if JPEG_DEBUG
+#define error(fmt, args...) do { \
+   snprintf(error_string, sizeof(error_string), fmt, ## args); \
+   return -1; \
+} while(0)
+
+#define trace(fmt, args...) do { \
+   fprintf(stderr, fmt, ## args); \
+   fflush(stderr); \
+} while(0)
+#else
+#define error(fmt, args...) do { return -1; } while(0)
+#define trace(fmt, args...) do { } while (0)
+#endif
+
+#ifndef __likely
+# define __likely(x) (!!(x))
+#endif
+#ifndef __unlikely
+# define __unlikely(x) (!!(x))
+#endif
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
+#if 0
+static char *print_bits(unsigned int value, char *bitstr)
+{
+  int i, j;
+  i=31;
+  while (i>0)
+   {
+     if (value & (1UL<<i))
+       break;
+     i--;
+   }
+  j=0;
+  while (i>=0)
+   {
+     bitstr[j++] = (value & (1UL<<i))?'1':'0';
+     i--;
+   }
+  bitstr[j] = 0;
+  return bitstr;
+}
+
+static void print_next_16bytes(int offset, const unsigned char *stream)
+{
+  trace("%4.4x: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
+	offset,
+	stream[0], stream[1], stream[2], stream[3],
+	stream[4], stream[5], stream[6], stream[7],
+	stream[8], stream[9], stream[10], stream[11],
+	stream[12], stream[13], stream[14], stream[15]);
+}
+
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/tinyjpeg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1038 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/* Global variable to return the last error found while deconding */
+static char error_string[256];
+
+static const unsigned char zigzag[64] =
+{
+   0,  1,  5,  6, 14, 15, 27, 28,
+   2,  4,  7, 13, 16, 26, 29, 42,
+   3,  8, 12, 17, 25, 30, 41, 43,
+   9, 11, 18, 24, 31, 40, 44, 53,
+  10, 19, 23, 32, 39, 45, 52, 54,
+  20, 22, 33, 38, 46, 51, 55, 60,
+  21, 34, 37, 47, 50, 56, 59, 61,
+  35, 36, 48, 49, 57, 58, 62, 63
+};
+
+/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+/* IMPORTANT: these are only valid for 8-bit data precision! */
+static const unsigned char bits_dc_luminance[17] =
+{
+  0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+static const unsigned char val_dc_luminance[] =
+{
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const unsigned char bits_dc_chrominance[17] =
+{
+  0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+};
+static const unsigned char val_dc_chrominance[] =
+{
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const unsigned char bits_ac_luminance[17] =
+{
+  0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+static const unsigned char val_ac_luminance[] =
+{
+  0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+  0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+  0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+  0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+  0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+  0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+  0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+  0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+  0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+  0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+  0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+  0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+  0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+  0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+  0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+  0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+  0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+  0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+  0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+  0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+  0xf9, 0xfa
+};
+
+static const unsigned char bits_ac_chrominance[17] =
+{
+  0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
+};
+
+static const unsigned char val_ac_chrominance[] =
+{
+  0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+  0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+  0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+  0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+  0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+  0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+  0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+  0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+  0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+  0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+  0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+  0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+  0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+  0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+  0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+  0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+  0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+  0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+  0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+  0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+  0xf9, 0xfa
+};
+
+
+/*
+ * 4 functions to manage the stream
+ *
+ *  fill_nbits: put at least nbits in the reservoir of bits.
+ *              But convert any 0xff,0x00 into 0xff
+ *  get_nbits: read nbits from the stream, and put it in result,
+ *             bits is removed from the stream and the reservoir is filled
+ *             automaticaly. The result is signed according to the number of
+ *             bits.
+ *  look_nbits: read nbits from the stream without marking as read.
+ *  skip_nbits: read nbits from the stream but do not return the result.
+ *
+ * stream: current pointer in the jpeg data (read bytes per bytes)
+ * nbits_in_reservoir: number of bits filled into the reservoir
+ * reservoir: register that contains bits information. Only nbits_in_reservoir
+ *            is valid.
+ *                          nbits_in_reservoir
+ *                        <--    17 bits    -->
+ *            Ex: 0000 0000 1010 0000 1111 0000   <== reservoir
+ *                        ^
+ *                        bit 1
+ *            To get two bits from this example
+ *                 result = (reservoir >> 15) & 3
+ *
+ */
+#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
+   while (nbits_in_reservoir<nbits_wanted) \
+    { \
+      unsigned char c; \
+      if (stream >= priv->stream_end) \
+        longjmp(priv->jump_state, -EIO); \
+      c = *stream++; \
+      reservoir <<= 8; \
+      if (c == 0xff && *stream == 0x00) \
+        stream++; \
+      reservoir |= c; \
+      nbits_in_reservoir+=8; \
+    } \
+}  while(0);
+
+/* Signed version !!!! */
+#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
+   fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
+   result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
+   nbits_in_reservoir -= (nbits_wanted);  \
+   reservoir &= ((1U<<nbits_in_reservoir)-1); \
+   if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \
+       result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \
+}  while(0);
+
+#define look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \
+   fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
+   result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
+}  while(0);
+
+/* To speed up the decoding, we assume that the reservoir have enough bit 
+ * slow version:
+ * #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
+ *   fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
+ *   nbits_in_reservoir -= (nbits_wanted); \
+ *   reservoir &= ((1U<<nbits_in_reservoir)-1); \
+ * }  while(0);
+ */
+#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
+   nbits_in_reservoir -= (nbits_wanted); \
+   reservoir &= ((1U<<nbits_in_reservoir)-1); \
+}  while(0);
+
+
+#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1])
+
+static void resync(struct jdec_private *priv);
+
+/**
+ * Get the next (valid) huffman code in the stream.
+ *
+ * To speedup the procedure, we look HUFFMAN_HASH_NBITS bits and the code is
+ * lower than HUFFMAN_HASH_NBITS we have automaticaly the length of the code
+ * and the value by using two lookup table.
+ * Else if the value is not found, just search (linear) into an array for each
+ * bits is the code is present.
+ *
+ * If the code is not present for any reason, -1 is return.
+ */
+static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table *huffman_table)
+{
+  int value, hcode;
+  unsigned int extra_nbits, nbits;
+  uint16_t *slowtable;
+
+  look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode);
+  value = huffman_table->lookup[hcode];
+  if (__likely(value >= 0))
+  {
+     unsigned int code_size = huffman_table->code_size[value];
+     skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size);
+     return value;
+  }
+
+  /* Decode more bits each time ... */
+  for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++)
+   {
+     nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits;
+
+     look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode);
+     slowtable = huffman_table->slowtable[extra_nbits];
+     /* Search if the code is in this array */
+     while (slowtable[0]) {
+	if (slowtable[0] == hcode) {
+	   skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits);
+	   return slowtable[1];
+	}
+	slowtable+=2;
+     }
+   }
+  return 0;
+}
+
+
+
+
+/**
+ *
+ * Decode a single block that contains the DCT coefficients.
+ * The table coefficients is already dezigzaged at the end of the operation.
+ *
+ */
+void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component)
+{
+  unsigned char j;
+  unsigned int huff_code;
+  unsigned char size_val, count_0;
+
+  struct component *c = &priv->component_infos[component];
+  short int DCT[64];
+
+
+  /* Initialize the DCT coef table */
+  memset(DCT, 0, sizeof(DCT));
+
+  /* DC coefficient decoding */
+  huff_code = get_next_huffman_code(priv, c->DC_table);
+  //trace("+ %x\n", huff_code);
+  if (huff_code) {
+     get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]);
+     DCT[0] += c->previous_DC;
+     c->previous_DC = DCT[0];
+  } else {
+     DCT[0] = c->previous_DC;
+  }
+
+  /* AC coefficient decoding */
+  j = 1;
+  while (j<64)
+   {
+     huff_code = get_next_huffman_code(priv, c->AC_table);
+     //trace("- %x\n", huff_code);
+
+     size_val = huff_code & 0xF;
+     count_0 = huff_code >> 4;
+
+     if (size_val == 0)
+      { /* RLE */
+	if (count_0 == 0)
+	  break;	/* EOB found, go out */
+	else if (count_0 == 0xF)
+	  j += 16;	/* skip 16 zeros */
+      }
+     else
+      {
+	j += count_0;	/* skip count_0 zeroes */
+	if (__unlikely(j >= 64))
+	 {
+	   snprintf(error_string, sizeof(error_string), "Bad huffman data (buffer overflow)");
+	   break;
+	 }
+	get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]);
+	j++;
+      }
+   }
+
+  for (j = 0; j < 64; j++)
+    c->DCT[j] = DCT[zigzag[j]];
+}
+
+/*
+ * Takes two array of bits, and build the huffman table for size, and code
+ *
+ * lookup will return the symbol if the code is less or equal than HUFFMAN_HASH_NBITS.
+ * code_size will be used to known how many bits this symbol is encoded.
+ * slowtable will be used when the first lookup didn't give the result.
+ */
+static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table)
+{
+  unsigned int i, j, code, code_size, val, nbits;
+  unsigned char huffsize[HUFFMAN_BITS_SIZE+1], *hz;
+  unsigned int huffcode[HUFFMAN_BITS_SIZE+1], *hc;
+
+  /*
+   * Build a temp array
+   *   huffsize[X] => numbers of bits to write vals[X]
+   */
+  hz = huffsize;
+  for (i=1; i<=16; i++)
+   {
+     for (j=1; j<=bits[i]; j++)
+       *hz++ = i;
+   }
+  *hz = 0;
+
+  memset(table->lookup, 0xff, sizeof(table->lookup));
+  for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++)
+    table->slowtable[i][0] = 0;
+
+  /* Build a temp array
+   *   huffcode[X] => code used to write vals[X]
+   */
+  code = 0;
+  hc = huffcode;
+  hz = huffsize;
+  nbits = *hz;
+  while (*hz)
+   {
+     while (*hz == nbits)
+      {
+	*hc++ = code++;
+	hz++;
+      }
+     code <<= 1;
+     nbits++;
+   }
+
+  /*
+   * Build the lookup table, and the slowtable if needed.
+   */
+  for (i=0; huffsize[i]; i++)
+   {
+     val = vals[i];
+     code = huffcode[i];
+     code_size = huffsize[i];
+
+     trace("val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);
+
+     table->code_size[val] = code_size;
+     if (code_size <= HUFFMAN_HASH_NBITS)
+      {
+	/*
+	 * Good: val can be put in the lookup table, so fill all value of this
+	 * column with value val
+	 */
+	int repeat = 1UL<<(HUFFMAN_HASH_NBITS - code_size);
+	code <<= HUFFMAN_HASH_NBITS - code_size;
+	while ( repeat-- )
+	  table->lookup[code++] = val;
+
+      }
+     else
+      {
+	/* Perhaps sorting the array will be an optimization */
+	uint16_t *slowtable = table->slowtable[code_size-HUFFMAN_HASH_NBITS-1];
+	while(slowtable[0])
+	  slowtable+=2;
+	slowtable[0] = code;
+	slowtable[1] = val;
+	slowtable[2] = 0;
+	/* TODO: NEED TO CHECK FOR AN OVERFLOW OF THE TABLE */
+      }
+
+   }
+}
+
+static void build_default_huffman_tables(struct jdec_private *priv)
+{
+  if (   (priv->flags & TINYJPEG_FLAGS_MJPEG_TABLE)
+      && priv->default_huffman_table_initialized)
+    return;
+
+  build_huffman_table(bits_dc_luminance, val_dc_luminance, &priv->HTDC[0]);
+  build_huffman_table(bits_ac_luminance, val_ac_luminance, &priv->HTAC[0]);
+
+  build_huffman_table(bits_dc_chrominance, val_dc_chrominance, &priv->HTDC[1]);
+  build_huffman_table(bits_ac_chrominance, val_ac_chrominance, &priv->HTAC[1]);
+
+  priv->default_huffman_table_initialized = 1;
+}
+
+
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+
+static void print_SOF(const unsigned char *stream)
+{
+#if JPEG_DEBUG
+  int width, height, nr_components, precision;
+  const char *nr_components_to_string[] = {
+     "????",
+     "Grayscale",
+     "????",
+     "YCbCr",
+     "CYMK"
+  };
+
+  precision = stream[2];
+  height = be16_to_cpu(stream+3);
+  width  = be16_to_cpu(stream+5);
+  nr_components = stream[7];
+
+  trace("> SOF marker\n");
+  trace("Size:%dx%d nr_components:%d (%s)  precision:%d\n",
+      width, height,
+      nr_components, nr_components_to_string[nr_components],
+      precision);
+#endif
+  (void)stream;
+}
+
+/*******************************************************************************
+ *
+ * JPEG/JFIF Parsing functions
+ *
+ * Note: only a small subset of the jpeg file format is supported. No markers,
+ * nor progressive stream is supported.
+ *
+ ******************************************************************************/
+
+static void build_quantization_table(float *qtable, const unsigned char *ref_table)
+{
+  /* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct.
+   * For float AA&N IDCT method, divisors are equal to quantization
+   * coefficients scaled by scalefactor[row]*scalefactor[col], where
+   *   scalefactor[0] = 1
+   *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
+   * We apply a further scale factor of 8.
+   * What's actually stored is 1/divisor so that the inner loop can
+   * use a multiplication rather than a division.
+   */
+  int i, j;
+  static const double aanscalefactor[8] = {
+     1.0, 1.387039845, 1.306562965, 1.175875602,
+     1.0, 0.785694958, 0.541196100, 0.275899379
+  };
+  const unsigned char *zz = zigzag;
+
+  for (i=0; i<8; i++) {
+     for (j=0; j<8; j++) {
+       *qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j];
+     }
+   }
+
+}
+
+static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
+{
+  int qi;
+  float *table;
+  const unsigned char *dqt_block_end;
+
+  trace("> DQT marker\n");
+  dqt_block_end = stream + be16_to_cpu(stream);
+  stream += 2;	/* Skip length */
+
+  while (stream < dqt_block_end)
+   {
+     qi = *stream++;
+#if SANITY_CHECK
+     if (qi>>4)
+       error("16 bits quantization table is not supported\n");
+     if (qi>4)
+       error("No more 4 quantization table is supported (got %d)\n", qi);
+#endif
+     table = priv->Q_tables[qi];
+     build_quantization_table(table, stream);
+     stream += 64;
+   }
+  trace("< DQT marker\n");
+  return 0;
+}
+
+static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
+{
+  int i, width, height, nr_components, cid, sampling_factor;
+  int Q_table;
+  struct component *c;
+
+  trace("> SOF marker\n");
+  print_SOF(stream);
+
+  height = be16_to_cpu(stream+3);
+  width  = be16_to_cpu(stream+5);
+  nr_components = stream[7];
+#if SANITY_CHECK
+  if (stream[2] != 8)
+    error("Precision other than 8 is not supported\n");
+  if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT)
+    error("Width and Height (%dx%d) seems suspicious\n", width, height);
+  if (nr_components != 3)
+    error("We only support YUV images\n");
+#endif
+  stream += 8;
+  for (i=0; i<nr_components; i++) {
+     cid = *stream++;
+     sampling_factor = *stream++;
+     Q_table = *stream++;
+     c = &priv->component_infos[i];
+#if SANITY_CHECK
+     c->cid = cid;
+     if (Q_table >= COMPONENTS)
+       error("Bad Quantization table index (got %d, max allowed %d)\n", Q_table, COMPONENTS-1);
+#endif
+     c->Vfactor = sampling_factor&0xf;
+     c->Hfactor = sampling_factor>>4;
+     c->Q_table = priv->Q_tables[Q_table];
+     trace("Component:%d  factor:%dx%d  Quantization table:%d\n",
+           cid, c->Hfactor, c->Hfactor, Q_table );
+
+  }
+  priv->width = width;
+  priv->height = height;
+
+  trace("< SOF marker\n");
+
+  return 0;
+}
+
+static int parse_SOS(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int i, cid, table;
+  unsigned int nr_components = stream[2];
+
+  trace("> SOS marker\n");
+
+#if SANITY_CHECK
+  if (nr_components != 3)
+    error("We only support YCbCr image\n");
+#endif
+
+  stream += 3;
+  for (i=0;i<nr_components;i++) {
+     cid = *stream++;
+     table = *stream++;
+#if SANITY_CHECK
+     if ((table&0xf)>=4)
+	error("We do not support more than 2 AC Huffman table\n");
+     if ((table>>4)>=4)
+	error("We do not support more than 2 DC Huffman table\n");
+     if (cid != priv->component_infos[i].cid)
+        error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n",
+	      i, cid, i, priv->component_infos[i].cid);
+     trace("ComponentId:%d  tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);
+#endif
+     priv->component_infos[i].AC_table = &priv->HTAC[table&0xf];
+     priv->component_infos[i].DC_table = &priv->HTDC[table>>4];
+  }
+  priv->stream = stream+3;
+  trace("< SOS marker\n");
+  return 0;
+}
+
+static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int count, i;
+  unsigned char huff_bits[17];
+  int length, index;
+
+  length = be16_to_cpu(stream) - 2;
+  stream += 2;	/* Skip length */
+
+  trace("> DHT marker (length=%d)\n", length);
+
+  while (length>0) {
+     index = *stream++;
+
+     /* We need to calculate the number of bytes 'vals' will takes */
+     huff_bits[0] = 0;
+     count = 0;
+     for (i=1; i<17; i++) {
+	huff_bits[i] = *stream++;
+	count += huff_bits[i];
+     }
+#if SANITY_CHECK
+     if (count >= HUFFMAN_BITS_SIZE)
+       error("No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
+     if ( (index &0xf) >= HUFFMAN_TABLES)
+       error("No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index&0xf);
+     trace("Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);
+#endif
+
+     if (index & 0xf0 )
+       build_huffman_table(huff_bits, stream, &priv->HTAC[index&0xf]);
+     else
+       build_huffman_table(huff_bits, stream, &priv->HTDC[index&0xf]);
+
+     length -= 1;
+     length -= 16;
+     length -= count;
+     stream += count;
+  }
+  trace("< DHT marker\n");
+  return 0;
+}
+
+static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
+{
+  unsigned int length;
+
+  trace("> DRI marker\n");
+
+  length = be16_to_cpu(stream);
+
+#if SANITY_CHECK
+  if (length != 4)
+    error("Length of DRI marker need to be 4\n");
+#endif
+
+  priv->restart_interval = be16_to_cpu(stream+2);
+
+#if JPEG_DEBUG
+  trace("Restart interval = %d\n", priv->restart_interval);
+#endif
+
+  trace("< DRI marker\n");
+
+  return 0;
+}
+
+
+
+static void resync(struct jdec_private *priv)
+{
+  int i;
+
+  /* Init DC coefficients */
+  for (i=0; i<COMPONENTS; i++)
+     priv->component_infos[i].previous_DC = 0;
+
+  priv->reservoir = 0;
+  priv->nbits_in_reservoir = 0;
+  if (priv->restart_interval > 0)
+    priv->restarts_to_go = priv->restart_interval;
+  else
+    priv->restarts_to_go = -1;
+}
+
+static int find_next_rst_marker(struct jdec_private *priv)
+{
+  int rst_marker_found = 0;
+  int marker;
+  const unsigned char *stream = priv->stream;
+
+  /* Parse marker */
+  while (!rst_marker_found)
+   {
+     while (*stream++ != 0xff)
+      {
+	if (stream >= priv->stream_end)
+	  error("EOF while search for a RST marker.");
+      }
+     /* Skip any padding ff byte (this is normal) */
+     while (*stream == 0xff)
+       stream++;
+
+     marker = *stream++;
+     if ((RST+priv->last_rst_marker_seen) == marker)
+       rst_marker_found = 1;
+     else if (marker >= RST && marker <= RST7)
+       error("Wrong Reset marker found, abording");
+     else if (marker == EOI)
+       return 0;
+   }
+  trace("RST Marker %d found at offset %d\n", priv->last_rst_marker_seen, stream - priv->stream_begin);
+
+  priv->stream = stream;
+  priv->last_rst_marker_seen++;
+  priv->last_rst_marker_seen &= 7;
+
+  return 0;
+}
+
+static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
+{
+  int chuck_len;
+  int marker;
+  int sos_marker_found = 0;
+  int dht_marker_found = 0;
+  const unsigned char *next_chunck;
+
+  /* Parse marker */
+  while (!sos_marker_found)
+   {
+     if (*stream++ != 0xff)
+       goto bogus_jpeg_format;
+     /* Skip any padding ff byte (this is normal) */
+     while (*stream == 0xff)
+       stream++;
+
+     marker = *stream++;
+     chuck_len = be16_to_cpu(stream);
+     next_chunck = stream + chuck_len;
+     switch (marker)
+      {
+       case SOF:
+	 if (parse_SOF(priv, stream) < 0)
+	   return -1;
+	 break;
+       case DQT:
+	 if (parse_DQT(priv, stream) < 0)
+	   return -1;
+	 break;
+       case SOS:
+	 if (parse_SOS(priv, stream) < 0)
+	   return -1;
+	 sos_marker_found = 1;
+	 break;
+       case DHT:
+	 if (parse_DHT(priv, stream) < 0)
+	   return -1;
+	 dht_marker_found = 1;
+	 break;
+       case DRI:
+	 if (parse_DRI(priv, stream) < 0)
+	   return -1;
+	 break;
+       default:
+	 trace("> Unknown marker %2.2x\n", marker);
+	 break;
+      }
+
+     stream = next_chunck;
+   }
+
+  if (!dht_marker_found) {
+    trace("No Huffman table loaded, using the default one\n");
+    build_default_huffman_tables(priv);
+  }
+
+#ifdef SANITY_CHECK
+  if (   (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor)
+      || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor))
+    error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n");
+  if (   (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor)
+      || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor))
+    error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n");
+  if (   (priv->component_infos[cCb].Hfactor!=1)
+      || (priv->component_infos[cCr].Hfactor!=1)
+      || (priv->component_infos[cCb].Vfactor!=1)
+      || (priv->component_infos[cCr].Vfactor!=1))
+    error("Sampling other than 1x1 for Cr and Cb is not supported");
+#endif
+
+  return 0;
+bogus_jpeg_format:
+  trace("Bogus jpeg format\n");
+  return -1;
+}
+
+/*******************************************************************************
+ *
+ * Functions exported of the library.
+ *
+ * Note: Some applications can access directly to internal pointer of the
+ * structure. It's is not recommended, but if you have many images to
+ * uncompress with the same parameters, some functions can be called to speedup
+ * the decoding.
+ *
+ ******************************************************************************/
+
+/**
+ * Allocate a new tinyjpeg decoder object.
+ *
+ * Before calling any other functions, an object need to be called.
+ */
+struct jdec_private *tinyjpeg_init(void)
+{
+  struct jdec_private *priv;
+
+  priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private));
+  if (priv == NULL)
+    return NULL;
+  return priv;
+}
+
+/**
+ * Free a tinyjpeg object.
+ *
+ * No others function can be called after this one.
+ */
+void tinyjpeg_free(struct jdec_private *priv)
+{
+  int i;
+  for (i=0; i<COMPONENTS; i++) {
+     if (priv->components[i])
+       free(priv->components[i]);
+     priv->components[i] = NULL;
+  }
+  free(priv);
+}
+
+/**
+ * Initialize the tinyjpeg object and prepare the decoding of the stream.
+ *
+ * Check if the jpeg can be decoded with this jpeg decoder.
+ * Fill some table used for preprocessing.
+ */
+int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size)
+{
+  int ret;
+
+  /* Identify the file */
+  if ((buf[0] != 0xFF) || (buf[1] != SOI))
+    error("Not a JPG file ?\n");
+
+  priv->stream_begin = buf+2;
+  priv->stream_length = size-2;
+  priv->stream_end = priv->stream_begin + priv->stream_length;
+
+  ret = parse_JFIF(priv, priv->stream_begin);
+
+  return ret;
+}
+
+/**
+ * Decode and convert the jpeg image into @pixfmt@ image
+ *
+ * Note: components will be automaticaly allocated if no memory is attached.
+ */
+int tinyjpeg_decode(struct jdec_private *priv,
+		    const struct tinyjpeg_colorspace *pixfmt)
+{
+  int x, y, sx, sy;
+  int xshift_by_mcu, yshift_by_mcu;
+  int xstride_by_mcu, ystride_by_mcu;
+  unsigned int bytes_per_blocklines[3], bytes_per_mcu[3];
+  decode_MCU_fct decode_MCU;
+  const decode_MCU_fct *decode_mcu_table;
+  convert_colorspace_fct convert_to_pixfmt;
+  uint8_t *pptr[3];
+
+  decode_mcu_table = pixfmt->decode_mcu_table;
+
+  /* Fix: check return value */
+  pixfmt->initialize(priv, bytes_per_blocklines, bytes_per_mcu);
+
+  xshift_by_mcu = yshift_by_mcu = 3;
+  if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) {
+     decode_MCU = decode_mcu_table[0];
+     convert_to_pixfmt = pixfmt->convert_colorspace[0];
+     trace("Use decode 1x1 sampling\n");
+  } else if (priv->component_infos[cY].Hfactor == 1) {
+     decode_MCU = decode_mcu_table[1];
+     convert_to_pixfmt = pixfmt->convert_colorspace[1];
+     yshift_by_mcu = 4;
+     trace("Use decode 1x2 sampling (not supported)\n");
+  } else if (priv->component_infos[cY].Vfactor == 2) {
+     decode_MCU = decode_mcu_table[3];
+     convert_to_pixfmt = pixfmt->convert_colorspace[3];
+     xshift_by_mcu = 4;
+     yshift_by_mcu = 4;
+     trace("Use decode 2x2 sampling\n");
+  } else {
+     decode_MCU = decode_mcu_table[2];
+     convert_to_pixfmt = pixfmt->convert_colorspace[2];
+     xshift_by_mcu = 4;
+     trace("Use decode 2x1 sampling\n");
+  }
+
+  resync(priv);
+
+  /* Don't forget to that block can be either 8 or 16 lines */
+  bytes_per_blocklines[0] <<= yshift_by_mcu-3;
+  bytes_per_blocklines[1] <<= yshift_by_mcu-3;
+  bytes_per_blocklines[2] <<= yshift_by_mcu-3;
+
+  bytes_per_mcu[0] <<= xshift_by_mcu-3;
+  bytes_per_mcu[1] <<= xshift_by_mcu-3;
+  bytes_per_mcu[2] <<= xshift_by_mcu-3;
+
+  xstride_by_mcu = 1 << xshift_by_mcu;
+  ystride_by_mcu = 1 << yshift_by_mcu;
+
+  pptr[0] = priv->components[0];
+  pptr[1] = priv->components[1];
+  pptr[2] = priv->components[2];
+
+  trace("bpbl = %d, bpmcu = %d\n",
+	bytes_per_blocklines[0], bytes_per_mcu[0]);
+
+  for (y = priv->height; y > 0; y -= ystride_by_mcu)
+   {
+     trace("Decoding row %d\n", priv->height-y);
+     priv->plane[0] = pptr[0];  pptr[0] += bytes_per_blocklines[0];
+     priv->plane[1] = pptr[1];  pptr[1] += bytes_per_blocklines[1];
+     priv->plane[2] = pptr[2];  pptr[2] += bytes_per_blocklines[2];
+
+     sy = min(y, ystride_by_mcu);
+
+     for (x = priv->width; x > 0; x -= xstride_by_mcu)
+      {
+	sx = min(x, xstride_by_mcu);
+	trace("Block size: %dx%d\n", sx, sy);
+
+	decode_MCU(priv);
+	convert_to_pixfmt(priv, sx, sy);
+	priv->plane[0] += bytes_per_mcu[0];
+	priv->plane[1] += bytes_per_mcu[1];
+	priv->plane[2] += bytes_per_mcu[2];
+	if (priv->restarts_to_go>0)
+	 {
+	   priv->restarts_to_go--;
+	   if (priv->restarts_to_go == 0)
+	    {
+	      priv->stream -= (priv->nbits_in_reservoir/8);
+	      resync(priv);
+	      if (find_next_rst_marker(priv) < 0)
+		return -1;
+	    }
+	 }
+      }
+   }
+
+  trace("Input file size: %d\n", priv->stream_length+2);
+  trace("Input bytes actually read: %d\n", priv->stream - priv->stream_begin + 2);
+
+  return 0;
+}
+
+const char *tinyjpeg_get_errorstring(struct jdec_private *priv)
+{
+  /* FIXME: the error string must be store in the context */
+  priv = priv;
+  return error_string;
+}
+
+void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height)
+{
+  *width = priv->width;
+  *height = priv->height;
+}
+
+int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents)
+{
+  unsigned int i;
+  if (ncomponents > COMPONENTS)
+    ncomponents = COMPONENTS;
+  for (i=0; i<ncomponents; i++)
+    components[i] = priv->components[i];
+  return 0;
+}
+
+int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents)
+{
+  unsigned int i;
+  if (ncomponents > COMPONENTS)
+    ncomponents = COMPONENTS;
+  for (i=0; i<ncomponents; i++)
+    priv->components[i] = components[i];
+  return 0;
+}
+
+int tinyjpeg_get_bytes_per_row(struct jdec_private *priv,
+			       unsigned int *bytes,
+			       unsigned int ncomponents)
+{
+  unsigned int i;
+  if (ncomponents > COMPONENTS)
+    ncomponents = COMPONENTS;
+  for (i=0; i<ncomponents; i++)
+    bytes[i] = priv->bytes_per_row[i];
+  return 0;
+}
+
+int tinyjpeg_set_bytes_per_row(struct jdec_private *priv,
+			       const unsigned int *bytes,
+			       unsigned int ncomponents)
+{
+  unsigned int i;
+  if (ncomponents > COMPONENTS)
+    ncomponents = COMPONENTS;
+  for (i=0; i<ncomponents; i++)
+    priv->bytes_per_row[i] = bytes[i];
+  return 0;
+}
+
+int tinyjpeg_set_flags(struct jdec_private *priv, int flags)
+{
+  int oldflags = priv->flags;
+  priv->flags = flags;
+  return oldflags;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/yuv420p.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/yuv420p.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/yuv420p.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,288 @@
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *  this list of conditions and the following disclaimer in the documentation
+ *  and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * yuv420p.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ * 
+ ******************************************************************************/
+
+/**
+ *  YCrCb -> YUV420P (1x1)
+ *  .---.
+ *  | 1 |
+ *  `---'
+ */
+static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *s, *y;
+  unsigned char *p;
+  int i,j;
+
+  p = priv->plane[0];
+  y = priv->Y;
+  for (i = sy; i > 0; i--)
+   {
+     memcpy(p, y, sx);
+     p += priv->bytes_per_row[0];
+     y += 8;
+   }
+
+  p = priv->plane[1];
+  s = priv->Cb;
+  for (i = sy; i > 0; i--)
+   {
+     for (j = sx; j >= 0; j -= 2) {
+       *p++ = *s;
+       s += 2;
+     }
+     s += 8; /* Skip one line */
+     p += priv->bytes_per_row[1] - 4;
+   }
+
+  p = priv->plane[2];
+  s = priv->Cr;
+  for (i=0; i<8; i+=2)
+   {
+     for (j = sx; j >= 0; j -= 2) {
+       *p++ = *s;
+       s += 2;
+     }
+     s += 8; /* Skip one line */
+     p += priv->bytes_per_row[2] - 4;
+   }
+}
+
+/**
+ *  YCrCb -> YUV420P (2x1)
+ *  .-------.
+ *  | 1 | 2 |
+ *  `-------'
+ */
+static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv, int sx, int sy)
+{
+  unsigned char *p;
+  const unsigned char *s, *y1;
+  unsigned int i;
+
+  p = priv->plane[0];
+  y1 = priv->Y;
+  for (i = sy; i > 0; i--)
+   {
+     memcpy(p, y1, sx);
+     p += priv->bytes_per_row[0];
+     y1 += 16;
+   }
+
+  sx = (sx+1) >> 1;
+
+  p = priv->plane[1];
+  s = priv->Cb;
+  for (i = sy; i > 0; i -= 2)
+   {
+     memcpy(p, s, sx);
+     s += 16; /* Skip one line */
+     p += priv->bytes_per_row[1];
+   }
+
+  p = priv->plane[2];
+  s = priv->Cr;
+  for (i = sy; i > 0; i -= 2)
+   {
+     memcpy(p, s, sx);
+     s += 16; /* Skip one line */
+     p += priv->bytes_per_row[2];
+   }
+}
+
+
+/**
+ *  YCrCb -> YUV420P (1x2)
+ *  .---.
+ *  | 1 |
+ *  |---|
+ *  | 2 |
+ *  `---'
+ */
+static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv, int sx, int sy)
+{
+  const unsigned char *s, *y;
+  unsigned char *p, *pr;
+  int i,j;
+
+  p = priv->plane[0];
+  y = priv->Y;
+  for (i = sy; i > 0; i++)
+   {
+     memcpy(p, y, sx);
+     p+=priv->bytes_per_row[0];
+     y+=8;
+   }
+
+  pr = priv->plane[1];
+  s = priv->Cb;
+  for (i = sy; i > 0; i -= 2)
+   {
+     p = pr;
+     for (j = sx; j > 0; j -= 2) {
+       *p++ = *s;
+       s += 2;
+     }
+     pr += priv->bytes_per_row[1];
+   }
+
+  pr = priv->plane[2];
+  s = priv->Cr;
+  for (i=0; i<8; i++)
+   {
+     p = pr;
+     for (j = sx; j > 0; j -= 2) {
+       *p++ = *s;
+       s += 2;
+     }
+     pr += priv->bytes_per_row[2] - 4;
+   }
+}
+
+/**
+ *  YCrCb -> YUV420P (2x2)
+ *  .-------.
+ *  | 1 | 2 |
+ *  |---+---|
+ *  | 3 | 4 |
+ *  `-------'
+ */
+static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv, int sx, int sy)
+{
+  unsigned char *p;
+  const unsigned char *s, *y1;
+  unsigned int i;
+
+  p = priv->plane[0];
+  y1 = priv->Y;
+  for (i = sy; i > 0; i--)
+   {
+     memcpy(p, y1, sx);
+     p += priv->bytes_per_row[0];
+     y1 += 16;
+   }
+
+  sx = (sx+1) >> 1;
+
+  p = priv->plane[1];
+  s = priv->Cb;
+  for (i = sy; i > 0; i -= 2)
+   {
+     memcpy(p, s, sx);
+     s += 8;
+     p += priv->bytes_per_row[1];
+   }
+
+  p = priv->plane[2];
+  s = priv->Cr;
+  for (i = sy; i > 0; i -= 2)
+   {
+     memcpy(p, s, sx);
+     s += 8;
+     p += priv->bytes_per_row[2];
+   }
+}
+
+static int initialize_yuv420p(struct jdec_private *priv,
+			      unsigned int *bytes_per_blocklines,
+			      unsigned int *bytes_per_mcu)
+{
+  int half_height = (priv->height + 1) >> 2;
+  int half_width  = (priv->width  + 1) >> 2;
+
+  if (!priv->bytes_per_row[0])
+    priv->bytes_per_row[0] = priv->width;
+  if (!priv->components[0])
+    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
+  if (!priv->bytes_per_row[1])
+    priv->bytes_per_row[1] = half_width;
+  if (!priv->components[1])
+    priv->components[1] = malloc(half_height * priv->bytes_per_row[1]);
+
+  if (!priv->bytes_per_row[2])
+    priv->bytes_per_row[2] = half_width;
+  if (!priv->components[2])
+    priv->components[2] = malloc(half_height * priv->bytes_per_row[2]);
+
+  bytes_per_mcu[0] = 8;
+  bytes_per_mcu[1] = 4;
+  bytes_per_mcu[2] = 4;
+
+  bytes_per_blocklines[0] = priv->width << 3;
+  bytes_per_blocklines[1] = half_width << 2;
+  bytes_per_blocklines[2] = half_width << 2;
+
+  /* Return nonzero on failure */
+  return !priv->components[0] || !priv->components[1] || !priv->components[2];
+}
+
+static const struct tinyjpeg_colorspace format_yuv420p =
+  {
+    {
+      YCrCB_to_YUV420P_1x1,
+      YCrCB_to_YUV420P_1x2,
+      YCrCB_to_YUV420P_2x1,
+      YCrCB_to_YUV420P_2x2,
+    },
+    tinyjpeg_decode_mcu_3comp_table,
+    initialize_yuv420p
+  };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P = &format_yuv420p;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashldi3.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashldi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashldi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashldi3.S
+ *
+ * 64-bit shl
+ */
+	.text
+	.align 4
+	.globl __ashldi3
+	.type __ashldi3,@function
+__ashldi3:
+#ifndef REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shldl %cl,%eax,%edx
+	shl   %cl,%eax
+	ret
+
+1:
+	xorl  %edx,%edx
+	shl   %cl,%eax
+	xchgl %edx,%eax
+	ret
+
+	.size __ashldi3,.-__ashldi3
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashrdi3.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashrdi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__ashrdi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashrdi3.S
+ *
+ * 64-bit sar
+ */
+	.text
+	.align 4
+	.globl __ashrdi3
+	.type __ashrdi3,@function
+__ashrdi3:
+#ifndef REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shrdl %cl,%edx,%eax
+	sarl  %cl,%edx
+	ret
+
+1:
+	sarl  %cl,%edx
+	movl  %edx,%eax
+	cdq
+	ret
+
+	.size __ashrdi3,.-__ashrdi3
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__divdi3.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__divdi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__divdi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem);
+
+int64_t __divdi3(int64_t num, int64_t den)
+{
+    int minus = 0;
+    int64_t v;
+
+    if (num < 0) {
+	num = -num;
+	minus = 1;
+    }
+    if (den < 0) {
+	den = -den;
+	minus ^= 1;
+    }
+
+    v = __udivmoddi4(num, den, NULL);
+    if (minus)
+	v = -v;
+
+    return v;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__lshrdi3.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__lshrdi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__lshrdi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__lshrdi3.S
+ *
+ * 64-bit shr
+ */
+	.text
+	.align 4
+	.globl __lshrdi3
+	.type __lshrdi3,@function
+__lshrdi3:
+#ifndef REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shrdl %cl,%edx,%eax
+	shrl  %cl,%edx
+	ret
+
+1:
+	shrl  %cl,%edx
+	xorl  %eax,%eax
+	xchgl %edx,%eax
+	ret
+
+	.size __lshrdi3,.-__lshrdi3
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__moddi3.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__moddi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__moddi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__moddi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem);
+
+int64_t __moddi3(int64_t num, int64_t den)
+{
+    int minus = 0;
+    int64_t v;
+
+    if (num < 0) {
+	num = -num;
+	minus = 1;
+    }
+    if (den < 0) {
+	den = -den;
+	minus ^= 1;
+    }
+
+    (void)__udivmoddi4(num, den, (uint64_t *)&v);
+    if (minus)
+	v = -v;
+
+    return v;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__muldi3.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__muldi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__muldi3.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/*
+ * arch/i386/libgcc/__muldi3.S
+ *
+ * 64*64 = 64 bit unsigned multiplication
+ */
+
+	.text
+	.align 4
+	.globl __muldi3
+	.type __muldi3,@function
+__muldi3:
+#if __SIZEOF_POINTER__ == 4
+	/* i386 */
+	push  %esi
+#ifndef REGPARM
+	movl  8(%esp),%eax
+	movl  %eax,%esi
+	movl  16(%esp),%ecx
+	mull  %ecx
+	imull 12(%esp),%ecx
+	imull 20(%esp),%esi
+	addl  %ecx,%edx
+	addl  %esi,%edx
+#else
+	movl  %eax,%esi
+	push  %edx
+	mull  %ecx
+	imull 8(%esp),%esi
+	addl  %esi,%edx
+	pop   %esi
+	imull %esi,%ecx
+	addl  %ecx,%edx
+#endif
+	pop   %esi
+	ret
+#elif __SIZEOF_POINTER__ == 8
+	/* x86_64 */
+	push  %rsi
+#ifndef REGPARM
+/*
+	movl  8(%esp),%eax
+	movl %eax,%esi
+	movl  16(%esp),%ecx
+	mull  %ecx
+	imull 12(%esp),%ecx
+	imull 20(%esp),%esi
+	addl  %ecx,%edx
+	addl  %esi,%edx
+*/
+	movq  8(%rsp),%rax
+	movq %rax,%rsi
+	movq  16(%rsp),%rcx
+	mulq  %rcx
+	imulq 12(%rsp),%rcx
+	imulq 20(%rsp),%rsi
+	addq  %rcx,%rdx
+	addq  %rsi,%rdx
+#else
+/*
+	movl  %eax,%esi
+	push  %edx
+	mull  %ecx
+	imull 8(%esp),%esi
+	addl  %esi,%edx
+	pop   %rsi
+	imull %esi,%ecx
+	addl  %ecx,%edx
+*/
+	movq  %rax,%rsi
+	pushq  %rdx
+	mulq  %rcx
+	imulq 8(%rsp),%rsi
+	addq  %rsi,%rdx
+	popq  %rsi
+	imulq %rsi,%rcx
+	addq  %rcx,%rdx
+#endif
+	pop   %rsi
+	ret
+#else
+#error "Unsupported architecture for __muldi3.S"
+#endif
+	.size __muldi3,.-__muldi3
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__negdi2.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__negdi2.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__negdi2.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * arch/i386/libgcc/__negdi2.S
+ *
+ * 64-bit negation
+ */
+
+	.text
+	.align 4
+	.globl __negdi2
+	.type __negdi2,@function
+__negdi2:
+#ifndef REGPARM
+	movl 4(%esp),%eax
+	movl 8(%esp),%edx
+#endif
+	negl %edx
+	negl %eax
+	sbbl $0,%edx
+	ret
+
+	.size __negdi2,.-__negdi2
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivdi3.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivdi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivdi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * arch/i386/libgcc/__divdi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem);
+
+uint64_t __udivdi3(uint64_t num, uint64_t den)
+{
+    return __udivmoddi4(num, den, NULL);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivmoddi4.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivmoddi4.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__udivmoddi4.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+#include <klibc/diverr.h>
+#include <stdint.h>
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem_p)
+{
+    uint64_t quot = 0, qbit = 1;
+
+    if (den == 0) {
+	__divide_error();
+	return 0;		/* If trap returns... */
+    }
+
+    /* Left-justify denominator and count shift */
+    while ((int64_t) den >= 0) {
+	den <<= 1;
+	qbit <<= 1;
+    }
+
+    while (qbit) {
+	if (den <= num) {
+	    num -= den;
+	    quot += qbit;
+	}
+	den >>= 1;
+	qbit >>= 1;
+    }
+
+    if (rem_p)
+	*rem_p = num;
+
+    return quot;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__umoddi3.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__umoddi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libgcc/__umoddi3.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * arch/i386/libgcc/__umoddi3.c
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem);
+
+uint64_t __umoddi3(uint64_t num, uint64_t den)
+{
+    uint64_t v;
+
+    (void)__udivmoddi4(num, den, &v);
+    return v;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/ANNOUNCE
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/ANNOUNCE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/ANNOUNCE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+
+Libpng 1.2.44 - June 26, 2010
+
+This is a public release of libpng, intended for use in production codes.
+
+Files available for download:
+
+Source files with LF line endings (for Unix/Linux) and with a
+"configure" script
+
+   libpng-1.2.44.tar.xz (LZMA-compressed, recommended)
+   libpng-1.2.44.tar.gz
+   libpng-1.2.44.tar.bz2
+
+Source files with LF line endings (for Unix/Linux) without the
+"configure" script
+
+   libpng-1.2.44-no-config.tar.xz (LZMA-compressed, recommended)
+   libpng-1.2.44-no-config.tar.gz
+   libpng-1.2.44-no-config.tar.bz2
+
+Source files with CRLF line endings (for Windows), without the
+"configure" script
+
+   lpng1244.zip
+   lpng1244.7z
+   lpng1244.tar.bz2
+
+Project files
+
+   libpng-1.2.44-project-netware.zip
+   libpng-1.2.44-project-wince.zip
+
+Other information:
+
+   libpng-1.2.44-README.txt
+   libpng-1.2.44-KNOWNBUGS.txt
+   libpng-1.2.44-LICENSE.txt
+   libpng-1.2.44-Y2K-compliance.txt
+   libpng-1.2.44-[previous version]-diff.txt
+
+Changes since the last public release (1.2.43):
+
+version 1.2.44 [June 26, 2010]
+
+  Rewrote png_process_IDAT_data to consistently treat extra data as warnings
+    and handle end conditions more cleanly.
+  Removed the now-redundant check for out-of-bounds new_row from example.c
+
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+
+(subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe) or to glennrp at users.sourceforge.net
+
+Glenn R-P
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/CHANGES
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/CHANGES	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/CHANGES	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2714 @@
+/*
+CHANGES - changes for libpng
+
+version 0.2
+  added reader into png.h
+  fixed small problems in stub file
+
+version 0.3
+  added pull reader
+  split up pngwrite.c to several files
+  added pnglib.txt
+  added example.c
+  cleaned up writer, adding a few new transformations
+  fixed some bugs in writer
+  interfaced with zlib 0.5
+  added K&R support
+  added check for 64 KB blocks for 16 bit machines
+
+version 0.4
+  cleaned up code and commented code
+  simplified time handling into png_time
+  created png_color_16 and png_color_8 to handle color needs
+  cleaned up color type defines
+  fixed various bugs
+  made various names more consistent
+  interfaced with zlib 0.71
+  cleaned up zTXt reader and writer (using zlib's Reset functions)
+  split transformations into pngrtran.c and pngwtran.c
+
+version 0.5
+  interfaced with zlib 0.8
+  fixed many reading and writing bugs
+  saved using 3 spaces instead of tabs
+
+version 0.6
+  added png_large_malloc() and png_large_free()
+  added png_size_t
+  cleaned up some compiler warnings
+  added png_start_read_image()
+
+version 0.7
+  cleaned up lots of bugs
+  finished dithering and other stuff
+  added test program
+  changed name from pnglib to libpng
+
+version 0.71 [June, 1995]
+  changed pngtest.png for zlib 0.93
+  fixed error in libpng.txt and example.c
+
+version 0.8
+  cleaned up some bugs
+  added png_set_filler()
+  split up pngstub.c into pngmem.c, pngio.c, and pngerror.c
+  added #define's to remove unwanted code
+  moved png_info_init() to png.c
+  added old_size into png_realloc()
+  added functions to manually set filtering and compression info
+  changed compression parameters based on image type
+  optimized filter selection code
+  added version info
+  changed external functions passing floats to doubles (k&r problems?)
+  put all the configurable stuff in pngconf.h
+  enabled png_set_shift to work with paletted images on read
+  added png_read_update_info() - updates info structure with
+     transformations
+
+version 0.81 [August, 1995]
+  incorporated Tim Wegner's medium model code (thanks, Tim)
+
+version 0.82 [September, 1995]
+  [unspecified changes]
+
+version 0.85 [December, 1995]
+  added more medium model code (almost everything's a far)
+  added i/o, error, and memory callback functions
+  fixed some bugs (16 bit, 4 bit interlaced, etc.)
+  added first run progressive reader (barely tested)
+
+version 0.86 [January, 1996]
+  fixed bugs
+  improved documentation
+
+version 0.87 [January, 1996]
+  fixed medium model bugs
+  fixed other bugs introduced in 0.85 and 0.86
+  added some minor documentation
+
+version 0.88 [January, 1996]
+  fixed progressive bugs
+  replaced tabs with spaces
+  cleaned up documentation
+  added callbacks for read/write and warning/error functions
+
+version 0.89 [July, 1996]
+  added new initialization API to make libpng work better with shared libs
+     we now have png_create_read_struct(), png_create_write_struct(),
+     png_create_info_struct(), png_destroy_read_struct(), and
+     png_destroy_write_struct() instead of the separate calls to
+     malloc and png_read_init(), png_info_init(), and png_write_init()
+  changed warning/error callback functions to fix bug - this means you
+     should use the new initialization API if you were using the old
+     png_set_message_fn() calls, and that the old API no longer exists
+     so that people are aware that they need to change their code
+  changed filter selection API to allow selection of multiple filters
+     since it didn't work in previous versions of libpng anyways
+  optimized filter selection code
+  fixed png_set_background() to allow using an arbitrary RGB color for
+     paletted images
+  fixed gamma and background correction for paletted images, so
+     png_correct_palette is not needed unless you are correcting an
+     external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
+     in pngconf.h) - if nobody uses this, it may disappear in the future.
+  fixed bug with Borland 64K memory allocation (Alexander Lehmann)
+  fixed bug in interlace handling (Smarasderagd, I think)
+  added more error checking for writing and image to reduce invalid files
+  separated read and write functions so that they won't both be linked
+     into a binary when only reading or writing functionality is used
+  new pngtest image also has interlacing and zTXt
+  updated documentation to reflect new API
+
+version 0.90 [January, 1997]
+  made CRC errors/warnings on critical and ancillary chunks configurable
+  libpng will use the zlib CRC routines by (compile-time) default
+  changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
+  added external C++ wrapper statements to png.h (Gilles Dauphin)
+  allow PNG file to be read when some or all of file signature has already
+     been read from the beginning of the stream.  ****This affects the size
+     of info_struct and invalidates all programs that use a shared libpng****
+  fixed png_filler() declarations
+  fixed? background color conversions
+  fixed order of error function pointers to match documentation
+  current chunk name is now available in png_struct to reduce the number
+     of nearly identical error messages (will simplify multi-lingual
+     support when available)
+  try to get ready for unknown-chunk callback functions:
+     - previously read critical chunks are flagged, so the chunk handling
+       routines can determine if the chunk is in the right place
+     - all chunk handling routines have the same prototypes, so we will
+       be able to handle all chunks via a callback mechanism
+  try to fix Linux "setjmp" buffer size problems
+  removed png_large_malloc, png_large_free, and png_realloc functions.
+
+version 0.95 [March, 1997]
+  fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
+  fixed bug in PNG file signature compares when start != 0
+  changed parameter type of png_set_filler(...filler...) from png_byte
+     to png_uint_32
+  added test for MACOS to ensure that both math.h and fp.h are not #included
+  added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
+  added "packswap" transformation, which changes the endianness of
+     packed-pixel bytes (Kevin Bracey)
+  added "strip_alpha" transformation, which removes the alpha channel of
+     input images without using it (not necessarily a good idea)
+  added "swap_alpha" transformation, which puts the alpha channel in front
+     of the color bytes instead of after
+  removed all implicit variable tests which assume NULL == 0 (I think)
+  changed several variables to "png_size_t" to show 16/32-bit limitations
+  added new pCAL chunk read/write support
+  added experimental filter selection weighting (Greg Roelofs)
+  removed old png_set_rgbx() and png_set_xrgb() functions that have been
+     obsolete for about 2 years now (use png_set_filler() instead)
+  added macros to read 16- and 32-bit ints directly from buffer, to be
+     used only on those systems that support it (namely PowerPC and 680x0)
+     With some testing, this may become the default for MACOS/PPC systems.
+  only calculate CRC on data if we are going to use it
+  added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
+  added macros for simple libpng debugging output selectable at compile time
+  removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
+  more description of info_struct in libpng.txt and png.h
+  more instructions in example.c
+  more chunk types tested in pngtest.c
+  renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
+     png_set_<chunk>.  We now have corresponding png_get_<chunk>
+     functions in pngget.c to get information in info_ptr.  This isolates
+     the application from the internal organization of png_info_struct
+     (good for shared library implementations).
+
+version 0.96 [May, 1997]
+  fixed serious bug with < 8bpp images introduced in 0.95
+  fixed 256-color transparency bug (Greg Roelofs)
+  fixed up documentation (Greg Roelofs, Laszlo Nyul)
+  fixed "error" in pngconf.h for Linux setjmp() behaviour
+  fixed DOS medium model support (Tim Wegner)
+  fixed png_check_keyword() for case with error in static string text
+  added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
+  added typecasts to quiet compiler errors
+  added more debugging info
+
+version 0.97 [January, 1998]
+  removed PNG_USE_OWN_CRC capability
+  relocated png_set_crc_action from pngrutil.c to pngrtran.c
+  fixed typecasts of "new_key", etc. (Andreas Dilger)
+  added RFC 1152 [sic] date support
+  fixed bug in gamma handling of 4-bit grayscale
+  added 2-bit grayscale gamma handling (Glenn R-P)
+  added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
+  minor corrections in libpng.txt
+  added simple sRGB support (Glenn R-P)
+  easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
+     all configurable options can be selected from command-line instead
+     of having to edit pngconf.h (Glenn R-P)
+  fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
+  added more conditions for png_do_background, to avoid changing
+     black pixels to background when a background is supplied and
+     no pixels are transparent
+  repaired PNG_NO_STDIO behaviour
+  tested NODIV support and made it default behaviour (Greg Roelofs)
+  added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
+  regularized version numbering scheme and bumped shared-library major
+     version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs)
+
+version 0.98 [January, 1998]
+  cleaned up some typos in libpng.txt and in code documentation
+  fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
+  cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
+  changed recommendation about file_gamma for PC images to .51 from .45,
+     in example.c and libpng.txt, added comments to distinguish between
+     screen_gamma, viewing_gamma, and display_gamma.
+  changed all references to RFC1152 to read RFC1123 and changed the
+     PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
+  added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
+  changed srgb_intent from png_byte to int to avoid compiler bugs
+
+version 0.99 [January 30, 1998]
+  free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
+  fixed a longstanding "packswap" bug in pngtrans.c
+  fixed some inconsistencies in pngconf.h that prevented compiling with
+     PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
+  fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
+  changed recommendation about file_gamma for PC images to .50 from .51 in
+     example.c and libpng.txt, and changed file_gamma for sRGB images to .45
+  added a number of functions to access information from the png structure
+     png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
+  added TARGET_MACOS similar to zlib-1.0.8
+  define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
+  added type casting to all png_malloc() function calls
+version 0.99a [January 31, 1998]
+  Added type casts and parentheses to all returns that return a value.(Tim W.)
+version 0.99b [February 4, 1998]
+  Added type cast png_uint_32 on malloc function calls where needed.
+  Changed type of num_hist from png_uint_32 to int (same as num_palette).
+  Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
+  Renamed makefile.elf to makefile.lnx.
+version 0.99c [February 7, 1998]
+  More type casting.  Removed erroneous overflow test in pngmem.c.
+  Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
+  Added UNIX manual pages libpng.3 (incorporating libpng.txt) and  png.5.
+version 0.99d [February 11, 1998]
+  Renamed "far_to_near()" "png_far_to_near()"
+  Revised libpng.3
+  Version 99c "buffered" operations didn't work as intended.  Replaced them
+    with png_memcpy_check() and png_memset_check().
+  Added many "if (png_ptr == NULL) return" to quell compiler warnings about
+    unused png_ptr, mostly in pngget.c and pngset.c.
+  Check for overlength tRNS chunk present when indexed-color PLTE is read.
+  Cleaned up spelling errors in libpng.3/libpng.txt
+  Corrected a problem with png_get_tRNS() which returned undefined trans array
+version 0.99e [February 28, 1998]
+  Corrected png_get_tRNS() again.
+  Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
+  Touched up example.c to make more of it compileable, although the entire
+    file still can't be compiled (Willem van Schaik)
+  Fixed a bug in png_do_shift() (Bryan Tsai)
+  Added a space in png.h prototype for png_write_chunk_start()
+  Replaced pngtest.png with one created with zlib 1.1.1
+  Changed pngtest to report PASS even when file size is different (Jean-loup G.)
+  Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
+version 0.99f [March 5, 1998]
+  Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
+  Moved makefiles into a "scripts" directory, and added INSTALL instruction file
+  Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
+  Added pointers to "note on libpng versions" in makefile.lnx and README
+  Added row callback feature when reading and writing nonprogressive rows
+     and added a test of this feature in pngtest.c
+  Added user transform callbacks, with test of the feature in pngtest.c
+version 0.99g [March 6, 1998, morning]
+  Minor changes to pngtest.c to suppress compiler warnings.
+  Removed "beta" language from documentation.
+version 0.99h [March 6, 1998, evening]
+  Minor changes to previous minor changes to pngtest.c
+  Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
+  and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
+  Added user transform capability
+
+version 1.00 [March 7, 1998]
+  Changed several typedefs in pngrutil.c
+  Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
+  replaced "while(1)" with "for(;;)"
+  added PNGARG() to prototypes in pngtest.c and removed some prototypes
+  updated some of the makefiles (Tom Lane)
+  changed some typedefs (s_start, etc.) in pngrutil.c
+  fixed dimensions of "short_months" array in pngwrite.c
+  Replaced ansi2knr.c with the one from jpeg-v6
+
+version 1.0.0 [March 8, 1998]
+  Changed name from 1.00 to 1.0.0 (Adam Costello)
+  Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
+version 1.0.0a [March 9, 1998]
+  Fixed three bugs in pngrtran.c to make gamma+background handling consistent
+  (Greg Roelofs)
+  Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
+  for major, minor, and bugfix releases.  This is 10001. (Adam Costello,
+  Tom Lane)
+  Make months range from 1-12 in png_convert_to_rfc1123
+version 1.0.0b [March 13, 1998]
+  Quieted compiler complaints about two empty "for" loops in pngrutil.c
+  Minor changes to makefile.s2x
+  Removed #ifdef/#endif around a png_free() in pngread.c
+
+version 1.0.1 [March 14, 1998]
+  Changed makefile.s2x to reduce security risk of using a relative pathname
+  Fixed some typos in the documentation (Greg).
+  Fixed a problem with value of "channels" returned by png_read_update_info()
+version 1.0.1a [April 21, 1998]
+  Optimized Paeth calculations by replacing abs() function calls with intrinsics
+  plus other loop optimizations. Improves avg decoding speed by about 20%.
+  Commented out i386istic "align" compiler flags in makefile.lnx.
+  Reduced the default warning level in some makefiles, to make them consistent.
+  Removed references to IJG and JPEG in the ansi2knr.c copyright statement.
+  Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.
+  Added grayscale and 16-bit capability to png_do_read_filler().
+  Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes
+    too large when writing an image with bit_depth < 8 (Bob Dellaca).
+  Corrected some bugs in the experimental weighted filtering heuristics.
+  Moved a misplaced pngrutil code block that truncates tRNS if it has more
+    than num_palette entries -- test was done before num_palette was defined.
+  Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).
+  Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen).
+version 1.0.1b [May 2, 1998]
+  Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).
+  Relocated the png_composite macros from pngrtran.c to png.h (Greg).
+  Added makefile.sco (contributed by Mike Hopkirk).
+  Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a.
+  Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.
+  More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert).
+  More work on loop optimization which may help when compiled with C++ compilers.
+  Added warnings when people try to use transforms they've defined out.
+  Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran.
+  Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)
+version 1.0.1c [May 11, 1998]
+  Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for
+    filler bytes should have been 0xff instead of 0xf.
+  Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.
+  Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED
+    out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h
+  Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED,
+    for consistency, in pngconf.h
+  Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier
+    to remove unwanted capabilities via the compile line
+  Made some corrections to grammar (which, it's) in documentation (Greg).
+  Corrected example.c, use of row_pointers in png_write_image().
+version 1.0.1d [May 24, 1998]
+  Corrected several statements that used side effects illegally in pngrutil.c
+    and pngtrans.c, that were introduced in version 1.0.1b
+  Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)
+  More corrections to example.c, use of row_pointers in png_write_image()
+    and png_read_rows().
+  Added pngdll.mak and pngdef.pas to scripts directory, contributed by
+    Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5
+  Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)
+  Changed several loops from count-down to count-up, for consistency.
+version 1.0.1e [June 6, 1998]
+  Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and
+    added warnings when people try to set png_read_fn and png_write_fn in
+    the same structure.
+  Added a test such that png_do_gamma will be done when num_trans==0
+    for truecolor images that have defined a background.  This corrects an
+    error that was introduced in libpng-0.90 that can cause gamma processing
+    to be skipped.
+  Added tests in png.h to include "trans" and "trans_values" in structures
+    when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.
+  Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()
+  Moved png_convert_to_rfc_1123() from pngwrite.c to png.c
+  Added capability for user-provided malloc_fn() and free_fn() functions,
+    and revised pngtest.c to demonstrate their use, replacing the
+    PNGTEST_DEBUG_MEM feature.
+  Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).
+
+version 1.0.2 [June 14, 1998]
+  Fixed two bugs in makefile.bor .
+version 1.0.2a [December 30, 1998]
+  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
+  Fixed a bug in png_do_filler() that made it fail to write filler bytes in
+    the left-most pixel of each row (Kevin Bracey).
+  Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
+    in pngtest.c (Duncan Simpson).
+  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
+    even when no tIME chunk was present in the source file.
+  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
+  Fixed a problem in png_read_push_finish_row(), which would not skip some
+    passes that it should skip, for images that are less than 3 pixels high.
+  Interchanged the order of calls to png_do_swap() and png_do_shift()
+    in pngwtran.c (John Cromer).
+  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
+  Changed "bad adaptive filter type" from error to warning in pngrutil.c .
+  Fixed a documentation error about default filtering with 8-bit indexed-color.
+  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
+    (L. Peter Deutsch).
+  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
+  Added png_get_copyright() and png_get_header_version() functions.
+  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
+  Added information about debugging in libpng.txt and libpng.3 .
+  Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
+  Removed lines after Dynamic Dependencies" in makefile.aco .
+  Revised makefile.dec to make a shared library (Jeremie Petit).
+  Removed trailing blanks from all files.
+version 1.0.2a [January 6, 1999]
+  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
+  Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
+  Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
+  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
+    which is obsolete.
+
+version 1.0.3 [January 14, 1999]
+  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
+  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
+version 1.0.3a [August 12, 1999]
+  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+     if an attempt is made to read an interlaced image when it's not supported.
+  Added check if png_ptr->trans is defined before freeing it in pngread.c
+  Modified the Y2K statement to include versions back to version 0.71
+  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+  Replaced leading blanks with tab characters in makefile.hux
+  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+  Changed (float)red and (float)green to (double)red, (double)green
+     in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+  Updated documentation to refer to the PNG-1.2 specification.
+  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+  Fixed bugs in calculation of the length of rowbytes when adding alpha
+    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+  Added function png_set_user_transform_info() to store user_transform_ptr,
+    user_depth, and user_channels into the png_struct, and a function
+    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+  Added function png_set_empty_plte_permitted() to make libpng useable
+    in MNG applications.
+  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+    consistent with PNG-1.2, and allow variance of 500 before complaining.
+  Added assembler code contributed by Intel in file pngvcrd.c and modified
+    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+  Added some aliases for png_set_expand() in pngrtran.c, namely
+    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
+    (Greg Roelofs, in "PNG: The Definitive Guide").
+  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+version 1.0.3b [August 26, 1999]
+  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+  Changed leading blanks to tabs in all makefiles.
+  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+  Made alternate versions of  png_set_expand() in pngrtran.c, namely
+    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+    (Greg Roelofs, in "PNG: The Definitive Guide").  Deleted the 1.0.3a aliases.
+  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+  Revised calculation of num_blocks in pngmem.c to avoid a potentially
+    negative shift distance, whose results are undefined in the C language.
+  Added a check in pngset.c to prevent writing multiple tIME chunks.
+  Added a check in pngwrite.c to detect invalid small window_bits sizes.
+version 1.0.3d [September 4, 1999]
+  Fixed type casting of igamma in pngrutil.c
+  Added new png_expand functions to scripts/pngdef.pas and pngos2.def
+  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+
+version 1.0.4 [September 24, 1999]
+  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+  Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
+  Made several minor corrections to pngtest.c
+  Renamed the makefiles with longer but more user friendly extensions.
+  Copied the PNG copyright and license to a separate LICENSE file.
+  Revised documentation, png.h, and example.c to remove reference to
+    "viewing_gamma" which no longer appears in the PNG specification.
+  Revised pngvcrd.c to use MMX code for interlacing only on the final pass.
+  Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a
+  Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX
+    assembler code) and makefile.vcwin32 (doesn't).
+  Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)
+  Added a copy of pngnow.png to the distribution.
+version 1.0.4a [September 25, 1999]
+  Increase max_pixel_depth in pngrutil.c if a user transform needs it.
+  Changed several division operations to right-shifts in pngvcrd.c
+version 1.0.4b [September 30, 1999]
+  Added parentheses in line 3732 of pngvcrd.c
+  Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1
+version 1.0.4c [October 1, 1999]
+  Added a "png_check_version" function in png.c and pngtest.c that will generate
+    a helpful compiler error if an old png.h is found in the search path.
+  Changed type of png_user_transform_depth|channels from int to png_byte.
+version 1.0.4d [October 6, 1999]
+  Changed 0.45 to 0.45455 in png_set_sRGB()
+  Removed unused PLTE entries from pngnow.png
+  Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
+version 1.0.4e [October 10, 1999]
+  Fixed sign error in pngvcrd.c (Greg Roelofs)
+  Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
+version 1.0.4f [October 15, 1999]
+  Surrounded example.c code with #if 0 .. #endif to prevent people from
+    inadvertently trying to compile it.
+  Changed png_get_header_version() from a function to a macro in png.h
+  Added type casting mostly in pngrtran.c and pngwtran.c
+  Removed some pointless "ptr = NULL" in pngmem.c
+  Added a "contrib" directory containing the source code from Greg's book.
+
+version 1.0.5 [October 15, 1999]
+  Minor editing of the INSTALL and README files.
+version 1.0.5a [October 23, 1999]
+  Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)
+  Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)
+  Further optimization and bugfix of pngvcrd.c
+  Revised pngset.c so that it does not allocate or free memory in the user's
+    text_ptr structure.  Instead, it makes its own copy.
+  Created separate write_end_info_struct in pngtest.c for a more severe test.
+  Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.
+version 1.0.5b [November 23, 1999]
+  Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and
+    PNG_FLAG_WROTE_tIME from flags to mode.
+  Added png_write_info_before_PLTE() function.
+  Fixed some typecasting in contrib/gregbook/*.c
+  Updated scripts/makevms.com and added makevms.com to contrib/gregbook
+    and contrib/pngminus (Martin Zinser)
+version 1.0.5c [November 26, 1999]
+  Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr.
+  Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to
+    accommodate making DLL's: Moved usr_png_ver from global variable to function
+    png_get_header_ver() in png.c.  Moved png_sig to png_sig_bytes in png.c and
+    eliminated use of png_sig in pngwutil.c.  Moved the various png_CHNK arrays
+    into pngtypes.h.  Eliminated use of global png_pass arrays.  Declared the
+    png_CHNK and png_pass arrays to be "const".  Made the global arrays
+    available to applications (although none are used in libpng itself) when
+    PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.
+  Removed some extraneous "-I" from contrib/pngminus/makefile.std
+  Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
+  Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
+version 1.0.5d [November 29, 1999]
+  Add type cast (png_const_charp) two places in png.c
+  Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
+  Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
+    to applications a macro "PNG_USE_LOCAL_ARRAYS".
+  Remove all the new declarations with #ifdef/#endif when
+    PNG_USE_GLOBAL_ARRAYS is defined.
+  Added PNG_EXPORT_VAR macro to accommodate making DLL's.
+version 1.0.5e [November 30, 1999]
+  Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
+    structure; refactored the inflate/deflate support to make adding new chunks
+    with trailing compressed parts easier in the future, and added new functions
+    png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
+    png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
+  NOTE: Applications that write text chunks MUST define png_text->lang
+    before calling png_set_text(). It must be set to NULL if you want to
+    write tEXt or zTXt chunks.  If you want your application to be able to
+    run with older versions of libpng, use
+
+      #ifdef PNG_iTXt_SUPPORTED
+         png_text[i].lang = NULL;
+      #endif
+
+  Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned
+    offsets (Eric S. Raymond).
+  Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into
+    PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED
+    macros, leaving the separate macros also available.
+  Removed comments on #endifs at the end of many short, non-nested #if-blocks.
+version 1.0.5f [December 6, 1999]
+  Changed makefile.solaris to issue a warning about potential problems when
+    the ucb "ld" is in the path ahead of the ccs "ld".
+  Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3.
+  Added sCAL chunk support (Eric S. Raymond).
+version 1.0.5g [December 7, 1999]
+  Fixed "png_free_spallettes" typo in png.h
+  Added code to handle new chunks in pngpread.c
+  Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block
+  Added "translated_key" to png_text structure and png_write_iTXt().
+  Added code in pngwrite.c to work around a newly discovered zlib bug.
+version 1.0.5h [December 10, 1999]
+  NOTE: regarding the note for version 1.0.5e, the following must also
+    be included in your code:
+        png_text[i].translated_key = NULL;
+  Unknown chunk handling is now supported.
+  Option to eliminate all floating point support was added.  Some new
+    fixed-point functions such as png_set_gAMA_fixed() were added.
+  Expanded tabs and removed trailing blanks in source files.
+version 1.0.5i [December 13, 1999]
+  Added some type casts to silence compiler warnings.
+  Renamed "png_free_spalette" to "png_free_spalettes" for consistency.
+  Removed leading blanks from a #define in pngvcrd.c
+  Added some parameters to the new png_set_keep_unknown_chunks() function.
+  Added a test for up->location != 0 in the first instance of writing
+    unknown chunks in pngwrite.c
+  Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to
+    prevent recursion.
+  Added png_free_hIST() function.
+  Various patches to fix bugs in the sCAL and integer cHRM processing,
+    and to add some convenience macros for use with sCAL.
+version 1.0.5j [December 21, 1999]
+  Changed "unit" parameter of png_write_sCAL from png_byte to int, to work
+    around buggy compilers.
+  Added new type "png_fixed_point" for integers that hold float*100000 values
+  Restored backward compatibility of tEXt/zTXt chunk processing:
+    Restored the first four members of png_text to the same order as v.1.0.5d.
+    Added members "lang_key" and "itxt_length" to png_text struct.  Set
+    text_length=0 when "text" contains iTXt data.  Use the "compression"
+    member to distinguish among tEXt/zTXt/iTXt types.  Added
+    PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.
+    The "Note" above, about backward incompatibility of libpng-1.0.5e, no
+    longer applies.
+  Fixed png_read|write_iTXt() to read|write parameters in the right order,
+    and to write the iTXt chunk after IDAT if it appears in the end_ptr.
+  Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)
+  Reversed the order of trying to write floating-point and fixed-point gAMA.
+version 1.0.5k [December 27, 1999]
+  Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))"
+  Added png_handle_as_unknown() function (Glenn)
+  Added png_free_chunk_list() function and chunk_list and num_chunk_list members
+    of png_ptr.
+  Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.
+  Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings
+    about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)
+  Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).
+  Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.
+  Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().
+version 1.0.5l [January 1, 2000]
+  Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()
+    for setting a callback function to handle unknown chunks and for
+    retrieving the associated user pointer (Glenn).
+version 1.0.5m [January 7, 2000]
+  Added high-level functions png_read_png(), png_write_png(), png_free_pixels().
+version 1.0.5n [January 9, 2000]
+  Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its
+    own memory for info_ptr->palette.  This makes it safe for the calling
+    application to free its copy of the palette any time after it calls
+    png_set_PLTE().
+version 1.0.5o [January 20, 2000]
+  Cosmetic changes only (removed some trailing blanks and TABs)
+version 1.0.5p [January 31, 2000]
+  Renamed pngdll.mak to makefile.bd32
+  Cosmetic changes in pngtest.c
+version 1.0.5q [February 5, 2000]
+  Relocated the makefile.solaris warning about PATH problems.
+  Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)
+  Revised makefile.gcmmx
+  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
+version 1.0.5r [February 7, 2000]
+  Removed superfluous prototype for png_get_itxt from png.h
+  Fixed a bug in pngrtran.c that improperly expanded the background color.
+  Return *num_text=0 from png_get_text() when appropriate, and fix documentation
+    of png_get_text() in libpng.txt/libpng.3.
+version 1.0.5s [February 18, 2000]
+  Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the
+    new error handler that's planned for the next libpng release, and changed
+    example.c, pngtest.c, and contrib programs to use this macro.
+  Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)
+  Fixed a bug in png_read_png() that caused it to fail to expand some images
+    that it should have expanded.
+  Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions
+    in pngget.c
+  Changed the allocation of palette, history, and trans arrays back to
+    the version 1.0.5 method (linking instead of copying) which restores
+    backward compatibility with version 1.0.5.  Added some remarks about
+    that in example.c.  Added "free_me" member to info_ptr and png_ptr
+    and added png_free_data() function.
+  Updated makefile.linux and makefile.gccmmx to make directories conditionally.
+  Made cosmetic changes to pngasmrd.h
+  Added png_set_rows() and png_get_rows(), for use with png_read|write_png().
+  Modified png_read_png() to allocate info_ptr->row_pointers only if it
+    hasn't already been allocated.
+version 1.0.5t [March 4, 2000]
+  Changed png_jmp_env() migration aiding macro to png_jmpbuf().
+  Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c
+  Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when
+    PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b
+  Files in contrib/gregbook were revised to use png_jmpbuf() and to select
+    a 24-bit visual if one is available, and to allow abbreviated options.
+  Files in contrib/pngminus were revised to use the png_jmpbuf() macro.
+  Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s
+version 1.0.5u [March 5, 2000]
+  Simplified the code that detects old png.h in png.c and pngtest.c
+  Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)
+  Increased precision of rgb_to_gray calculations from 8 to 15 bits and
+    added png_set_rgb_to_gray_fixed() function.
+  Added makefile.bc32 (32-bit Borland C++, C mode)
+version 1.0.5v [March 11, 2000]
+  Added some parentheses to the png_jmpbuf macro definition.
+  Updated references to the zlib home page, which has moved to freesoftware.com.
+  Corrected bugs in documentation regarding png_read_row() and png_write_row().
+  Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.
+  Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,
+    revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)
+
+version 1.0.6 [March 20, 2000]
+  Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c
+  Added makefile.sggcc (SGI IRIX with gcc)
+version 1.0.6d [April 7, 2000]
+  Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO
+  Added data_length parameter to png_decompress_chunk() function
+  Revised documentation to remove reference to abandoned png_free_chnk functions
+  Fixed an error in png_rgb_to_gray_fixed()
+  Revised example.c, usage of png_destroy_write_struct().
+  Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file
+  Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c
+  Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().
+version 1.0.6e [April 9, 2000]
+  Added png_data_freer() function.
+  In the code that checks for over-length tRNS chunks, added check of
+    info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)
+  Minor revisions of libpng.txt/libpng.3.
+  Check for existing data and free it if the free_me flag is set, in png_set_*()
+    and png_handle_*().
+  Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED
+    is defined.
+  Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c
+    and mentioned the purposes of the two macros in libpng.txt/libpng.3.
+version 1.0.6f [April 14, 2000]
+  Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.
+  Add checks in png_set_text() for NULL members of the input text structure.
+  Revised libpng.txt/libpng.3.
+  Removed superfluous prototype for png_set_itxt from png.h
+  Removed "else" from pngread.c, after png_error(), and changed "0" to "length".
+  Changed several png_errors about malformed ancillary chunks to png_warnings.
+version 1.0.6g [April 24, 2000]
+  Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.
+  Relocated paragraph about png_set_background() in libpng.3/libpng.txt
+    and other revisions (Matthias Benckmann)
+  Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and
+    png_ptr members to restore binary compatibility with libpng-1.0.5
+    (breaks compatibility with libpng-1.0.6).
+version 1.0.6h [April 24, 2000]
+  Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds
+    libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)
+    This is a temporary change for test purposes.
+version 1.0.6i [May 2, 2000]
+  Rearranged some members at the end of png_info and png_struct, to put
+    unknown_chunks_num and free_me within the original size of the png_structs
+    and free_me, png_read_user_fn, and png_free_fn within the original png_info,
+    because some old applications allocate the structs directly instead of
+    using png_create_*().
+  Added documentation of user memory functions in libpng.txt/libpng.3
+  Modified png_read_png so that it will use user_allocated row_pointers
+    if present, unless free_me directs that it be freed, and added description
+    of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.
+  Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version
+    1.00) members of png_struct and png_info, to regain binary compatibility
+    when you define this macro.  Capabilities lost in this event
+    are user transforms (new in version 1.0.0),the user transform pointer
+    (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,
+    the high-level interface, and unknown chunks support (all new in 1.0.6).
+    This was necessary because of old applications that allocate the structs
+    directly as authors were instructed to do in libpng-0.88 and earlier,
+    instead of using png_create_*().
+  Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which
+    can be used to detect codes that directly allocate the structs, and
+    code to check these modes in png_read_init() and png_write_init() and
+    generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED
+    was not defined.
+  Added makefile.intel and updated makefile.watcom (Pawel Mrochen)
+version 1.0.6j [May 3, 2000]
+  Overloaded png_read_init() and png_write_init() with macros that convert
+    calls to png_read_init_2() or png_write_init_2() that check the version
+    and structure sizes.
+version 1.0.7beta11 [May 7, 2000]
+  Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
+    which are no longer used.
+  Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
+    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED
+    is defined.
+  Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
+    overrun when old applications fill the info_ptr->text structure directly.
+  Added PNGAPI macro, and added it to the definitions of all exported functions.
+  Relocated version macro definitions ahead of the includes of zlib.h and
+    pngconf.h in png.h.
+version 1.0.7beta12 [May 12, 2000]
+  Revised pngset.c to avoid a problem with expanding the png_debug macro.
+  Deleted some extraneous defines from pngconf.h
+  Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.
+  Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.
+  Added png_access_version_number() function.
+  Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().
+  Expanded libpng.3/libpng.txt information about png_data_freer().
+version 1.0.7beta14 [May 17, 2000] (beta13 was not published)
+  Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as
+    warnings instead of errors, as pngrutil.c does.
+  Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()
+    will actually write IDATs.
+  Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.
+  Make png_free_data() ignore its final parameter except when freeing data
+    that can have multiple instances (text, sPLT, unknowns).
+  Fixed a new bug in png_set_rows().
+  Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.
+  Added png_set_invalid() function.
+  Fixed incorrect illustrations of png_destroy_write_struct() in example.c.
+version 1.0.7beta15 [May 30, 2000]
+  Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce
+    fewer error messages.
+  Rearranged checks for Z_OK to check the most likely path first in pngpread.c
+    and pngwutil.c.
+  Added checks in pngtest.c for png_create_*() returning NULL, and mentioned
+    in libpng.txt/libpng.3 the need for applications to check this.
+  Changed names of png_default_*() functions in pngtest to pngtest_*().
+  Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.
+  Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c
+  Set each pointer to NULL after freeing it in png_free_data().
+  Worked around a problem in pngconf.h; AIX's strings.h defines an "index"
+    macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos)
+  Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux).
+version 1.0.7beta16 [June 4, 2000]
+  Revised the workaround of AIX string.h "index" bug.
+  Added a check for overlength PLTE chunk in pngrutil.c.
+  Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer
+    indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.
+  Added a warning in png_decompress_chunk() when it runs out of data, e.g.
+    when it tries to read an erroneous PhotoShop iCCP chunk.
+  Added PNG_USE_DLL macro.
+  Revised the copyright/disclaimer/license notice.
+  Added contrib/msvctest directory
+version 1.0.7rc1 [June 9, 2000]
+  Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA  (0x0400 not 0x0200)
+  Added contrib/visupng directory (Willem van Schaik)
+version 1.0.7beta18 [June 23, 2000]
+  Revised PNGAPI definition, and pngvcrd.c to work with __GCC__
+    and do not redefine PNGAPI if it is passed in via a compiler directive.
+  Revised visupng/PngFile.c to remove returns from within the Try block.
+  Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros.
+  Updated contrib/visupng/cexcept.h to version 1.0.0.
+  Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.
+version 1.0.7rc2 [June 28, 2000]
+  Updated license to include disclaimers required by UCITA.
+  Fixed "DJBPP" typo in pnggccrd.c introduced in beta18.
+
+version 1.0.7 [July 1, 2000]
+  Revised the definition of "trans_values" in libpng.3/libpng.txt
+version 1.0.8beta1 [July 8, 2000]
+  Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.
+  Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and
+     pngwutil.c.
+  Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.
+  Removed unused "#include <assert.h>" from png.c
+  Added WindowsCE support.
+  Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.
+version 1.0.8beta2 [July 10, 2000]
+  Added project files to the wince directory and made further revisions
+     of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.
+version 1.0.8beta3 [July 11, 2000]
+  Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()
+     for indexed-color input files to avoid potential double-freeing trans array
+     under some unusual conditions; problem was introduced in version 1.0.6f.
+  Further revisions to pngtest.c and files in the wince subdirectory.
+version 1.0.8beta4 [July 14, 2000]
+  Added the files pngbar.png and pngbar.jpg to the distribution.
+  Added makefile.cygwin, and cygwin support in pngconf.h
+  Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)
+version 1.0.8rc1 [July 16, 2000]
+  Revised png_debug() macros and statements to eliminate compiler warnings.
+
+version 1.0.8 [July 24, 2000]
+  Added png_flush() in pngwrite.c, after png_write_IEND().
+  Updated makefile.hpux to build a shared library.
+version 1.0.9beta1 [November 10, 2000]
+  Fixed typo in scripts/makefile.hpux
+  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
+  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+  Changed "cdrom.com" in documentation to "libpng.org"
+  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
+  Changed type of "params" from voidp to png_voidp in png_read|write_png().
+  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
+  Revised the 3 instances of WRITEFILE in pngtest.c.
+  Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory.
+  Updated png.rc in dll/msvc project
+  Revised makefile.dec to define and use LIBPATH and INCPATH
+  Increased size of global png_libpng_ver[] array from 12 to 18 chars.
+  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
+  Removed duplicate png_crc_finish() from png_handle_bKGD() function.
+  Added a warning when application calls png_read_update_info() multiple times.
+  Revised makefile.cygwin
+  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
+  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
+version 1.0.9beta2 [November 19, 2000]
+  Renamed the "dll" subdirectory "projects".
+  Added borland project files to "projects" subdirectory.
+  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
+  Add error message in png_set_compression_buffer_size() when malloc fails.
+version 1.0.9beta3 [November 23, 2000]
+  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
+  Removed the png_flush() in pngwrite.c that crashes some applications
+    that don't set png_output_flush_fn.
+  Added makefile.macosx and makefile.aix to scripts directory.
+version 1.0.9beta4 [December 1, 2000]
+  Change png_chunk_warning to png_warning in png_check_keyword().
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
+version 1.0.9beta5 [December 15, 2000]
+  Added support for filter method 64 (for PNG datastreams embedded in MNG).
+version 1.0.9beta6 [December 18, 2000]
+  Revised png_set_filter() to accept filter method 64 when appropriate.
+  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
+    help prevent applications from using MNG features in PNG datastreams.
+  Added png_permit_mng_features() function.
+  Revised libpng.3/libpng.txt.  Changed "filter type" to "filter method".
+version 1.0.9rc1 [December 23, 2000]
+  Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c
+  Fixed error handling of unknown compression type in png_decompress_chunk().
+  In pngconf.h, define __cdecl when _MSC_VER is defined.
+version 1.0.9beta7 [December 28, 2000]
+  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
+  Revised memory management in png_set_hIST and png_handle_hIST in a backward
+    compatible manner.  PLTE and tRNS were revised similarly.
+  Revised the iCCP chunk reader to ignore trailing garbage.
+version 1.0.9beta8 [January 12, 2001]
+  Moved pngasmrd.h into pngconf.h.
+  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
+version 1.0.9beta9 [January 15, 2001]
+  Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to
+    wince and msvc project module definition files.
+  Minor revision of makefile.cygwin.
+  Fixed bug with progressive reading of narrow interlaced images in pngpread.c
+version 1.0.9beta10 [January 16, 2001]
+  Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.
+  Fixed "png_mmx_supported" typo in project definition files.
+version 1.0.9beta11 [January 19, 2001]
+  Updated makefile.sgi to make shared library.
+  Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED
+    by default, for the benefit of DLL forward compatibility.  These will
+    be re-enabled in version 1.2.0.
+version 1.0.9rc2 [January 22, 2001]
+  Revised cygwin support.
+
+version 1.0.9 [January 31, 2001]
+  Added check of cygwin's ALL_STATIC in pngconf.h
+  Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
+version 1.0.10beta1 [March 14, 2001]
+  Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc.
+  Reformatted libpng.3 to eliminate bad line breaks.
+  Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c
+  Added prototype for png_mmx_support() near the top of pnggccrd.c
+  Moved some error checking from png_handle_IHDR to png_set_IHDR.
+  Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros.
+  Revised png_mmx_support() function in pnggccrd.c
+  Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c
+  Fixed memory leak in contrib/visupng/PngFile.c
+  Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version)
+  Added warnings when retrieving or setting gamma=0.
+  Increased the first part of msg buffer from 16 to 18 in png_chunk_warning().
+version 1.0.10rc1 [March 23, 2001]
+  Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy,
+    and png_strlen.
+  Revised png_mmx_supported() function in pnggccrd.c to return proper value.
+  Fixed bug in progressive reading (pngpread.c) with small images (height < 8).
+
+version 1.0.10 [March 30, 2001]
+  Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin
+  Added beos project files (Chris Herborth)
+version 1.0.11beta1 [April 3, 2001]
+  Added type casts on several png_malloc() calls (Dimitri Papadapoulos).
+  Removed a no-longer needed AIX work-around from pngconf.h
+  Changed several "//" single-line comments to C-style in pnggccrd.c
+version 1.0.11beta2 [April 11, 2001]
+  Removed PNGAPI from several functions whose prototypes did not have PNGAPI.
+  Updated scripts/pngos2.def
+version 1.0.11beta3 [April 14, 2001]
+  Added checking the results of many instances of png_malloc() for NULL
+version 1.0.11beta4 [April 20, 2001]
+  Undid the changes from version 1.0.11beta3.  Added a check for NULL return
+    from user's malloc_fn().
+  Removed some useless type casts of the NULL pointer.
+  Added makefile.netbsd
+
+version 1.0.11 [April 27, 2001]
+  Revised makefile.netbsd
+version 1.0.12beta1 [May 14, 2001]
+  Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot)
+  Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h
+  Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings.
+  Eliminated the png_error about apps using png_read|write_init().  Instead,
+    libpng will reallocate the png_struct and info_struct if they are too small.
+    This retains future binary compatibility for old applications written for
+    libpng-0.88 and earlier.
+version 1.2.0beta1 [May 6, 2001]
+  Bumped DLLNUM to 2.
+  Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED
+    by default.
+  Added runtime selection of MMX features.
+  Added png_set_strip_error_numbers function and related macros.
+version 1.2.0beta2 [May 7, 2001]
+  Finished merging 1.2.0beta1 with version 1.0.11
+  Added a check for attempts to read or write PLTE in grayscale PNG datastreams.
+version 1.2.0beta3 [May 17, 2001]
+  Enabled user memory function by default.
+  Modified png_create_struct so it passes user mem_ptr to user memory allocator.
+  Increased png_mng_features flag from png_byte to png_uint_32.
+  Bumped shared-library (so-number) and dll-number to 3.
+version 1.2.0beta4 [June 23, 2001]
+  Check for missing profile length field in iCCP chunk and free chunk_data
+     in case of truncated iCCP chunk.
+  Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc
+  Bumped dll-number from 2 to 3 in makefile.cygwin
+  Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly
+     if user attempts to run it on an 8-bit display.
+  Updated contrib/gregbook
+  Use png_malloc instead of png_zalloc to allocate palette in pngset.c
+  Updated makefile.ibmc
+  Added some typecasts to eliminate gcc 3.0 warnings.  Changed prototypes
+     of png_write_oFFS width and height from png_uint_32 to png_int_32.
+  Updated example.c
+  Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c
+version 1.2.0beta5 [August 8, 2001]
+  Revised contrib/gregbook
+  Revised makefile.gcmmx
+  Revised pnggccrd.c to conditionally compile some thread-unsafe code only
+     when PNG_THREAD_UNSAFE_OK is defined.
+  Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with
+     value exceeding 2^bit_depth-1
+  Revised makefile.sgi and makefile.sggcc
+  Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c
+  Removed restriction that do_invert_mono only operate on 1-bit opaque files
+
+version 1.2.0 [September 1, 2001]
+  Changed a png_warning() to png_debug() in pnggccrd.c
+  Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC().
+version 1.2.1beta1 [October 19, 2001]
+  Revised makefile.std in contrib/pngminus
+  Include background_1 in png_struct regardless of gamma support.
+  Revised makefile.netbsd and makefile.macosx, added makefile.darwin.
+  Revised example.c to provide more details about using row_callback().
+version 1.2.1beta2 [October 25, 2001]
+  Added type cast to each NULL appearing in a function call, except for
+    WINCE functions.
+  Added makefile.so9.
+version 1.2.1beta3 [October 27, 2001]
+  Removed type casts from all NULLs.
+  Simplified png_create_struct_2().
+version 1.2.1beta4 [November 7, 2001]
+  Revised png_create_info_struct() and png_creat_struct_2().
+  Added error message if png_write_info() was omitted.
+  Type cast NULLs appearing in function calls when _NO_PROTO or
+    PNG_TYPECAST_NULL is defined.
+version 1.2.1rc1 [November 24, 2001]
+  Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL
+    is defined.
+  Changed typecast of "size" argument to png_size_t in pngmem.c calls to
+    the user malloc_fn, to agree with the prototype in png.h
+  Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev)
+  Updated makefile.sgi to recognize LIBPATH and INCPATH.
+  Updated various makefiles so "make clean" does not remove previous major
+    version of the shared library.
+version 1.2.1rc2 [December 4, 2001]
+  Always allocate 256-entry internal palette, hist, and trans arrays, to
+    avoid out-of-bounds memory reference caused by invalid PNG datastreams.
+  Added a check for prefix_length > data_length in iCCP chunk handler.
+
+version 1.2.1 [December 7, 2001]
+  None.
+version 1.2.2beta1 [February 22, 2002]
+  Fixed a bug with reading the length of iCCP profiles (Larry Reeves).
+  Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate
+    libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h
+  Revised makefile.darwin to remove "-undefined suppress" option.
+  Added checks for gamma and chromaticity values over 21474.83, which exceed
+    the limit for PNG unsigned 32-bit integers when encoded.
+  Revised calls to png_create_read_struct() and png_create_write_struct()
+    for simpler debugging.
+  Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)
+version 1.2.2beta2 [February 23, 2002]
+  Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.
+  Check for invalid image dimensions in png_get_IHDR.
+  Added missing "fi;" in the install target of the SGI makefiles.
+  Added install-static to all makefiles that make shared libraries.
+  Always do gamma compensation when image is partially transparent.
+version 1.2.2beta3 [March 7, 2002]
+  Compute background.gray and background_1.gray even when color_type is RGB
+    in case image gets reduced to gray later.
+  Modified shared-library makefiles to install pkgconfig/libpngNN.pc.
+  Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown
+  Removed unused png_write_destroy_info prototype from png.h
+  Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case
+  Added install-shared target to all makefiles that make shared libraries.
+  Stopped a double free of palette, hist, and trans when not using free_me.
+  Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64.
+version 1.2.2beta4 [March 8, 2002]
+  Compute background.gray and background_1.gray even when color_type is RGB
+    in case image gets reduced to gray later (Jason Summers).
+  Relocated a misplaced /bin/rm in the "install-shared" makefile targets
+  Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library.
+version 1.2.2beta5 [March 26, 2002]
+  Added missing PNGAPI to several function definitions.
+  Check for invalid bit_depth or color_type in png_get_IHDR(), and
+    check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen).
+  Revised iTXt support to accept NULL for lang and lang_key.
+  Compute gamma for color components of background even when color_type is gray.
+  Changed "()" to "{}" in scripts/libpng.pc.in.
+  Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN
+  Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so
+version 1.2.2beta6 [March 31, 2002]
+version 1.0.13beta1 [March 31, 2002]
+  Prevent png_zalloc() from trying to memset memory that it failed to acquire.
+  Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate).
+  Ensure that the right function (user or default) is used to free the
+    png_struct after an error in png_create_read_struct_2().
+version 1.2.2rc1 [April 7, 2002]
+version 1.0.13rc1 [April 7, 2002]
+  Save the ebx register in pnggccrd.c (Sami Farin)
+  Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner).
+  Updated makefiles to put headers in include/libpng and remove old include/*.h.
+
+version 1.2.2 [April 15, 2002]
+version 1.0.13 [April 15, 2002]
+  Revised description of png_set_filter() in libpng.3/libpng.txt.
+  Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd
+version 1.0.13patch01 [April 17, 2002]
+version 1.2.2patch01 [April 17, 2002]
+  Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc
+  Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install
+  Added install: target to makefile.32sunu and makefile.64sunu
+version 1.0.13patch03 [April 18, 2002]
+version 1.2.2patch03 [April 18, 2002]
+  Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng
+  subdirectory to libpngNN subdirectory without the full pathname.
+  Moved generation of libpng.pc from "install" to "all" in 15 makefiles.
+version 1.2.3rc1 [April 28, 2002]
+  Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos).
+  Added $(DESTDIR) feature to 24 makefiles (Tim Mooney)
+  Fixed bug with $prefix, should be $(prefix) in makefile.hpux.
+  Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin
+  Added a link from libpngNN.pc to libpng.pc in 15 makefiles.
+  Added links from include/libpngNN/*.h to include/*.h in 24 makefiles.
+  Revised makefile.darwin to make relative links without full pathname.
+  Added setjmp() at the end of png_create_*_struct_2() in case user forgets
+    to put one in their application.
+  Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and
+    removed them from module definition files.
+version 1.2.3rc2 [May 1, 2002]
+  Fixed bug in reporting number of channels in pngget.c and pngset.c,
+    that was introduced in version 1.2.2beta5.
+  Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(),
+    png_default_flush(), and png_push_fill_buffer() and included them in
+    module definition files.
+  Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles.
+version 1.2.3rc3 [May 1, 2002]
+  Revised prototype for png_default_flush()
+  Remove old libpng.pc and libpngNN.pc before installing new ones.
+version 1.2.3rc4 [May 2, 2002]
+  Typos in *.def files (png_default_read|write -> png_default_read|write_data)
+  In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc
+  Added libpng-config and libpngNN-config and modified makefiles to install them.
+  Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles
+  Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp
+version 1.2.3rc5 [May 11, 2002]
+  Changed "error" and "message" in prototypes to "error_message" and
+    "warning_message" to avoid namespace conflict.
+  Revised 15 makefiles to build libpng-config from libpng-config-*.in
+  Once more restored png_zalloc and png_zfree to regular nonexported form.
+  Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer
+    to nonexported form, but with PNGAPI, and removed them from module def files.
+version 1.2.3rc6 [May 14, 2002]
+  Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c
+  Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp.
+  Removed leftover libpng-config "sed" script from four makefiles.
+  Revised libpng-config creating script in 16 makefiles.
+
+version 1.2.3 [May 22, 2002]
+  Revised libpng-config target in makefile.cygwin.
+  Removed description of png_set_mem_fn() from documentation.
+  Revised makefile.freebsd.
+  Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR).
+  Revised projects/msvc/README.txt
+  Changed -lpng to -lpngNN in LDFLAGS in several makefiles.
+version 1.2.4beta1 [May 24, 2002]
+  Added libpng.pc and libpng-config to "all:" target in 16 makefiles.
+  Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH)
+  Added missing "\" before closing double quote in makefile.gcmmx.
+  Plugged various memory leaks; added png_malloc_warn() and png_set_text_2()
+    functions.
+version 1.2.4beta2 [June 25, 2002]
+  Plugged memory leak of png_ptr->current_text (Matt Holgate).
+  Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison)
+  Added -soname to the loader flags in makefile.dec, makefile.sgi, and
+    makefile.sggcc.
+  Added "test-installed" target to makefile.linux, makefile.gcmmx,
+    makefile.sgi, and makefile.sggcc.
+version 1.2.4beta3 [June 28, 2002]
+  Plugged memory leak of row_buf in pngtest.c when there is a png_error().
+  Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.
+  Added "test-installed" target to makefile.32sunu, makefile.64sunu,
+    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx,
+    makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.
+version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]
+  Added "test-installed" target to makefile.cygwin and makefile.sco.
+  Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.
+
+version 1.2.4 and 1.0.14 [July 8, 2002]
+  Changed png_warning() to png_error() when width is too large to process.
+version 1.2.4patch01 [July 20, 2002]
+  Revised makefile.cygwin to use DLL number 12 instead of 13.
+version 1.2.5beta1 [August 6, 2002]
+  Added code to contrib/gregbook/readpng2.c to ignore unused chunks.
+  Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)
+  Removed some stray *.o files from contrib/gregbook.
+  Changed png_error() to png_warning() about "Too much data" in pngpread.c
+    and about "Extra compressed data" in pngrutil.c.
+  Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().
+  Updated makefile.hpgcc
+  Updated png.c and pnggccrd.c handling of return from png_mmx_support()
+version 1.2.5beta2 [August 15, 2002]
+  Only issue png_warning() about "Too much data" in pngpread.c when avail_in
+    is nonzero.
+  Updated makefiles to install a separate libpng.so.3 with its own rpath.
+version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002]
+  Revised makefiles to not remove previous minor versions of shared libraries.
+version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002]
+  Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared
+    library loader directive.
+  Added missing "$OBJSDLL" line to makefile.gcmmx.
+  Added missing "; fi" to makefile.32sunu.
+version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002]
+  Revised libpng-config script.
+
+version 1.2.5 and 1.0.15 [October 3, 2002]
+  Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux,
+    and makefile.aix.
+  Relocated two misplaced PNGAPI lines in pngtest.c
+version 1.2.6beta1 [October 22, 2002]
+  Commented out warning about uninitialized mmx_support in pnggccrd.c.
+  Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h.
+  Relocated two more misplaced PNGAPI lines in pngtest.c
+  Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams,
+    introduced in version 1.0.2.
+  Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu.
+version 1.2.6beta2 [November 1, 2002]
+  Added libpng-config "--ldopts" output.
+  Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)"
+    in makefiles.
+version 1.2.6beta3 [July 18, 2004]
+  Reverted makefile changes from version 1.2.6beta2 and some of the changes
+    from version 1.2.6beta1; these will be postponed until version 1.2.7.
+    Version 1.2.6 is going to be a simple bugfix release.
+  Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile.
+  Fixed potential overrun in pngerror.c by using strncpy instead of memcpy.
+  Added "#!/bin/sh" at the top of configure, for recognition of the
+    'x' flag under Cygwin (Cosmin).
+  Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin).
+  Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin).
+  Fixed the special memory handler for Borland C under DOS, in pngmem.c
+    (Cosmin).
+  Removed some spurious assignments in pngrutil.c (Cosmin).
+  Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings
+    on 16-bit platforms (Cosmin).
+  Enclosed shift op expressions in parentheses, to silence warnings (Cosmin).
+  Used proper type png_fixed_point, to avoid problems on 16-bit platforms,
+    in png_handle_sRGB() (Cosmin).
+  Added compression_type to png_struct, and optimized the window size
+    inside the deflate stream (Cosmin).
+  Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin).
+  Fixed handling of unknown chunks that come after IDAT (Cosmin).
+  Allowed png_error() and png_warning() to work even if png_ptr == NULL
+    (Cosmin).
+  Replaced row_info->rowbytes with row_bytes in png_write_find_filter()
+    (Cosmin).
+  Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre).
+  Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded
+    values in png.c (Simon-Pierre, Cosmin).
+  Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre).
+  Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc
+    (Simon-Pierre).
+  Moved the definition of PNG_HEADER_VERSION_STRING near the definitions
+    of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin).
+  Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin).
+  Updated scripts/makefile.vc(a)win32 (Cosmin).
+  Updated the MSVC project (Simon-Pierre, Cosmin).
+  Updated the Borland C++ Builder project (Cosmin).
+  Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin).
+  Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin).
+  Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin).
+  Added extra guard around inclusion of Turbo C memory headers, in pngconf.h
+    (Cosmin).
+  Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to
+    projects/cbuilder5/ (Cosmin).
+  Moved projects/visualc6/png32ms.def to scripts/pngw32.def,
+    and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin).
+  Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin).
+  Changed line endings to DOS style in cbuilder5 and visualc6 files, even
+    in the tar.* distributions (Cosmin).
+  Updated contrib/visupng/VisualPng.dsp (Cosmin).
+  Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin).
+  Added a separate distribution with "configure" and supporting files (Junichi).
+version 1.2.6beta4 [July 28, 2004]
+  Added user ability to change png_size_t via a PNG_SIZE_T macro.
+  Added png_sizeof() and png_convert_size() functions.
+  Added PNG_SIZE_MAX (maximum value of a png_size_t variable.
+  Added check in png_malloc_default() for (size_t)size != (png_uint_32)size
+    which would indicate an overflow.
+  Changed sPLT failure action from png_error to png_warning and abandon chunk.
+  Changed sCAL and iCCP failures from png_error to png_warning and abandon.
+  Added png_get_uint_31(png_ptr, buf) function.
+  Added PNG_UINT_32_MAX macro.
+  Renamed PNG_MAX_UINT to PNG_UINT_31_MAX.
+  Made png_zalloc() issue a png_warning and return NULL on potential
+    overflow.
+  Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x
+  Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4.
+  Revised Borland portion of png_malloc() to return NULL or issue
+    png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK.
+  Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove
+    sequential read support.
+  Added some "#if PNG_WRITE_SUPPORTED" blocks.
+  Removed some redundancy with #ifdef/#endif in png_malloc_default().
+  Use png_malloc instead of png_zalloc to allocate the pallete.
+version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]
+  Fixed buffer overflow vulnerability in png_handle_tRNS()
+  Fixed integer arithmetic overflow vulnerability in png_read_png().
+  Fixed some harmless bugs in png_handle_sBIT, etc, that would cause
+    duplicate chunk types to go undetected.
+  Fixed some timestamps in the -config version
+  Rearranged order of processing of color types in png_handle_tRNS().
+  Added ROWBYTES macro to calculate rowbytes without integer overflow.
+  Updated makefile.darwin and removed makefile.macosx from scripts directory.
+  Imposed default one million column, one-million row limits on the image
+    dimensions, and added png_set_user_limits() function to override them.
+  Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro.
+  Fixed wrong cast of returns from png_get_user_width|height_max().
+  Changed some "keep the compiler happy" from empty statements to returns,
+  Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution
+version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004]
+  Revised makefile.darwin and makefile.solaris.  Removed makefile.macosx.
+  Revised pngtest's png_debug_malloc() to use png_malloc() instead of
+    png_malloc_default() which is not supposed to be exported.
+  Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in
+    pngpread.c.  Bug was introduced in 1.2.6rc1.
+  Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1.
+  Fixed old bug in RGB to Gray transformation.
+  Fixed problem with 64-bit compilers by casting arguments to abs()
+    to png_int_32.
+  Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9).
+  Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin)
+  Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles.
+  Added code to update the row_info->colortype in png_do_read_filler() (MSB).
+version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004]
+  Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid
+    trouble with some 64-bit compilers.  Created PNG_OUT_OF_RANGE() macro.
+  Revised documentation of png_set_keep_unknown_chunks().
+  Check handle_as_unknown status in pngpread.c, as in pngread.c previously.
+  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h
+  Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c
+version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004]
+  Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of
+    "pinfo" was out of place).
+version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004]
+  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED
+     section of png.h where they were inadvertently placed in version rc3.
+
+version 1.2.6 and 1.0.16 [August 15, 2004]
+  Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1.
+version 1.2.7beta1 [August 26, 2004]
+  Removed unused pngasmrd.h file.
+  Removed references to uu.net for archived files.  Added references to
+    PNG Spec (second edition) and the PNG ISO/IEC Standard.
+  Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR.
+  Fixed bug with "optimized window size" in the IDAT datastream, that
+    causes libpng to write PNG files with incorrect zlib header bytes.
+version 1.2.7beta2 [August 28, 2004]
+  Fixed bug with sCAL chunk and big-endian machines (David Munro).
+  Undid new code added in 1.2.6rc2 to update the color_type in
+    png_set_filler().
+  Added png_set_add_alpha() that updates color type.
+version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004]
+  Revised png_set_strip_filler() to not remove alpha if color_type has alpha.
+
+version 1.2.7 and 1.0.17 [September 12, 2004]
+  Added makefile.hp64
+  Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin
+version 1.2.8beta1 [November 1, 2004]
+  Fixed bug in png_text_compress() that would fail to complete a large block.
+  Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during
+    strip alpha operation in png_do_strip_filler().
+  Added PNG_1_2_X definition in pngconf.h
+  Comment out with #ifdef/#endif png_info_init in png.c and png_read_init
+    in pngread.c (as of 1.3.0)
+version 1.2.8beta2 [November 2, 2004]
+  Reduce color_type to a nonalpha type after strip alpha operation in
+    png_do_strip_filler().
+version 1.2.8beta3 [November 3, 2004]
+  Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM
+version 1.2.8beta4 [November 12, 2004]
+  Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin).
+  Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin).
+  Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection
+    of data type in deflate (Cosmin).
+  Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of
+    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.
+version 1.2.8beta5 [November 20, 2004]
+  Use png_ptr->flags instead of png_ptr->transformations to pass
+    PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI
+    compatibility.
+  Revised handling of SPECIALBUILD, PRIVATEBUILD,
+    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.
+version 1.2.8rc1 [November 24, 2004]
+  Moved handling of BUILD macros from pngconf.h to png.h
+  Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently
+    omitted from beta5.
+  Revised scripts/pngw32.rc
+  Despammed mailing addresses by masking "@" with "at".
+  Inadvertently installed a supposedly faster test version of pngrutil.c
+version 1.2.8rc2 [November 26, 2004]
+  Added two missing "\" in png.h
+  Change tests in pngread.c and pngpread.c to
+    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+       png_do_read_transformations(png_ptr);
+version 1.2.8rc3 [November 28, 2004]
+  Reverted pngrutil.c to version libpng-1.2.8beta5.
+  Added scripts/makefile.elf with supporting code in pngconf.h for symbol
+    versioning (John Bowler).
+version 1.2.8rc4 [November 29, 2004]
+  Added projects/visualc7 (Simon-pierre).
+version 1.2.8rc5 [November 29, 2004]
+  Fixed new typo in scripts/pngw32.rc
+
+version 1.2.8 [December 3, 2004]
+  Removed projects/visualc7, added projects/visualc71.
+
+version 1.2.9beta1 [February 21, 2006]
+
+  Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints
+  Revised man page and libpng.txt to make it clear that one should not call
+    png_read_end or png_write_end after png_read_png or png_write_png.
+  Updated references to png-mng-implement mailing list.
+  Fixed an incorrect typecast in pngrutil.c
+  Added PNG_NO_READ_SUPPORTED conditional for making a write-only library.
+  Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional.
+  Optimized alpha-inversion loops in pngwtran.c
+  Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c
+  Make sure num_trans is <= 256 before copying data in png_set_tRNS().
+  Make sure num_palette is <= 256 before copying data in png_set_PLTE().
+  Interchanged order of write_swap_alpha and write_invert_alpha transforms.
+  Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin).
+  Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin).
+  Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin).
+  Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16,
+    png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin).
+  Added type cast (png_byte) in png_write_sCAL() (Cosmin).
+  Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin).
+  Default iTXt support was inadvertently enabled.
+
+version 1.2.9beta2 [February 21, 2006]
+
+  Check for png_rgb_to_gray and png_gray_to_rgb read transformations before
+    checking for png_read_dither in pngrtran.c
+  Revised checking of chromaticity limits to accommodate extended RGB
+    colorspace (John Denker).
+  Changed line endings in some of the project files to CRLF, even in the
+    "Unix" tar distributions (Cosmin).
+  Made png_get_int_32 and png_save_int_32 always available (Cosmin).
+  Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def
+    with the newly exported functions.
+  Eliminated distributions without the "configure" script.
+  Updated INSTALL instructions.
+
+version 1.2.9beta3 [February 24, 2006]
+
+  Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp
+  Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler)
+  Removed reference to pngasmrd.h from Makefile.am
+  Renamed CHANGES to ChangeLog.
+  Renamed LICENSE to COPYING.
+  Renamed ANNOUNCE to NEWS.
+  Created AUTHORS file.
+
+version 1.2.9beta4 [March 3, 2006]
+
+  Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac
+  Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING.
+  Removed newline from the end of some error and warning messages.
+  Removed test for sqrt() from configure.ac and configure.
+  Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix).
+  Disabled default iTXt support that was inadvertently enabled in
+    libpng-1.2.9beta1.
+  Added "OS2" to list of systems that don't need underscores, in pnggccrd.c
+  Removed libpng version and date from *.c files.
+
+version 1.2.9beta5 [March 4, 2006]
+  Removed trailing blanks from source files.
+  Put version and date of latest change in each source file, and changed
+    copyright year accordingly.
+  More cleanup of configure.ac, Makefile.ac, and associated scripts.
+  Restored scripts/makefile.elf which was inadvertently deleted.
+
+version 1.2.9beta6 [March 6, 2006]
+  Fixed typo (RELEASE) in configuration files.
+
+version 1.2.9beta7 [March 7, 2006]
+  Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am
+  Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s()
+    in png.h.
+  Updated makefile.elf as suggested by debian.
+  Made cosmetic changes to some makefiles, adding LN_SF and other macros.
+  Made some makefiles accept "exec_prefix".
+
+version 1.2.9beta8 [March 9, 2006]
+  Fixed some "#if defined (..." which should be "#if defined(..."
+    Bug introduced in libpng-1.2.8.
+  Fixed inconsistency in definition of png_default_read_data()
+  Restored blank that was lost from makefile.sggcc "clean" target in beta7.
+  Revised calculation of "current" and "major" for irix in ltmain.sh
+  Changed "mkdir" to "MKDIR_P" in some makefiles.
+  Separated PNG_EXPAND and PNG_EXPAND_tRNS.
+  Added png_set_expand_gray_1_2_4_to_8() and deprecated
+    png_set_gray_1_2_4_to_8() which also expands tRNS to alpha.
+
+version 1.2.9beta9 [March 10, 2006]
+  Include "config.h" in pngconf.h when available.
+  Added some checks for NULL png_ptr or NULL info_ptr (timeless)
+
+version 1.2.9beta10 [March 20, 2006]
+  Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin)
+  Made pnggccrd.c PIC-compliant (Christian Aichinger).
+  Added makefile.mingw (Wolfgang Glas).
+  Revised pngconf.h MMX checking.
+
+version 1.2.9beta11 [March 22, 2006]
+  Fixed out-of-order declaration in pngwrite.c that was introduced in beta9
+  Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros.
+
+version 1.2.9rc1 [March 31, 2006]
+  Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin).
+  Removed nonsensical assertion check from pngtest.c (Cosmin).
+
+version 1.2.9 [April 14, 2006]
+  Revised makefile.beos and added "none" selector in ltmain.sh
+
+version 1.2.10beta1 [April 15, 2006]
+  Renamed "config.h" to "png_conf.h" and revised Makefile.am to add
+    -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h
+    to include png_conf.h only when PNG_BUILDING_LIBPNG is defined.
+
+version 1.2.10beta2 [April 15, 2006]
+  Manually updated Makefile.in and configure.  Changed png_conf.h.in
+    back to config.h.
+
+version 1.2.10beta3 [April 15, 2006]
+  Change png_conf.h back to config.h in pngconf.h.
+
+version 1.2.10beta4 [April 16, 2006]
+  Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*.
+
+version 1.2.10beta5 [April 16, 2006]
+  Added a configure check for compiling assembler code in pnggccrd.c
+
+version 1.2.10beta6 [April 17, 2006]
+  Revised the configure check for pnggccrd.c
+  Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@
+  Added @LIBPNG_DEFINES@ to arguments when building libpng.sym
+
+version 1.2.10beta7 [April 18, 2006]
+  Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles.
+
+version 1.2.10rc1 [April 19, 2006]
+  Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD
+  Fixed "LN_FS" typo in makefile.sco and makefile.solaris.
+
+version 1.2.10rc2 [April 20, 2006]
+  Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE
+   in configure.ac and configure
+  Made the configure warning about versioned symbols less arrogant.
+
+version 1.2.10rc3 [April 21, 2006]
+  Added a note in libpng.txt that png_set_sig_bytes(8) can be used when
+    writing an embedded PNG without the 8-byte signature.
+  Revised makefiles and configure to avoid making links to libpng.so.*
+
+version 1.2.10 [April 23, 2006]
+  Reverted configure to "rc2" state.
+
+version 1.2.11beta1 [May 31, 2006]
+  scripts/libpng.pc.in contained "configure" style version info and would
+    not work with makefiles.
+  The shared-library makefiles were linking to libpng.so.0 instead of
+    libpng.so.3 compatibility as the library.
+
+version 1.2.11beta2 [June 2, 2006]
+  Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid
+    buffer overflow.
+  Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb)
+
+version 1.2.11beta3 [June 5, 2006]
+  Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin).
+  Removed the accidental leftover Makefile.in~ (Cosmin).
+  Avoided potential buffer overflow and optimized buffer in
+    png_write_sCAL(), png_write_sCAL_s() (Cosmin).
+  Removed the include directories and libraries from CFLAGS and LDFLAGS
+    in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin).
+
+version 1.2.11beta4 [June 6, 2006]
+  Allow zero-length IDAT chunks after the entire zlib datastream, but not
+    after another intervening chunk type.
+
+version 1.0.19rc1, 1.2.11rc1 [June 13, 2006]
+  Deleted extraneous square brackets from [config.h] in configure.ac
+
+version 1.0.19rc2, 1.2.11rc2 [June 14, 2006]
+  Added prototypes for PNG_INCH_CONVERSIONS functions to png.h
+  Revised INSTALL and autogen.sh
+  Fixed typo in several makefiles (-W1 should be -Wl)
+  Added typedef for png_int_32 and png_uint_32 on 64-bit systems.
+
+version 1.0.19rc3, 1.2.11rc3 [June 15, 2006]
+  Removed the new typedefs for 64-bit systems (delay until version 1.4.0)
+  Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid
+    reading out of bounds.
+
+version 1.0.19rc4, 1.2.11rc4 [June 15, 2006]
+  Really removed the new typedefs for 64-bit systems.
+
+version 1.0.19rc5, 1.2.11rc5 [June 22, 2006]
+  Removed png_sig_bytes entry from scripts/pngw32.def
+
+version 1.0.19, 1.2.11 [June 26, 2006]
+  None.
+
+version 1.0.20, 1.2.12 [June 27, 2006]
+  Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid
+    buffer overflow.
+
+version 1.2.13beta1 [October 2, 2006]
+  Removed AC_FUNC_MALLOC from configure.ac
+  Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h
+  Change "logical" to "bitwise" throughout documentation.
+  Detect and fix attempt to write wrong iCCP profile length.
+
+version 1.0.21, 1.2.13 [November 14, 2006]
+  Fix potential buffer overflow in sPLT chunk handler.
+  Fix Makefile.am to not try to link to noexistent files.
+  Check all exported functions for NULL png_ptr.
+
+version 1.2.14beta1 [November 17, 2006]
+  Relocated three misplaced tests for NULL png_ptr.
+  Built Makefile.in with automake-1.9.6 instead of 1.9.2.
+  Build configure with autoconf-2.60 instead of 2.59
+
+version 1.2.14beta2 [November 17, 2006]
+  Added some typecasts in png_zalloc().
+
+version 1.2.14rc1 [November 20, 2006]
+  Changed "strtod" to "png_strtod" in pngrutil.c
+
+version 1.0.22, 1.2.14    [November 27, 2006]
+  Added missing "$(srcdir)" in Makefile.am and Makefile.in
+
+version 1.2.15beta1 [December 3, 2006]
+  Generated configure with autoconf-2.61 instead of 2.60
+  Revised configure.ac to update libpng.pc and libpng-config.
+
+version 1.2.15beta2 [December 3, 2006]
+  Always export MMX asm functions, just stubs if not building pnggccrd.c
+
+version 1.2.15beta3 [December 4, 2006]
+  Add "png_bytep" typecast to profile while calculating length in pngwutil.c
+
+version 1.2.15beta4 [December 7, 2006]
+  Added scripts/CMakeLists.txt
+  Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta
+
+version 1.2.15beta5 [December 7, 2006]
+  Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c
+  Revised scripts/CMakeLists.txt
+
+version 1.2.15beta6 [December 13, 2006]
+  Revised scripts/CMakeLists.txt and configure.ac
+
+version 1.2.15rc1 [December 18, 2006]
+  Revised scripts/CMakeLists.txt
+
+version 1.2.15rc2 [December 21, 2006]
+  Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers.
+  Added scripts/makefile.nommx
+
+version 1.2.15rc3 [December 25, 2006]
+  Fixed shared library numbering error that was introduced in 1.2.15beta6.
+
+version 1.2.15rc4 [December 27, 2006]
+  Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set.
+
+version 1.2.15rc5 [December 31, 2006]
+  Revised handling of rgb_to_gray.
+
+version 1.0.23, 1.2.15 [January 5, 2007]
+  Added some (unsigned long) typecasts in pngtest.c to avoid printing errors.
+
+version 1.2.16beta1 [January 6, 2007]
+  Fix bugs in makefile.nommx
+
+version 1.2.16beta2 [January 16, 2007]
+  Revised scripts/CMakeLists.txt
+
+version 1.0.24, 1.2.16 [January 31, 2007]
+  No changes.
+
+version 1.2.17beta1 [March 6, 2007]
+  Revised scripts/CMakeLists.txt to install both shared and static libraries.
+  Deleted a redundant line from pngset.c.
+
+version 1.2.17beta2 [April 26, 2007]
+  Relocated misplaced test for png_ptr == NULL in pngpread.c
+  Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN
+    flags.
+  Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_*
+  Added pngerror() when write_IHDR fails in deflateInit2().
+  Added "const" to some array declarations.
+  Mention examples of libpng usage in the libpng*.txt and libpng.3 documents.
+
+version 1.2.17rc1 [May 4, 2007]
+  No changes.
+
+version 1.2.17rc2 [May 8, 2007]
+  Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications
+    calling set_unknown_chunk_location() need them.
+  Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in
+    png_set_expand_gray_1_2_4_to_8().
+  Added png_ptr->unknown_chunk to hold working unknown chunk data, so it
+    can be free'ed in case of error.  Revised unknown chunk handling in
+    pngrutil.c and pngpread.c to use this structure.
+
+version 1.2.17rc3 [May 8, 2007]
+  Revised symbol-handling in configure script.
+
+version 1.2.17rc4 [May 10, 2007]
+  Revised unknown chunk handling to avoid storing unknown critical chunks.
+
+version 1.0.25 [May 15, 2007]
+version 1.2.17 [May 15, 2007]
+  Added "png_ptr->num_trans=0" before error return in png_handle_tRNS,
+    to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664)
+
+version 1.0.26 [May 15, 2007]
+version 1.2.18 [May 15, 2007]
+  Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script
+
+version 1.2.19beta1 [May 18, 2007]
+  Changed "const static" to "static PNG_CONST" everywhere, mostly undoing
+    change of libpng-1.2.17beta2.  Changed other "const" to "PNG_CONST"
+  Changed some handling of unused parameters, to avoid compiler warnings.
+    "if (unused == NULL) return;" becomes "unused = unused".
+
+version 1.2.19beta2 [May 18, 2007]
+  Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier)
+
+version 1.2.19beta3 [May 19, 2007]
+  Add some "png_byte" typecasts in png_check_keyword() and write new_key
+  instead of key in zTXt chunk (Kevin Ryde).
+
+version 1.2.19beta4 [May 21, 2007]
+  Add png_snprintf() function and use it in place of sprint() for improved
+    defense against buffer overflows.
+
+version 1.2.19beta5 [May 21, 2007]
+  Fixed png_handle_tRNS() to only use the valid bits of tRNS value.
+  Changed handling of more unused parameters, to avoid compiler warnings.
+  Removed some PNG_CONST in pngwutil.c to avoid compiler warnings.
+
+version 1.2.19beta6 [May 22, 2007]
+  Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c
+  Added a special "_MSC_VER" case that defines png_snprintf to _snprintf
+
+version 1.2.19beta7 [May 22, 2007]
+  Squelched png_squelch_warnings() in pnggccrd.c and added
+    an #ifdef PNG_MMX_CODE_SUPPORTED/#endif block around the declarations
+    that caused the warnings that png_squelch_warnings was squelching.
+
+version 1.2.19beta8 [May 22, 2007]
+  Removed __MMX__ from test in pngconf.h.
+
+version 1.2.19beta9 [May 23, 2007]
+  Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro.
+  Revised png_squelch_warnings() so it might work.
+  Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86.
+
+version 1.2.19beta10 [May 24, 2007]
+  Resquelched png_squelch_warnings(), use "__attribute__((used))" instead.
+
+version 1.2.19beta11 [May 28, 2007]
+  Return 0 from png_get_sPLT() and png_get_unknown_chunks() if png_ptr is NULL;
+    changed three remaining instances of png_strcpy() to png_strncpy() (David
+    Hill).
+  Make test for NULL row_buf at the beginning of png_do_read_transformations
+    unconditional.
+
+version 1.2.19beta12 [May 28, 2007]
+  Revised pnggccrd.c.
+
+version 1.2.19beta13 [June 14, 2007]
+  Prefer PNG_USE_PNGVCRD when _MSC_VER is defined in pngconf.h
+
+version 1.2.19beta14 [June 16, 2007]
+  Fix bug with handling of 16-bit transparency, introduced in 1.2.19beta2
+
+version 1.2.19beta15 [June 17, 2007]
+  Revised pnggccrd.c.
+
+version 1.2.19beta16 [June 18, 2007]
+  Revised pnggccrd.c again.
+  Updated contrib/gregbook.
+  Changed '#include "pnggccrd.c"' to 'include "$srcdir/pnggccrd.c"'
+    in configure.ac
+
+version 1.2.19beta17 [June 19, 2007]
+  Revised many of the makefiles, to set -DPNG_NO_MMX_CODE where needed
+    and to not use -O3 unless -DPNG_NO_MMX_CODE is also set.
+
+version 1.2.19beta18 [June 23, 2007]
+  Replaced some C++ style comments with C style comments in pnggccrd.c.
+  Copied optimized C code from pnggccrd.c to pngrutil.c, removed dependency
+    on pnggccrd.o from many makefiles.
+  Added sl and dylib to list of extensions be installed by Makefile.am
+
+version 1.2.19beta19 [June 28, 2007]
+  Fixed testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN in pngrtran.c
+  More cleanup of pnggccrd.c and pngvcrd.c
+
+version 1.2.19beta20 [June 29, 2007]
+  Rebuilt Makefile.in and configure using libtool-1.5.24.
+  Fixed typo in pnggccrd.c
+
+version 1.2.19beta21 [June 30, 2007]
+  More revision of pnggccrd.c
+  Added "test" target to Makefile.in and Makefile.am
+
+version 1.2.19beta22 [July 3, 2007]
+  Added info about pngrutil/pnggccrd/pngvcrd to png_get_header_version()
+  Fix type definition of dummy_value_a, b in pnggccrd.c
+
+version 1.2.19beta23 [July 10, 2007]
+  Revert change to type definition of dummy_value_a, b in pnggccrd.c
+  Make sure __PIC__ is defined in pnggccrd.c when PIC is defined.
+  Require gcc-4.1 or better to use PNG_HAVE_MMX_FILTER_ROW on x86_64 platforms
+
+version 1.2.19beta24 [July 14, 2007]
+  Added PNG_NO_READ_FILTER, PNG_NO_WRITE_FILTER, PNG_NO_WARNING macros.
+  Added contrib/pngminim to demonstrate building minimal encoder and decoder
+
+version 1.2.19beta25 [July 15, 2007]
+  Removed the new PNG_NO_READ_FILTER macro since it would make the library
+    unable to read valid PNG files, and filtering is at the heart of the
+    PNG format.
+
+version 1.2.19beta26 [July 16, 2007]
+  Changed "png_free(str)" to "png_free(png_ptr,str)" in pngrutil.c WinCE
+    code (Yves Piguet).  This bug was introduced in libpng-1.2.14.
+  Updated scripts/CMakeLists.txt
+  Relocated a misplaced #endif in pnggccrd.c
+
+version 1.2.19beta27 [July 17, 2007]
+  Fixed incorrect stride and number of bytes copied (was 4 instead of
+    6 bytes) in the cleanup loop of pnggccrd.c and pngvcrd.c for handling
+    the end of 48-bit interlaced rows (Glenn R-P).
+
+version 1.2.19beta28 [July 19, 2007]
+  Removed requirement for gcc-4.1 or better to use PNG_HAVE_MMX_FILTER_ROW
+    on x86_64 platforms
+  Added png_warning() in pngrutil.c for short iCCP, iTXt, sPLT, or zTXT chunks.
+  Revised pngtest.c so warnings are displayed regardless of PNG_NO_STDIO.
+
+version 1.2.19beta29 [July 20, 2007]
+  Fix typo in pnggccrd.c (%%eax should be %%ax in secondloop48)
+
+version 1.2.19beta30 [July 26, 2007]
+  Revised pnggccrd.c
+
+version 1.2.19beta31 [July 27, 2007]
+  Fix typos in pnggccrd.c
+
+version 1.0.27rc1 and 1.2.19rc1 [July 31, 2007]
+  Disable PNG_MMX_CODE_SUPPORTED when PNG_ASSEMBLER_CODE_SUPPORTED is off.
+  Enable PNG_MMX_READ_FILTER_* by default, except when gcc-3.x is being
+    used (they were inadvertently disabled in libpng-1.2.19beta23).
+  Fix some debugging statements in pnggccrd.c and pngrutil.c
+  Added information about disabling the MMX code in libpng documentation.
+
+version 1.0.27rc2 and 1.2.19rc2 [August 4, 2007]
+  Removed some "#if 0" blocks.
+  Made a global struct local in pngvcrd.c to make it thread safe.
+  Issue a png_error() if application attempts to transform a row tht
+    has not been initialized.
+
+version 1.0.27rc3 and 1.2.19rc3 [August 9, 2007]
+  Slightly revised pngvcrd.c
+
+version 1.0.27rc4 and 1.2.19rc4 [August 9, 2007]
+  Revised pnggccrd.c debugging change of rc1, which was broken.
+  Revised scripts/CMakeLists.txt
+  Change default to PNG_NO_GLOBAL_ARRAYS for MSVC.
+  Turn off PNG_FLAG_ROW_INIT flag when setting transforms that expand pixels.
+
+version 1.0.27rc5 and 1.2.19rc5 [August 10, 2007]
+  Fix typo (missing '"') in pnggccrd.c
+  Revise handling of png_strtod in recent versions of WINCE
+
+version 1.0.27rc6 and 1.2.19rc6 [August 15, 2007]
+  Fix typo (missing ',') in contrib/gregbook/readpng2.c
+  Undid row initialization error exit added to rc2 and rc4.
+
+version 1.0.27 and 1.2.19 [August 18, 2007]
+  Conditionally restored row initialization error exit.
+
+version 1.2.20beta01 [August 19, 2007]
+  Fixed problem with compiling pnggccrd.c on Intel-Apple platforms.
+  Changed png_malloc() to png_malloc_warn() in png_set_sPLT().
+  Added PNG_NO_ERROR_TEXT feature, with demo in contrib/pngminim
+  Removed define PNG_WARN_UNINITIALIZED_ROW 1 /* 0: warning; 1: error */
+    because it caused some trouble.
+
+version 1.2.20beta02 [August 20, 2007]
+  Avoid compiling pnggccrd.c on Intel-Apple platforms.
+
+version 1.2.20beta03 [August 20, 2007]
+  Added "/D PNG_NO_MMX_CODE" to the non-mmx builds of projects/visualc6
+    and visualc71.
+
+version 1.2.20beta04 [August 21, 2007]
+  Revised pngvcrd.c for improved efficiency (Steve Snyder).
+
+version 1.2.20rc1 [August 23, 2007]
+  Revised pngconf.h to set PNG_NO_MMX_CODE for gcc-3.x compilers.
+
+version 1.2.20rc2 [August 27, 2007]
+  Revised scripts/CMakeLists.txt
+  Revised #ifdefs to ensure one and only one of pnggccrd.c, pngvcrd.c,
+    or part of pngrutil.c is selected.
+
+version 1.2.20rc3 [August 30, 2007]
+  Remove a little more code in pngwutil.c when PNG_NO_WRITE_FILTER is selected.
+  Added /D _CRT_SECURE_NO_WARNINGS to visual6c and visualc71 projects.
+  Compile png_mmx_support() in png.c even when PNG_NO_MMX_CODE is defined.
+  Restored a "superfluous" #ifdef that was removed from 1.2.20rc2 pnggccrd.c,
+    breaking the png_mmx_support() function.
+
+version 1.2.20rc4 [September 1, 2007]
+  Removed Intel contributions (MMX, Optimized C).
+
+version 1.2.20rc5 [September 2, 2007]
+  Restored configure and Makefile.in to rc3 and put a snippet of code in
+    pnggccrd.c, to ensure configure makes the same PNG_NO_MMX_CODE selection
+
+version 1.2.20rc6 [September 2, 2007]
+  Fixed bugs in scripts/CMakeLists.txt
+  Removed pngvcrd.c references from msvc projects.
+
+version 1.0.28 and 1.2.20 [September 8, 2007]
+  Removed "(NO READ SUPPORT)" from png_get_header_version() string.
+
+version 1.2.21beta1 [September 14, 2007]
+  Fixed various mistakes reported by George Cook and Jeff Phillips:
+  logical vs bitwise NOT in pngrtran.c, bug introduced in 1.2.19rc2
+  16-bit cheap transparency expansion, bug introduced in 1.2.19beta2
+  errors with sizeof(unknown_chunk.name), bugs introduced in 1.2.19beta11
+  <= compare with unsigned var in pngset.c, should be ==.
+
+version 1.2.21beta2 [September 18, 2007]
+  Removed some extraneous typecasts.
+
+version 1.2.21rc1 [September 25, 2007]
+  Fixed potential out-of-bounds reads in png_handle_pCAL() and
+    png_handle_ztXt() ("flayer" results reported by Tavis Ormandy).
+
+version 1.2.21rc2 [September 26, 2007]
+  Fixed potential out-of-bounds reads in png_handle_sCAL(),
+    png_handle_iTXt(), and png_push_read_tEXt().
+  Remove some PNG_CONST declarations from pngwutil.c to avoid compiler warnings
+  Revised makefiles to update paths in libpng.pc properly.
+
+version 1.2.21rc3 [September 27, 2007]
+  Revised makefiles to update "Libs" in libpng.pc properly.
+
+version 1.0.29 and 1.2.21rc3 [October 4, 2007]
+  No changes.
+
+version 1.2.22beta1 [October 4, 2007]
+  Again, fixed logical vs bitwise NOT in pngrtran.c, bug introduced
+    in 1.2.19rc2
+
+version 1.2.22beta2 [October 5, 2007]
+  Fixed string length error in pngset.c (caused crashes while decoding iCCP)
+  Add terminating NULL after each instance of png_strncpy().
+
+version 1.2.22beta3 [October 6, 2007]
+  Fix two off-by-one terminating NULL after png_strncpy().
+
+version 1.2.22beta4 [October 7, 2007]
+  Changed some 0 to '\0'.
+
+version 1.0.30rc1 and 1.2.22rc1 [October 8, 2007]
+  No changes.
+
+version 1.0.30 and 1.2.22 [October 13, 2007]
+  No changes.
+
+version 1.2.23beta01 [October 15, 2007]
+  Reduced number of invocations of png_strlen() in pngset.c.
+  Changed [azAZ09_] to [_abcde...89] in Makefile.am for better localization.
+
+version 1.2.23beta02 [October 16, 2007]
+  Eliminated png_strncpy() and png_strcpy() (Pierre Poissinger)
+  Changed $AN to $(AN) in Makefile.am.
+
+version 1.2.23beta03 [October 16, 2007]
+  Fixed off-by-one error in pngset.c
+  Restore statement to set last character of buffer to \0 in pngerror.c
+
+version 1.2.23beta04 [October 23, 2007]
+  Reject attempt to set all-zero cHRM values.
+
+version 1.2.23beta05 [October 26, 2007]
+  Add missing quotes in projects/visualc6, lost in version 1.2.20rc3
+
+version 1.2.23rc01 [November 2, 2007]
+  No changes.
+
+version 1.2.23 [November 6, 2007]
+  No changes.
+
+version 1.2.24beta01 [November 19, 2007]
+  Moved misplaced test for malloc failure in png_set_sPLT().  This bug was
+    introduced in libpng-1.2.20beta01.
+  Ifdef out avg_row etc from png.h and pngwrite.c when PNG_NO_WRITE_FILTER
+  Do not use png_ptr->free_fn and png_ptr->mem_fn in png_destroy_read_struct()
+    when png_ptr is NULL (Marshall Clow).
+  Updated handling of symbol prefixes in Makefile.am and configure.ac (Mike
+    Frysinger).
+
+version 1.2.24beta02 [November 30, 2007]
+  Removed a useless test and fixed incorrect test in png_set_cHRM_fixed()
+    (David Hill).
+
+version 1.2.24rc01 [December 7, 2007]
+  No changes.
+
+version 1.2.24     [December 14, 2007]
+  Make sure not to redefine _BSD_SOURCE in pngconf.h
+  Revised gather.sh and makefile.std in contrib/pngminim to avoid compiling
+    unused files.
+
+version 1.2.25beta01 [January 7, 2008]
+  Fixed bug with unknown chunk handling, introduced in version 1.2.17rc2
+
+version 1.2.25beta02 [January 10, 2008]
+  Prevent gamma from being applied twice.
+
+version 1.2.25rc01 [January 17, 2008]
+  No changes.
+
+version 1.2.25beta03 [January 22, 2008]
+  Fixed some continue-after-malloc-failure errors in pngset.c (David Hill)
+  Check for info_ptr == NULL in png_read_info() and png_process_data().
+  Check for possible use of NULL user_png_ver[] in png_create_read_struct().
+  Change "if (swidth == NULL)" to "if (sheight == NULL)" in png_handle_sCAL
+    (bug introduced in libpng-1.2.4/1.0.13).
+  Return from png_destroy_read_struct() if png_ptr_ptr is NULL.
+  Fix overflow of "msg" in png_decompress_chunk().
+
+version 1.2.25beta04 [January 26, 2008]
+  Work around Coverity bug report by slightly refactoring
+    png_read_push_finish_row()
+
+version 1.2.25beta05 [January 31, 2008]
+  Added libpng-1.2.25beta05.tar.lzma to distribution.  Get the lzma codec
+    from <http://tukaani.org/lzma>.
+  Added lp1225b05.7z to distribution.  Get the 7-zip decoder from
+    from <http://www.7-zip.org>.
+  Fixed some broken links in the README file.
+
+version 1.2.25beta06 [February 6, 2008]
+  Refactored png_read_push_finish_row() again, trying to satisfy Coverity.
+  Fixed potential NULL dereference of png_ptr in png_destroy_write_struct();
+  clarified potential NULL dereference of png_ptr in png_destroy_read_struct();
+  fixed potential NULL dereference of info_ptr in png_handle_bKGD();
+  fixed potential NULL dereference of user_png_ver[] in
+    png_create_write_struct_2(). (Coverity)
+
+version 1.2.25rc02 [February 10, 2008]
+  Reset png_ptr->pass in png_read_push_finish_row() before break.
+  Changed "pass" from png_byte to int.
+
+version 1.2.25 and 1.0.31 [February 18, 2008]
+  No changes.
+
+version 1.2.26beta01 [February 21, 2008]
+  Added missing "(" in pngmem.c.  Bug introduced in libpng-1.2.2/1.0.13
+
+version 1.2.26beta02 [March 12, 2008]
+  Refined error message returned from deflateInit2 in pngwutil.c
+  Check IHDR length in png_push_read_chunk() before saving it.
+
+version 1.2.26beta03 [March 16, 2008]
+  Revised contrib/gregbook to handle premature end-of-file and file
+    read errors correctly.
+
+version 1.2.26beta04 [March 18, 2008]
+  Free png_ptr->big_row_buf and png_ptr->prev_row before allocating
+    new copies in png_read_start_row().  Bug introduced in libpng-1.2.22.
+
+version 1.2.26beta05 [March 19, 2008]
+  Removed extra png_free() added in libpng-1.2.26beta04.
+
+version 1.2.26beta06 [March 19, 2008]
+  Avoid reallocating big_row_buf and prev_row when the size does not increase.
+
+version 1.2.26rc01 [March 26, 2008]
+  Ifdef out some code that is unused when interlacing is not supported.
+
+versions 1.0.32 and 1.2.26 [April 2, 2008]
+  No changes.
+
+version 1.2.27beta01 [April 12, 2008]
+  Fixed bug (introduced in libpng-1.0.5h) with handling zero-length
+    unknown chunks.
+  Added more information about png_set_keep_unknown_chunks() to the
+    documentation.
+  Reject tRNS chunk with out-of-range samples instead of masking off
+    the invalid high bits as done in since libpng-1.2.19beta5.
+
+version 1.2.27beta02 [April 13, 2008]
+  Revised documentation about unknown chunk and user chunk handling.
+  Keep tRNS chunk with out-of-range samples and issue a png_warning().
+
+version 1.2.27beta03 [April 14, 2008]
+  Added check for NULL ptr in TURBOC version of png_free_default().
+  Removed several unnecessary checks for NULL before calling png_free().
+  Revised png_set_tRNS() so that calling it twice removes and invalidates
+    the previous call.
+  Revised pngtest to check for out-of-range tRNS samples.
+
+version 1.2.27beta04 [April 18, 2008]
+  Added AC_LIBTOOL_WIN32_DLL to configure.ac
+  Rebuilt Makefile.in, aclocal.m4, and configure with autoconf-2.62
+
+version 1.2.27beta05 [April 19, 2008]
+  Added MAINTAINERCLEANFILES variable to Makefile.am
+
+version 1.2.27beta06 [April 21, 2008]
+  Avoid changing color_type from GRAY to RGB by
+    png_set_expand_gray_1_2_4_to_8().
+
+version 1.2.27rc01 [April 23, 2008]
+  Fix broken URL for rfc2083 in png.5 and libpng-*.txt
+
+version 1.0.33 and 1.2.27 [April 30, 2008]
+  No changes.
+
+version 1.0.34 and 1.2.28 [April 30, 2008]
+  Rebuilt Makefile.in, aclocal.m4, and configure with autoconf-2.61
+    due to backward incompatibilities.
+  Removed a stray object file from contrib/gregbook
+
+version 1.2.29beta01 [May 1, 2008]
+  Removed some stray *.diff and *.orig files
+
+version 1.2.29beta02 [May 1, 2008]
+  Reverted Makefile.in, aclocal.m4, and configure to the libpng-1.2.26
+    versions.
+
+version 1.2.29beta03 [May 2, 2008]
+  Added --force to autogen libtoolize options and --force-missing to
+    automake options.
+  Changed $(ECHO) to echo in Makefile.am and Makefile.in
+  Updated all configure files to autoconf-2.62
+  Comment out pnggcrd.c code with #ifdef/#endif if using MSC_VER
+
+version 1.2.29rc01 [May 4, 2008]
+  No changes.
+
+version 1.0.35 and 1.2.29 [May 8, 2008]
+  No changes.
+
+version 1.0.37 [May 9, 2008]
+  Updated Makefile.in and configure (omitted version 1.0.36).
+
+version 1.2.30beta01 [May 29, 2008]
+  Updated libpng.pc-configure.in and libpng-config.in per debian bug reports.
+
+version 1.2.30beta02 [June 25, 2008]
+  Restored png_flush(png_ptr) at the end of png_write_end(), that was
+    removed from libpng-1.0.9beta03.
+
+version 1.2.30beta03 [July 6, 2008]
+  Merged some cosmetic whitespace changes from libpng-1.4.0beta19.
+  Inline call of png_get_uint_32() in png_get_uint_31(), as in 1.4.0beta19.
+  Added demo of decoding vpAg and sTER chunks to pngtest.c, from 1.4.0beta19.
+  Changed PNGMAJ from 0 to 12 in makefile.darwin, which does not like 0.
+  Added new private function png_read_chunk_header() from 1.4.0beta19.
+  Merge reading of chunk length and chunk type into a single 8-byte read.
+  Merge writing of chunk length and chunk type into a single 8-byte write.
+
+version 1.2.30beta04 [July 10, 2008]
+  Merged more cosmetic whitespace changes from libpng-1.4.0beta19.
+
+version 1.0.38rc01, 1.2.30rc01 [July 18, 2008]
+  No changes.
+
+version 1.0.38rc02, 1.2.30rc02 [July 21, 2008]
+  Moved local array "chunkdata" from pngrutil.c to the png_struct, so
+    it will be freed by png_read_destroy() in case of a read error (Kurt
+    Christensen).
+
+version 1.0.38rc03, 1.2.30rc03 [July 21, 2008]
+  Changed "purpose" and "buffer" to png_ptr->chunkdata to avoid memory leaking.
+
+version 1.0.38rc04, 1.2.30rc04 [July 22, 2008]
+  Changed "chunkdata = NULL" to "png_ptr->chunkdata = NULL" several places in
+    png_decompress_chunk().
+
+version 1.0.38rc05, 1.2.30rc05 [July 25, 2008]
+  Changed all remaining "chunkdata" to "png_ptr->chunkdata" in
+    png_decompress_chunk() and remove chunkdata from parameter list.
+  Put a call to png_check_chunk_name() in png_read_chunk_header().
+  Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte.
+  Removed two calls to png_check_chunk_name() occuring later in the process.
+
+version 1.0.38rc06, 1.2.30rc06 [July 29, 2008]
+  Added a call to png_check_chunk_name() in pngpread.c
+  Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte.
+
+version 1.0.38r07, 1.2.30r07 [August 2, 2008]
+  Changed "-Wall" to "-W -Wall" in the CFLAGS in all makefiles (Cosmin Truta)
+  Declared png_ptr "volatile" in pngread.c and pngwrite.c to avoid warnings.
+  Added code in pngset.c to quiet compiler warnings.
+  Updated contrib/visupng/cexcept.h to version 2.0.1
+  Relocated a misplaced "#endif /* PNG_NO_WRITE_FILTER */" in pngwutil.c
+
+version 1.0.38r08, 1.2.30r08 [August 2, 2008]
+  Enclose "volatile" declarations in #ifdef PNG_SETJMP_SUPPORTED (Cosmin).
+
+version 1.0.38, 1.2.30 [August 14, 2008]
+  No changes.
+
+version 1.2.31rc01 [August 19, 2008]
+  Removed extra crc check at the end of png_handle_cHRM().  Bug introduced
+    in libpng-1.2.30beta03 (Heiko Nitzsche).
+
+version 1.2.31rc02 [August 19, 2008]
+  Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call.
+
+version 1.2.31rc03 [August 19, 2008]
+  Added PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED block, off by default, around
+    new png_flush().
+
+version 1.0.39, 1.2.31 [August 21, 2008]
+  No changes.
+
+version 1.2.32beta01 [September 6, 2008]
+  Shortened tIME_string to 29 bytes in pngtest.c (bug introduced in
+    libpng-1.2.22).
+  Fixed off-by-one error introduced in png_push_read_zTXt() function in
+    libpng-1.2.30beta04/pngpread.c (Harald van Dijk)
+  These bugs have been given the vulnerability id CVE-2008-3964.
+
+version 1.0.40, 1.2.32 [September 18, 2008]
+  No changes.
+
+version 1.2.33beta01 [October 6, 2008]
+  Revised makefile.darwin to fix shared library numbering.
+  Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8()
+    in example.c (debian bug report)
+
+version 1.2.33rc01 [October 15, 2008]
+  No changes.
+
+version 1.0.41rc01, version 1.2.33rc02 [October 23, 2008]
+  Changed remaining "key" to "png_ptr->chunkdata" in png_handle_tEXt()
+    to avoid memory leak after memory failure while reading tEXt chunk.`
+
+version 1.2.33 [October 31, 2008]
+  No changes.
+
+version 1.2.34beta01 [November 27, 2008]
+  Revised png_warning() to write its message on standard output by default
+    when warning_fn is NULL. This was the behavior prior to libpng-1.2.9beta9.
+  Fixed string vs pointer-to-string error in png_check_keyword().
+  Added png_check_cHRM_fixed() in png.c and moved checking from pngget.c,
+    pngrutil.c, and pngwrite.c, and eliminated floating point cHRM checking.
+  Added check for zero-area RGB cHRM triangle in png_check_cHRM_fixed().
+  In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant
+    check for all-zero coordinates that is detected by the triangle check.
+  Revised png_warning() to write its message on standard output by default
+    when warning_fn is NULL.
+
+version 1.2.34beta02 [November 28, 2008]
+  Corrected off-by-one error in bKGD validity check in png_write_bKGD()
+    and in png_handle_bKGD().
+
+version 1.2.34beta03 [December 1, 2008]
+  Revised bKGD validity check to use >= x instead of > x + 1
+  Merged with png_debug from libpng-1.4.0 to remove newlines.
+
+version 1.2.34beta04 [December 2, 2008]
+  More merging with png_debug from libpng-1.4.0 to remove newlines.
+
+version 1.2.34beta05 [December 5, 2008]
+  Removed redundant check for key==NULL before calling png_check_keyword()
+    to ensure that new_key gets initialized and removed extra warning
+    (Arvan Pritchard).
+
+version 1.2.34beta06 [December 9, 2008]
+  In png_write_png(), respect the placement of the filler bytes in an earlier
+    call to png_set_filler() (Jim Barry).
+
+version 1.2.34beta07 [December 9, 2008]
+  Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and
+    PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated
+    PNG_TRANSFORM_STRIP_FILLER (Jim Barry).
+
+version 1.0.42rc01, 1.2.34rc01 [December 11, 2008]
+  No changes.
+
+version 1.0.42, 1.2.34 [December 18, 2008]
+  No changes.
+
+version 1.2.35beta01 [February 4, 2009]
+  Zero out some arrays of pointers after png_malloc(). (Tavis Ormandy)
+
+version 1.2.35beta02 [February 4, 2009]
+  Zero out more arrays of pointers after png_malloc().
+
+version 1.2.35beta03 [February 5, 2009]
+  Use png_memset() instead of a loop to intialize pointers.  We realize
+    this will not work on platforms where the NULL pointer is not all zeroes.
+
+version 1.2.35rc01 [February 11, 2009]
+  No changes.
+
+version 1.2.35rc02 [February 12, 2009]
+  Fix typo in new png_memset call in pngset.c (png_color should be png_charp)
+
+version 1.0.43 and 1.2.35 [February 14, 2009]
+  No changes.
+
+version 1.2.36beta01 [February 28, 2009]
+  Revised comments in png_set_read_fn() and png_set_write_fn().
+  Revised order of #ifdef's and indentation in png_debug definitions of png.h
+    bug introduced in libpng-1.2.34.
+
+version 1.2.36beta02 [March 21, 2009]
+  Use png_memset() after png_malloc() of big_row_buf when reading an
+    interlaced file, to avoid a possible UMR.
+  Undid recent revision of PNG_NO_STDIO version of png_write_flush().  Users
+    having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined.
+  Revised libpng*.txt documentation about use of png_write_flush().
+  Removed fflush() from pngtest.c.
+  Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h
+
+version 1.2.36beta03 [March 27, 2009]
+  Relocated misplaced PNG_1_0_X define in png.h that caused the prototype
+    for png_set_strip_error_numbers() to be omitted from PNG_NO_ASSEMBLER_CODE
+    builds.  This bug was introduced in libpng-1.2.15beta4.
+  Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt
+
+version 1.2.36beta04 [April 5, 2009]
+  Fixed potential memory leak of "new_name" in png_write_iCCP() (Ralph Giles)
+
+version 1.2.36beta05 [April 24, 2009]
+  Added "ifndef PNG_SKIP_SETJMP_CHECK" block in pngconf.h to allow
+    application code writers to bypass the check for multiple inclusion
+    of setjmp.h when they know that it is safe to ignore the situation.
+  Made some cosmetic changes to whitespace in pngtest output.
+  Renamed "user_chunk_data" to "my_user_chunk_data" in pngtest.c to suppress
+    "shadowed declaration" warning from gcc-4.3.3.
+  Renamed "gamma" to "png_gamma" in pngset.c to avoid "shadowed declaration"
+    warning about a global "gamma" variable in math.h on some platforms.
+
+version 1.2.36rc01 [April 30, 2009]
+  No changes.
+
+version 1.0.44 and 1.2.36 [May 7, 2009]
+  No changes.
+
+version 1.2.37beta01 [May 14, 2009]
+  Fixed inconsistency in pngrutil.c, introduced in libpng-1.2.36.  The
+    memset() was using "png_ptr->rowbytes" instead of "row_bytes", which
+    the corresponding png_malloc() uses (Joe Drew).
+  Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri)
+  Updated some of the makefiles in the scripts directory (merged with
+    those in libpng-1.4.0beta57).
+
+version 1.2.37beta02 [May 19, 2009]
+  Fixed typo in libpng documentation (FILTER_AVE should be FILTER_AVG)
+  Relocated misplaced #endif in pngwrite.c, sCAL chunk handler.
+  Conditionally compile png_read_finish_row() which is not used by
+    progressive readers.
+  Added contrib/pngminim/preader to demonstrate building minimal progressive
+    decoder, based on contrib/gregbook with embedded libpng and zlib.
+
+version 1.2.37beta03 [May 20, 2009]
+  In contrib/pngminim/*, renamed "makefile.std" to "makefile", since there
+    is only one makefile in those directories, and revised the README files
+    accordingly.
+  Reformated sources in libpng style (3-space indentation, comment format)
+
+version 1.2.37rc01 [May 27, 2009]
+  No changes.
+
+versions 1.2.37 and 1.0.45 [June 4, 2009]
+  Reformatted several remaining "else statement;" and "if () statement;" into
+    two lines.
+  Added "#define PNG_NO_WRITE_SWAP" to contrib/pngminim/encoder/pngusr.h
+    and "define PNG_NO_READ_SWAP" to decoder/pngusr.h and preader/pngusr.h
+  Added sections about the git repository and our coding style to the
+    documentation (merged from libpng-1.4.0beta62)
+  Added a section to the libpng documentation about using png_get_io_ptr()
+    in configure scripts to detect the presence of libpng.
+
+version 1.2.38beta01 [June 17, 2009]
+  Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR()
+    multiple times and to specify the sample order in the tRNS chunk,
+    because the ISO PNG specification has a typo in the tRNS table.
+  Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to
+    PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism
+    available for ignoring known chunks even when not saving unknown chunks.
+  Adopted preference for consistent use of "#ifdef" and "#ifndef" versus
+    "#if defined()" and "if !defined()" where possible.
+  Added PNG_NO_HANDLE_AS_UNKNOWN in the PNG_LEGACY_SUPPORTED block of
+    pngconf.h, and moved the various unknown chunk macro definitions
+    outside of the PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks.
+
+version 1.0.46 [June 18, 2009]
+  Removed some editing cruft from scripts/libpng.pc.in and some makefiles.
+
+version 1.2.38rc01 [June 24, 2009]
+  No changes.
+
+version 1.2.38rc02 [June 29, 2009]
+  Added a reference to the libpng license in each source file.
+
+version 1.2.38rc03 [July 11, 2009]
+  Revised references to the libpng license in pngconf.h and contrib/visupng
+    source files.
+  Rebuilt configure scripts with autoconf-2.63.
+
+version 1.0.47 and 1.2.38 [July 16, 2009]
+  No changes.
+
+version 1.2.39beta01 [July 25, 2009]
+  Added a prototype for png_64bit_product() in png.c
+
+version 1.2.39beta02 [July 27, 2009]
+  Avoid a possible NULL dereference in debug build, in png_set_text_2().
+    (bug introduced in libpng-0.95, discovered by Evan Rouault)
+
+version 1.2.39beta03 [July 29, 2009]
+  Relocated new png_64_bit_product() prototype into png.h
+  Expanded the information about prototypes in the libpng style section of
+    the documentation.
+  Rebuilt configure scripts with autoconf-2.64.
+
+version 1.2.39beta04 [August 1, 2009]
+  Replaced *.tar.lzma with *.txz in distribution.  Get the xz codec
+    from <http://tukaani.org/xz>.
+
+version 1.2.39beta05 [August 1, 2009]
+  Reject attempt to write iCCP chunk with negative embedded profile length
+    (JD Chen)
+
+version 1.2.39c01 [August 6, 2009]
+  No changes.
+
+version 1.2.39 and 1.0.48 [August 13, 2009]
+  No changes.
+
+version 1.2.40beta01 [August 20, 2009]
+  Removed an extra png_debug() recently added to png_write_find_filter().
+  Fixed incorrect #ifdef in pngset.c regarding unknown chunk support.
+
+version 1.2.40rc01 [September 2, 2009]
+  Various bugfixes and improvements to CMakeLists.txt (Philip Lowman)
+
+version 1.2.40 and 1.0.49 [September 2, 2009]
+  No changes.
+
+version 1.0.50 [September 10, 2009]
+  Removed some editing cruft from pngset.c and pngwutil.c.
+
+version 1.2.41beta01 [September 25, 2009]
+  Moved redundant IHDR checking into new png_check_IHDR() in png.c
+    and report all errors found in the IHDR data.
+  Eliminated useless call to png_check_cHRM() from pngset.c
+  Expanded TAB characters in pngrtran.c
+
+version 1.2.41beta02 [September 30, 2009]
+  Revised png_check_IHDR().
+
+version 1.2.41beta03 [October 1, 2009]
+  Revised png_check_IHDR() again, to check info_ptr members instead of
+    the contents of the returned parameters.
+
+version 1.2.41beta04 [October 7, 2009]
+  Added "xcode" project similar one already in libpng-1.4.0beta (Alam Arias).
+  Ported some cosmetic changes from libpng-1.4.0beta86.
+  Eliminated a shadowed declaration of "pp" in png_handle_sPLT().
+
+version 1.2.41beta05 [October 17, 2009]
+  Revised pngconf.h to make it easier to enable iTXt support.  From libpng
+    version 1.2.9 through 1.2.40, defining PNG_iTXt_SUPPORTED did not work
+    as expected.
+  Ported some cosmetic changes from libpng-1.4.0beta87, changing
+    many "#if defined(x)" to "#ifdef x".
+
+version 1.2.41beta06 [October 18, 2009]
+  Restored PNG_USE_LOCAL_ARRAYS code in pngread.c that was inadvertently
+    deleted in libpng-1.2.41beta05.
+  Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h
+    as in libpng-1.4.0beta78 and later.
+
+version 1.2.41beta07 [October 21, 2009]
+  Ported some cosmetic changes from libpng-1.4.0rc01, changing
+    many "#if defined(x)" to "#ifdef x" in png.h and pngconf.h.
+
+version 1.2.41beta08 [October 30, 2009]
+  Ported from libpng-1.4.0rc01: png_calloc(), png_get_io_chunk_name(),
+    png_get_io_state(), png_set_user_cache_max(), png_get_user_cache_max(),
+    png_set_premultiply_alpha, and png_do_read_premultiply_alpha().
+  Relocated png_do_chop() ahead of building gamma tables in pngrtran.c
+    This avoids building 16-bit gamma tables unnecessarily.
+
+version 1.2.41beta09 [November 1, 2009]
+  Removed a harmless extra png_set_invert_alpha() from pngwrite.c
+  More bugfixes and improvements to CMakeLists.txt (Philip Lowman)
+  Moved CMakeLists.txt from scripts into the main libpng directory.
+  Apply png_user_chunk_cache_max within png_decompress_chunk().
+  Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate.
+
+version 1.2.41beta10 [November 1, 2009]
+  Enabled iTXt support by default. To ensure binary compatibility with
+    previous versions, the "lang" and "lang_key" members will be assumed
+    to be omitted from previous versions unless the current libpng
+    version was built with PNG_iTXt_SUPPORTED (which is otherwise no
+    longer necessary to gain iTXt support), as a signal that the user has
+    been building previous versions with PNG_iTXt_SUPPORTED as well.
+
+version 1.2.41beta11 [November 2, 2009]
+  Store user's user_png_ver in new png_ptr->user_png_ver element.
+  Revised iTXt support. To ensure binary compatibility with
+    previous versions, the "lang" and "lang_key" members will be assumed
+    to be omitted from versions prior to 1.2.41beta11 whenever there is a
+    library mismatch.
+
+version 1.2.41beta12 [November 2, 2009]
+  Free png_ptr->user_png_ver when destroying png_ptr.
+
+version 1.2.41beta13 [November 3, 2009]
+  Updated scripts/pngw32.def and projects/wince/png32ce.def
+  Copied projects/wince/png32ce.def to the scripts directory.
+  Added scripts/makefile.wce
+  Patched ltmain.sh for wince support.
+  Added PNG_CONVERT_tIME_SUPPORTED macro.
+
+version 1.2.41beta14 [November 8, 2009]
+  versions 1.2.41beta05 through 1.2.41beta13 were abandoned.
+  The 1.0.x/1.2.x series will only receive security updates from now on.
+  Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED
+  Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED
+  Reverted iTXt compatibility stuff from 1.2.41beta05, 1.2.41beta11, and
+    1.2.41beta12.
+  Reverted IOSTATE feature, user_cache_max, and premultiply_alpha features
+    from 1.2.41beta08.
+  Retained png_calloc() from 1.2.41beta08 but as a non-exported function,
+    and removed reference to png_calloc from scripts/*.def
+
+version 1.2.41beta15 [November 8, 2009]
+  Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and
+    PNG_ALLOCATED macros to detect deprecated direct access to the
+    png_struct or info_struct members and other deprecated usage in
+    applications (John Bowler).
+  Updated scripts/makefile* to add "-DPNG_CONFIGURE_LIBPNG" to CFLAGS,
+    to prevent warnings about direct access to png structs by libpng
+    functions while building libpng.  They need to be tested, especially
+    those using compilers other than gcc.
+  Updated projects/visualc6 and visualc71 with "/d PNG_CONFIGURE_LIBPNG".
+
+version 1.2.41beta16 [November 9, 2009]
+  Removed three direct references to read_info_ptr members in pngtest.c
+    that were detected by the new PNG_DEPSTRUCT macro.
+  Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined.
+
+version 1.2.41beta17 [November 10, 2009]
+  Updated CMakeLists.txt to add "-DPNG_CONFIGURE_LIBPNG" to the definitions.
+  Marked deprecated function prototypes with PNG_DEPRECATED.
+  Marked memory allocation function prototypes with PNG_ALLOCATED.
+  Changed png_check_sig() to !png_sig_cmp() in contrib programs.
+  Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c
+  Added "-DPNG_CONFIGURE_LIBPNG" to the contrib/pngminum makefiles.
+
+version 1.2.41beta18 [November 11, 2009]
+  Renamed scripts/makefile.wce to scripts/makefile.cegcc
+  Marked nonexported functions with PNG_PRIVATE macro.
+
+version 1.2.41rc01 and 1.0.51rc01 [November 18, 2009]
+  Revised scripts/*.def to reflect functions actually exported by libpng.
+  Updated the copyright year in scripts/pngw32.rc from 2004 to 2009.
+  Moved descriptions of makefiles and other scripts out of INSTALL into
+    scripts/README.txt
+
+version 1.2.41rc02 [November 22, 2009]
+  Rebuilt the configure scripts with autoconf-2.65
+
+version 1.2.41rc03 [November 25, 2009]
+  Disabled the new pedantic warnings about deprecated function use
+    and deprecated structure access unless the user defines
+    PNG_PEDANTIC_WARNINGS.
+  Added "#define PNG_NO_PEDANTIC_WARNINGS" in the libpng source files.
+  Removed "-DPNG_CONFIGURE_LIBPNG" from the makefiles and projects.
+
+version 1.2.41 and 1.0.51 [December 3, 2009]
+  Updated the list of files and made some cosmetic changes in README.
+
+version 1.2.42beta01 [December 4, 2009]
+  Removed "#define PNG_NO_ERROR_NUMBERS" that was inadvertently added
+    to pngconf.h in version 1.2.41.
+  Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco
+    to put png.h and pngconf.h in $prefix/include, like the other scripts,
+    instead of in $prefix/include/libpng.  Also revised makefile.sco
+    to put them in $prefix/include/libpng12 instead of in
+    $prefix/include/libpng/libpng12.
+  Removed leftover "-DPNG_CONFIGURE_LIBPNG" from scripts/makefile.darwin
+
+version 1.2.42beta02 [December 11, 2009]
+  Removed leftover "-DPNG_CONFIGURE_LIBPNG" from contrib/pngminim/*/makefile
+  Relocated png_do_chop() to its original position in pngrtran.c. The
+    change in version 1.2.41beta08 caused transparency to be handled wrong
+    in some 16-bit datastreams (Yusaku Sugai).
+
+version 1.2.42rc01 [December 17, 2009]
+  No changes.
+
+version 1.2.42rc02 [December 22, 2009]
+  Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt
+    (revising changes made in 1.2.41beta17 and 1.2.41rc01)
+
+version 1.2.42rc03 [December 25, 2009]
+  Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+    in pngset.c to be consistent with other changes in version 1.2.38.
+
+version 1.2.42rc04 [January 1, 2010]
+  Marked png_memcpy_check() and png_memset_check() PNG_DEPRECATED.
+  Updated copyright year.
+
+version 1.2.42rc05 [January 2, 2010]
+  Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr
+    in pngtest.c
+
+version 1.2.42 and 1.0.52 [January 3, 2010]
+  No changes.
+
+version 1.2.43beta01 [January 27, 2010]
+  Updated CMakeLists.txt for consistent indentation and to avoid an
+    unclosed if-statement warning (Philip Lowman).
+  Removed "#ifdef PNG_1_0_X / #endif" surrounding
+    PNG_READ_16_TO_8_SUPPORTED and PNG_READ_GRAY_TO_RGB_SUPPORTED
+    in pngconf.h.  These were added in libpng-1.2.41beta08 and libpng-1.0.51,
+    which introduced a binary incompatibility with libpng-1.0.50.
+  Backported new png_decompress_chunk() algorithm from libpng-1.4.1.
+
+version 1.2.43beta02 [February 1, 2010]
+  Backported two-pass png_decompress_chunk() algorithm from libpng-1.4.1.
+
+version 1.2.43beta03 [February 6, 2010]
+  Backported fast png_push_save_buffer() algorithm from libpng-1.4.1.
+  Backported some cosmetic changes from libpng-1.4.1.
+
+version 1.2.43beta04 [February 8, 2010]
+  Reverted recent changes to png_push_save-buffer().
+  Removed PNGAPI declaration of png_calloc() and png_write_sig() in
+    1ibpng-1.2.X, introduced by mistake in libpng-1.2.41.
+  Return allocated "old_buffer" in png_push_save_buffer() before png_error()
+    to avoid a potential memory leak.
+
+version 1.2.43beta05 [February 8, 2010]
+  Ported rewritten png_decompress_chunk() by John Bowler from libpng-1.4.1.
+
+version 1.0.53rc01 and 1.2.43rc01 [February 18, 2010]
+  No changes.
+
+version 1.0.53rc02 and 1.2.43rc02 [February 19, 2010]
+  Define _ALL_SOURCE in configure.ac, makefile.aix, and CMakeLists.txt
+    when using AIX compiler.
+
+version 1.0.53 and 1.2.43 [February 25, 2010]
+  Removed unused gzio.c from contrib/pngminim gather and makefile scripts
+
+version 1.2.44beta01 [June 18, 2010]
+  In pngpread.c: png_push_have_row() add check for new_row > height
+  Removed the now-redundant check for out-of-bounds new_row from example.c
+
+version 1.2.44beta02 [June 19, 2010]
+  In pngpread.c: png_push_process_row() add check for too many rows.
+  Removed the now-redundant check for new_row > height in png_push_have_row().
+
+version 1.2.44beta03 [June 20, 2010]
+  Rewrote png_process_IDAT_data() to consistently treat extra data as warnings
+    and handle end conditions more cleanly.
+  Removed the new (beta02) check in png_push_process_row().
+
+version 1.2.44rc01 [June 21, 2010]
+  Revised some comments in png_process_IDAT_data().
+
+version 1.2.44rc02 [June 22, 2010]
+  Stop memory leak when reading a malformed sCAL chunk.
+
+version 1.2.44rc03 [June 23, 2010]
+  Revised pngpread.c patch of beta05 to avoid an endless loop.
+
+version 1.2.44 [June 26, 2010]
+  Updated some of the "last changed" dates.
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+(subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe)
+or to glennrp at users.sourceforge.net
+
+Glenn R-P
+*/
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/KNOWNBUG
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/KNOWNBUG	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/KNOWNBUG	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+
+Known bugs in libpng version 1.2.44
+
+1. December 4, 2009: The PNG_NO_ERROR_NUMBERS macro was inadvertently
+   defined in libpng-1.2.41/pngconf.h, which may cause a problem with
+   building a binary-compatible library.
+
+   STATUS: This will be fixed in libpng-1.2.42.  In the meantime, simply
+   delete the definition from line :
+
+2. February 23, 2006: The custom makefiles don't build libpng with -lz.
+
+   STATUS: This is a subject of debate. The change will probably be made
+   as a part of a major overhaul of the makefiles in libpng version 1.4.0.
+
+3. February 24, 2006: The Makefile generated by the "configure" script
+   fails to install symbolic links
+   libpng12.so => libpng12.so.0.1.2.9betaN
+   that are generated by the custom makefiles.
+
+4. September 4, 2007:  There is a report that pngtest crashes on MacOS 10.
+
+   STATUS: workarounds are
+      1) Compile without optimization (crashes are observed with
+         -arch i386 and -O2 or -O3, using gcc-4.0.1).
+      2) Compile pngtest.c with PNG_DEBUG defined (the bug goes away if
+         you try to look at it).
+      3) Ignore the crash.  The library itself seems to be OK.
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/LICENSE
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/LICENSE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/LICENSE	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,111 @@
+
+This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.44, June 26, 2010, are
+Copyright (c) 2004, 2006-2009 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+   be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+   source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+June 26, 2010
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,275 @@
+README for libpng version 1.2.44 - June 26, 2010 (shared library 12.0)
+See the note about version numbers near the top of png.h
+
+See INSTALL for instructions on how to install libpng.
+
+Libpng comes in several distribution formats.  Get libpng-*.tar.gz,
+libpng-*.tar.xz, or libpng-*.tar.bz2 if you want UNIX-style line
+endings in the text files, or lpng*.7z or lpng*.zip if you want DOS-style
+line endings.  You can get UNIX-style line endings from the *.zip file
+by using "unzip -a" but there seems to be no simple way to recover
+UNIX-style line endings from the *.7z file.  The *.tar.xz file is
+recommended for *NIX users instead.
+
+Version 0.89 was the first official release of libpng.  Don't let the
+fact that it's the first release fool you.  The libpng library has been in
+extensive use and testing since mid-1995.  By late 1997 it had
+finally gotten to the stage where there hadn't been significant
+changes to the API in some time, and people have a bad feeling about
+libraries with versions < 1.0.  Version 1.0.0 was released in
+March 1998.
+
+****
+Note that some of the changes to the png_info structure render this
+version of the library binary incompatible with libpng-0.89 or
+earlier versions if you are using a shared library.  The type of the
+"filler" parameter for png_set_filler() has changed from png_byte to
+png_uint_32, which will affect shared-library applications that use
+this function.
+
+To avoid problems with changes to the internals of png_info_struct,
+new APIs have been made available in 0.95 to avoid direct application
+access to info_ptr.  These functions are the png_set_<chunk> and
+png_get_<chunk> functions.  These functions should be used when
+accessing/storing the info_struct data, rather than manipulating it
+directly, to avoid such problems in the future.
+
+It is important to note that the APIs do not make current programs
+that access the info struct directly incompatible with the new
+library.  However, it is strongly suggested that new programs use
+the new APIs (as shown in example.c and pngtest.c), and older programs
+be converted to the new format, to facilitate upgrades in the future.
+****
+
+Additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the info struct.
+Experimental functions include the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16->8 bit color
+conversion.
+
+The additions since 0.89 include the ability to read from a PNG stream
+which has had some (or all) of the signature bytes read by the calling
+application.  This also allows the reading of embedded PNG streams that
+do not have the PNG file signature.  As well, it is now possible to set
+the library action on the detection of chunk CRC errors.  It is possible
+to set different actions based on whether the CRC error occurred in a
+critical or an ancillary chunk.
+
+The changes made to the library, and bugs fixed are based on discussions
+on the png-mng-implement mailing list and not on material submitted
+privately to Guy, Andreas, or Glenn.  They will forward any good
+suggestions to the list.
+
+For a detailed description on using libpng, read libpng.txt.  For
+examples of libpng in a program, see example.c and pngtest.c.  For usage
+information and restrictions (what little they are) on libpng, see
+png.h.  For a description on using zlib (the compression library used by
+libpng) and zlib's restrictions, see zlib.h
+
+I have included a general makefile, as well as several machine and
+compiler specific ones, but you may have to modify one for your own needs.
+
+You should use zlib 1.0.4 or later to run this, but it MAY work with
+versions as old as zlib 0.95.  Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images.  You will definitely need zlib 1.0.4 or later if you are
+taking advantage of the MS-DOS "far" structure allocation for the small
+and medium memory models.  You should also note that zlib is a
+compression library that is useful for more things than just PNG files.
+You can use zlib as a drop-in replacement for fread() and fwrite() if
+you are so inclined.
+
+zlib should be available at the same place that libpng is, or at
+ftp://ftp.simplesystems.org/pub/png/src/
+
+You may also want a copy of the PNG specification.  It is available
+as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
+these at http://www.libpng.org/pub/png/pngdocs.html
+
+This code is currently being archived at libpng.sf.net in the
+[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT)
+at GO GRAPHSUP.  If you can't find it in any of those places,
+e-mail me, and I'll help you find it.
+
+If you have any code changes, requests, problems, etc., please e-mail
+them to me.  Also, I'd appreciate any make files or project files,
+and any modifications you needed to make to get libpng to compile,
+along with a #define variable to tell what compiler/system you are on.
+If you needed to add transformations to libpng, or wish libpng would
+provide the image in a different way, drop me a note (and code, if
+possible), so I can consider supporting the transformation.
+Finally, if you get any warning messages when compiling libpng
+(note: not zlib), and they are easy to fix, I'd appreciate the
+fix.  Please mention "libpng" somewhere in the subject line.  Thanks.
+
+This release was created and will be supported by myself (of course
+based in a large way on Guy's and Andreas' earlier work), and the PNG
+development group.
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+(subscription required; visit 
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe) or to glennrp at users.sourceforge.net
+
+You can't reach Guy, the original libpng author, at the addresses
+given in previous versions of this document.  He and Andreas will
+read mail addressed to the png-mng-implement list, however.
+
+Please do not send general questions about PNG.  Send them to
+the (png-mng-misc at lists.sourceforge.net, subscription required, visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
+subscribe). On the other hand, please do not send libpng questions to
+that address, send them to me or to the png-mng-implement list.  I'll
+get them in the end anyway.  If you have a question about something
+in the PNG specification that is related to using libpng, send it
+to me.  Send me any questions that start with "I was using libpng,
+and ...".  If in doubt, send questions to me.  I'll bounce them
+to others, if necessary.
+
+Please do not send suggestions on how to change PNG.  We have
+been discussing PNG for twelve years now, and it is official and
+finished.  If you have suggestions for libpng, however, I'll
+gladly listen.  Even if your suggestion is not used immediately,
+it may be used later.
+
+Files in this distribution:
+
+      ANNOUNCE      =>  Announcement of this version, with recent changes
+      CHANGES       =>  Description of changes between libpng versions
+      KNOWNBUG      =>  List of known bugs and deficiencies
+      LICENSE       =>  License to use and redistribute libpng
+      README        =>  This file
+      TODO          =>  Things not implemented in the current library
+      Y2KINFO       =>  Statement of Y2K compliance
+      example.c     =>  Example code for using libpng functions
+      libpng-*-*-diff.txt => Diff from previous release
+      libpng.3      =>  manual page for libpng (includes libpng.txt)
+      libpng.txt    =>  Description of libpng and its functions
+      libpngpf.3    =>  manual page for libpng's private functions
+      png.5         =>  manual page for the PNG format
+      png.c         =>  Basic interface functions common to library
+      png.h         =>  Library function and interface declarations
+      pngconf.h     =>  System specific library configuration
+      pngerror.c    =>  Error/warning message I/O functions
+      pngget.c      =>  Functions for retrieving info from struct
+      pngmem.c      =>  Memory handling functions
+      pngbar.png    =>  PNG logo, 88x31
+      pngnow.png    =>  PNG logo, 98x31
+      pngpread.c    =>  Progressive reading functions
+      pngread.c     =>  Read data/helper high-level functions
+      pngrio.c      =>  Lowest-level data read I/O functions
+      pngrtran.c    =>  Read data transformation functions
+      pngrutil.c    =>  Read data utility functions
+      pngset.c      =>  Functions for storing data into the info_struct
+      pngtest.c     =>  Library test program
+      pngtest.png   =>  Library test sample image
+      pngtrans.c    =>  Common data transformation functions
+      pngwio.c      =>  Lowest-level write I/O functions
+      pngwrite.c    =>  High-level write functions
+      pngwtran.c    =>  Write data transformations
+      pngwutil.c    =>  Write utility functions
+      contrib       =>  Contributions
+       gregbook         =>  source code for PNG reading and writing, from
+                            Greg Roelofs' "PNG: The Definitive Guide",
+                            O'Reilly, 1999
+       msvctest     =>  Builds and runs pngtest using a MSVC workspace
+       pngminim     =>  Simple pnm2pngm and png2pnmm programs
+       pngminus     =>  Simple pnm2png and png2pnm programs
+       pngsuite     =>  Test images
+       visupng      =>  Contains a MSVC workspace for VisualPng
+      projects      =>  Contains project files and workspaces for
+                        building a DLL
+       beos             =>  Contains a Beos workspace for building libpng
+       c5builder        =>  Contains a Borland workspace for building
+                            libpng and zlib
+       netware.txt      =>  Contains instructions for downloading a set
+                            of project files for building libpng and
+                            zlib on Netware.
+       visualc6         =>  Contains a Microsoft Visual C++ (MSVC)
+                            workspace for building libpng and zlib
+       wince.txt        =>  Contains instructions for downloading a
+                            Microsoft Visual C++ (Windows CD Toolkit)
+                            workspace for building libpng and zlib on
+                            WindowsCE
+       xcode            =>  Contains xcode project files
+      scripts       =>  Directory containing scripts for building libpng:
+       descrip.mms      =>  VMS makefile for MMS or MMK
+       makefile.std     =>  Generic UNIX makefile (cc, creates static
+                            libpng.a)
+       makefile.elf     =>  Linux/ELF gcc makefile symbol versioning,
+                            creates libpng12.so.0.1.2.44)
+       makefile.linux   =>  Linux/ELF makefile (gcc, creates
+                            libpng12.so.0.1.2.44)
+       makefile.gcmmx   =>  Linux/ELF makefile (gcc, creates
+                            libpng12.so.0.1.2.44, previously
+                            used assembler code tuned for Intel MMX
+                            platform)
+       makefile.gcc     =>  Generic makefile (gcc, creates static
+                            libpng.a)
+       makefile.knr     =>  Archaic UNIX Makefile that converts files
+                            with ansi2knr (Requires ansi2knr.c from
+                            ftp://ftp.cs.wisc.edu/ghost)
+       makefile.aix     =>  AIX makefile
+       makefile.cygwin  =>  Cygwin/gcc makefile
+       makefile.darwin  =>  Darwin makefile
+       makefile.dec     =>  DEC Alpha UNIX makefile
+       makefile.freebsd =>  FreeBSD makefile
+       makefile.hpgcc   =>  HPUX makefile using gcc
+       makefile.hpux    =>  HPUX (10.20 and 11.00) makefile
+       makefile.hp64    =>  HPUX (10.20 and 11.00) makefile, 64 bit
+       makefile.ibmc    =>  IBM C/C++ version 3.x for Win32 and OS/2
+                            (static)
+       makefile.intel   =>  Intel C/C++ version 4.0 and later
+       libpng.icc       =>  Project file, IBM VisualAge/C++ 4.0 or later
+       makefile.netbsd  =>  NetBSD/cc makefile, makes libpng.so.
+       makefile.ne12bsd  =>  NetBSD/cc makefile, makes libpng12.so
+       makefile.openbsd =>  OpenBSD makefile
+       makefile.sgi     =>  Silicon Graphics IRIX (cc, creates static lib)
+       makefile.sggcc   =>  Silicon Graphics
+                            (gcc, creates libpng12.so.0.1.2.44)
+       makefile.sunos   =>  Sun makefile
+       makefile.solaris =>  Solaris 2.X makefile
+                            (gcc, creates libpng12.so.0.1.2.44)
+       makefile.so9     =>  Solaris 9 makefile
+                            (gcc, creates libpng12.so.0.1.2.44)
+       makefile.32sunu  =>  Sun Ultra 32-bit makefile
+       makefile.64sunu  =>  Sun Ultra 64-bit makefile
+       makefile.sco     =>  For SCO OSr5  ELF and Unixware 7 with Native cc
+       makefile.mips    =>  MIPS makefile
+       makefile.acorn   =>  Acorn makefile
+       makefile.amiga   =>  Amiga makefile
+       smakefile.ppc    =>  AMIGA smakefile for SAS C V6.58/7.00 PPC
+                            compiler (Requires SCOPTIONS, copied from
+                            scripts/SCOPTIONS.ppc)
+       makefile.atari   =>  Atari makefile
+       makefile.beos    =>  BEOS makefile for X86
+       makefile.bor     =>  Borland makefile (uses bcc)
+       makefile.bc32    =>  32-bit Borland C++ (all modules compiled in C mode)
+       makefile.tc3     =>  Turbo C 3.0 makefile
+       makefile.dj2     =>  DJGPP 2 makefile
+       makefile.msc     =>  Microsoft C makefile
+       makefile.vcawin32=>  makefile for Microsoft Visual C++ 5.0 and
+                            later (previously used assembler code tuned
+                            for Intel MMX platform)
+       makefile.vcwin32 =>  makefile for Microsoft Visual C++ 4.0 and
+                            later (does not use assembler code)
+       makefile.os2     =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+       pngos2.def       =>  OS/2 module definition file used by makefile.os2
+       makefile.watcom  =>  Watcom 10a+ Makefile, 32-bit flat memory model
+       makevms.com      =>  VMS build script
+       SCOPTIONS.ppc    =>  Used with smakefile.ppc
+
+Good luck, and happy coding.
+
+-Glenn Randers-Pehrson (current maintainer, since 1998)
+ Internet: glennrp at users.sourceforge.net
+
+-Andreas Eric Dilger (former maintainer, 1996-1997)
+ Internet: adilger at enel.ucalgary.ca
+ Web: http://members.shaw.ca/adilger/
+
+-Guy Eric Schalnat (original author and former maintainer, 1995-1996)
+ (formerly of Group 42, Inc)
+ Internet: gschal at infinet.com
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/TODO
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/TODO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/TODO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+TODO - list of things to do for libpng:
+
+Final bug fixes.
+Improve API by hiding the png_struct and png_info structs.
+Finish work on the no-floating-point version (including gamma compensation)
+Better C++ wrapper/full C++ implementation?
+Fix problem with C++ and EXTERN "C".
+cHRM transformation.
+Improve setjmp/longjmp usage or remove it in favor of returning error codes.
+Add "grayscale->palette" transformation and "palette->grayscale" detection.
+Improved dithering.
+Multi-lingual error and warning message support.
+Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Man pages for function calls.
+Better documentation.
+Better filter selection
+   (counting huffman bits/precompression?  filter inertia?  filter costs?).
+Histogram creation.
+Text conversion between different code pages (Latin-1 -> Mac and DOS).
+Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety?
+Build gamma tables using fixed point (and do away with floating point entirely).
+Use greater precision when changing to linear gamma for compositing against
+  background and doing rgb-to-gray transformation.
+Investigate pre-incremented loop counters and other loop constructions.
+Add interpolated method of handling interlacing.
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/Y2KINFO
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/Y2KINFO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/Y2KINFO	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+   Y2K compliance in libpng:
+   =========================
+
+      June 26, 2010
+
+      Since the PNG Development group is an ad-hoc body, we can't make
+      an official declaration.
+
+      This is your unofficial assurance that libpng from version 0.71 and
+      upward through 1.2.44 are Y2K compliant.  It is my belief that earlier
+      versions were also Y2K compliant.
+
+      Libpng only has three year fields.  One is a 2-byte unsigned integer
+      that will hold years up to 65535.  The other two hold the date in text
+      format, and will hold years up to 9999.
+
+      The integer is
+          "png_uint_16 year" in png_time_struct.
+
+      The strings are
+          "png_charp time_buffer" in png_struct and
+          "near_time_buffer", which is a local character string in png.c.
+
+      There are seven time-related functions:
+
+          png_convert_to_rfc_1123() in png.c
+            (formerly png_convert_to_rfc_1152() in error)
+          png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+          png_convert_from_time_t() in pngwrite.c
+          png_get_tIME() in pngget.c
+          png_handle_tIME() in pngrutil.c, called in pngread.c
+          png_set_tIME() in pngset.c
+          png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+      All appear to handle dates properly in a Y2K environment.  The
+      png_convert_from_time_t() function calls gmtime() to convert from system
+      clock time, which returns (year - 1900), which we properly convert to
+      the full 4-digit year.  There is a possibility that applications using
+      libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+      function, or that they are incorrectly passing only a 2-digit year
+      instead of "year - 1900" into the png_convert_from_struct_tm() function,
+      but this is not under our control.  The libpng documentation has always
+      stated that it works with 4-digit years, and the APIs have been
+      documented as such.
+
+      The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+      integer to hold the year, and can hold years as large as 65535.
+
+      zlib, upon which libpng depends, is also Y2K compliant.  It contains
+      no date-related code.
+
+
+         Glenn Randers-Pehrson
+         libpng maintainer
+         PNG Development Group
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/example.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/example.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/example.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,832 @@
+
+#if 0 /* in case someone actually tries to compile this */
+
+/* example.c - an example of using libpng
+ * Last changed in libpng 1.2.37 [June 4, 2009]
+ * This file has been placed in the public domain by the authors.
+ * Maintained 1998-2010 Glenn Randers-Pehrson
+ * Maintained 1996, 1997 Andreas Dilger)
+ * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* This is an example of how to use libpng to read and write PNG files.
+ * The file libpng.txt is much more verbose then this.  If you have not
+ * read it, do so first.  This was designed to be a starting point of an
+ * implementation.  This is not officially part of libpng, is hereby placed
+ * in the public domain, and therefore does not require a copyright notice.
+ *
+ * This file does not currently compile, because it is missing certain
+ * parts, like allocating memory to hold an image.  You will have to
+ * supply these parts to get it to compile.  For an example of a minimal
+ * working PNG reader/writer, see pngtest.c, included in this distribution;
+ * see also the programs in the contrib directory.
+ */
+
+#include "png.h"
+
+ /* The png_jmpbuf() macro, used in error handling, became available in
+  * libpng version 1.0.6.  If you want to be able to run your code with older
+  * versions of libpng, you must define the macro yourself (but only if it
+  * is not already defined by libpng!).
+  */
+
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
+/* Check to see if a file is a PNG file using png_sig_cmp().  png_sig_cmp()
+ * returns zero if the image is a PNG and nonzero if it isn't a PNG.
+ *
+ * The function check_if_png() shown here, but not used, returns nonzero (true)
+ * if the file can be opened and is a PNG, 0 (false) otherwise.
+ *
+ * If this call is successful, and you are going to keep the file open,
+ * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
+ * you have created the png_ptr, so that libpng knows your application
+ * has read that many bytes from the start of the file.  Make sure you
+ * don't call png_set_sig_bytes() with more than 8 bytes read or give it
+ * an incorrect number of bytes read, or you will either have read too
+ * many bytes (your fault), or you are telling libpng to read the wrong
+ * number of magic bytes (also your fault).
+ *
+ * Many applications already read the first 2 or 4 bytes from the start
+ * of the image to determine the file type, so it would be easiest just
+ * to pass the bytes to png_sig_cmp() or even skip that if you know
+ * you have a PNG file, and call png_set_sig_bytes().
+ */
+#define PNG_BYTES_TO_CHECK 4
+int check_if_png(char *file_name, FILE **fp)
+{
+   char buf[PNG_BYTES_TO_CHECK];
+
+   /* Open the prospective PNG file. */
+   if ((*fp = fopen(file_name, "rb")) == NULL)
+      return 0;
+
+   /* Read in some of the signature bytes */
+   if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
+      return 0;
+
+   /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
+      Return nonzero (true) if they match */
+
+   return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
+}
+
+/* Read a PNG file.  You may want to return an error code if the read
+ * fails (depending upon the failure).  There are two "prototypes" given
+ * here - one where we are given the filename, and we need to open the
+ * file, and the other where we are given an open file (possibly with
+ * some or all of the magic bytes read - see comments above).
+ */
+#ifdef open_file /* prototype 1 */
+void read_png(char *file_name)  /* We need to open the file */
+{
+   png_structp png_ptr;
+   png_infop info_ptr;
+   unsigned int sig_read = 0;
+   png_uint_32 width, height;
+   int bit_depth, color_type, interlace_type;
+   FILE *fp;
+
+   if ((fp = fopen(file_name, "rb")) == NULL)
+      return (ERROR);
+
+#else no_open_file /* prototype 2 */
+void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
+{
+   png_structp png_ptr;
+   png_infop info_ptr;
+   png_uint_32 width, height;
+   int bit_depth, color_type, interlace_type;
+#endif no_open_file /* Only use one prototype! */
+
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also supply the
+    * the compiler header file version, so that we know if the application
+    * was compiled with a compatible version of the library.  REQUIRED
+    */
+   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+      png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (png_ptr == NULL)
+   {
+      fclose(fp);
+      return (ERROR);
+   }
+
+   /* Allocate/initialize the memory for image information.  REQUIRED. */
+   info_ptr = png_create_info_struct(png_ptr);
+   if (info_ptr == NULL)
+   {
+      fclose(fp);
+      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
+      return (ERROR);
+   }
+
+   /* Set error handling if you are using the setjmp/longjmp method (this is
+    * the normal method of doing things with libpng).  REQUIRED unless you
+    * set up your own error handlers in the png_create_read_struct() earlier.
+    */
+
+   if (setjmp(png_jmpbuf(png_ptr)))
+   {
+      /* Free all of the memory associated with the png_ptr and info_ptr */
+      png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+      fclose(fp);
+      /* If we get here, we had a problem reading the file */
+      return (ERROR);
+   }
+
+   /* One of the following I/O initialization methods is REQUIRED */
+#ifdef streams /* PNG file I/O method 1 */
+   /* Set up the input control if you are using standard C streams */
+   png_init_io(png_ptr, fp);
+
+#else no_streams /* PNG file I/O method 2 */
+   /* If you are using replacement read functions, instead of calling
+    * png_init_io() here you would call:
+    */
+   png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
+   /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* Use only one I/O method! */
+
+   /* If we have already read some of the signature */
+   png_set_sig_bytes(png_ptr, sig_read);
+
+#ifdef hilevel
+   /*
+    * If you have enough memory to read in the entire image at once,
+    * and you need to specify only transforms that can be controlled
+    * with one of the PNG_TRANSFORM_* bits (this presently excludes
+    * dithering, filling, setting background, and doing gamma
+    * adjustment), then you can read the entire image (including
+    * pixels) into the info structure with this call:
+    */
+   png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
+
+#else
+   /* OK, you're doing it the hard way, with the lower-level functions */
+
+   /* The call to png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).  REQUIRED
+    */
+   png_read_info(png_ptr, info_ptr);
+
+   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+       &interlace_type, int_p_NULL, int_p_NULL);
+
+   /* Set up the data transformations you want.  Note that these are all
+    * optional.  Only call them if you want/need them.  Many of the
+    * transformations only work on specific types of images, and many
+    * are mutually exclusive.
+    */
+
+   /* Tell libpng to strip 16 bit/color files down to 8 bits/color */
+   png_set_strip_16(png_ptr);
+
+   /* Strip alpha bytes from the input data without combining with the
+    * background (not recommended).
+    */
+   png_set_strip_alpha(png_ptr);
+
+   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   png_set_packing(png_ptr);
+
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing). */
+   png_set_packswap(png_ptr);
+
+   /* Expand paletted colors into true RGB triplets */
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+      png_set_palette_to_rgb(png_ptr);
+
+   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+      png_set_expand_gray_1_2_4_to_8(png_ptr);
+
+   /* Expand paletted or RGB images with transparency to full alpha channels
+    * so the data will be available as RGBA quartets.
+    */
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+      png_set_tRNS_to_alpha(png_ptr);
+
+   /* Set the background color to draw transparent and alpha images over.
+    * It is possible to set the red, green, and blue components directly
+    * for paletted images instead of supplying a palette index.  Note that
+    * even if the PNG file supplies a background, you are not required to
+    * use it - you should use the (solid) application background if it has one.
+    */
+
+   png_color_16 my_background, *image_background;
+
+   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+      png_set_background(png_ptr, image_background,
+                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+   else
+      png_set_background(png_ptr, &my_background,
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+   /* Some suggestions as to how to get a screen gamma value
+    *
+    * Note that screen gamma is the display_exponent, which includes
+    * the CRT_exponent and any correction for viewing conditions
+    */
+   if (/* We have a user-defined screen gamma value */)
+   {
+      screen_gamma = user-defined screen_gamma;
+   }
+   /* This is one way that applications share the same screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
+   {
+      screen_gamma = atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2;  /* A good guess for a PC monitor in a dimly
+                              lit room */
+      screen_gamma = 1.7 or 1.0;  /* A good guess for Mac systems */
+   }
+
+   /* Tell libpng to handle the gamma conversion for you.  The final call
+    * is a good guess for PC generated images, but it should be configurable
+    * by the user at run time by the user.  It is strongly suggested that
+    * your application support gamma correction.
+    */
+
+   int intent;
+
+   if (png_get_sRGB(png_ptr, info_ptr, &intent))
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+   else
+   {
+      double image_gamma;
+      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
+         png_set_gamma(png_ptr, screen_gamma, image_gamma);
+      else
+         png_set_gamma(png_ptr, screen_gamma, 0.45455);
+   }
+
+   /* Dither RGB files down to 8 bit palette or reduce palettes
+    * to the number of colors available on your screen.
+    */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      int num_palette;
+      png_colorp palette;
+
+      /* This reduces the image to the application supplied palette */
+      if (/* We have our own palette */)
+      {
+         /* An array of colors to which the image should be dithered */
+         png_color std_color_cube[MAX_SCREEN_COLORS];
+
+         png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
+            MAX_SCREEN_COLORS, png_uint_16p_NULL, 0);
+      }
+      /* This reduces the image to the palette supplied in the file */
+      else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
+      {
+         png_uint_16p histogram = NULL;
+
+         png_get_hIST(png_ptr, info_ptr, &histogram);
+
+         png_set_dither(png_ptr, palette, num_palette,
+                        max_screen_colors, histogram, 0);
+      }
+   }
+
+   /* Invert monochrome files to have 0 as white and 1 as black */
+   png_set_invert_mono(png_ptr);
+
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   {
+      png_color_8p sig_bit_p;
+
+      png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
+      png_set_shift(png_ptr, sig_bit_p);
+   }
+
+   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+      png_set_bgr(png_ptr);
+
+   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   png_set_swap_alpha(png_ptr);
+
+   /* Swap bytes of 16 bit files to least significant byte first */
+   png_set_swap(png_ptr);
+
+   /* Add filler (or alpha) byte (before/after each RGB triplet) */
+   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+   /* Turn on interlace handling.  REQUIRED if you are not using
+    * png_read_image().  To see how to handle interlacing passes,
+    * see the png_read_row() method below:
+    */
+   number_passes = png_set_interlace_handling(png_ptr);
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (ie you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* Allocate the memory to hold the image using the fields of info_ptr. */
+
+   /* The easiest way to read the image: */
+   png_bytep row_pointers[height];
+
+   /* Clear the pointer array */
+   for (row = 0; row < height; row++)
+      row_pointers[row] = NULL;
+
+   for (row = 0; row < height; row++)
+      row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
+         info_ptr));
+
+   /* Now it's time to read the image.  One of these methods is REQUIRED */
+#ifdef entire /* Read the entire image in one go */
+   png_read_image(png_ptr, row_pointers);
+
+#else no_entire /* Read the image one or more scanlines at a time */
+   /* The other way to read images - deal with interlacing: */
+
+   for (pass = 0; pass < number_passes; pass++)
+   {
+#ifdef single /* Read the image a single row at a time */
+      for (y = 0; y < height; y++)
+      {
+         png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1);
+      }
+
+#else no_single /* Read the image several rows at a time */
+      for (y = 0; y < height; y += number_of_rows)
+      {
+#ifdef sparkle /* Read the image using the "sparkle" effect. */
+         png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL,
+            number_of_rows);
+#else no_sparkle /* Read the image using the "rectangle" effect */
+         png_read_rows(png_ptr, png_bytepp_NULL, &row_pointers[y],
+            number_of_rows);
+#endif no_sparkle /* Use only one of these two methods */
+      }
+
+      /* If you want to display the image after every pass, do so here */
+#endif no_single /* Use only one of these two methods */
+   }
+#endif no_entire /* Use only one of these two methods */
+
+   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+#endif hilevel
+
+   /* At this point you have read the entire image */
+
+   /* Clean up after the read, and free any memory allocated - REQUIRED */
+   png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+
+   /* Close the file */
+   fclose(fp);
+
+   /* That's it */
+   return (OK);
+}
+
+/* Progressively read a file */
+
+int
+initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
+{
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also check that
+    * the library version is compatible in case we are using dynamically
+    * linked libraries.
+    */
+   *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (*png_ptr == NULL)
+   {
+      *info_ptr = NULL;
+      return (ERROR);
+   }
+
+   *info_ptr = png_create_info_struct(png_ptr);
+
+   if (*info_ptr == NULL)
+   {
+      png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+      return (ERROR);
+   }
+
+   if (setjmp(png_jmpbuf((*png_ptr))))
+   {
+      png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+      return (ERROR);
+   }
+
+   /* This one's new.  You will need to provide all three
+    * function callbacks, even if you aren't using them all.
+    * If you aren't using all functions, you can specify NULL
+    * parameters.  Even when all three functions are NULL,
+    * you need to call png_set_progressive_read_fn().
+    * These functions shouldn't be dependent on global or
+    * static variables if you are decoding several images
+    * simultaneously.  You should store stream specific data
+    * in a separate struct, given as the second parameter,
+    * and retrieve the pointer from inside the callbacks using
+    * the function png_get_progressive_ptr(png_ptr).
+    */
+   png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
+      info_callback, row_callback, end_callback);
+
+   return (OK);
+}
+
+int
+process_data(png_structp *png_ptr, png_infop *info_ptr,
+   png_bytep buffer, png_uint_32 length)
+{
+   if (setjmp(png_jmpbuf((*png_ptr))))
+   {
+      /* Free the png_ptr and info_ptr memory on error */
+      png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+      return (ERROR);
+   }
+
+   /* This one's new also.  Simply give it chunks of data as
+    * they arrive from the data stream (in order, of course).
+    * On segmented machines, don't give it any more than 64K.
+    * The library seems to run fine with sizes of 4K, although
+    * you can give it much less if necessary (I assume you can
+    * give it chunks of 1 byte, but I haven't tried with less
+    * than 256 bytes yet).  When this function returns, you may
+    * want to display any rows that were generated in the row
+    * callback, if you aren't already displaying them there.
+    */
+   png_process_data(*png_ptr, *info_ptr, buffer, length);
+   return (OK);
+}
+
+info_callback(png_structp png_ptr, png_infop info)
+{
+   /* Do any setup here, including setting any of the transformations
+    * mentioned in the Reading PNG files section.  For now, you _must_
+    * call either png_start_read_image() or png_read_update_info()
+    * after all the transformations are set (even if you don't set
+    * any).  You may start getting rows before png_process_data()
+    * returns, so this is your last chance to prepare for that.
+    */
+}
+
+row_callback(png_structp png_ptr, png_bytep new_row,
+   png_uint_32 row_num, int pass)
+{
+   /*
+    * This function is called for every row in the image.  If the
+    * image is interlaced, and you turned on the interlace handler,
+    * this function will be called for every row in every pass.
+    *
+    * In this function you will receive a pointer to new row data from
+    * libpng called new_row that is to replace a corresponding row (of
+    * the same data format) in a buffer allocated by your application.
+    *
+    * The new row data pointer "new_row" may be NULL, indicating there is
+    * no new data to be replaced (in cases of interlace loading).
+    *
+    * If new_row is not NULL then you need to call
+    * png_progressive_combine_row() to replace the corresponding row as
+    * shown below:
+    */
+
+   /* Get pointer to corresponding row in our
+    * PNG read buffer.
+    */
+   png_bytep old_row = ((png_bytep *)our_data)[row_num];
+
+   /* If both rows are allocated then copy the new row
+    * data to the corresponding row data.
+    */
+   if ((old_row != NULL) && (new_row != NULL))
+   png_progressive_combine_row(png_ptr, old_row, new_row);
+
+   /*
+    * The rows and passes are called in order, so you don't really
+    * need the row_num and pass, but I'm supplying them because it
+    * may make your life easier.
+    *
+    * For the non-NULL rows of interlaced images, you must call
+    * png_progressive_combine_row() passing in the new row and the
+    * old row, as demonstrated above.  You can call this function for
+    * NULL rows (it will just return) and for non-interlaced images
+    * (it just does the png_memcpy for you) if it will make the code
+    * easier.  Thus, you can just do this for all cases:
+    */
+
+   png_progressive_combine_row(png_ptr, old_row, new_row);
+
+   /* where old_row is what was displayed for previous rows.  Note
+    * that the first pass (pass == 0 really) will completely cover
+    * the old row, so the rows do not have to be initialized.  After
+    * the first pass (and only for interlaced images), you will have
+    * to pass the current row as new_row, and the function will combine
+    * the old row and the new row.
+    */
+}
+
+end_callback(png_structp png_ptr, png_infop info)
+{
+   /* This function is called when the whole image has been read,
+    * including any chunks after the image (up to and including
+    * the IEND).  You will usually have the same info chunk as you
+    * had in the header, although some data may have been added
+    * to the comments and time fields.
+    *
+    * Most people won't do much here, perhaps setting a flag that
+    * marks the image as finished.
+    */
+}
+
+/* Write a png file */
+void write_png(char *file_name /* , ... other image information ... */)
+{
+   FILE *fp;
+   png_structp png_ptr;
+   png_infop info_ptr;
+   png_colorp palette;
+
+   /* Open the file */
+   fp = fopen(file_name, "wb");
+   if (fp == NULL)
+      return (ERROR);
+
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also check that
+    * the library version is compatible with the one used at compile time,
+    * in case we are using dynamically linked libraries.  REQUIRED.
+    */
+   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+      png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (png_ptr == NULL)
+   {
+      fclose(fp);
+      return (ERROR);
+   }
+
+   /* Allocate/initialize the image information data.  REQUIRED */
+   info_ptr = png_create_info_struct(png_ptr);
+   if (info_ptr == NULL)
+   {
+      fclose(fp);
+      png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
+      return (ERROR);
+   }
+
+   /* Set error handling.  REQUIRED if you aren't supplying your own
+    * error handling functions in the png_create_write_struct() call.
+    */
+   if (setjmp(png_jmpbuf(png_ptr)))
+   {
+      /* If we get here, we had a problem writing the file */
+      fclose(fp);
+      png_destroy_write_struct(&png_ptr, &info_ptr);
+      return (ERROR);
+   }
+
+   /* One of the following I/O initialization functions is REQUIRED */
+
+#ifdef streams /* I/O initialization method 1 */
+   /* Set up the output control if you are using standard C streams */
+   png_init_io(png_ptr, fp);
+
+#else no_streams /* I/O initialization method 2 */
+   /* If you are using replacement write functions, instead of calling
+    * png_init_io() here you would call
+    */
+   png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
+      user_IO_flush_function);
+   /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* Only use one initialization method */
+
+#ifdef hilevel
+   /* This is the easy way.  Use it if you already have all the
+    * image info living in the structure.  You could "|" many
+    * PNG_TRANSFORM flags into the png_transforms integer here.
+    */
+   png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
+
+#else
+   /* This is the hard way */
+
+   /* Set the image information here.  Width and height are up to 2^31,
+    * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
+    * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
+    * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
+    * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
+    * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
+    * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
+    */
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
+      PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+   /* Set the palette if there is one.  REQUIRED for indexed-color images */
+   palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
+             * png_sizeof(png_color));
+   /* ... Set palette colors ... */
+   png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
+   /* You must not free palette here, because png_set_PLTE only makes a link to
+    * the palette that you malloced.  Wait until you are about to destroy
+    * the png structure.
+    */
+
+   /* Optional significant bit (sBIT) chunk */
+   png_color_8 sig_bit;
+   /* If we are dealing with a grayscale image then */
+   sig_bit.gray = true_bit_depth;
+   /* Otherwise, if we are dealing with a color image then */
+   sig_bit.red = true_red_bit_depth;
+   sig_bit.green = true_green_bit_depth;
+   sig_bit.blue = true_blue_bit_depth;
+   /* If the image has an alpha channel then */
+   sig_bit.alpha = true_alpha_bit_depth;
+   png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+
+   /* Optional gamma chunk is strongly suggested if you have any guess
+    * as to the correct gamma of the image.
+    */
+   png_set_gAMA(png_ptr, info_ptr, gamma);
+
+   /* Optionally write comments into the image */
+   text_ptr[0].key = "Title";
+   text_ptr[0].text = "Mona Lisa";
+   text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr[1].key = "Author";
+   text_ptr[1].text = "Leonardo DaVinci";
+   text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr[2].key = "Description";
+   text_ptr[2].text = "<long text>";
+   text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr[0].lang = NULL;
+   text_ptr[1].lang = NULL;
+   text_ptr[2].lang = NULL;
+#endif
+   png_set_text(png_ptr, info_ptr, text_ptr, 3);
+
+   /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
+
+   /* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
+    * on read and, if your application chooses to write them, they must
+    * be written in accordance with the sRGB profile
+    */
+
+   /* Write the file header information.  REQUIRED */
+   png_write_info(png_ptr, info_ptr);
+
+   /* If you want, you can write the info in two steps, in case you need to
+    * write your private chunk ahead of PLTE:
+    *
+    *   png_write_info_before_PLTE(write_ptr, write_info_ptr);
+    *   write_my_chunk();
+    *   png_write_info(png_ptr, info_ptr);
+    *
+    * However, given the level of known- and unknown-chunk support in 1.2.0
+    * and up, this should no longer be necessary.
+    */
+
+   /* Once we write out the header, the compression type on the text
+    * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
+    * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
+    * at the end.
+    */
+
+   /* Set up the transformations you want.  Note that these are
+    * all optional.  Only call them if you want them.
+    */
+
+   /* Invert monochrome pixels */
+   png_set_invert_mono(png_ptr);
+
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   png_set_shift(png_ptr, &sig_bit);
+
+   /* Pack pixels into bytes */
+   png_set_packing(png_ptr);
+
+   /* Swap location of alpha bytes from ARGB to RGBA */
+   png_set_swap_alpha(png_ptr);
+
+   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+    * RGB (4 channels -> 3 channels). The second parameter is not used.
+    */
+   png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+   /* Flip BGR pixels to RGB */
+   png_set_bgr(png_ptr);
+
+   /* Swap bytes of 16-bit files to most significant byte first */
+   png_set_swap(png_ptr);
+
+   /* Swap bits of 1, 2, 4 bit packed pixel formats */
+   png_set_packswap(png_ptr);
+
+   /* Turn on interlace handling if you are not using png_write_image() */
+   if (interlacing)
+      number_passes = png_set_interlace_handling(png_ptr);
+   else
+      number_passes = 1;
+
+   /* The easiest way to write the image (you may have a different memory
+    * layout, however, so choose what fits your needs best).  You need to
+    * use the first method if you aren't handling interlacing yourself.
+    */
+   png_uint_32 k, height, width;
+   png_byte image[height][width*bytes_per_pixel];
+   png_bytep row_pointers[height];
+
+   if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+     png_error (png_ptr, "Image is too tall to process in memory");
+
+   for (k = 0; k < height; k++)
+     row_pointers[k] = image + k*width*bytes_per_pixel;
+
+   /* One of the following output methods is REQUIRED */
+
+#ifdef entire /* Write out the entire image data in one call */
+   png_write_image(png_ptr, row_pointers);
+
+   /* The other way to write the image - deal with interlacing */
+
+#else no_entire /* Write out the image data by one or more scanlines */
+
+   /* The number of passes is either 1 for non-interlaced images,
+    * or 7 for interlaced images.
+    */
+   for (pass = 0; pass < number_passes; pass++)
+   {
+      /* Write a few rows at a time. */
+      png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
+
+      /* If you are only writing one row at a time, this works */
+      for (y = 0; y < height; y++)
+         png_write_rows(png_ptr, &row_pointers[y], 1);
+   }
+#endif no_entire /* Use only one output method */
+
+   /* You can write optional chunks like tEXt, zTXt, and tIME at the end
+    * as well.  Shouldn't be necessary in 1.2.0 and up as all the public
+    * chunks are supported and you can use png_set_unknown_chunks() to
+    * register unknown chunks into the info structure to be written out.
+    */
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+#endif hilevel
+
+   /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
+    * as recommended in versions 1.0.5m and earlier of this example; if
+    * libpng mallocs info_ptr->palette, libpng will free it).  If you
+    * allocated it with malloc() instead of png_malloc(), use free() instead
+    * of png_free().
+    */
+   png_free(png_ptr, palette);
+   palette = NULL;
+
+   /* Similarly, if you png_malloced any data that you passed in with
+    * png_set_something(), such as a hist or trans array, free it here,
+    * when you can be sure that libpng is through with it.
+    */
+   png_free(png_ptr, trans);
+   trans = NULL;
+   /* Whenever you use png_free() it is a good idea to set the pointer to
+    * NULL in case your application inadvertently tries to png_free() it
+    * again.  When png_free() sees a NULL it returns without action, thus
+    * avoiding the double-free security problem.
+    */
+
+   /* Clean up after the write, and free any memory allocated */
+   png_destroy_write_struct(&png_ptr, &info_ptr);
+
+   /* Close the file */
+   fclose(fp);
+
+   /* That's it */
+   return (OK);
+}
+
+#endif /* if 0 */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.3
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4490 @@
+.TH LIBPNG 3 "June 26, 2010"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.44
+.SH SYNOPSIS
+\fI\fB
+
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fB#if \fI!defined(PNG_1_0_X)
+
+\fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB#endif
+
+\fI\fB
+
+\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)
+
+\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP
+
+\fI\fB
+
+\fB#if \fI!defined(PNG_1_0_X)
+
+\fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_uint_31 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB#endif
+
+\fI\fB
+
+\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_user_height_max( png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_user_width_max (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fB#if \fI!defined(PNG_1_0_X)
+
+\fBpng_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
+
+\fI\fB#endif
+
+\fI\fB
+
+\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_expand_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
+
+\fI\fB
+
+.SH DESCRIPTION
+The
+.I libpng
+library supports encoding, decoding, and various manipulations of
+the Portable Network Graphics (PNG) format image files.  It uses the
+.IR zlib(3)
+compression library.
+Following is a copy of the libpng.txt file that accompanies libpng.
+.SH LIBPNG.TXT
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.44 - June 26, 2010
+ Updated and distributed by Glenn Randers-Pehrson
+ <glennrp at users.sourceforge.net>
+ Copyright (c) 1998-2009 Glenn Randers-Pehrson
+
+ This document is released under the libpng license.
+ For conditions of distribution and use, see the disclaimer
+ and license in png.h
+
+ Based on:
+
+ libpng versions 0.97, January 1998, through 1.2.44 - June 26, 2010
+ Updated and distributed by Glenn Randers-Pehrson
+ Copyright (c) 1998-2009 Glenn Randers-Pehrson
+
+ libpng 1.0 beta 6  version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+.SH I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use.  There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms.  In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need.  We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+For examples of libpng usage, see the files "example.c", "pngtest.c",
+and the files in the "contrib" directory, all of which are included in
+the libpng distribution.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG specification (second edition), November 2003, is available as
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+<http://www.w3.org/TR/2003/REC-PNG-20031110/
+The W3C and ISO documents have identical technical content.
+
+The PNG-1.2 specification is available at
+<http://www.libpng.org/pub/png/documents/>.  It is technically equivalent
+to the PNG specification (second edition) but has some additional material.
+
+The PNG-1.0 specification is available
+as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>.
+
+Some additional chunks are described in the special-purpose public chunks
+documents at <http://www.libpng.org/pub/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more.  All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C.  Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use.  The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible.  While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually find the source files for the zlib utility wherever you
+find the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures.  Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure.
+
+.SH II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info.  The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file.  At one time, the fields of png_info were intended to be
+directly accessible to the user.  However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+.SH III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+.SS Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo.  Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file.  Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 (false) if the bytes match the
+corresponding bytes of the PNG signature, or nonzero (true) otherwise.
+Of course, the more bytes you pass in, the greater the accuracy of the
+prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning.  Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to replace them with custom functions.  See the discussion under
+Customizing libpng.
+
+
+    FILE *fp = fopen(file_name, "rb");
+    if (!fp)
+    {
+        return (ERROR);
+    }
+    fread(header, 1, number, fp);
+    is_png = !png_sig_cmp(header, 0, number);
+    if (!is_png)
+    {
+        return (NOT_PNG);
+    }
+
+
+Next, png_struct and png_info need to be allocated and initialized.  In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures.  We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used).  See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+    png_structp png_ptr = png_create_read_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr,
+           (png_infopp)NULL, (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+          (png_infopp)NULL);
+        return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+    png_structp png_ptr = png_create_read_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine.  Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr).  If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           &end_info);
+        fclose(fp);
+        return (ERROR);
+    }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code.  The default for libpng is to
+use the C function fread().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+    png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+    png_set_sig_bytes(png_ptr, number);
+
+.SS Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data, along with similar data for any other
+          unknown chunks: */
+
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+
+       /* Note that libpng has already taken care of
+          the CRC handling */
+
+       /* put your code here.  Search for your chunk in the
+          unknown chunk structure, process it, and return one
+          of the following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
+If you call the png_set_read_user_chunk_fn() function, then all unknown
+chunks will be saved when read, in case your callback function will need
+one or more of them.  This behavior can be changed with the
+png_set_keep_unknown_chunks() function, described below.
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void read_row_callback(png_ptr ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_status_fn(png_ptr, read_row_callback);
+
+.SS Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members while unknown chunks will be discarded. This
+behavior can be wasteful if your application will never use some known
+chunk types. To change this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: default unknown chunk handling
+                 1: ignore; do not keep
+                 2: keep only if safe-to-copy
+                 3: keep even if unsafe-to-copy
+               You can use these definitions:
+                 PNG_HANDLE_CHUNK_AS_DEFAULT   0
+                 PNG_HANDLE_CHUNK_NEVER        1
+                 PNG_HANDLE_CHUNK_IF_SAFE      2
+                 PNG_HANDLE_CHUNK_ALWAYS       3
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected.  If nonzero,
+                 only the chunks in the list are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.  The IHDR and IEND chunks should not be named in
+chunk_list; if they are, libpng will process them normally anyway.
+
+Here is an example of the usage of png_set_keep_unknown_chunks(),
+where the private "vpAg" chunk will later be processed by a user chunk
+callback function:
+
+    png_byte vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
+
+    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+      png_byte unused_chunks[]=
+      {
+        104,  73,  83,  84, (png_byte) '\0',   /* hIST */
+        105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
+        112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
+        115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
+        115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
+        116,  73,  77,  69, (png_byte) '\0',   /* tIME */
+      };
+    #endif
+
+    ...
+
+    #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+      /* ignore all unknown chunks: */
+      png_set_keep_unknown_chunks(read_ptr, 1, NULL, 0);
+      /* except for vpAg: */
+      png_set_keep_unknown_chunks(read_ptr, 2, vpAg, 1);
+      /* also ignore unused known chunks: */
+      png_set_keep_unknown_chunks(read_ptr, 1, unused_chunks,
+         (int)sizeof(unused_chunks)/5);
+    #endif
+
+.SS User limits
+
+The PNG specification allows the width and height of an image to be as
+large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
+Since very few applications really need to process such large images,
+we have imposed an arbitrary 1-million limit on rows and columns.
+Larger images will be rejected immediately with a png_error() call. If
+you wish to override this limit, you can use
+
+   png_set_user_limits(png_ptr, width_max, height_max);
+
+to set your own limits, or use width_max = height_max = 0x7fffffffL
+to allow all valid dimensions (libpng may reject some very large images
+anyway because of potential buffer overflow conditions).
+
+You should put this statement after you create the PNG structure and
+before calling png_read_info(), png_read_png(), or png_process_data().
+If you need to retrieve the limits that are being applied, use
+
+   width_max = png_get_user_width_max(png_ptr);
+   height_max = png_get_user_height_max(png_ptr);
+
+The PNG specification sets no limit on the number of ancillary chunks
+allowed in a PNG datastream.  You can impose a limit on the total number
+of sPLT, tEXt, iTXt, zTXt, and unknown chunks that will be stored, with
+
+   png_set_chunk_cache_max(png_ptr, user_chunk_cache_max);
+
+where 0x7fffffffL means unlimited.  You can retrieve this limit with
+
+   chunk_cache_max = png_get_chunk_cache_max(png_ptr);
+
+This limit also applies to the number of buffers that can be allocated
+by png_decompress_chunk() while decompressing iTXt, zTXt, and iCCP chunks.
+
+.SS The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
+                                8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
+                                samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_GRAY_TO_RGB   Expand grayscale samples
+                                to RGB (or GA to RGBA)
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the bitwise OR of some
+set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_read_png().
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+   row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+   png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+      png_error (png_ptr,
+         "Image is too tall to process in memory");
+   if (width > PNG_UINT_32_MAX/pixel_size)
+      png_error (png_ptr,
+         "Image is too wide to process in memory");
+   row_pointers = png_malloc(png_ptr,
+      height*png_sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=NULL;  /* security precaution */
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr,
+         width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+.SS The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
+
+    png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+.SS Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height,
+       &bit_depth, &color_type, &interlace_type,
+       &compression_type, &filter_method);
+
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.  (valid values are
+                     1, 2, 4, 8, 16 and depend also on
+                     the color_type.  See also
+                     significant bits (sBIT) below).
+    color_type     - describes which color/alpha channels
+                         are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
+    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+                     for PNG 1.0)
+    interlace_type - (PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7)
+
+    Any or all of interlace_type, compression_type, or
+    filter_method can be NULL if you are
+    not interested in their values.
+
+    Note that png_get_IHDR() returns 32-bit data into
+    the application's width and height variables.
+    This is an unsafe situation if these are 16-bit
+    variables.  In such situations, the
+    png_get_image_width() and png_get_image_height()
+    functions described below are safer.
+
+    width            = png_get_image_width(png_ptr,
+                         info_ptr);
+    height           = png_get_image_height(png_ptr,
+                         info_ptr);
+    bit_depth        = png_get_bit_depth(png_ptr,
+                         info_ptr);
+    color_type       = png_get_color_type(png_ptr,
+                         info_ptr);
+    filter_method    = png_get_filter_type(png_ptr,
+                         info_ptr);
+    compression_type = png_get_compression_type(png_ptr,
+                         info_ptr);
+    interlace_type   = png_get_interlace_type(png_ptr,
+                         info_ptr);
+
+    channels = png_get_channels(png_ptr, info_ptr);
+    channels       - number of channels of info for the
+                     color type (valid values are 1 (GRAY,
+                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+                     4 (RGB_ALPHA or RGB + filler byte))
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    rowbytes       - number of bytes needed to hold a row
+
+    signature = png_get_signature(png_ptr, info_ptr);
+    signature      - holds the signature read from the
+                     file (if any).  The data is kept in
+                     the same offset it would be if the
+                     whole signature were read (i.e. if an
+                     application had already read in 4
+                     bytes of signature before starting
+                     libpng, the remaining 4 bytes would
+                     be in signature[4] through signature[7]
+                     (see png_set_sig_bytes())).
+
+These are also important, but their validity depends on whether the chunk
+has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing.  The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a
+pointer into the info_ptr is returned for any complex types.
+
+    png_get_PLTE(png_ptr, info_ptr, &palette,
+                     &num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_get_gAMA(png_ptr, info_ptr, &gamma);
+    gamma          - the gamma the file is written
+                     at (PNG_INFO_gAMA)
+
+    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
+                     The presence of the sRGB chunk
+                     means that the pixel data is in the
+                     sRGB color space.  This chunk also
+                     implies specific values of gAMA and
+                     cHRM.
+
+    png_get_iCCP(png_ptr, info_ptr, &name,
+       &compression_type, &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray,
+                     red, green, and blue channels,
+                     whichever are appropriate for the
+                     given color type (png_color_16)
+
+    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+                     &trans_values);
+    trans          - array of transparent
+                     entries for palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_get_hIST(png_ptr, info_ptr, &hist);
+                     (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_get_tIME(png_ptr, info_ptr, &mod_time);
+    mod_time       - time image was last modified
+                    (PNG_VALID_tIME)
+
+    png_get_bKGD(png_ptr, info_ptr, &background);
+    background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
+
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].lang_key  - keyword in UTF-8
+                         (empty string for unknown).
+    Note that the itxt_length, lang, and lang_key
+    members of the text_ptr structure only exist
+    when the library is built with iTXt chunk support.
+
+    num_text       - number of comments (same as
+                     num_comments; you can put NULL here
+                     to avoid the duplication)
+    Note while png_set_text() will accept text, language,
+    and translated keywords that can be NULL pointers, the
+    structure returned by png_get_text will always contain
+    regular zero-terminated C strings.  They might be
+    empty strings but they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+       &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks
+                     read.
+    num_spalettes  - number of sPLT chunks read.
+
+    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+       &unit_type);
+    offset_x       - positive offset from the left edge
+                     of the screen
+    offset_y       - positive offset from the top edge
+                     of the screen
+    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+       &unit_type);
+    res_x          - pixels/unit physical resolution in
+                     x direction
+    res_y          - pixels/unit physical resolution in
+                     x direction
+    unit_type      - PNG_RESOLUTION_UNKNOWN,
+                     PNG_RESOLUTION_METER
+
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+       info_ptr, &unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the
+    chunks were read from the PNG file or inserted with the
+    png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+    res_x = png_get_x_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+       info_ptr)
+    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+       info_ptr)
+
+   (Each of these returns 0 [signifying "unknown"] if
+       the data is not present or if res_x is 0;
+       res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the
+       chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents.  Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text.  PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size.  While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings.  It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations.  Non-printing
+symbols are not allowed.  See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword.  It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+.SS Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data.  They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data.  The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called.  8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()
+is called to insert filler bytes, either before or after each RGB triplet.
+16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant
+byte of the color value first, unless png_set_strip_16() is called to
+transform it to regular RGB RGB triplets, or png_set_filler() or
+png_set_add alpha() is called to insert filler bytes, either before or
+after each RRGGBB triplet.  Similarly, 8-bit or 16-bit grayscale data can
+be modified with
+png_set_filler(), png_set_add_alpha(), or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk.  This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
+
+    if (color_type == PNG_COLOR_TYPE_GRAY &&
+        bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
+
+    if (png_get_valid(png_ptr, info_ptr,
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
+
+As of libpng version 1.2.9, png_set_expand_gray_1_2_4_to_8() was
+added.  It expands the sample depth without changing tRNS to alpha.
+
+As of libpng version 1.2.44, not all possible expansions are supported.
+
+In the following table, the 01 means grayscale with depth<8, 31 means
+indexed with depth<8, other numerals represent the color type, "T" means
+the tRNS chunk is present, A means an alpha channel is present, and O
+means tRNS or alpha is present but all pixels in the image are opaque.
+
+  FROM  01  31   0  0T  0O   2  2T  2O   3  3T  3O  4A  4O  6A  6O 
+   TO
+   01    -                   
+   31        -
+    0    1       -           
+   0T                -
+   0O                    -
+    2           GX           -
+   2T                            -
+   2O                                -
+    3        1                           -
+   3T                                        -
+   3O                                            -
+   4A                T                               -
+   4O                                                    -
+   6A               GX         TX           TX               -
+   6O                   GX                      TX               -
+
+Within the matrix,
+     "-" means the transformation is not supported.
+     "X" means the transformation is obtained by png_set_expand().
+     "1" means the transformation is obtained by
+         png_set_expand_gray_1_2_4_to_8
+     "G" means the transformation is obtained by
+         png_set_gray_to_rgb().
+     "P" means the transformation is obtained by
+         png_set_expand_palette_to_rgb().
+     "T" means the transformation is obtained by
+         png_set_tRNS_to_alpha().
+
+PNG can have files with 16 bits per channel.  If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+    if (bit_depth == 16)
+        png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+        png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
+The PNG format only supports pixels with postmultiplied alpha.
+If you want to replace the pixels, after reading them, with pixels
+that have premultiplied color samples, you can do this with
+
+    png_set_premultiply_alpha(png_ptr);
+
+If you do this, any input with a tRNS chunk will be expanded to
+have an alpha channel.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files.  This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31]
+to 8 bits/sample in the range [0, 255]).  However, it is also possible
+to convert the PNG pixel data back to the original bit depth of the
+image.  This call reduces the pixels back down to the original bit depth:
+
+    png_color_8p sig_bit;
+
+    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+        png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order.  This code
+changes the storage of the pixels to blue, green, red:
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+    if (color_type == PNG_COLOR_TYPE_RGB)
+        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after.  This transformation
+does not affect images that already have full alpha channels.  To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+Note that png_set_filler() does not change the color type.  If you want
+to do that, you can add a true alpha channel with
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+           color_type == PNG_COLOR_TYPE_GRAY)
+    png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
+
+where "filler" contains the alpha value to assign to each pixel.
+This function was added in libpng-1.2.7.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB.  This code will do that conversion:
+
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+          png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
+
+    error_action = 1: silently do the conversion
+    error_action = 2: issue a warning if the original
+                      image has any pixel where
+                      red != green or red != blue
+    error_action = 3: issue an error and abort the
+                      conversion if the original
+                      image has any pixel where
+                      red != green or red != blue
+
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels.  bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton <poynton at inforamp.net>
+
+    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+
+which can be expressed with integers as
+
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0).  Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+    png_color_16 my_background;
+    png_color_16p image_background;
+
+    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+        png_set_background(png_ptr, image_background,
+          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+        png_set_background(png_ptr, &my_background,
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is.  Ideally, the user will know this, and
+the application will allow them to set it.  One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
+
+   if (/* We have a user-defined screen
+       gamma value */)
+   {
+      screen_gamma = user_defined_screen_gamma;
+   }
+   /* One way that applications can share the same
+      screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA"))
+      != NULL)
+   {
+      screen_gamma = (double)atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2; /* A good guess for a
+           PC monitor in a bright office or a dim room */
+      screen_gamma = 2.0; /* A good guess for a
+           PC monitor in a dark room */
+      screen_gamma = 1.7 or 1.0;  /* A good
+           guess for Mac systems */
+   }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma.  If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs).  Note
+that file gammas are inverted from screen gammas.  See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it.  It is strongly
+recommended that PNG viewers support gamma correction.
+
+   if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+      png_set_gamma(png_ptr, screen_gamma, gamma);
+   else
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that.  Note that this is a simple match dither that merely
+finds the closest color available.  This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes.  If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors.  If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette.  If there is no
+histogram, it may not do as good a job.
+
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      if (png_get_valid(png_ptr, info_ptr,
+         PNG_INFO_PLTE))
+      {
+         png_uint_16p histogram = NULL;
+
+         png_get_hIST(png_ptr, info_ptr,
+            &histogram);
+         png_set_dither(png_ptr, palette, num_palette,
+            max_screen_colors, histogram, 1);
+      }
+      else
+      {
+         png_color std_color_cube[MAX_SCREEN_COLORS] =
+            { ... colors ... };
+
+         png_set_dither(png_ptr, std_color_cube,
+            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+            NULL,0);
+      }
+   }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+      png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+   if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+    if (bit_depth == 16)
+        png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+    number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call.  This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory.  This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+    png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image.  The row data is simply
+raw byte data for all forms of images.  As the actual allocation
+varies among applications, no example will be given.  If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+.SS Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call.  If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied.  You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+   png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+   png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead.  If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that.  The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read.  The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read.  The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images.  Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0).  The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0).  The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0).  The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines.  Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+    if (interlace_type == PNG_INTERLACE_ADAM7)
+        number_of_passes
+           = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect.  This effect is faster and the end result of either method
+is exactly the same.  If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL.  Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls.  You can change the locations of the data, just
+not the data.  Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+    png_read_rows(png_ptr, NULL, row_pointers,
+       number_of_rows);
+
+.SS Finishing a sequential read
+
+After you are finished reading the image through the
+low-level interface, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
+
+   png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+   png_destroy_read_struct(&png_ptr, &info_ptr,
+       &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask - identifies data to be freed, a mask
+           containing the bitwise OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    seq  - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those cases do nothing.
+The "seq" parameter is ignored if only one item of the selected data
+type, such as PLTE, is allowed.  If "seq" is not -1, and multiple items
+are allowed for the data type identified in the mask, such as text or
+sPLT, only the n'th item in the structure is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by
+your application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the bitwise OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+.SS Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader.  Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image.  You
+set up these callbacks with png_set_progressive_read_fn().  You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data().  I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /*  An example code fragment of how you would
+     initialize the progressive reader in your
+     application. */
+ int
+ initialize_png_reader()
+ {
+    png_ptr = png_create_read_struct
+        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+         user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+    info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new.  You can provide functions
+       to be called when the header info is valid,
+       when each row is completed, and when the image
+       is finished.  If you aren't using all functions,
+       you can specify NULL parameters.  Even when all
+       three functions are NULL, you need to call
+       png_set_progressive_read_fn().  You can use
+       any struct as the user_ptr (cast to a void pointer
+       for the function call), and retrieve the pointer
+       from inside the callbacks using the function
+
+          png_get_progressive_ptr(png_ptr);
+
+       which will return a void pointer, which you have
+       to cast appropriately.
+     */
+    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+        info_callback, row_callback, end_callback);
+
+    return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+   of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new also.  Simply give it a chunk
+       of data from the file stream (in order, of
+       course).  On machines with segmented memory
+       models machines, don't give it any more than
+       64K.  The library seems to run fine with sizes
+       of 4K. Although you can give it much less if
+       necessary (I assume you can give it chunks of
+       1 byte, I haven't tried less then 256 bytes
+       yet).  When this function returns, you may
+       want to display any rows that were generated
+       in the row callback if you don't already do
+       so there.
+     */
+    png_process_data(png_ptr, info_ptr, buffer, length);
+    return 0;
+ }
+
+ /* This function is called (as set by
+    png_set_progressive_read_fn() above) when enough data
+    has been supplied so all of the header has been
+    read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+    /* Do any setup here, including setting any of
+       the transformations mentioned in the Reading
+       PNG files section.  For now, you _must_ call
+       either png_start_read_image() or
+       png_read_update_info() after all the
+       transformations are set (even if you don't set
+       any).  You may start getting rows before
+       png_process_data() returns, so this is your
+       last chance to prepare for that.
+     */
+ }
+
+ /* This function is called when each row of image
+    data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+    png_uint_32 row_num, int pass)
+ {
+    /* If the image is interlaced, and you turned
+       on the interlace handler, this function will
+       be called for every row in every pass.  Some
+       of these rows will not be changed from the
+       previous pass.  When the row is not changed,
+       the new_row variable will be NULL.  The rows
+       and passes are called in order, so you don't
+       really need the row_num and pass, but I'm
+       supplying them because it may make your life
+       easier.
+
+       For the non-NULL rows of interlaced images,
+       you must call png_progressive_combine_row()
+       passing in the row and the old row.  You can
+       call this function for NULL rows (it will just
+       return) and for non-interlaced images (it just
+       does the memcpy for you) if it will make the
+       code easier.  Thus, you can just do this for
+       all cases:
+     */
+
+        png_progressive_combine_row(png_ptr, old_row,
+          new_row);
+
+    /* where old_row is what was displayed for
+       previously for the row.  Note that the first
+       pass (pass == 0, really) will completely cover
+       the old row, so the rows do not have to be
+       initialized.  After the first pass (and only
+       for interlaced images), you will have to pass
+       the current row, and the function will combine
+       the old row and the new row.
+    */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+    /* This function is called after the whole image
+       has been read, including any chunks after the
+       image (up to and including the IEND).  You
+       will usually have the same info chunk as you
+       had in the header, although some data may have
+       been added to the comments and time fields.
+
+       Most people won't do much here, perhaps setting
+       a flag that marks the image as finished.
+     */
+ }
+
+
+
+.SH IV. Writing
+
+Much of this is very similar to reading.  However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+.SS Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to replace them with
+custom writing functions.  See the discussion under Customizing libpng.
+
+    FILE *fp = fopen(file_name, "wb");
+    if (!fp)
+    {
+       return (ERROR);
+    }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare.  Of course, you
+will want to check if they return NULL.  If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr".  Look at pngtest.c, for example.
+
+    png_structp png_ptr = png_create_write_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+       return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       png_destroy_write_struct(&png_ptr,
+         (png_infopp)NULL);
+       return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+    png_structp png_ptr = png_create_write_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling.  When libpng encounters an error, it expects to
+longjmp() back to your routine.  Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp.  See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
+    }
+    ...
+    return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code.  The default for libpng is to
+use the C function fwrite().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+    png_init_io(png_ptr, fp);
+
+If you are embedding your PNG into a datastream such as MNG, and don't
+want libpng to write the 8-byte signature, or if you have already
+written the signature in your application, use
+
+    png_set_sig_bytes(png_ptr, 8);
+
+to inform libpng that it should not write a signature.
+
+.SS Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void write_row_callback(png_ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run.  The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing.  If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific
+filter types.
+
+
+    /* turn on or off filtering, and/or choose
+       specific filters.  You can use either a single
+       PNG_FILTER_VALUE_NAME or the bitwise OR of one
+       or more PNG_FILTER_NAME masks. */
+    png_set_filter(png_ptr, 0,
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing.  The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+    /* set the zlib compression level */
+    png_set_compression_level(png_ptr,
+        Z_BEST_COMPRESSION);
+
+    /* set other zlib parameters */
+    png_set_compression_mem_level(png_ptr, 8);
+    png_set_compression_strategy(png_ptr,
+        Z_DEFAULT_STRATEGY);
+    png_set_compression_window_bits(png_ptr, 15);
+    png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+.SS Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image.  Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
+the latest PNG specification for more information on that.  If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid.  If you want to wait until after the data, don't
+fill them until png_write_end().  For all the fields in png_info and
+their data types, see png.h.  For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+       bit_depth, color_type, interlace_type,
+       compression_type, filter_method)
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.
+                     (valid values are 1, 2, 4, 8, 16
+                     and depend also on the
+                     color_type.  See also significant
+                     bits (sBIT) below).
+    color_type     - describes which color/alpha
+                     channels are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    interlace_type - PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7
+    compression_type - (must be
+                     PNG_COMPRESSION_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
+
+If you call png_set_IHDR(), the call must appear before any of the
+other png_set_*() functions, because they might require access to some of
+the IHDR settings.  The remaining png_set_*() functions can be called
+in any order.
+
+If you wish, you can reset the compression_type, interlace_type, or
+filter_method later by calling png_set_IHDR() again; if you do this, the
+width, height, bit_depth, and color_type must be the same in each call.
+
+    png_set_PLTE(png_ptr, info_ptr, palette,
+       num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_set_gAMA(png_ptr, info_ptr, gamma);
+    gamma          - the gamma the image was created
+                     at (PNG_INFO_gAMA)
+
+    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of
+                     the sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This chunk also implies specific
+                     values of gAMA and cHRM.  Rendering
+                     intent is the CSS-1 property that
+                     has been defined by the International
+                     Color Consortium
+                     (http://www.color.org).
+                     It can be one of
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
+
+
+    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+       srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of the
+                     sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This function also causes gAMA and
+                     cHRM chunks with the specific values
+                     that are consistent with sRGB to be
+                     written.
+
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_set_sBIT(png_ptr, info_ptr, sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray, red,
+                     green, and blue channels, whichever are
+                     appropriate for the given color type
+                     (png_color_16)
+
+    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+       trans_values);
+    trans          - array of transparent
+                     entries for palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values
+                     (in order red, green, blue) of the
+                     single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_set_hIST(png_ptr, info_ptr, hist);
+                    (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_set_tIME(png_ptr, info_ptr, mod_time);
+    mod_time       - time image was last modified
+                     (PNG_VALID_tIME)
+
+    png_set_bKGD(png_ptr, info_ptr, background);
+    background     - background color (PNG_VALID_bKGD)
+
+    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    Note that the itxt_length, lang, and lang_key
+    members of the text_ptr structure only exist
+    when the library is built with iTXt chunk support.
+
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+       num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures
+                     to be added to the list of palettes
+                     in the info structure.
+    num_spalettes  - number of palette structures to be
+                     added.
+
+    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+        unit_type);
+    offset_x  - positive offset from the left
+                     edge of the screen
+    offset_y  - positive offset from the top
+                     edge of the screen
+    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+        unit_type);
+    res_x       - pixels/unit physical resolution
+                  in x direction
+    res_y       - pixels/unit physical resolution
+                  in y direction
+    unit_type   - PNG_RESOLUTION_UNKNOWN,
+                  PNG_RESOLUTION_METER
+
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+       num_unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c.  Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text.  text is an array of png_text
+structures.  num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data.  Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed.  So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+    Title            Short (one line) title or
+                     caption for image
+    Author           Name of image's creator
+    Description      Description of image (possibly long)
+    Copyright        Copyright notice
+    Creation Time    Time of original image creation
+                     (usually RFC 1123 format, see below)
+    Software         Software used to create the image
+    Disclaimer       Legal disclaimer
+    Warning          Warning of nature of content
+    Source           Device used to create the image
+    Comment          Miscellaneous comment; conversion
+                     from other image format
+
+The keyword-text pairs work like this.  Keywords should be short
+simple descriptions of what the comment is about.  Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords.  You can repeat keywords in a file.  You can even write
+some text before the image and some after.  For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image.  Finally, keywords should be full
+words, not abbreviations.  Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters.  To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set.  The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure.  Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm.  The
+time_t routine uses gmtime().  You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time.  Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword.  This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself.  In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement.  Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software.  To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+.SS Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+.SS The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER        Strip out filler
+                                      bytes (deprecated).
+    PNG_TRANSFORM_STRIP_FILLER_BEFORE Strip out leading
+                                      filler bytes
+    PNG_TRANSFORM_STRIP_FILLER_AFTER  Strip out trailing
+                                      filler bytes
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the bitwise OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_write_png().
+
+.SS The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of transparency,
+you can invert the alpha channel before you write it, so that 0 is
+fully transparent and 255 (in 8-bit or paletted images) or 65535
+(in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
+    png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+    png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+    /* Set the true bit depth of the image data */
+    if (color_type & PNG_COLOR_MASK_COLOR)
+    {
+        sig_bit.red = true_bit_depth;
+        sig_bit.green = true_bit_depth;
+        sig_bit.blue = true_bit_depth;
+    }
+    else
+    {
+        sig_bit.gray = true_bit_depth;
+    }
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+    {
+        sig_bit.alpha = true_bit_depth;
+    }
+
+    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+    png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+    if (bit_depth > 8)
+       png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order.  This code
+would be used if they are supplied as blue, green, red:
+
+    png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+    png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_write_user_transform_fn(png_ptr,
+       write_transform_fn);
+
+You must supply the function
+
+    void write_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written.  To
+flush the output stream a single time call:
+
+    png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+    png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications).  Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+.SS Writing the image data
+
+That's it for the transformations.  Now you can write the image data.
+The simplest way to do this is in one function call.  If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image.  You will need to pass in an array of pointers to
+each row.  This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+    png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+    png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead.  If the file is not interlaced,
+this is simple:
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+
+    png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more complicated.
+The only currently (as of the PNG Specification version 1.2, dated July
+1999) defined interlacing scheme for PNG files is the "Adam7" interlace
+scheme, that breaks down an image into seven smaller images of varying
+size.  libpng will build these images for you, or you can do them
+yourself.  If you want to build them yourself, see the PNG specification
+for details of which pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+    number_of_passes =
+       png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this is seven,
+but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+As some of these rows are not used, and thus return immediately, you may
+want to read about interlacing in the PNG specification, and only update
+the rows that are actually used.
+
+.SS Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file.  If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer.  If you are not interested,
+you can pass NULL.
+
+    png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask  - identifies data to be freed, a mask
+            containing the bitwise OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    seq   - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those cases do nothing.
+The "seq" parameter is ignored if only one item of the selected data
+type, such as PLTE, is allowed.  If "seq" is not -1, and multiple items
+are allowed for the data type identified in the mask, such as text or
+sPLT, only the n'th item in the structure is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed in to libpng
+with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+.SH V. Modifying/Customizing libpng:
+
+There are two issues here.  The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc(), png_calloc(),
+and png_free().  These currently just call the standard C functions.
+png_calloc() calls png_malloc() and then png_memset() to clear the newly
+allocated memory to zero.  If your pointers can't access more then 64K
+at a time, you will want to set MAXSEG_64K in zlib.h.  Since it is
+unlikely that the method of handling memory allocation on a platform
+will change between applications, these functions must be modified in
+the library at compile time.  If you prefer to use a different method
+of allocating and freeing data, you can use png_create_read_struct_2() or
+png_create_write_struct_2() to register your own functions as described
+above.  These functions also provide a void pointer that can be retrieved
+via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr,
+       png_size_t size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() must return NULL in case of failure.  The png_malloc()
+function will normally call png_error() if it receives a NULL from the
+system memory allocator or from your replacement malloc_fn().
+
+Your free_fn() will never be called with a NULL ptr, since libpng's
+png_free() checks for NULL before calling free_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite().  The FILE * is stored in
+png_struct and is initialized via png_init_io().  If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function.  These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr().  For example:
+
+    png_set_read_fn(png_structp read_ptr,
+        voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+    png_set_write_fn(png_structp write_ptr,
+        voidp write_io_ptr, png_rw_ptr write_data_fn,
+        png_flush_ptr output_flush_fn);
+
+    voidp read_io_ptr = png_get_io_ptr(read_ptr);
+    voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The replacement I/O functions must have prototypes as follows:
+
+    void user_read_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_write_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_flush_data(png_structp png_ptr);
+
+The user_read_data() function is responsible for detecting and
+handling end-of-data errors.
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions, which expect the io_ptr to
+point to a standard *FILE structure.  It is probably a mistake
+to use NULL for one of write_data_fn and output_flush_fn but not both
+of them, unless you have built libpng with PNG_NO_WRITE_FLUSH defined.
+It is an error to read from a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller.  Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
+
+    png_set_error_fn(png_structp png_ptr,
+        png_voidp error_ptr, png_error_ptr error_fn,
+        png_error_ptr warning_fn);
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered.  The replacement error functions should have
+parameters as follows:
+
+    void user_error_fn(png_structp png_ptr,
+        png_const_charp error_msg);
+    void user_warning_fn(png_structp png_ptr,
+        png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods.  This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything
+after setjmp returns non-zero besides returning itself.  Consult your
+compiler documentation for more details.  For an alternative approach, you
+may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+.SS Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  However, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of understanding of how it works.
+Pay particular attention to the sections that describe chunk names,
+and look at how other chunks were designed, so you can do things
+similarly.  Second, check out the sections of libpng that read and
+write chunks.  Try to find a chunk that is similar to yours and use
+it as a template.  More details can be found in the comments inside
+the code.  It is best to handle unknown chunks in a generic method,
+via callback functions, instead of by modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work.  Try to find a similar
+transformation to the one you want to add and copy off of it.  More details
+can be found in the comments inside the code itself.
+
+.SS Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+.SS Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+.SS Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+.SS Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn().  On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+.SS Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add, change
+or delete an include, this is the place to do it.
+The includes that are not needed outside libpng are protected by the
+PNG_INTERNAL definition, which is only defined for those routines inside
+libpng itself.  The files in libpng proper only include png.h, which
+includes pngconf.h.
+
+.SS Configuring zlib:
+
+There are special functions to configure the compression.  Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9.  The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster.  For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap.  You can specify the
+compression level by calling:
+
+    png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+    png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib.  They are not recommended
+for normal use and may result in writing an invalid PNG file.  See
+zlib.h for more information on what these mean.
+
+    png_set_compression_strategy(png_ptr,
+        strategy);
+    png_set_compression_window_bits(png_ptr,
+        window_bits);
+    png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
+
+.SS Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions.  The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image.  Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification.  The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types.  (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+              PNG_FILTER_UP | PNG_FILTER_AVG |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+       filters);
+              The second parameter can also be
+              PNG_INTRAPIXEL_DIFFERENCING if you are
+              writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the
+              same as the value of filter_method used
+              in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters.  This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+    double weights[3] = {1.5, 1.3, 1.1},
+       costs[PNG_FILTER_VALUE_LAST] =
+       {1.0, 1.3, 1.3, 1.5, 1.7};
+
+    png_set_filter_heuristics(png_ptr,
+       PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+       weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter.  In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen.  Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters.  This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage.  Little testing has
+been done to find optimum values for either the costs or the weights.
+
+.SS Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra
+transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks. Use of the
+PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
+that is incapable of reading or writing ancillary chunks.  If you are
+not using the progressive reading capability, you can turn that off
+with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
+capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw.  The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+.SS Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout.  Set it to an integer value in the range 0 to 3.  Higher
+numbers result in increasing amounts of debugging information.  The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+   png_debug(level, message)
+   png_debug1(level, message, p1)
+   png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives.  For example,
+
+   png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+   if(PNG_DEBUG > 2)
+     fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+   #ifdef PNG_DEBUG
+       fprintf(stderr, ...
+   #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed.  There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+.SH VI.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the bitwise OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_uint_32 that is the bitwise AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+.SH VII.  Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not.  The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero.  It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+.SH VIII.  Changes to Libpng from version 1.0.x to 1.2.x
+
+Support for user memory management was enabled by default.  To
+accomplish this, the functions png_create_read_struct_2(),
+png_create_write_struct_2(), png_set_mem_fn(), png_get_mem_ptr(),
+png_malloc_default(), and png_free_default() were added.
+
+Support for the iTXt chunk has been enabled by default as of
+version 1.2.41.
+
+Support for certain MNG features was enabled.
+
+Support for numbered error messages was added.  However, we never got
+around to actually numbering the error messages.  The function
+png_set_strip_error_numbers() was added (Note: the prototype for this
+function was inadvertently removed from png.h in PNG_NO_ASSEMBLER_CODE
+builds of libpng-1.2.15.  It was restored in libpng-1.2.36).
+
+The png_malloc_warn() function was added at libpng-1.2.3.  This issues
+a png_warning and returns NULL instead of aborting when it fails to
+acquire the requested memory allocation.
+
+Support for setting user limits on image width and height was enabled
+by default.  The functions png_set_user_limits(), png_get_user_width_max(),
+and png_get_user_height_max() were added at libpng-1.2.6.
+
+The png_set_add_alpha() function was added at libpng-1.2.7.
+
+The function png_set_expand_gray_1_2_4_to_8() was added at libpng-1.2.9.
+Unlike png_set_gray_1_2_4_to_8(), the new function does not expand the
+tRNS chunk to alpha. The png_set_gray_1_2_4_to_8() function is
+deprecated.
+
+A number of macro definitions in support of runtime selection of
+assembler code features (especially Intel MMX code support) were
+added at libpng-1.2.0:
+
+    PNG_ASM_FLAG_MMX_SUPPORT_COMPILED
+    PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
+    PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
+    PNG_ASM_FLAG_MMX_READ_INTERLACE
+    PNG_ASM_FLAG_MMX_READ_FILTER_SUB
+    PNG_ASM_FLAG_MMX_READ_FILTER_UP
+    PNG_ASM_FLAG_MMX_READ_FILTER_AVG
+    PNG_ASM_FLAG_MMX_READ_FILTER_PAETH
+    PNG_ASM_FLAGS_INITIALIZED
+    PNG_MMX_READ_FLAGS
+    PNG_MMX_FLAGS
+    PNG_MMX_WRITE_FLAGS
+    PNG_MMX_FLAGS
+
+We added the following functions in support of runtime
+selection of assembler code features:
+
+    png_get_mmx_flagmask()
+    png_set_mmx_thresholds()
+    png_get_asm_flags()
+    png_get_mmx_bitdepth_threshold()
+    png_get_mmx_rowbytes_threshold()
+    png_set_asm_flags()
+
+We replaced all of these functions with simple stubs in libpng-1.2.20,
+when the Intel assembler code was removed due to a licensing issue.
+
+These macros are deprecated:
+
+    PNG_READ_TRANSFORMS_NOT_SUPPORTED
+    PNG_PROGRESSIVE_READ_NOT_SUPPORTED
+    PNG_NO_SEQUENTIAL_READ_SUPPORTED
+    PNG_WRITE_TRANSFORMS_NOT_SUPPORTED
+    PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED
+    PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED
+
+They have been replaced, respectively, by:
+
+    PNG_NO_READ_TRANSFORMS
+    PNG_NO_PROGRESSIVE_READ
+    PNG_NO_SEQUENTIAL_READ
+    PNG_NO_WRITE_TRANSFORMS
+    PNG_NO_READ_ANCILLARY_CHUNKS
+    PNG_NO_WRITE_ANCILLARY_CHUNKS
+
+PNG_MAX_UINT was replaced with PNG_UINT_31_MAX.  It has been
+deprecated since libpng-1.0.16 and libpng-1.2.6.
+
+The function
+    png_check_sig(sig, num)
+was replaced with
+    !png_sig_cmp(sig, 0, num)
+It has been deprecated since libpng-0.90.
+
+The function
+    png_set_gray_1_2_4_to_8()
+which also expands tRNS to alpha was replaced with
+    png_set_expand_gray_1_2_4_to_8()
+which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
+
+.SH IX.  (Omitted)
+
+
+.SH X. Detecting libpng
+
+The png_get_io_ptr() function has been present since libpng-0.88, has never
+changed, and is unaffected by conditional compilation macros.  It is the
+best choice for use in configure scripts for detecting the presence of any
+libpng version since 0.88.  In an autoconf "configure.in" you could use
+
+    AC_CHECK_LIB(png, png_get_io_ptr, ...
+
+.SH XI. Source code repository
+
+Since about February 2009, version 1.2.34, libpng has been under "git" source
+control.  The git repository was built from old libpng-x.y.z.tar.gz files
+going back to version 0.70.  You can access the git repository (read only)
+at
+
+    git://libpng.git.sourceforge.net/gitroot/libpng
+
+or you can browse it via "gitweb" at
+
+    http://libpng.git.sourceforge.net/git/gitweb.cgi?p=libpng
+
+Patches can be sent to glennrp at users.sourceforge.net or to
+png-mng-implement at lists.sourceforge.net or you can upload them to
+the libpng bug tracker at
+
+    http://libpng.sourceforge.net
+
+.SH XII. Coding style
+
+Our coding style is similar to the "Allman" style, with curly
+braces on separate lines:
+
+    if (condition)
+    {
+       action;
+    }
+
+    else if (another condition)
+    {
+       another action;
+    }
+
+The braces can be omitted from simple one-line actions:
+
+    if (condition)
+       return (0);
+
+We use 3-space indentation, except for continued statements which
+are usually indented the same as the first line of the statement
+plus four more spaces.
+
+For macro definitions we use 2-space indentation, always leaving the "#"
+in the first column.
+
+    #ifndef PNG_NO_FEATURE
+    #  ifndef PNG_FEATURE_SUPPORTED
+    #    define PNG_FEATURE_SUPPORTED
+    #  endif
+    #endif
+
+Comments appear with the leading "/*" at the same indentation as
+the statement that follows the comment:
+
+    /* Single-line comment */
+    statement;
+
+    /* Multiple-line
+     * comment
+     */
+    statement;
+
+Very short comments can be placed at the end of the statement
+to which they pertain:
+
+    statement;    /* comment */
+
+We don't use C++ style ("//") comments. We have, however,
+used them in the past in some now-abandoned MMX assembler
+code.
+
+Functions and their curly braces are not indented, and
+exported functions are marked with PNGAPI:
+
+ /* This is a public function that is visible to
+  * application programers. It does thus-and-so.
+  */
+ void PNGAPI
+ png_exported_function(png_ptr, png_info, foo)
+ {
+    body;
+ }
+
+The prototypes for all exported functions appear in png.h,
+above the comment that says
+
+    /* Maintainer: Put new public prototypes here ... */
+
+We mark all non-exported functions with "/* PRIVATE */"":
+
+ void /* PRIVATE */
+ png_non_exported_function(png_ptr, png_info, foo)
+ {
+    body;
+ }
+
+The prototypes for non-exported functions (except for those in
+pngtest) appear in
+the PNG_INTERNAL section of png.h
+above the comment that says
+
+  /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+The names of all exported functions and variables begin
+with  "png_", and all publicly visible C preprocessor
+macros begin with "PNG_".
+
+We put a space after each comma and after each semicolon
+in "for" statments, and we put spaces before and after each
+C binary operator and after "for" or "while".  We don't
+put a space between a typecast and the expression being
+cast, nor do we put one between a function name and the
+left parenthesis that follows it:
+
+    for (i = 2; i > 0; --i)
+       y[i] = a(x) + (int)b;
+
+We prefer #ifdef and #ifndef to #if defined() and if !defined()
+when there is only one macro being tested.
+
+We do not use the TAB character for indentation in the C sources.
+
+Lines do not exceed 80 characters.
+
+Other rules can be inferred by inspecting the libpng source.
+
+.SH XIII. Y2K Compliance in libpng
+
+June 26, 2010
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.44 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields.  One is a 2-byte unsigned integer that
+will hold years up to 65535.  The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+    "png_uint_16 year" in png_time_struct.
+
+The strings are
+    "png_charp time_buffer" in png_struct and
+    "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+    png_convert_to_rfc_1123() in png.c
+      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_from_struct_tm() in pngwrite.c, called
+      in pngwrite.c
+    png_convert_from_time_t() in pngwrite.c
+    png_get_tIME() in pngget.c
+    png_handle_tIME() in pngrutil.c, called in pngread.c
+    png_set_tIME() in pngset.c
+    png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment.  The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year.  There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
+
+   Glenn Randers-Pehrson
+   libpng maintainer
+   PNG Development Group
+
+.SH NOTE
+
+Note about libpng version numbers:
+
+Due to various miscommunications, unforeseen code incompatibilities
+and occasional factors outside the authors' control, version numbering
+on the library has not always been consistent and straightforward.
+The following table summarizes matters since version 0.89c, which was
+the first widely used release:
+
+ source             png.h  png.h  shared-lib
+ version            string   int  version
+ -------            ------  ----- ----------
+ 0.89c ("beta 3")  0.89       89  1.0.89
+ 0.90  ("beta 4")  0.90       90  0.90
+ 0.95  ("beta 5")  0.95       95  0.95
+ 0.96  ("beta 6")  0.96       96  0.96
+ 0.97b ("beta 7")  1.00.97    97  1.0.1
+ 0.97c             0.97       97  2.0.97
+ 0.98              0.98       98  2.0.98
+ 0.99              0.99       98  2.0.99
+ 0.99a-m           0.99       99  2.0.99
+ 1.00              1.00      100  2.1.0
+ 1.0.0             1.0.0     100  2.1.0
+ 1.0.0   (from here on, the  100  2.1.0
+ 1.0.1    png.h string is  10001  2.1.0
+ 1.0.1a-e identical to the 10002  from here on, the
+ 1.0.2    source version)  10002  shared library is 2.V
+ 1.0.2a-b                  10003  where V is the source
+ 1.0.1                     10001  code version except as
+ 1.0.1a-e                  10002  2.1.0.1a-e   noted.
+ 1.0.2                     10002  2.1.0.2
+ 1.0.2a-b                  10003  2.1.0.2a-b
+ 1.0.3                     10003  2.1.0.3
+ 1.0.3a-d                  10004  2.1.0.3a-d
+ 1.0.4                     10004  2.1.0.4
+ 1.0.4a-f                  10005  2.1.0.4a-f
+ 1.0.5 (+ 2 patches)       10005  2.1.0.5
+ 1.0.5a-d                  10006  2.1.0.5a-d
+ 1.0.5e-r                  10100  2.1.0.5e-r
+ 1.0.5s-v                  10006  2.1.0.5s-v
+ 1.0.6 (+ 3 patches)       10006  2.1.0.6
+ 1.0.6d-g                  10007  2.1.0.6d-g
+ 1.0.6h                    10007  10.6h
+ 1.0.6i                    10007  10.6i
+ 1.0.6j                    10007  2.1.0.6j
+ 1.0.7beta11-14    DLLNUM  10007  2.1.0.7beta11-14
+ 1.0.7beta15-18       1    10007  2.1.0.7beta15-18
+ 1.0.7rc1-2           1    10007  2.1.0.7rc1-2
+ 1.0.7                1    10007  2.1.0.7
+ 1.0.8beta1-4         1    10008  2.1.0.8beta1-4
+ 1.0.8rc1             1    10008  2.1.0.8rc1
+ 1.0.8                1    10008  2.1.0.8
+ 1.0.9beta1-6         1    10009  2.1.0.9beta1-6
+ 1.0.9rc1             1    10009  2.1.0.9rc1
+ 1.0.9beta7-10        1    10009  2.1.0.9beta7-10
+ 1.0.9rc2             1    10009  2.1.0.9rc2
+ 1.0.9                1    10009  2.1.0.9
+ 1.0.10beta1          1    10010  2.1.0.10beta1
+ 1.0.10rc1            1    10010  2.1.0.10rc1
+ 1.0.10               1    10010  2.1.0.10
+ 1.0.11beta1-3        1    10011  2.1.0.11beta1-3
+ 1.0.11rc1            1    10011  2.1.0.11rc1
+ 1.0.11               1    10011  2.1.0.11
+ 1.0.12beta1-2        2    10012  2.1.0.12beta1-2
+ 1.0.12rc1            2    10012  2.1.0.12rc1
+ 1.0.12               2    10012  2.1.0.12
+ 1.1.0a-f             -    10100  2.1.1.0a-f abandoned
+ 1.2.0beta1-2         2    10200  2.1.2.0beta1-2
+ 1.2.0beta3-5         3    10200  3.1.2.0beta3-5
+ 1.2.0rc1             3    10200  3.1.2.0rc1
+ 1.2.0                3    10200  3.1.2.0
+ 1.2.1beta-4          3    10201  3.1.2.1beta1-4
+ 1.2.1rc1-2           3    10201  3.1.2.1rc1-2
+ 1.2.1                3    10201  3.1.2.1
+ 1.2.2beta1-6        12    10202  12.so.0.1.2.2beta1-6
+ 1.0.13beta1         10    10013  10.so.0.1.0.13beta1
+ 1.0.13rc1           10    10013  10.so.0.1.0.13rc1
+ 1.2.2rc1            12    10202  12.so.0.1.2.2rc1
+ 1.0.13              10    10013  10.so.0.1.0.13
+ 1.2.2               12    10202  12.so.0.1.2.2
+ 1.2.3rc1-6          12    10203  12.so.0.1.2.3rc1-6
+ 1.2.3               12    10203  12.so.0.1.2.3
+ 1.2.4beta1-3        13    10204  12.so.0.1.2.4beta1-3
+ 1.2.4rc1            13    10204  12.so.0.1.2.4rc1
+ 1.0.14              10    10014  10.so.0.1.0.14
+ 1.2.4               13    10204  12.so.0.1.2.4
+ 1.2.5beta1-2        13    10205  12.so.0.1.2.5beta1-2
+ 1.0.15rc1           10    10015  10.so.0.1.0.15rc1
+ 1.0.15              10    10015  10.so.0.1.0.15
+ 1.2.5               13    10205  12.so.0.1.2.5
+ 1.2.6beta1-4        13    10206  12.so.0.1.2.6beta1-4
+ 1.2.6rc1-5          13    10206  12.so.0.1.2.6rc1-5
+ 1.0.16              10    10016  10.so.0.1.0.16
+ 1.2.6               13    10206  12.so.0.1.2.6
+ 1.2.7beta1-2        13    10207  12.so.0.1.2.7beta1-2
+ 1.0.17rc1           10    10017  10.so.0.1.0.17rc1
+ 1.2.7rc1            13    10207  12.so.0.1.2.7rc1
+ 1.0.17              10    10017  10.so.0.1.0.17
+ 1.2.7               13    10207  12.so.0.1.2.7
+ 1.2.8beta1-5        13    10208  12.so.0.1.2.8beta1-5
+ 1.0.18rc1-5         10    10018  10.so.0.1.0.18rc1-5
+ 1.2.8rc1-5          13    10208  12.so.0.1.2.8rc1-5
+ 1.0.18              10    10018  10.so.0.1.0.18
+ 1.2.8               13    10208  12.so.0.1.2.8
+ 1.2.9beta1-3        13    10209  12.so.0.1.2.9beta1-3
+ 1.2.9beta4-11       13    10209  12.so.0.9[.0]
+ 1.2.9rc1            13    10209  12.so.0.9[.0]
+ 1.2.9               13    10209  12.so.0.9[.0]
+ 1.2.10beta1-8       13    10210  12.so.0.10[.0]
+ 1.2.10rc1-3         13    10210  12.so.0.10[.0]
+ 1.2.10              13    10210  12.so.0.10[.0]
+ 1.2.11beta1-4       13    10211  12.so.0.11[.0]
+ 1.0.19rc1-5         10    10019  10.so.0.19[.0]
+ 1.2.11rc1-5         13    10211  12.so.0.11[.0]
+ 1.0.19              10    10019  10.so.0.19[.0]
+ 1.2.11              13    10211  12.so.0.11[.0]
+ 1.0.20              10    10020  10.so.0.20[.0]
+ 1.2.12              13    10212  12.so.0.12[.0]
+ 1.2.13beta1         13    10213  12.so.0.13[.0]
+ 1.0.21              10    10021  10.so.0.21[.0]
+ 1.2.13              13    10213  12.so.0.13[.0]
+ 1.2.14beta1-2       13    10214  12.so.0.14[.0]
+ 1.0.22rc1           10    10022  10.so.0.22[.0]
+ 1.2.14rc1           13    10214  12.so.0.14[.0]
+ 1.2.15beta1-6       13    10215  12.so.0.15[.0]
+ 1.0.23rc1-5         10    10023  10.so.0.23[.0]
+ 1.2.15rc1-5         13    10215  12.so.0.15[.0]
+ 1.0.23              10    10023  10.so.0.23[.0]
+ 1.2.15              13    10215  12.so.0.15[.0]
+ 1.2.16beta1-2       13    10216  12.so.0.16[.0]
+ 1.2.16rc1           13    10216  12.so.0.16[.0]
+ 1.0.24              10    10024  10.so.0.24[.0]
+ 1.2.16              13    10216  12.so.0.16[.0]
+ 1.2.17beta1-2       13    10217  12.so.0.17[.0]
+ 1.0.25rc1           10    10025  10.so.0.25[.0]
+ 1.2.17rc1-3         13    10217  12.so.0.17[.0]
+ 1.0.25              10    10025  10.so.0.25[.0]
+ 1.2.17              13    10217  12.so.0.17[.0]
+ 1.0.26              10    10026  10.so.0.26[.0]
+ 1.2.18              13    10218  12.so.0.18[.0]
+ 1.2.19beta1-31      13    10219  12.so.0.19[.0]
+ 1.0.27rc1-6         10    10027  10.so.0.27[.0]
+ 1.2.19rc1-6         13    10219  12.so.0.19[.0]
+ 1.0.27              10    10027  10.so.0.27[.0]
+ 1.2.19              13    10219  12.so.0.19[.0]
+ 1.2.20beta01-04     13    10220  12.so.0.20[.0]
+ 1.0.28rc1-6         10    10028  10.so.0.28[.0]
+ 1.2.20rc1-6         13    10220  12.so.0.20[.0]
+ 1.0.28              10    10028  10.so.0.28[.0]
+ 1.2.20              13    10220  12.so.0.20[.0]
+ 1.2.21beta1-2       13    10221  12.so.0.21[.0]
+ 1.2.21rc1-3         13    10221  12.so.0.21[.0]
+ 1.0.29              10    10029  10.so.0.29[.0]
+ 1.2.21              13    10221  12.so.0.21[.0]
+ 1.2.22beta1-4       13    10222  12.so.0.22[.0]
+ 1.0.30rc1           13    10030  10.so.0.30[.0]
+ 1.2.22rc1           13    10222  12.so.0.22[.0]
+ 1.0.30              10    10030  10.so.0.30[.0]
+ 1.2.22              13    10222  12.so.0.22[.0]
+ 1.2.23beta01-05     13    10223  12.so.0.23[.0]
+ 1.2.23rc01          13    10223  12.so.0.23[.0]
+ 1.2.23              13    10223  12.so.0.23[.0]
+ 1.2.24beta01-02     13    10224  12.so.0.24[.0]
+ 1.2.24rc01          13    10224  12.so.0.24[.0]
+ 1.2.24              13    10224  12.so.0.24[.0]
+ 1.2.25beta01-06     13    10225  12.so.0.25[.0]
+ 1.2.25rc01-02       13    10225  12.so.0.25[.0]
+ 1.0.31              10    10031  10.so.0.31[.0]
+ 1.2.25              13    10225  12.so.0.25[.0]
+ 1.2.26beta01-06     13    10226  12.so.0.26[.0]
+ 1.2.26rc01          13    10226  12.so.0.26[.0]
+ 1.2.26              13    10226  12.so.0.26[.0]
+ 1.0.32              10    10032  10.so.0.32[.0]
+ 1.2.27beta01-06     13    10227  12.so.0.27[.0]
+ 1.2.27rc01          13    10227  12.so.0.27[.0]
+ 1.0.33              10    10033  10.so.0.33[.0]
+ 1.2.27              13    10227  12.so.0.27[.0]
+ 1.0.34              10    10034  10.so.0.34[.0]
+ 1.2.28              13    10228  12.so.0.28[.0]
+ 1.2.29beta01-03     13    10229  12.so.0.29[.0]
+ 1.2.29rc01          13    10229  12.so.0.29[.0]
+ 1.0.35              10    10035  10.so.0.35[.0]
+ 1.2.29              13    10229  12.so.0.29[.0]
+ 1.0.37              10    10037  10.so.0.37[.0]
+ 1.2.30beta01-04     13    10230  12.so.0.30[.0]
+ 1.0.38rc01-08       10    10038  10.so.0.38[.0]
+ 1.2.30rc01-08       13    10230  12.so.0.30[.0]
+ 1.0.38              10    10038  10.so.0.38[.0]
+ 1.2.30              13    10230  12.so.0.30[.0]
+ 1.0.39rc01-03       10    10039  10.so.0.39[.0]
+ 1.2.31rc01-03       13    10231  12.so.0.31[.0]
+ 1.0.39              10    10039  10.so.0.39[.0]
+ 1.2.31              13    10231  12.so.0.31[.0]
+ 1.2.32beta01-02     13    10232  12.so.0.32[.0]
+ 1.0.40rc01          10    10040  10.so.0.40[.0]
+ 1.2.32rc01          13    10232  12.so.0.32[.0]
+ 1.0.40              10    10040  10.so.0.40[.0]
+ 1.2.32              13    10232  12.so.0.32[.0]
+ 1.2.33beta01-02     13    10233  12.so.0.33[.0]
+ 1.2.33rc01-02       13    10233  12.so.0.33[.0]
+ 1.0.41rc01          10    10041  10.so.0.41[.0]
+ 1.2.33              13    10233  12.so.0.33[.0]
+ 1.0.41              10    10041  10.so.0.41[.0]
+ 1.2.34beta01-07     13    10234  12.so.0.34[.0]
+ 1.0.42rc01          10    10042  10.so.0.42[.0]
+ 1.2.34rc01          13    10234  12.so.0.34[.0]
+ 1.0.42              10    10042  10.so.0.42[.0]
+ 1.2.34              13    10234  12.so.0.34[.0]
+ 1.2.35beta01-03     13    10235  12.so.0.35[.0]
+ 1.0.43rc01-02       10    10043  10.so.0.43[.0]
+ 1.2.35rc01-02       13    10235  12.so.0.35[.0]
+ 1.0.43              10    10043  10.so.0.43[.0]
+ 1.2.35              13    10235  12.so.0.35[.0]
+ 1.2.36beta01-05     13    10236  12.so.0.36[.0]
+ 1.2.36rc01          13    10236  12.so.0.36[.0]
+ 1.0.44              10    10044  10.so.0.44[.0]
+ 1.2.36              13    10236  12.so.0.36[.0]
+ 1.2.37beta01-03     13    10237  12.so.0.37[.0]
+ 1.2.37rc01          13    10237  12.so.0.37[.0]
+ 1.2.37              13    10237  12.so.0.37[.0]
+ 1.2.45              10    10045  12.so.0.45[.0]
+ 1.0.46              10    10046  10.so.0.46[.0]
+ 1.2.38beta01        13    10238  12.so.0.38[.0]
+ 1.2.38rc01-03       13    10238  12.so.0.38[.0]
+ 1.0.47              10    10047  10.so.0.47[.0]
+ 1.2.38              13    10238  12.so.0.38[.0]
+ 1.2.39beta01-05     13    10239  12.so.0.39[.0]
+ 1.2.39rc01          13    10239  12.so.0.39[.0]
+ 1.0.48              10    10048  10.so.0.48[.0]
+ 1.2.39              13    10239  12.so.0.39[.0]
+ 1.2.40beta01        13    10240  12.so.0.40[.0]
+ 1.2.40rc01          13    10240  12.so.0.40[.0]
+ 1.0.49              10    10049  10.so.0.49[.0]
+ 1.2.40              13    10240  12.so.0.40[.0]
+ 1.0.50              10    10050  10.so.0.50[.0]
+ 1.2.41beta01-18     13    10241  12.so.0.41[.0]
+ 1.0.51rc01          10    10051  10.so.0.51[.0]
+ 1.2.41rc01-03       13    10241  12.so.0.41[.0]
+ 1.0.51              10    10051  10.so.0.51[.0]
+ 1.2.41              13    10241  12.so.0.41[.0]
+ 1.2.42beta01-02     13    10242  12.so.0.42[.0]
+ 1.2.42rc01-05       13    10242  12.so.0.42[.0]
+ 1.0.52              10    10052  10.so.0.52[.0]
+ 1.2.42              13    10242  12.so.0.42[.0]
+ 1.2.43beta01-05     13    10243  12.so.0.43[.0]
+ 1.0.53rc01-02       10    10053  10.so.0.53[.0]
+ 1.2.43rc01-02       13    10243  12.so.0.43[.0]
+ 1.0.53              10    10053  10.so.0.53[.0]
+ 1.2.43              13    10243  12.so.0.43[.0]
+ 1.2.44beta01-03     13    10244  12.so.0.44[.0]
+ 1.2.44rc01-03       13    10244  12.so.0.44[.0]
+ 1.2.44              13    10244  12.so.0.44[.0]
+
+Henceforth the source version will match the shared-library minor
+and patch numbers; the shared-library major version number will be
+used for changes in backward compatibility, as it is intended.  The
+PNG_PNGLIB_VER macro, which is not used within libpng but is available
+for applications, is an unsigned integer of the form xyyzz corresponding
+to the source version x.y.z (leading zeros in y and z).  Beta versions
+were given the previous public release number plus a letter, until
+version 1.0.6j; from then on they were given the upcoming public
+release number plus "betaNN" or "rcN".
+
+.SH "SEE ALSO"
+.IR libpngpf(3) ", " png(5)
+.LP
+.IR libpng :
+.IP
+http://libpng.sourceforge.net (follow the [DOWNLOAD] link)
+http://www.libpng.org/pub/png
+
+.LP
+.IR zlib :
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ftp.info-zip.org/pub/infozip/zlib
+
+.LP
+.IR PNG specification: RFC 2083
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ftp.rfc-editor.org:/in-notes/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+
+.LP
+In the case of any inconsistency between the PNG specification
+and this library, the specification takes precedence.
+
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+<glennrp at users.sourceforge.net>
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience.  This wouldn't have been
+possible without all of you.
+
+Thanks to Frank J. T. Wojcik for helping with the documentation.
+
+Libpng version 1.2.44 - June 26, 2010:
+Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
+Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
+
+Supported by the PNG development group
+.br
+png-mng-implement at lists.sf.net
+(subscription required; visit
+png-mng-implement at lists.sourceforge.net (subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe).
+
+.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+(This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.)
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.44, June 26, 2010, are
+Copyright (c) 2004,2006-2008 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your
+   enjoyment of the library or against infringement.
+   There is no warranty that our efforts or the library
+   will fulfill any of your particular purposes or needs.
+   This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and
+   effort is with the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+Distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and
+   must not be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from
+   any source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+June 26, 2010
+
+.\" end of man page
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.txt
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpng.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2959 @@
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.8 - December 3, 2004
+ Updated and distributed by Glenn Randers-Pehrson
+ <glennrp at users.sourceforge.net>
+ Copyright (c) 1998-2004 Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6  version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use.  There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms.  In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need.  We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG specification (second edition), November 2003, is available as
+a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
+<http://www.w3.org/TR/2003/REC-PNG-20031110/
+The W3C and ISO documents have identical technical content.
+
+The PNG-1.2 specification is available at
+<http://www.libpng.org/pub/png/documents/>
+
+The PNG-1.0 specification is available
+as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <http://www.libpng.org/pub/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more.  All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C.  Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use.  The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible.  While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually find the source files for the zlib utility wherever you
+find the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures.  Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure.  Note: thread safety may be defeated
+by use of some of the MMX assembler code in pnggccrd.c, which is only
+compiled when the user defines PNG_THREAD_UNSAFE_OK.
+
+II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info.  The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file.  At one time, the fields of png_info were intended to be
+directly accessible to the user.  However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed.  The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order.  In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one.  See example.c and png.h for more detail.  While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo.  Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file.  Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning.  Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to replace them with custom functions.  See the discussion under
+Customizing libpng.
+
+
+    FILE *fp = fopen(file_name, "rb");
+    if (!fp)
+    {
+        return (ERROR);
+    }
+    fread(header, 1, number, fp);
+    is_png = !png_sig_cmp(header, 0, number);
+    if (!is_png)
+    {
+        return (NOT_PNG);
+    }
+
+
+Next, png_struct and png_info need to be allocated and initialized.  In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures.  We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used).  See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+    png_structp png_ptr = png_create_read_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr,
+           (png_infopp)NULL, (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+          (png_infopp)NULL);
+        return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+    png_structp png_ptr = png_create_read_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine.  Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr).  If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp.  See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling.  If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           &end_info);
+        fclose(fp);
+        return (ERROR);
+    }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code.  The default for libpng is to
+use the C function fread().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+    png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+    png_set_sig_bytes(png_ptr, number);
+
+Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+    read_chunk_callback(png_ptr ptr,
+         png_unknown_chunkp chunk);
+    {
+       /* The unknown chunk structure contains your
+          chunk data: */
+           png_byte name[5];
+           png_byte *data;
+           png_size_t size;
+       /* Note that libpng has already taken care of
+          the CRC handling */
+
+       /* put your code here.  Return one of the
+          following: */
+
+       return (-n); /* chunk had an error */
+       return (0); /* did not recognize */
+       return (n); /* success */
+    }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+        read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+    png_get_user_chunk_ptr(png_ptr);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void read_row_callback(png_ptr ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_status_fn(png_ptr, read_row_callback);
+
+Width and height limits
+
+The PNG specification allows the width and height of an image to be as
+large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
+Since very few applications really need to process such large images,
+we have imposed an arbitrary 1-million limit on rows and columns.
+Larger images will be rejected immediately with a png_error() call. If
+you wish to override this limit, you can use
+
+   png_set_user_limits(png_ptr, width_max, height_max);
+
+to set your own limits, or use width_max = height_max = 0x7fffffffL
+to allow all valid dimensions (libpng may reject some very large images
+anyway because of potential buffer overflow conditions).
+
+You should put this statement after you create the PNG structure and
+before calling png_read_info(), png_read_png(), or png_process_data().
+If you need to retrieve the limits that are being applied, use
+
+   width_max = png_get_user_width_max(png_ptr);
+   height_max = png_get_user_height_max(png_ptr);
+
+Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read.  Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+    png_set_keep_unknown_chunks(png_ptr, keep,
+        chunk_list, num_chunks);
+    keep       - 0: do not handle as unknown
+                 1: do not keep
+                 2: keep only if safe-to-copy
+                 3: keep even if unsafe-to-copy
+               You can use these definitions:
+                 PNG_HANDLE_CHUNK_AS_DEFAULT   0
+                 PNG_HANDLE_CHUNK_NEVER        1
+                 PNG_HANDLE_CHUNK_IF_SAFE      2
+                 PNG_HANDLE_CHUNK_ALWAYS       3
+    chunk_list - list of chunks affected (a byte string,
+                 five bytes per chunk, NULL or '\0' if
+                 num_chunks is 0)
+    num_chunks - number of chunks affected; if 0, all
+                 unknown chunks are affected.  If nonzero,
+                 only the chunks in the list are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures.  If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive.  If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.  The IHDR and IEND chunks should not be named in
+chunk_list; if they are, libpng will process them normally anyway.
+
+The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
+                                8 bits
+    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
+    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
+                                samples to bytes
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_EXPAND        Perform set_expand()
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.)  If this is the case, simply do this:
+
+    png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags.  This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform mask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future input transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_read_png().
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+   row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+   png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
+      png_error (png_ptr,
+         "Image is too tall to process in memory");
+   if (width > PNG_UINT_32_MAX/pixel_size)
+      png_error (png_ptr,
+         "Image is too wide to process in memory");
+   row_pointers = png_malloc(png_ptr,
+      height*png_sizeof(png_bytep));
+   for (int i=0; i<height, i++)
+      row_pointers[i]=png_malloc(png_ptr,
+         width*pixel_size);
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data.  You do this with a
+call to png_read_info().
+
+    png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read.  Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height,
+       &bit_depth, &color_type, &interlace_type,
+       &compression_type, &filter_method);
+
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.  (valid values are
+                     1, 2, 4, 8, 16 and depend also on
+                     the color_type.  See also
+                     significant bits (sBIT) below).
+    color_type     - describes which color/alpha channels
+                         are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    filter_method  - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0, and can also be
+                     PNG_INTRAPIXEL_DIFFERENCING if
+                     the PNG datastream is embedded in
+                     a MNG-1.0 datastream)
+    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+                     for PNG 1.0)
+    interlace_type - (PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7)
+    Any or all of interlace_type, compression_type, of
+    filter_method can be NULL if you are
+    not interested in their values.
+
+    channels = png_get_channels(png_ptr, info_ptr);
+    channels       - number of channels of info for the
+                     color type (valid values are 1 (GRAY,
+                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+                     4 (RGB_ALPHA or RGB + filler byte))
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    rowbytes       - number of bytes needed to hold a row
+
+    signature = png_get_signature(png_ptr, info_ptr);
+    signature      - holds the signature read from the
+                     file (if any).  The data is kept in
+                     the same offset it would be if the
+                     whole signature were read (i.e. if an
+                     application had already read in 4
+                     bytes of signature before starting
+                     libpng, the remaining 4 bytes would
+                     be in signature[4] through signature[7]
+                     (see png_set_sig_bytes())).
+
+
+    width            = png_get_image_width(png_ptr,
+                         info_ptr);
+    height           = png_get_image_height(png_ptr,
+                         info_ptr);
+    bit_depth        = png_get_bit_depth(png_ptr,
+                         info_ptr);
+    color_type       = png_get_color_type(png_ptr,
+                         info_ptr);
+    filter_method    = png_get_filter_type(png_ptr,
+                         info_ptr);
+    compression_type = png_get_compression_type(png_ptr,
+                         info_ptr);
+    interlace_type   = png_get_interlace_type(png_ptr,
+                         info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing.  The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+    png_get_PLTE(png_ptr, info_ptr, &palette,
+                     &num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_get_gAMA(png_ptr, info_ptr, &gamma);
+    gamma          - the gamma the file is written
+                     at (PNG_INFO_gAMA)
+
+    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
+                     The presence of the sRGB chunk
+                     means that the pixel data is in the
+                     sRGB color space.  This chunk also
+                     implies specific values of gAMA and
+                     cHRM.
+
+    png_get_iCCP(png_ptr, info_ptr, &name,
+       &compression_type, &profile, &proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray,
+                     red, green, and blue channels,
+                     whichever are appropriate for the
+                     given color type (png_color_16)
+
+    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+                     &trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_get_hIST(png_ptr, info_ptr, &hist);
+                     (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_get_tIME(png_ptr, info_ptr, &mod_time);
+    mod_time       - time image was last modified
+                    (PNG_VALID_tIME)
+
+    png_get_bKGD(png_ptr, info_ptr, &background);
+    background     - background color (PNG_VALID_bKGD)
+                     valid 16-bit red, green and blue
+                     values, regardless of color_type
+
+    num_comments   = png_get_text(png_ptr, info_ptr,
+                     &text_ptr, &num_text);
+    num_comments   - number of comments
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                         1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (empty
+                         string for unknown).
+    text_ptr[i].lang_key  - keyword in UTF-8
+                         (empty string for unknown).
+    num_text       - number of comments (same as
+                     num_comments; you can put NULL here
+                     to avoid the duplication)
+    Note while png_set_text() will accept text, language,
+    and translated keywords that can be NULL pointers, the
+    structure returned by png_get_text will always contain
+    regular zero-terminated C strings.  They might be
+    empty strings but they will never be NULL pointers.
+
+    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+       &palette_ptr);
+    palette_ptr    - array of palette structures holding
+                     contents of one or more sPLT chunks
+                     read.
+    num_spalettes  - number of sPLT chunks read.
+
+    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+       &unit_type);
+    offset_x       - positive offset from the left edge
+                     of the screen
+    offset_y       - positive offset from the top edge
+                     of the screen
+    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+       &unit_type);
+    res_x          - pixels/unit physical resolution in
+                     x direction
+    res_y          - pixels/unit physical resolution in
+                     x direction
+    unit_type      - PNG_RESOLUTION_UNKNOWN,
+                     PNG_RESOLUTION_METER
+
+    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are doubles)
+
+    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+       &height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+       info_ptr, &unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position of chunk in file
+
+    The value of "i" corresponds to the order in which the
+    chunks were read from the PNG file or inserted with the
+    png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+    res_x = png_get_x_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_meter(png_ptr,
+       info_ptr)
+    res_x = png_get_x_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_y = png_get_y_pixels_per_inch(png_ptr,
+       info_ptr)
+    res_x_and_y = png_get_pixels_per_inch(png_ptr,
+       info_ptr)
+    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+       info_ptr)
+
+   (Each of these returns 0 [signifying "unknown"] if
+       the data is not present or if res_x is 0;
+       res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+   (Each of these returns 0 [signifying "unknown" if both
+       x and y are 0] if the data is not present or if the
+       chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents.  Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text.  PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size.  While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings.  It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations.  Non-printing
+symbols are not allowed.  See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword.  It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string.  The text string, language code, and translated
+keyword may be empty or NULL pointers.  The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image.  This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data.  They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data.  The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called.  8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()
+is called to insert filler bytes, either before or after each RGB triplet.
+16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant
+byte of the color value first, unless png_set_strip_16() is called to
+transform it to regular RGB RGB triplets, or png_set_filler() or
+png_set_add alpha() is called to insert filler bytes, either before or
+after each RRGGBB triplet.  Similarly, 8-bit or 16-bit grayscale data can
+be modified with
+png_set_filler(), png_set_add_alpha(), or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk.  This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
+        png_set_palette_to_rgb(png_ptr);
+
+    if (color_type == PNG_COLOR_TYPE_GRAY &&
+        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
+
+    if (png_get_valid(png_ptr, info_ptr,
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
+
+PNG can have files with 16 bits per channel.  If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+    if (bit_depth == 16)
+        png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+        png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity.  If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files.  This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]).  However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+    png_color_8p sig_bit;
+
+    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+        png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order.  This code
+changes the storage of the pixels to blue, green, red:
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+    if (color_type == PNG_COLOR_TYPE_RGB)
+        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after.  This transformation
+does not affect images that already have full alpha channels.  To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+Note that png_set_filler() does not change the color type.  If you want
+to do that, you can add a true alpha channel with
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+           color_type == PNG_COLOR_TYPE_GRAY)
+    png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
+
+where "filler" contains the alpha value to assign to each pixel.
+This function was added in libpng-1.2.7.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB.  This code will do that conversion:
+
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+          png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+          png_set_rgb_to_gray_fixed(png_ptr, error_action,
+             int red_weight, int green_weight);
+
+    error_action = 1: silently do the conversion
+    error_action = 2: issue a warning if the original
+                      image has any pixel where
+                      red != green or red != blue
+    error_action = 3: issue an error and abort the
+                      conversion if the original
+                      image has any pixel where
+                      red != green or red != blue
+
+    red_weight:       weight of red component times 100000
+    green_weight:     weight of green component times 100000
+                      If either weight is negative, default
+                      weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels.  bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+    int rw = red_weight * 65536;
+    int gw = green_weight * 65536;
+    int bw = 65536 - (rw + gw);
+    gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton <poynton at inforamp.net>
+
+    Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+    Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+
+which can be expressed with integers as
+
+    Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0).  Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+    png_color_16 my_background;
+    png_color_16p image_background;
+
+    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+        png_set_background(png_ptr, image_background,
+          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+        png_set_background(png_ptr, &my_background,
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is.  Ideally, the user will know this, and
+the application will allow them to set it.  One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment.  In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+   double gamma, screen_gamma;
+
+   if (/* We have a user-defined screen
+       gamma value */)
+   {
+      screen_gamma = user_defined_screen_gamma;
+   }
+   /* One way that applications can share the same
+      screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA"))
+      != NULL)
+   {
+      screen_gamma = (double)atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2; /* A good guess for a
+           PC monitor in a bright office or a dim room */
+      screen_gamma = 2.0; /* A good guess for a
+           PC monitor in a dark room */
+      screen_gamma = 1.7 or 1.0;  /* A good
+           guess for Mac systems */
+   }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma.  If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs).  Note
+that file gammas are inverted from screen gammas.  See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it.  It is strongly
+recommended that PNG viewers support gamma correction.
+
+   if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+      png_set_gamma(png_ptr, screen_gamma, gamma);
+   else
+      png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that.  Note that this is a simple match dither that merely
+finds the closest color available.  This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes.  If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors.  If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette.  If there is no
+histogram, it may not do as good a job.
+
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      if (png_get_valid(png_ptr, info_ptr,
+         PNG_INFO_PLTE))
+      {
+         png_uint_16p histogram = NULL;
+
+         png_get_hIST(png_ptr, info_ptr,
+            &histogram);
+         png_set_dither(png_ptr, palette, num_palette,
+            max_screen_colors, histogram, 1);
+      }
+      else
+      {
+         png_color std_color_cube[MAX_SCREEN_COLORS] =
+            { ... colors ... };
+
+         png_set_dither(png_ptr, std_color_cube,
+            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+            NULL,0);
+      }
+   }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+   if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+      png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+   if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+    if (bit_depth == 16)
+        png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+    number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call.  This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory.  This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+    png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image.  The row data is simply
+raw byte data for all forms of images.  As the actual allocation
+varies among applications, no example will be given.  If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call.  If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied.  You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+   png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+   png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead.  If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+    png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder.  The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that.  The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read.  The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read.  The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images.  Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0).  The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0).  The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0).  The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines.  Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+    if (interlace_type == PNG_INTERLACE_ADAM7)
+        number_of_passes
+           = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect.  This effect is faster and the end result of either method
+is exactly the same.  If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL.  Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls.  You can change the locations of the data, just
+not the data.  Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+    png_read_rows(png_ptr, NULL, row_pointers,
+       number_of_rows);
+
+Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file.  If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate.  If you are not interested, you can pass NULL.
+
+   png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+   png_destroy_read_struct(&png_ptr, &info_ptr,
+       &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask - identifies data to be freed, a mask
+           containing the logical OR of one or
+           more of
+             PNG_FREE_PLTE, PNG_FREE_TRNS,
+             PNG_FREE_HIST, PNG_FREE_ICCP,
+             PNG_FREE_PCAL, PNG_FREE_ROWS,
+             PNG_FREE_SCAL, PNG_FREE_SPLT,
+             PNG_FREE_TEXT, PNG_FREE_UNKN,
+           or simply PNG_FREE_ALL
+    seq  - sequence number of item to be freed
+           (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data.  When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees.  If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+    png_set_invalid(png_ptr, info_ptr, mask);
+    mask - identifies the chunks to be made invalid,
+           containing the logical OR of one or
+           more of
+             PNG_INFO_gAMA, PNG_INFO_sBIT,
+             PNG_INFO_cHRM, PNG_INFO_PLTE,
+             PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_hIST, PNG_INFO_pHYs,
+             PNG_INFO_oFFs, PNG_INFO_tIME,
+             PNG_INFO_pCAL, PNG_INFO_sRGB,
+             PNG_INFO_iCCP, PNG_INFO_sPLT,
+             PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader.  Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image.  You
+set up these callbacks with png_set_progressive_read_fn().  You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data().  I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /*  An example code fragment of how you would
+     initialize the progressive reader in your
+     application. */
+ int
+ initialize_png_reader()
+ {
+    png_ptr = png_create_read_struct
+        (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+         user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return (ERROR);
+    info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new.  You can provide functions
+       to be called when the header info is valid,
+       when each row is completed, and when the image
+       is finished.  If you aren't using all functions,
+       you can specify NULL parameters.  Even when all
+       three functions are NULL, you need to call
+       png_set_progressive_read_fn().  You can use
+       any struct as the user_ptr (cast to a void pointer
+       for the function call), and retrieve the pointer
+       from inside the callbacks using the function
+
+          png_get_progressive_ptr(png_ptr);
+
+       which will return a void pointer, which you have
+       to cast appropriately.
+     */
+    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+        info_callback, row_callback, end_callback);
+
+    return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+   of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return (ERROR);
+    }
+
+    /* This one's new also.  Simply give it a chunk
+       of data from the file stream (in order, of
+       course).  On machines with segmented memory
+       models machines, don't give it any more than
+       64K.  The library seems to run fine with sizes
+       of 4K. Although you can give it much less if
+       necessary (I assume you can give it chunks of
+       1 byte, I haven't tried less then 256 bytes
+       yet).  When this function returns, you may
+       want to display any rows that were generated
+       in the row callback if you don't already do
+       so there.
+     */
+    png_process_data(png_ptr, info_ptr, buffer, length);
+    return 0;
+ }
+
+ /* This function is called (as set by
+    png_set_progressive_read_fn() above) when enough data
+    has been supplied so all of the header has been
+    read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+    /* Do any setup here, including setting any of
+       the transformations mentioned in the Reading
+       PNG files section.  For now, you _must_ call
+       either png_start_read_image() or
+       png_read_update_info() after all the
+       transformations are set (even if you don't set
+       any).  You may start getting rows before
+       png_process_data() returns, so this is your
+       last chance to prepare for that.
+     */
+ }
+
+ /* This function is called when each row of image
+    data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+    png_uint_32 row_num, int pass)
+ {
+    /* If the image is interlaced, and you turned
+       on the interlace handler, this function will
+       be called for every row in every pass.  Some
+       of these rows will not be changed from the
+       previous pass.  When the row is not changed,
+       the new_row variable will be NULL.  The rows
+       and passes are called in order, so you don't
+       really need the row_num and pass, but I'm
+       supplying them because it may make your life
+       easier.
+
+       For the non-NULL rows of interlaced images,
+       you must call png_progressive_combine_row()
+       passing in the row and the old row.  You can
+       call this function for NULL rows (it will just
+       return) and for non-interlaced images (it just
+       does the memcpy for you) if it will make the
+       code easier.  Thus, you can just do this for
+       all cases:
+     */
+
+        png_progressive_combine_row(png_ptr, old_row,
+          new_row);
+
+    /* where old_row is what was displayed for
+       previously for the row.  Note that the first
+       pass (pass == 0, really) will completely cover
+       the old row, so the rows do not have to be
+       initialized.  After the first pass (and only
+       for interlaced images), you will have to pass
+       the current row, and the function will combine
+       the old row and the new row.
+    */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+    /* This function is called after the whole image
+       has been read, including any chunks after the
+       image (up to and including the IEND).  You
+       will usually have the same info chunk as you
+       had in the header, although some data may have
+       been added to the comments and time fields.
+
+       Most people won't do much here, perhaps setting
+       a flag that marks the image as finished.
+     */
+ }
+
+
+
+IV. Writing
+
+Much of this is very similar to reading.  However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to replace them with
+custom writing functions.  See the discussion under Customizing libpng.
+
+    FILE *fp = fopen(file_name, "wb");
+    if (!fp)
+    {
+       return (ERROR);
+    }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare.  Of course, you
+will want to check if they return NULL.  If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr".  Look at pngtest.c, for example.
+
+    png_structp png_ptr = png_create_write_struct
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+       return (ERROR);
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       png_destroy_write_struct(&png_ptr,
+         (png_infopp)NULL);
+       return (ERROR);
+    }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+    png_structp png_ptr = png_create_write_struct_2
+       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+        user_error_fn, user_warning_fn, (png_voidp)
+        user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling.  When libpng encounters an error, it expects to
+longjmp() back to your routine.  Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr).  If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function.  See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp.  See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       fclose(fp);
+       return (ERROR);
+    }
+    ...
+    return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code.  The default for libpng is to
+use the C function fwrite().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+    png_init_io(png_ptr, fp);
+
+Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void write_row_callback(png_ptr, png_uint_32 row,
+       int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run.  The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing.  If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream).  The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline.  See the PNG specification for details on the specific filter
+types.
+
+
+    /* turn on or off filtering, and/or choose
+       specific filters.  You can use either a single
+       PNG_FILTER_VALUE_NAME or the logical OR of one
+       or more PNG_FILTER_NAME masks. */
+    png_set_filter(png_ptr, 0,
+       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
+       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
+       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
+       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |
+       PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+       PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing.  The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data.  See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+    /* set the zlib compression level */
+    png_set_compression_level(png_ptr,
+        Z_BEST_COMPRESSION);
+
+    /* set other zlib parameters */
+    png_set_compression_mem_level(png_ptr, 8);
+    png_set_compression_strategy(png_ptr,
+        Z_DEFAULT_STRATEGY);
+    png_set_compression_window_bits(png_ptr, 15);
+    png_set_compression_method(png_ptr, 8);
+    png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image.  Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
+the latest PNG specification for more information on that.  If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid.  If you want to wait until after the data, don't
+fill them until png_write_end().  For all the fields in png_info and
+their data types, see png.h.  For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+       bit_depth, color_type, interlace_type,
+       compression_type, filter_method)
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.
+                     (valid values are 1, 2, 4, 8, 16
+                     and depend also on the
+                     color_type.  See also significant
+                     bits (sBIT) below).
+    color_type     - describes which color/alpha
+                     channels are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    interlace_type - PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7
+    compression_type - (must be
+                     PNG_COMPRESSION_TYPE_DEFAULT)
+    filter_method  - (must be PNG_FILTER_TYPE_DEFAULT
+                     or, if you are writing a PNG to
+                     be embedded in a MNG datastream,
+                     can also be
+                     PNG_INTRAPIXEL_DIFFERENCING)
+
+    png_set_PLTE(png_ptr, info_ptr, palette,
+       num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_set_gAMA(png_ptr, info_ptr, gamma);
+    gamma          - the gamma the image was created
+                     at (PNG_INFO_gAMA)
+
+    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of
+                     the sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This chunk also implies specific
+                     values of gAMA and cHRM.  Rendering
+                     intent is the CSS-1 property that
+                     has been defined by the International
+                     Color Consortium
+                     (http://www.color.org).
+                     It can be one of
+                     PNG_sRGB_INTENT_SATURATION,
+                     PNG_sRGB_INTENT_PERCEPTUAL,
+                     PNG_sRGB_INTENT_ABSOLUTE, or
+                     PNG_sRGB_INTENT_RELATIVE.
+
+
+    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+       srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of the
+                     sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This function also causes gAMA and
+                     cHRM chunks with the specific values
+                     that are consistent with sRGB to be
+                     written.
+
+    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+                      profile, proflen);
+    name            - The profile name.
+    compression     - The compression type; always
+                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+                      You may give NULL to this argument to
+                      ignore it.
+    profile         - International Color Consortium color
+                      profile data. May contain NULs.
+    proflen         - length of profile data in bytes.
+
+    png_set_sBIT(png_ptr, info_ptr, sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray, red,
+                     green, and blue channels, whichever are
+                     appropriate for the given color type
+                     (png_color_16)
+
+    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+       trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - graylevel or color sample values of
+                     the single transparent color for
+                     non-paletted images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_set_hIST(png_ptr, info_ptr, hist);
+                    (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_uint_16)
+
+    png_set_tIME(png_ptr, info_ptr, mod_time);
+    mod_time       - time image was last modified
+                     (PNG_VALID_tIME)
+
+    png_set_bKGD(png_ptr, info_ptr, background);
+    background     - background color (PNG_VALID_bKGD)
+
+    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i].compression - type of compression used
+                 on "text" PNG_TEXT_COMPRESSION_NONE
+                           PNG_TEXT_COMPRESSION_zTXt
+                           PNG_ITXT_COMPRESSION_NONE
+                           PNG_ITXT_COMPRESSION_zTXt
+    text_ptr[i].key   - keyword for comment.  Must contain
+                 1-79 characters.
+    text_ptr[i].text  - text comments for current
+                         keyword.  Can be NULL or empty.
+    text_ptr[i].text_length - length of text string,
+                 after decompression, 0 for iTXt
+    text_ptr[i].itxt_length - length of itxt string,
+                 after decompression, 0 for tEXt/zTXt
+    text_ptr[i].lang  - language of comment (NULL or
+                         empty for unknown).
+    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
+                         or empty for unknown).
+    num_text       - number of comments
+
+    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+       num_spalettes);
+    palette_ptr    - array of png_sPLT_struct structures
+                     to be added to the list of palettes
+                     in the info structure.
+    num_spalettes  - number of palette structures to be
+                     added.
+
+    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+        unit_type);
+    offset_x  - positive offset from the left
+                     edge of the screen
+    offset_y  - positive offset from the top
+                     edge of the screen
+    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+        unit_type);
+    res_x       - pixels/unit physical resolution
+                  in x direction
+    res_y       - pixels/unit physical resolution
+                  in y direction
+    unit_type   - PNG_RESOLUTION_UNKNOWN,
+                  PNG_RESOLUTION_METER
+
+    png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                  (width and height are doubles)
+
+    png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+    unit        - physical scale units (an integer)
+    width       - width of a pixel in physical scale units
+    height      - height of a pixel in physical scale units
+                 (width and height are strings like "2.54")
+
+    png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+       num_unknowns)
+    unknowns          - array of png_unknown_chunk
+                        structures holding unknown chunks
+    unknowns[i].name  - name of unknown chunk
+    unknowns[i].data  - data of unknown chunk
+    unknowns[i].size  - size of unknown chunk's data
+    unknowns[i].location - position to write chunk in file
+                           0: do not write chunk
+                           PNG_HAVE_IHDR: before PLTE
+                           PNG_HAVE_PLTE: before IDAT
+                           PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c.  Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text.  text is an array of png_text
+structures.  num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data.  Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed.  So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+    Title            Short (one line) title or
+                     caption for image
+    Author           Name of image's creator
+    Description      Description of image (possibly long)
+    Copyright        Copyright notice
+    Creation Time    Time of original image creation
+                     (usually RFC 1123 format, see below)
+    Software         Software used to create the image
+    Disclaimer       Legal disclaimer
+    Warning          Warning of nature of content
+    Source           Device used to create the image
+    Comment          Miscellaneous comment; conversion
+                     from other image format
+
+The keyword-text pairs work like this.  Keywords should be short
+simple descriptions of what the comment is about.  Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords.  You can repeat keywords in a file.  You can even write
+some text before the image and some after.  For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image.  Finally, keywords should be full
+words, not abbreviations.  Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters.  To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set.  The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure.  Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm.  The
+time_t routine uses gmtime().  You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time.  Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword.  This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself.  In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement.  Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software.  To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing.  You give it a chunk name, raw data, and a size; that's
+all there is to it.  The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure.  All defined output
+transformations are permitted, enabled by the following masks.
+
+    PNG_TRANSFORM_IDENTITY      No transformation
+    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
+    PNG_TRANSFORM_PACKSWAP      Change order of packed
+                                pixels to LSB first
+    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
+    PNG_TRANSFORM_SHIFT         Normalize pixels to the
+                                sBIT depth
+    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
+                                to BGRA
+    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
+                                to AG
+    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
+                                to transparency
+    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples
+    PNG_TRANSFORM_STRIP_FILLER  Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+    png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags.  This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform mask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used.  Someday it might point
+to transformation parameters required by some future output transform.)
+
+You must use png_transforms and not call any png_set_transform() functions
+when you use png_write_png().
+
+The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data.  You do
+this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info().  In PNG files, the alpha channel in an image is the
+level of opacity.  If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written.  If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+    png_write_info_before_PLTE(png_ptr, info_ptr);
+    png_set_unknown_chunks(png_ptr, info_ptr, ...);
+    png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+    png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+    /* Set the true bit depth of the image data */
+    if (color_type & PNG_COLOR_MASK_COLOR)
+    {
+        sig_bit.red = true_bit_depth;
+        sig_bit.green = true_bit_depth;
+        sig_bit.blue = true_bit_depth;
+    }
+    else
+    {
+        sig_bit.gray = true_bit_depth;
+    }
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+    {
+        sig_bit.alpha = true_bit_depth;
+    }
+
+    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+    png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+    if (bit_depth > 8)
+       png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order.  This code
+would be used if they are supplied as blue, green, red:
+
+    png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+    png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_write_user_transform_fn(png_ptr,
+       write_transform_fn);
+
+You must supply the function
+
+    void write_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data)
+
+See pngtest.c for a working example.  Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written.  To
+flush the output stream a single time call:
+
+    png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+    png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications).  Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+Writing the image data
+
+That's it for the transformations.  Now you can write the image data.
+The simplest way to do this is in one function call.  If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image.  You will need to pass in an array of pointers to
+each row.  This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+    png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+    png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead.  If the file is not interlaced,
+this is simple:
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+    png_bytep row_pointer = row;
+
+    png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated.  The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size.  libpng will build
+these images for you, or you can do them yourself.  If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+    number_of_passes =
+       png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file.  If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer.  If you are not interested,
+you can pass NULL.
+
+    png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+    png_free_data(png_ptr, info_ptr, mask, seq)
+    mask  - identifies data to be freed, a mask
+            containing the logical OR of one or
+            more of
+              PNG_FREE_PLTE, PNG_FREE_TRNS,
+              PNG_FREE_HIST, PNG_FREE_ICCP,
+              PNG_FREE_PCAL, PNG_FREE_ROWS,
+              PNG_FREE_SCAL, PNG_FREE_SPLT,
+              PNG_FREE_TEXT, PNG_FREE_UNKN,
+            or simply PNG_FREE_ALL
+    seq   - sequence number of item to be freed
+            (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user  and not by libpng,  and will in those
+cases do nothing.  The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed.  If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the mask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng.  This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+    png_data_freer(png_ptr, info_ptr, freer, mask)
+    mask   - which data elements are affected
+             same choices as in png_free_data()
+    freer  - one of
+               PNG_DESTROY_WILL_FREE_DATA
+               PNG_SET_WILL_FREE_DATA
+               PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+    png_data_freer(read_ptr, read_info_ptr,
+       PNG_USER_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+    png_data_freer(write_ptr, write_info_ptr,
+       PNG_DESTROY_WILL_FREE_DATA,
+       PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function.  Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key.  Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+V. Modifying/Customizing libpng:
+
+There are three issues here.  The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them.  The third is a
+run-time issue:  choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively.  To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc()
+and png_free().  These currently just call the standard C functions.  If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time.  If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register
+your own functions as described above.
+These functions also provide a void pointer that can be retrieved via
+
+    mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your replacement memory functions must have prototypes as follows:
+
+    png_voidp malloc_fn(png_structp png_ptr,
+       png_size_t size);
+    void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() must return NULL in case of failure.  The png_malloc()
+function will normally call png_error() if it receives a NULL from the
+system memory allocator or from your replacement malloc_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite().  The FILE * is stored in
+png_struct and is initialized via png_init_io().  If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function.  These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr().  For example:
+
+    png_set_read_fn(png_structp read_ptr,
+        voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+    png_set_write_fn(png_structp write_ptr,
+        voidp write_io_ptr, png_rw_ptr write_data_fn,
+        png_flush_ptr output_flush_fn);
+
+    voidp read_io_ptr = png_get_io_ptr(read_ptr);
+    voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The replacement I/O functions must have prototypes as follows:
+
+    void user_read_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_write_data(png_structp png_ptr,
+        png_bytep data, png_size_t length);
+    void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions.  It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller.  Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available).  If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks.  These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own replacement
+functions after png_create_*_struct() has been called by calling:
+
+    png_set_error_fn(png_structp png_ptr,
+        png_voidp error_ptr, png_error_ptr error_fn,
+        png_error_ptr warning_fn);
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered.  The replacement error functions should have
+parameters as follows:
+
+    void user_error_fn(png_structp png_ptr,
+        png_const_charp error_msg);
+    void user_warning_fn(png_structp png_ptr,
+        png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods.  This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself.  Consult your compiler
+documentation for more details.  For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code.  The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks.  Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works.  Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk
+that is similar to yours and use it as a template.  More details can
+be found in the comments inside the code.  It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work.  Try to find a similar
+transformation to the one you want to add and copy off of it.  More details
+can be found in the comments inside the code itself.
+
+Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn().  On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add/change/delete
+an include, this is the place to do it.  The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself.  The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+Configuring zlib:
+
+There are special functions to configure the compression.  Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9.  The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster.  For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap.  You can specify the
+compression level by calling:
+
+    png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+    png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib.  They are not recommended
+for normal use and may result in writing an invalid PNG file.  See
+zlib.h for more information on what these mean.
+
+    png_set_compression_strategy(png_ptr,
+        strategy);
+    png_set_compression_window_bits(png_ptr,
+        window_bits);
+    png_set_compression_method(png_ptr, method);
+    png_set_compression_buffer_size(png_ptr, size);
+
+Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions.  The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image.  Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification.  The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types.  (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+              PNG_FILTER_UP | PNG_FILTER_AVE |
+              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+       filters);
+              The second parameter can also be
+              PNG_INTRAPIXEL_DIFFERENCING if you are
+              writing a PNG to be embedded in a MNG
+              datastream.  This parameter must be the
+              same as the value of filter_method used
+              in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters.  This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+    double weights[3] = {1.5, 1.3, 1.1},
+       costs[PNG_FILTER_VALUE_LAST] =
+       {1.0, 1.3, 1.3, 1.5, 1.7};
+
+    png_set_filter_heuristics(png_ptr,
+       PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+       weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter.  In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen.  Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters.  This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage.  Little testing has
+been done to find optimum values for either the costs or the weights.
+
+Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want.  The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks
+Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw.  The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout.  Set it to an integer value in the range 0 to 3.  Higher
+numbers result in increasing amounts of debugging information.  The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+   png_debug(level, message)
+   png_debug1(level, message, p1)
+   png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives.  For example,
+
+   png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+   if(PNG_DEBUG > 2)
+     fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+   #ifdef PNG_DEBUG
+       fprintf(stderr, ...
+   #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed.  There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+VI.  Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines.  Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transparent row data with previous row data.  Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions.  (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them.  Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations.  For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       png_uint_32 mask, flags;
+
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags | mask);
+    #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagmask(); similarly for optimizing
+only writing.  To disable all optimizations:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = png_get_asm_flags(png_ptr);
+       mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+       png_set_asm_flags(png_ptr, flags & ~mask);
+    #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagmask()
+in place of png_get_asm_flagmask().  The mmx version takes one additional
+parameter:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+       int compilerID;
+
+       mask = png_get_mmx_flagmask(selection, &compilerID);
+    #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled.  Currently two flavors exist:  Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use.  In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled.  It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+             | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+             | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+       png_set_asm_flags(png_ptr, flags);
+    #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used.  (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+    #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+       mmxsupport = png_mmx_support();
+    #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available.  Note that png_mmx_support(), png_get_mmx_flagmask(),
+and png_get_asm_flagmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+  && defined(PNG_THREAD_UNSAFE_OK)
+    /* Disable thread-unsafe features of pnggccrd */
+    if (png_access_version() >= 10200)
+    {
+      png_uint_32 mmx_disable_mask = 0;
+      png_uint_32 asm_flags;
+
+      mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
+                          | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+      asm_flags = png_get_asm_flags(png_ptr);
+      png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+    }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+VII.  MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions.  To enable them, use the
+png_permit_mng_features() function:
+
+   feature_set = png_permit_mng_features(png_ptr, mask)
+   mask is a png_uint_32 containing the logical OR of the
+        features you want to enable.  These include
+        PNG_FLAG_MNG_EMPTY_PLTE
+        PNG_FLAG_MNG_FILTER_64
+        PNG_ALL_MNG_FEATURES
+   feature_set is a png_uint_32 that is the logical AND of
+      your mask with the set of MNG features that is
+      supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature.  The PNG datastream must be wrapped
+in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks.  Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them.  You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+VIII.  Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not.  The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero.  It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can find out which version of the library
+you are using at run-time:
+
+   png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+   png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+IX. Y2K Compliance in libpng
+
+December 3, 2004
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.8 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields.  One is a 2-byte unsigned integer that
+will hold years up to 65535.  The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+    "png_uint_16 year" in png_time_struct.
+
+The strings are
+    "png_charp time_buffer" in png_struct and
+    "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+    png_convert_to_rfc_1123() in png.c
+      (formerly png_convert_to_rfc_1152() in error)
+    png_convert_from_struct_tm() in pngwrite.c, called
+      in pngwrite.c
+    png_convert_from_time_t() in pngwrite.c
+    png_get_tIME() in pngget.c
+    png_handle_tIME() in pngrutil.c, called in pngread.c
+    png_set_tIME() in pngset.c
+    png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment.  The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year.  There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
+
+   Glenn Randers-Pehrson
+   libpng maintainer
+   PNG Development Group
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpngpf.3
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpngpf.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/libpngpf.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,806 @@
+.TH LIBPNGPF 3 "June 26, 2010"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.44
+(private functions)
+.SH SYNOPSIS
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBvoid png_64bit_product (long \fP\fIv1\fP\fB, long \fP\fIv2\fP\fB, unsigned long \fI*hi_product,
+
+\fBunsigned long \fI*lo_product\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBint png_check_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_fixed_point \fP\fIint_white_x\fP\fB, png_fixed_point \fP\fIint_white_y\fP\fB, png_fixed_point \fP\fIint_red_x\fP\fB, png_fixed_point \fP\fIint_red_y\fP\fB, png_fixed_point \fP\fIint_green_x\fP\fB, png_fixed_point \fP\fIint_green_y\fP\fB, png_fixed_point \fP\fIint_blue_x\fP\fB, png_fixed_point \fIint_blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_check_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fImask\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBpng_voidp png_create_struct (int \fItype\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBpng_voidp png_create_struct_2 (int \fP\fItype\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_decompress_chunk (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcomp_type\fP\fB, png_charp \fP\fIchunkdata\fP\fB, png_size_t \fP\fIchunklength\fP\fB, png_size_t \fP\fIprefix_length\fP\fB, png_size_t \fI*data_length\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fP\fIfree_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_iTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_init_mmx_flags (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBpng_uint_32 png_read_chunk_header (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBint png_set_text_2 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_find_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIint_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, int \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_iTXt (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcompression\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fIlang\fP\fB, png_charp \fP\fItranslated_key\fP\fB, png_charp \fItext\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_spalette_p \fIpalette\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fI\fB
+
+.SH DESCRIPTION
+The functions listed above are used privately by libpng
+and are not recommended for use by applications.  They are
+not "exported" to applications using shared libraries.  They
+are listed alphabetically here as an aid to libpng maintainers.
+See png.h for more information on these functions.
+
+.SH SEE ALSO
+.IR libpng(3) ", " png(5)
+.SH AUTHOR
+Glenn Randers-Pehrson
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.5
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.5	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.5	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,74 @@
+.TH PNG 5 "June 26, 2010"
+.SH NAME
+png \- Portable Network Graphics (PNG) format
+.SH DESCRIPTION
+PNG (Portable Network Graphics) is an extensible file format for the
+lossless, portable, well-compressed storage of raster images. PNG provides
+a patent-free replacement for GIF and can also replace many
+common uses of TIFF. Indexed-color, grayscale, and truecolor images are
+supported, plus an optional alpha channel. Sample depths range from
+1 to 16 bits.
+.br
+
+PNG is designed to work well in online viewing applications, such as the
+World Wide Web, so it is fully streamable with a progressive display
+option. PNG is robust, providing both full file integrity checking and
+fast, simple detection of common transmission errors. Also, PNG can store
+gamma and chromaticity data for improved color matching on heterogeneous
+platforms.
+
+.SH "SEE ALSO"
+.IR libpng(3) ", " zlib(3) ", " deflate(5) ", and " zlib(5)
+.LP
+PNG specification (second edition), November 2003:
+.IP
+.br
+  <http://www.w3.org/TR/2003/REC-PNG-20031110/
+PNG 1.2 specification, July 1999:
+.IP
+.br
+http://www.libpng.org/pub/png
+.LP
+PNG 1.0 specification, October 1996:
+.IP
+.br
+RFC 2083
+.IP
+.br
+ftp://ftp.rfc-editor.org:/in-notes/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+.LP
+Portable Network Graphics (PNG) Specification (Second Edition)
+Information technology - Computer graphics and image processing -
+Portable Network Graphics (PNG): Functional specification.
+ISO/IEC 15948:2003 (E) (November 10, 2003): David Duce and others.
+.LP
+Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
+Glenn Randers-Pehrson and others (png-list).
+.LP
+Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
+Thomas Boutell and others (png-list).
+.LP
+
+
+.SH COPYRIGHT NOTICE
+.LP
+This man page is Copyright (c) 1998-2006 Glenn Randers-Pehrson.  See png.h
+for conditions of use and distribution.
+.LP
+The PNG Specification (Second Edition) is
+Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved.
+.LP
+The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of
+Technology.  See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/png.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1100 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_44 Your_png_h_is_not_version_1_2_44;
+
+/* Version information for C files.  This had better match the version
+ * string defined in png.h.
+ */
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
+
+#ifdef PNG_READ_SUPPORTED
+
+/* png_sig was changed to a function in version 1.0.5c */
+/* Place to hold the signature string for a PNG file. */
+PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+#endif /* PNG_READ_SUPPORTED */
+
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+
+#ifdef PNG_READ_SUPPORTED
+/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* Start of interlace block */
+PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* Offset to next interlace block */
+PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* Start of interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* Offset to next interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* Height of interlace block.  This is not currently used - if you need
+ * it, uncomment it here and in png.h
+PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+PNG_CONST int FARDATA png_pass_mask[] =
+    {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+PNG_CONST int FARDATA png_pass_dsp_mask[]
+   = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature.  If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+   png_debug(1, "in png_set_sig_bytes");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (num_bytes > 8)
+      png_error(png_ptr, "Too many bytes for PNG signature.");
+
+   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature.  We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance.  Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+   if (num_to_check > 8)
+      num_to_check = 8;
+   else if (num_to_check < 1)
+      return (-1);
+
+   if (start > 7)
+      return (-1);
+
+   if (start + num_to_check > 8)
+      num_to_check = 8 - start;
+
+   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* (Obsolete) function to check signature bytes.  It does not allow one
+ * to check a partial signature.  This function might be removed in the
+ * future - use png_sig_cmp().  Returns true (nonzero) if the file is PNG.
+ */
+int PNGAPI
+png_check_sig(png_bytep sig, int num)
+{
+  return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib and clear it to 0. */
+#ifdef PNG_1_0_X
+voidpf PNGAPI
+#else
+voidpf /* PRIVATE */
+#endif
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+   png_voidp ptr;
+   png_structp p=(png_structp)png_ptr;
+   png_uint_32 save_flags=p->flags;
+   png_uint_32 num_bytes;
+
+   if (png_ptr == NULL)
+      return (NULL);
+   if (items > PNG_UINT_32_MAX/size)
+   {
+     png_warning (p, "Potential overflow in png_zalloc()");
+     return (NULL);
+   }
+   num_bytes = (png_uint_32)items * size;
+
+   p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+   p->flags=save_flags;
+
+#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
+   if (ptr == NULL)
+       return ((voidpf)ptr);
+
+   if (num_bytes > (png_uint_32)0x8000L)
+   {
+      png_memset(ptr, 0, (png_size_t)0x8000L);
+      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+   }
+   else
+   {
+      png_memset(ptr, 0, (png_size_t)num_bytes);
+   }
+#endif
+   return ((voidpf)ptr);
+}
+
+/* Function to free memory for zlib */
+#ifdef PNG_1_0_X
+void PNGAPI
+#else
+void /* PRIVATE */
+#endif
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+   png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structp png_ptr)
+{
+   png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data.  We can only pass as
+ * much data to this routine as the largest single buffer size.  We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   if (need_crc)
+      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application.  We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future.  This should be used in favour of malloc(png_sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop PNGAPI
+png_create_info_struct(png_structp png_ptr)
+{
+   png_infop info_ptr;
+
+   png_debug(1, "in png_create_info_struct");
+
+   if (png_ptr == NULL)
+      return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
+      png_ptr->malloc_fn, png_ptr->mem_ptr);
+#else
+   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+#endif
+   if (info_ptr != NULL)
+      png_info_init_3(&info_ptr, png_sizeof(png_info));
+
+   return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void PNGAPI
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+   png_infop info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_info_struct");
+
+   if (png_ptr == NULL)
+      return;
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      png_info_destroy(png_ptr, info_ptr);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
+          png_ptr->mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+}
+
+/* Initialize the info structure.  This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+#undef png_info_init
+void PNGAPI
+png_info_init(png_infop info_ptr)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+   png_info_init_3(&info_ptr, 0);
+}
+#endif
+
+void PNGAPI
+png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
+{
+   png_infop info_ptr = *ptr_ptr;
+
+   png_debug(1, "in png_info_init_3");
+
+   if (info_ptr == NULL)
+      return;
+
+   if (png_sizeof(png_info) > png_info_struct_size)
+   {
+      png_destroy_struct(info_ptr);
+      info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+      *ptr_ptr = info_ptr;
+   }
+
+   /* Set everything to 0 */
+   png_memset(info_ptr, 0, png_sizeof(png_info));
+}
+
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+   int freer, png_uint_32 mask)
+{
+   png_debug(1, "in png_data_freer");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (freer == PNG_DESTROY_WILL_FREE_DATA)
+      info_ptr->free_me |= mask;
+   else if (freer == PNG_USER_WILL_FREE_DATA)
+      info_ptr->free_me &= ~mask;
+   else
+      png_warning(png_ptr,
+         "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
+   int num)
+{
+   png_debug(1, "in png_free_data");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#ifdef PNG_TEXT_SUPPORTED
+   /* Free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_TEXT)
+#endif
+   {
+      if (num != -1)
+      {
+         if (info_ptr->text && info_ptr->text[num].key)
+         {
+            png_free(png_ptr, info_ptr->text[num].key);
+            info_ptr->text[num].key = NULL;
+         }
+      }
+      else
+      {
+         int i;
+         for (i = 0; i < info_ptr->num_text; i++)
+             png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+         png_free(png_ptr, info_ptr->text);
+         info_ptr->text = NULL;
+         info_ptr->num_text=0;
+      }
+   }
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+   /* Free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+   if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+   {
+      png_free(png_ptr, info_ptr->trans);
+      info_ptr->trans = NULL;
+      info_ptr->valid &= ~PNG_INFO_tRNS;
+#ifndef PNG_FREE_ME_SUPPORTED
+      png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+   }
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+   /* Free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_SCAL)
+#endif
+   {
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, info_ptr->scal_s_width);
+      png_free(png_ptr, info_ptr->scal_s_height);
+      info_ptr->scal_s_width = NULL;
+      info_ptr->scal_s_height = NULL;
+#endif
+      info_ptr->valid &= ~PNG_INFO_sCAL;
+   }
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+   /* Free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_PCAL)
+#endif
+   {
+      png_free(png_ptr, info_ptr->pcal_purpose);
+      png_free(png_ptr, info_ptr->pcal_units);
+      info_ptr->pcal_purpose = NULL;
+      info_ptr->pcal_units = NULL;
+      if (info_ptr->pcal_params != NULL)
+         {
+            int i;
+            for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+            {
+               png_free(png_ptr, info_ptr->pcal_params[i]);
+               info_ptr->pcal_params[i] = NULL;
+            }
+            png_free(png_ptr, info_ptr->pcal_params);
+            info_ptr->pcal_params = NULL;
+         }
+      info_ptr->valid &= ~PNG_INFO_pCAL;
+   }
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+   /* Free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_ICCP)
+#endif
+   {
+      png_free(png_ptr, info_ptr->iccp_name);
+      png_free(png_ptr, info_ptr->iccp_profile);
+      info_ptr->iccp_name = NULL;
+      info_ptr->iccp_profile = NULL;
+      info_ptr->valid &= ~PNG_INFO_iCCP;
+   }
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_SPLT)
+#endif
+   {
+      if (num != -1)
+      {
+         if (info_ptr->splt_palettes)
+         {
+            png_free(png_ptr, info_ptr->splt_palettes[num].name);
+            png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+            info_ptr->splt_palettes[num].name = NULL;
+            info_ptr->splt_palettes[num].entries = NULL;
+         }
+      }
+      else
+      {
+         if (info_ptr->splt_palettes_num)
+         {
+            int i;
+            for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+               png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+            png_free(png_ptr, info_ptr->splt_palettes);
+            info_ptr->splt_palettes = NULL;
+            info_ptr->splt_palettes_num = 0;
+         }
+         info_ptr->valid &= ~PNG_INFO_sPLT;
+      }
+   }
+#endif
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+   if (png_ptr->unknown_chunk.data)
+   {
+      png_free(png_ptr, png_ptr->unknown_chunk.data);
+      png_ptr->unknown_chunk.data = NULL;
+   }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_UNKN)
+#endif
+   {
+      if (num != -1)
+      {
+          if (info_ptr->unknown_chunks)
+          {
+             png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+             info_ptr->unknown_chunks[num].data = NULL;
+          }
+      }
+      else
+      {
+         int i;
+
+         if (info_ptr->unknown_chunks_num)
+         {
+            for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+               png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+            png_free(png_ptr, info_ptr->unknown_chunks);
+            info_ptr->unknown_chunks = NULL;
+            info_ptr->unknown_chunks_num = 0;
+         }
+      }
+   }
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+   /* Free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
+#else
+   if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+   {
+      png_free(png_ptr, info_ptr->hist);
+      info_ptr->hist = NULL;
+      info_ptr->valid &= ~PNG_INFO_hIST;
+#ifndef PNG_FREE_ME_SUPPORTED
+      png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+   }
+#endif
+
+   /* Free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+   if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+   {
+      png_zfree(png_ptr, info_ptr->palette);
+      info_ptr->palette = NULL;
+      info_ptr->valid &= ~PNG_INFO_PLTE;
+#ifndef PNG_FREE_ME_SUPPORTED
+      png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+      info_ptr->num_palette = 0;
+   }
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+   /* Free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+   if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+   if (mask & PNG_FREE_ROWS)
+#endif
+   {
+      if (info_ptr->row_pointers)
+      {
+         int row;
+         for (row = 0; row < (int)info_ptr->height; row++)
+         {
+            png_free(png_ptr, info_ptr->row_pointers[row]);
+            info_ptr->row_pointers[row] = NULL;
+         }
+         png_free(png_ptr, info_ptr->row_pointers);
+         info_ptr->row_pointers = NULL;
+      }
+      info_ptr->valid &= ~PNG_INFO_IDAT;
+   }
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (num == -1)
+      info_ptr->free_me &= ~mask;
+   else
+      info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
+#endif
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself.  Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void /* PRIVATE */
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_info_destroy");
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   if (png_ptr->num_chunk_list)
+   {
+      png_free(png_ptr, png_ptr->chunk_list);
+      png_ptr->chunk_list = NULL;
+      png_ptr->num_chunk_list = 0;
+   }
+#endif
+
+   png_info_init_3(&info_ptr, png_sizeof(png_info));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+   return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the default input/output functions for the PNG file.  If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io().  If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
+{
+   png_debug(1, "in png_init_io");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp PNGAPI
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+   static PNG_CONST char short_months[12][4] =
+        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+   if (png_ptr == NULL)
+      return (NULL);
+   if (png_ptr->time_buffer == NULL)
+   {
+      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+         png_sizeof(char)));
+   }
+
+#ifdef _WIN32_WCE
+   {
+      wchar_t time_buf[29];
+      wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+          ptime->day % 32, short_months[(ptime->month - 1) % 12],
+        ptime->year, ptime->hour % 24, ptime->minute % 60,
+          ptime->second % 61);
+      WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer,
+          29, NULL, NULL);
+   }
+#else
+#ifdef USE_FAR_KEYWORD
+   {
+      char near_time_buf[29];
+      png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
+          ptime->day % 32, short_months[(ptime->month - 1) % 12],
+          ptime->year, ptime->hour % 24, ptime->minute % 60,
+          ptime->second % 61);
+      png_memcpy(png_ptr->time_buffer, near_time_buf,
+          29*png_sizeof(char));
+   }
+#else
+   png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
+       ptime->day % 32, short_months[(ptime->month - 1) % 12],
+       ptime->year, ptime->hour % 24, ptime->minute % 60,
+       ptime->second % 61);
+#endif
+#endif /* _WIN32_WCE */
+   return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+png_charp PNGAPI
+png_get_copyright(png_structp png_ptr)
+{
+   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+#ifdef PNG_STRING_COPYRIGHT
+      return PNG_STRING_COPYRIGHT
+#else
+#ifdef __STDC__
+   return ((png_charp) PNG_STRING_NEWLINE \
+     "libpng version 1.2.44 - June 26, 2010" PNG_STRING_NEWLINE \
+     "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+     "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+     "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+     PNG_STRING_NEWLINE);
+#else
+      return ((png_charp) "libpng version 1.2.44 - June 26, 2010\
+      Copyright (c) 1998-2010 Glenn Randers-Pehrson\
+      Copyright (c) 1996-1997 Andreas Dilger\
+      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
+#endif
+#endif
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+   /* Version of *.c files used when building libpng */
+   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+   return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+   /* Version of *.h files used when building libpng */
+   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+   return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+   /* Returns longer string containing both version and date */
+   png_ptr = png_ptr;  /* Silence compiler warning about unused png_ptr */
+#ifdef __STDC__
+   return ((png_charp) PNG_HEADER_VERSION_STRING
+#ifndef PNG_READ_SUPPORTED
+   "     (NO READ SUPPORT)"
+#endif
+   PNG_STRING_NEWLINE);
+#else
+   return ((png_charp) PNG_HEADER_VERSION_STRING);
+#endif
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
+   int i;
+   png_bytep p;
+   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
+      return 0;
+   p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
+   for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
+      if (!png_memcmp(chunk_name, p, 4))
+        return ((int)*(p + 4));
+   return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return Z_STREAM_ERROR;
+   return (inflateReset(&png_ptr->zstream));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+   /* Version of *.c files used when building libpng */
+   return((png_uint_32) PNG_LIBPNG_VER);
+}
+
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#ifndef PNG_1_0_X
+/* This function was added to libpng 1.2.0 */
+int PNGAPI
+png_mmx_support(void)
+{
+   /* Obsolete, to be removed from libpng-1.4.0 */
+    return -1;
+}
+#endif /* PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_SIZE_T
+/* Added at libpng version 1.2.6 */
+   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+png_size_t PNGAPI
+png_convert_size(size_t size)
+{
+   if (size > (png_size_t)-1)
+      PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
+   return ((png_size_t)size);
+}
+#endif /* PNG_SIZE_T */
+
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+
+/*
+ *    Multiply two 32-bit numbers, V1 and V2, using 32-bit
+ *    arithmetic, to produce a 64 bit result in the HI/LO words.
+ *
+ *                  A B
+ *                x C D
+ *               ------
+ *              AD || BD
+ *        AC || CB || 0
+ *
+ *    where A and B are the high and low 16-bit words of V1,
+ *    C and D are the 16-bit words of V2, AD is the product of
+ *    A and D, and X || Y is (X << 16) + Y.
+*/
+
+void /* PRIVATE */
+png_64bit_product (long v1, long v2, unsigned long *hi_product,
+   unsigned long *lo_product)
+{
+   int a, b, c, d;
+   long lo, hi, x, y;
+
+   a = (v1 >> 16) & 0xffff;
+   b = v1 & 0xffff;
+   c = (v2 >> 16) & 0xffff;
+   d = v2 & 0xffff;
+
+   lo = b * d;                   /* BD */
+   x = a * d + c * b;            /* AD + CB */
+   y = ((lo >> 16) & 0xffff) + x;
+
+   lo = (lo & 0xffff) | ((y & 0xffff) << 16);
+   hi = (y >> 16) & 0xffff;
+
+   hi += a * c;                  /* AC */
+
+   *hi_product = (unsigned long)hi;
+   *lo_product = (unsigned long)lo;
+}
+
+int /* PRIVATE */
+png_check_cHRM_fixed(png_structp png_ptr,
+   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+   png_fixed_point blue_x, png_fixed_point blue_y)
+{
+   int ret = 1;
+   unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
+
+   png_debug(1, "in function png_check_cHRM_fixed");
+
+   if (png_ptr == NULL)
+      return 0;
+
+   if (white_x < 0 || white_y <= 0 ||
+         red_x < 0 ||   red_y <  0 ||
+       green_x < 0 || green_y <  0 ||
+        blue_x < 0 ||  blue_y <  0)
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set negative chromaticity value");
+      ret = 0;
+   }
+   if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
+       white_y > (png_fixed_point) PNG_UINT_31_MAX ||
+         red_x > (png_fixed_point) PNG_UINT_31_MAX ||
+         red_y > (png_fixed_point) PNG_UINT_31_MAX ||
+       green_x > (png_fixed_point) PNG_UINT_31_MAX ||
+       green_y > (png_fixed_point) PNG_UINT_31_MAX ||
+        blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
+        blue_y > (png_fixed_point) PNG_UINT_31_MAX )
+   {
+      png_warning(png_ptr,
+        "Ignoring attempt to set chromaticity value exceeding 21474.83");
+      ret = 0;
+   }
+   if (white_x > 100000L - white_y)
+   {
+      png_warning(png_ptr, "Invalid cHRM white point");
+      ret = 0;
+   }
+   if (red_x > 100000L - red_y)
+   {
+      png_warning(png_ptr, "Invalid cHRM red point");
+      ret = 0;
+   }
+   if (green_x > 100000L - green_y)
+   {
+      png_warning(png_ptr, "Invalid cHRM green point");
+      ret = 0;
+   }
+   if (blue_x > 100000L - blue_y)
+   {
+      png_warning(png_ptr, "Invalid cHRM blue point");
+      ret = 0;
+   }
+
+   png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
+   png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);
+
+   if (xy_hi == yx_hi && xy_lo == yx_lo)
+   {
+      png_warning(png_ptr,
+         "Ignoring attempt to set cHRM RGB triangle with zero area");
+      ret = 0;
+   }
+
+   return ret;
+}
+#endif /* PNG_CHECK_cHRM_SUPPORTED */
+#endif /* PNG_cHRM_SUPPORTED */
+
+void /* PRIVATE */
+png_check_IHDR(png_structp png_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)
+{
+   int error = 0;
+
+   /* Check for width and height valid values */
+   if (width == 0)
+   {
+      png_warning(png_ptr, "Image width is zero in IHDR");
+      error = 1;
+   }
+
+   if (height == 0)
+   {
+      png_warning(png_ptr, "Image height is zero in IHDR");
+      error = 1;
+   }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX)
+#else
+   if (width > PNG_USER_WIDTH_MAX)
+#endif
+   {
+      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+      error = 1;
+   }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX)
+#else
+   if (height > PNG_USER_HEIGHT_MAX)
+#endif
+   {
+      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+      error = 1;
+   }
+
+   if (width > PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr, "Invalid image width in IHDR");
+      error = 1;
+   }
+
+   if ( height > PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr, "Invalid image height in IHDR");
+      error = 1;
+   }
+
+   if ( width > (PNG_UINT_32_MAX
+                 >> 3)      /* 8-byte RGBA pixels */
+                 - 64       /* bigrowbuf hack */
+                 - 1        /* filter byte */
+                 - 7*8      /* rounding of width to multiple of 8 pixels */
+                 - 8)       /* extra max_pixel_depth pad */
+      png_warning(png_ptr, "Width is too large for libpng to process pixels");
+
+   /* Check other values */
+   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+       bit_depth != 8 && bit_depth != 16)
+   {
+      png_warning(png_ptr, "Invalid bit depth in IHDR");
+      error = 1;
+   }
+
+   if (color_type < 0 || color_type == 1 ||
+       color_type == 5 || color_type > 6)
+   {
+      png_warning(png_ptr, "Invalid color type in IHDR");
+      error = 1;
+   }
+
+   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+       ((color_type == PNG_COLOR_TYPE_RGB ||
+         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+   {
+      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
+      error = 1;
+   }
+
+   if (interlace_type >= PNG_INTERLACE_LAST)
+   {
+      png_warning(png_ptr, "Unknown interlace method in IHDR");
+      error = 1;
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Unknown compression method in IHDR");
+      error = 1;
+   }
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   /* Accept filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not read a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
+       png_ptr->mng_features_permitted)
+      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+         (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+         ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+         (color_type == PNG_COLOR_TYPE_RGB ||
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+      {
+         png_warning(png_ptr, "Unknown filter method in IHDR");
+         error = 1;
+      }
+
+      if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
+      {
+         png_warning(png_ptr, "Invalid filter method in IHDR");
+         error = 1;
+      }
+   }
+
+#else
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Unknown filter method in IHDR");
+      error = 1;
+   }
+#endif
+
+   if (error == 1)
+      png_error(png_ptr, "Invalid IHDR data");
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngerror.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngerror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngerror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,386 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.2.41 [December 3, 2009]
+ * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all error handling.  Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions.  See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
+  png_const_charp error_message)) PNG_NORETURN;
+#ifdef PNG_WARNINGS_SUPPORTED
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
+  png_const_charp warning_message));
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called whenever there is a fatal error.  This function
+ * should not be changed.  If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+void PNGAPI
+png_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   char msg[16];
+   if (png_ptr != NULL)
+   {
+     if (png_ptr->flags&
+       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+     {
+       if (*error_message == PNG_LITERAL_SHARP)
+       {
+           /* Strip "#nnnn " from beginning of error message. */
+           int offset;
+           for (offset = 1; offset<15; offset++)
+              if (error_message[offset] == ' ')
+                  break;
+           if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+           {
+              int i;
+              for (i = 0; i < offset - 1; i++)
+                 msg[i] = error_message[i + 1];
+              msg[i - 1] = '\0';
+              error_message = msg;
+           }
+           else
+              error_message += offset;
+       }
+       else
+       {
+           if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+           {
+              msg[0] = '0';
+              msg[1] = '\0';
+              error_message = msg;
+           }
+       }
+     }
+   }
+#endif
+   if (png_ptr != NULL && png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_ptr, error_message);
+
+   /* If the custom handler doesn't exist, or if it returns,
+      use the default handler, which will not return. */
+   png_default_error(png_ptr, error_message);
+}
+#else
+void PNGAPI
+png_err(png_structp png_ptr)
+{
+   if (png_ptr != NULL && png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_ptr, '\0');
+
+   /* If the custom handler doesn't exist, or if it returns,
+      use the default handler, which will not return. */
+   png_default_error(png_ptr, '\0');
+}
+#endif /* PNG_ERROR_TEXT_SUPPORTED */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called whenever there is a non-fatal error.  This function
+ * should not be changed.  If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+   int offset = 0;
+   if (png_ptr != NULL)
+   {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (png_ptr->flags&
+     (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+     {
+       if (*warning_message == PNG_LITERAL_SHARP)
+       {
+           for (offset = 1; offset < 15; offset++)
+              if (warning_message[offset] == ' ')
+                  break;
+       }
+     }
+   }
+   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+      (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
+   else
+      png_default_warning(png_ptr, warning_message + offset);
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_benign_error(png_structp png_ptr, png_const_charp error_message)
+{
+  if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+    png_warning(png_ptr, error_message);
+  else
+    png_error(png_ptr, error_message);
+}
+#endif
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message.  The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+   'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+#define PNG_MAX_ERROR_TEXT 64
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+static void /* PRIVATE */
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+   error_message)
+{
+   int iout = 0, iin = 0;
+
+   while (iin < 4)
+   {
+      int c = png_ptr->chunk_name[iin++];
+      if (isnonalpha(c))
+      {
+         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
+         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+         buffer[iout++] = png_digit[c & 0x0f];
+         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
+      }
+      else
+      {
+         buffer[iout++] = (png_byte)c;
+      }
+   }
+
+   if (error_message == NULL)
+      buffer[iout] = '\0';
+   else
+   {
+      buffer[iout++] = ':';
+      buffer[iout++] = ' ';
+      png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
+      buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
+   }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_chunk_error(png_structp png_ptr, png_const_charp error_message)
+{
+   char msg[18+PNG_MAX_ERROR_TEXT];
+   if (png_ptr == NULL)
+     png_error(png_ptr, error_message);
+   else
+   {
+     png_format_buffer(png_ptr, msg, error_message);
+     png_error(png_ptr, msg);
+   }
+}
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void PNGAPI
+png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+   char msg[18+PNG_MAX_ERROR_TEXT];
+   if (png_ptr == NULL)
+     png_warning(png_ptr, warning_message);
+   else
+   {
+     png_format_buffer(png_ptr, msg, warning_message);
+     png_warning(png_ptr, msg);
+   }
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_READ_SUPPORTED
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
+{
+  if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+    png_chunk_warning(png_ptr, error_message);
+  else
+    png_chunk_error(png_ptr, error_message);
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void /* PRIVATE */
+png_default_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (*error_message == PNG_LITERAL_SHARP)
+   {
+     /* Strip "#nnnn " from beginning of error message. */
+     int offset;
+     char error_number[16];
+     for (offset = 0; offset<15; offset++)
+     {
+         error_number[offset] = error_message[offset + 1];
+         if (error_message[offset] == ' ')
+             break;
+     }
+     if ((offset > 1) && (offset < 15))
+     {
+       error_number[offset - 1] = '\0';
+       fprintf(stderr, "libpng error no. %s: %s",
+          error_number, error_message + offset + 1);
+       fprintf(stderr, PNG_STRING_NEWLINE);
+     }
+     else
+     {
+       fprintf(stderr, "libpng error: %s, offset=%d",
+          error_message, offset);
+       fprintf(stderr, PNG_STRING_NEWLINE);
+     }
+   }
+   else
+#endif
+   {
+      fprintf(stderr, "libpng error: %s", error_message);
+      fprintf(stderr, PNG_STRING_NEWLINE);
+   }
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   if (png_ptr)
+   {
+#  ifdef USE_FAR_KEYWORD
+   {
+      jmp_buf jmpbuf;
+      png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+     longjmp(jmpbuf,1);
+   }
+#  else
+   longjmp(png_ptr->jmpbuf, 1);
+#  endif
+   }
+#endif
+   /* Here if not setjmp support or if png_ptr is null. */
+   PNG_ABORT();
+#ifndef PNG_CONSOLE_IO_SUPPORTED
+   error_message = error_message; /* Make compiler happy */
+#endif
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want them to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
+   if (*warning_message == PNG_LITERAL_SHARP)
+   {
+     int offset;
+     char warning_number[16];
+     for (offset = 0; offset < 15; offset++)
+     {
+        warning_number[offset] = warning_message[offset + 1];
+        if (warning_message[offset] == ' ')
+            break;
+     }
+     if ((offset > 1) && (offset < 15))
+     {
+       warning_number[offset + 1] = '\0';
+       fprintf(stderr, "libpng warning no. %s: %s",
+          warning_number, warning_message + offset);
+       fprintf(stderr, PNG_STRING_NEWLINE);
+     }
+     else
+     {
+       fprintf(stderr, "libpng warning: %s",
+          warning_message);
+       fprintf(stderr, PNG_STRING_NEWLINE);
+     }
+   }
+   else
+#  endif
+   {
+     fprintf(stderr, "libpng warning: %s", warning_message);
+     fprintf(stderr, PNG_STRING_NEWLINE);
+   }
+#else
+   warning_message = warning_message; /* Make compiler happy */
+#endif
+   png_ptr = png_ptr; /* Make compiler happy */
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings.  Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur.  The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+   if (png_ptr == NULL)
+      return;
+   png_ptr->error_ptr = error_ptr;
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return NULL;
+   return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+{
+   if (png_ptr != NULL)
+   {
+     png_ptr->flags &=
+       ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+   }
+}
+#endif
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pnggccrd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pnggccrd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pnggccrd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,103 @@
+/* pnggccrd.c was removed from libpng-1.2.20. */
+
+/* This code snippet is for use by configure's compilation test. */
+
+#if (!defined _MSC_VER) && \
+    defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
+    defined(PNG_MMX_CODE_SUPPORTED)
+
+int PNGAPI png_dummy_mmx_support(void);
+
+static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
+
+int PNGAPI
+png_dummy_mmx_support(void) __attribute__((noinline));
+
+int PNGAPI
+png_dummy_mmx_support(void)
+{
+   int result;
+#ifdef PNG_MMX_CODE_SUPPORTED  // superfluous, but what the heck
+    __asm__ __volatile__ (
+#ifdef __x86_64__
+        "pushq %%rbx          \n\t"  // rbx gets clobbered by CPUID instruction
+        "pushq %%rcx          \n\t"  // so does rcx...
+        "pushq %%rdx          \n\t"  // ...and rdx (but rcx & rdx safe on Linux)
+        "pushfq               \n\t"  // save Eflag to stack
+        "popq %%rax           \n\t"  // get Eflag from stack into rax
+        "movq %%rax, %%rcx    \n\t"  // make another copy of Eflag in rcx
+        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+        "pushq %%rax          \n\t"  // save modified Eflag back to stack
+        "popfq                \n\t"  // restore modified value to Eflag reg
+        "pushfq               \n\t"  // save Eflag to stack
+        "popq %%rax           \n\t"  // get Eflag from stack
+        "pushq %%rcx          \n\t"  // save original Eflag to stack
+        "popfq                \n\t"  // restore original Eflag
+#else
+        "pushl %%ebx          \n\t"  // ebx gets clobbered by CPUID instruction
+        "pushl %%ecx          \n\t"  // so does ecx...
+        "pushl %%edx          \n\t"  // ...and edx (but ecx & edx safe on Linux)
+        "pushfl               \n\t"  // save Eflag to stack
+        "popl %%eax           \n\t"  // get Eflag from stack into eax
+        "movl %%eax, %%ecx    \n\t"  // make another copy of Eflag in ecx
+        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+        "pushl %%eax          \n\t"  // save modified Eflag back to stack
+        "popfl                \n\t"  // restore modified value to Eflag reg
+        "pushfl               \n\t"  // save Eflag to stack
+        "popl %%eax           \n\t"  // get Eflag from stack
+        "pushl %%ecx          \n\t"  // save original Eflag to stack
+        "popfl                \n\t"  // restore original Eflag
+#endif
+        "xorl %%ecx, %%eax    \n\t"  // compare new Eflag with original Eflag
+        "jz 0f                \n\t"  // if same, CPUID instr. is not supported
+
+        "xorl %%eax, %%eax    \n\t"  // set eax to zero
+//      ".byte  0x0f, 0xa2    \n\t"  // CPUID instruction (two-byte opcode)
+        "cpuid                \n\t"  // get the CPU identification info
+        "cmpl $1, %%eax       \n\t"  // make sure eax return non-zero value
+        "jl 0f                \n\t"  // if eax is zero, MMX is not supported
+
+        "xorl %%eax, %%eax    \n\t"  // set eax to zero and...
+        "incl %%eax           \n\t"  // ...increment eax to 1.  This pair is
+                                     // faster than the instruction "mov eax, 1"
+        "cpuid                \n\t"  // get the CPU identification info again
+        "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
+        "cmpl $0, %%edx       \n\t"  // 0 = MMX not supported
+        "jz 0f                \n\t"  // non-zero = yes, MMX IS supported
+
+        "movl $1, %%eax       \n\t"  // set return value to 1
+        "jmp  1f              \n\t"  // DONE:  have MMX support
+
+    "0:                       \n\t"  // .NOT_SUPPORTED: target label for jump instructions
+        "movl $0, %%eax       \n\t"  // set return value to 0
+    "1:                       \n\t"  // .RETURN: target label for jump instructions
+#ifdef __x86_64__
+        "popq %%rdx           \n\t"  // restore rdx
+        "popq %%rcx           \n\t"  // restore rcx
+        "popq %%rbx           \n\t"  // restore rbx
+#else
+        "popl %%edx           \n\t"  // restore edx
+        "popl %%ecx           \n\t"  // restore ecx
+        "popl %%ebx           \n\t"  // restore ebx
+#endif
+
+//      "ret                  \n\t"  // DONE:  no MMX support
+                                     // (fall through to standard C "ret")
+
+        : "=a" (result)              // output list
+
+        :                            // any variables used on input (none)
+
+                                     // no clobber list
+//      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
+//      , "memory"   // if write to a variable gcc thought was in a reg
+//      , "cc"       // "condition codes" (flag bits)
+    );
+    _mmx_supported = result;
+#else
+    _mmx_supported = 0;
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+    return _mmx_supported;
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngget.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngget.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngget.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,944 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->valid & flag);
+
+   else
+      return(0);
+}
+
+png_uint_32 PNGAPI
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->rowbytes);
+
+   else
+      return(0);
+}
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->row_pointers);
+
+   else
+      return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->width;
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->height;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->bit_depth;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->color_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->filter_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->interlace_type;
+
+   return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return info_ptr->compression_type;
+
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_x_pixels_per_meter");
+
+      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+
+      else
+          return (info_ptr->x_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_y_pixels_per_meter");
+
+      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+
+      else
+          return (info_ptr->y_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
+      if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+         info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+          return (0);
+
+      else
+          return (info_ptr->x_pixels_per_unit);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+   {
+   if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+
+   if (info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
+      if (info_ptr->x_pixels_per_unit == 0)
+         return ((float)0.0);
+
+      else
+         return ((float)((float)info_ptr->y_pixels_per_unit
+            /(float)info_ptr->x_pixels_per_unit));
+   }
+#else
+      return (0.0);
+#endif
+   return ((float)0.0);
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_oFFs_SUPPORTED
+
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+      if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+
+      else
+          return (info_ptr->x_offset);
+   }
+#else
+      return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+      if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+
+      else
+          return (info_ptr->y_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+      if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+
+      else
+          return (info_ptr->x_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+      if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+
+      else
+          return (info_ptr->y_offset);
+   }
+#else
+   return (0);
+#endif
+   return (0);
+}
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+     *.0254 +.5));
+}
+
+float PNGAPI
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+     *.00003937);
+}
+
+float PNGAPI
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+     *.00003937);
+}
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function", "pHYs");
+
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+         if (*unit_type == 1)
+         {
+            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+         }
+      }
+   }
+   return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif  /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif  /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte PNGAPI
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->channels);
+   else
+      return (0);
+}
+
+png_bytep PNGAPI
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->signature);
+   else
+      return (NULL);
+}
+
+#ifdef PNG_bKGD_SUPPORTED
+png_uint_32 PNGAPI
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+   png_color_16p *background)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+      && background != NULL)
+   {
+      png_debug1(1, "in %s retrieval function", "bKGD");
+
+      *background = &(info_ptr->background);
+      return (PNG_INFO_bKGD);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double *white_x, double *white_y, double *red_x, double *red_y,
+   double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      png_debug1(1, "in %s retrieval function", "cHRM");
+
+      if (white_x != NULL)
+         *white_x = (double)info_ptr->x_white;
+      if (white_y != NULL)
+         *white_y = (double)info_ptr->y_white;
+      if (red_x != NULL)
+         *red_x = (double)info_ptr->x_red;
+      if (red_y != NULL)
+         *red_y = (double)info_ptr->y_red;
+      if (green_x != NULL)
+         *green_x = (double)info_ptr->x_green;
+      if (green_y != NULL)
+         *green_y = (double)info_ptr->y_green;
+      if (blue_x != NULL)
+         *blue_x = (double)info_ptr->x_blue;
+      if (blue_y != NULL)
+         *blue_y = (double)info_ptr->y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+   png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+   png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+   png_debug1(1, "in %s retrieval function", "cHRM");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      if (white_x != NULL)
+         *white_x = info_ptr->int_x_white;
+      if (white_y != NULL)
+         *white_y = info_ptr->int_y_white;
+      if (red_x != NULL)
+         *red_x = info_ptr->int_x_red;
+      if (red_y != NULL)
+         *red_y = info_ptr->int_y_red;
+      if (green_x != NULL)
+         *green_x = info_ptr->int_x_green;
+      if (green_y != NULL)
+         *green_y = info_ptr->int_y_green;
+      if (blue_x != NULL)
+         *blue_x = info_ptr->int_x_blue;
+      if (blue_y != NULL)
+         *blue_y = info_ptr->int_y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+   png_debug1(1, "in %s retrieval function", "gAMA");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && file_gamma != NULL)
+   {
+      *file_gamma = (double)info_ptr->gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+    png_fixed_point *int_file_gamma)
+{
+   png_debug1(1, "in %s retrieval function", "gAMA");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && int_file_gamma != NULL)
+   {
+      *int_file_gamma = info_ptr->int_gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+   png_debug1(1, "in %s retrieval function", "sRGB");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+      && file_srgb_intent != NULL)
+   {
+      *file_srgb_intent = (int)info_ptr->srgb_intent;
+      return (PNG_INFO_sRGB);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charpp name, int *compression_type,
+             png_charpp profile, png_uint_32 *proflen)
+{
+   png_debug1(1, "in %s retrieval function", "iCCP");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+      && name != NULL && profile != NULL && proflen != NULL)
+   {
+      *name = info_ptr->iccp_name;
+      *profile = info_ptr->iccp_profile;
+      /* Compression_type is a dummy so the API won't have to change
+       * if we introduce multiple compression types later.
+       */
+      *proflen = (int)info_ptr->iccp_proflen;
+      *compression_type = (int)info_ptr->iccp_compression;
+      return (PNG_INFO_iCCP);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+             png_sPLT_tpp spalettes)
+{
+   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+   {
+     *spalettes = info_ptr->splt_palettes;
+     return ((png_uint_32)info_ptr->splt_palettes_num);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+png_uint_32 PNGAPI
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+   png_debug1(1, "in %s retrieval function", "hIST");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+      && hist != NULL)
+   {
+      *hist = info_ptr->hist;
+      return (PNG_INFO_hIST);
+   }
+   return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+   int *color_type, int *interlace_type, int *compression_type,
+   int *filter_type)
+
+{
+   png_debug1(1, "in %s retrieval function", "IHDR");
+
+   if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
+       height == NULL || bit_depth == NULL || color_type == NULL)
+      return (0);
+
+   *width = info_ptr->width;
+   *height = info_ptr->height;
+   *bit_depth = info_ptr->bit_depth;
+   *color_type = info_ptr->color_type;
+
+   if (compression_type != NULL)
+      *compression_type = info_ptr->compression_type;
+
+   if (filter_type != NULL)
+      *filter_type = info_ptr->filter_type;
+
+   if (interlace_type != NULL)
+      *interlace_type = info_ptr->interlace_type;
+
+   /* This is redundant if we can be sure that the info_ptr values were all
+    * assigned in png_set_IHDR().  We do the check anyhow in case an
+    * application has ignored our advice not to mess with the members
+    * of info_ptr directly.
+    */
+   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+       info_ptr->compression_type, info_ptr->filter_type);
+
+   return (1);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+   png_debug1(1, "in %s retrieval function", "oFFs");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+      && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+   {
+      *offset_x = info_ptr->x_offset;
+      *offset_y = info_ptr->y_offset;
+      *unit_type = (int)info_ptr->offset_unit_type;
+      return (PNG_INFO_oFFs);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+   png_charp *units, png_charpp *params)
+{
+   png_debug1(1, "in %s retrieval function", "pCAL");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+       && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+       nparams != NULL && units != NULL && params != NULL)
+   {
+      *purpose = info_ptr->pcal_purpose;
+      *X0 = info_ptr->pcal_X0;
+      *X1 = info_ptr->pcal_X1;
+      *type = (int)info_ptr->pcal_type;
+      *nparams = (int)info_ptr->pcal_nparams;
+      *units = info_ptr->pcal_units;
+      *params = info_ptr->pcal_params;
+      return (PNG_INFO_pCAL);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int *unit, double *width, double *height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+        (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_pixel_width;
+        *height = info_ptr->scal_pixel_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int *unit, png_charpp width, png_charpp height)
+{
+    if (png_ptr != NULL && info_ptr != NULL &&
+        (info_ptr->valid & PNG_INFO_sCAL))
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_s_width;
+        *height = info_ptr->scal_s_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   png_debug1(1, "in %s retrieval function", "pHYs");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+      (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+      }
+   }
+   return (retval);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+   int *num_palette)
+{
+   png_debug1(1, "in %s retrieval function", "PLTE");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+       && palette != NULL)
+   {
+      *palette = info_ptr->palette;
+      *num_palette = info_ptr->num_palette;
+      png_debug1(3, "num_palette = %d", *num_palette);
+      return (PNG_INFO_PLTE);
+   }
+   return (0);
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+   png_debug1(1, "in %s retrieval function", "sBIT");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+      && sig_bit != NULL)
+   {
+      *sig_bit = &(info_ptr->sig_bit);
+      return (PNG_INFO_sBIT);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+   int *num_text)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+   {
+      png_debug1(1, "in %s retrieval function",
+         (png_ptr->chunk_name[0] == '\0' ? "text"
+             : (png_const_charp)png_ptr->chunk_name));
+
+      if (text_ptr != NULL)
+         *text_ptr = info_ptr->text;
+
+      if (num_text != NULL)
+         *num_text = info_ptr->num_text;
+
+      return ((png_uint_32)info_ptr->num_text);
+   }
+   if (num_text != NULL)
+     *num_text = 0;
+   return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+   png_debug1(1, "in %s retrieval function", "tIME");
+
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+       && mod_time != NULL)
+   {
+      *mod_time = &(info_ptr->mod_time);
+      return (PNG_INFO_tIME);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+   png_uint_32 retval = 0;
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+   {
+      png_debug1(1, "in %s retrieval function", "tRNS");
+
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+          if (trans != NULL)
+          {
+             *trans = info_ptr->trans;
+             retval |= PNG_INFO_tRNS;
+          }
+
+          if (trans_values != NULL)
+             *trans_values = &(info_ptr->trans_values);
+      }
+      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+      {
+          if (trans_values != NULL)
+          {
+             *trans_values = &(info_ptr->trans_values);
+             retval |= PNG_INFO_tRNS;
+          }
+
+          if (trans != NULL)
+             *trans = NULL;
+      }
+      if (num_trans != NULL)
+      {
+         *num_trans = info_ptr->num_trans;
+         retval |= PNG_INFO_tRNS;
+      }
+   }
+   return (retval);
+}
+#endif
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+             png_unknown_chunkpp unknowns)
+{
+   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+   {
+     *unknowns = info_ptr->unknown_chunks;
+     return ((png_uint_32)info_ptr->unknown_chunks_num);
+   }
+   return (0);
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_structp png_ptr)
+{
+   return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+   return (png_ptr? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+   return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifndef PNG_1_0_X
+/* This function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flags (png_structp png_ptr)
+{
+    /* Obsolete, to be removed from libpng-1.4.0 */
+    return (png_ptr? 0L: 0L);
+}
+
+/* This function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flagmask (int flag_select)
+{
+    /* Obsolete, to be removed from libpng-1.4.0 */
+    flag_select=flag_select;
+    return 0L;
+}
+
+    /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
+/* This function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_flagmask (int flag_select, int *compilerID)
+{
+    /* Obsolete, to be removed from libpng-1.4.0 */
+    flag_select=flag_select;
+    *compilerID = -1;   /* unknown (i.e., no asm/MMX code compiled) */
+    return 0L;
+}
+
+/* This function was added to libpng 1.2.0 */
+png_byte PNGAPI
+png_get_mmx_bitdepth_threshold (png_structp png_ptr)
+{
+    /* Obsolete, to be removed from libpng-1.4.0 */
+    return (png_ptr? 0: 0);
+}
+
+/* This function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_rowbytes_threshold (png_structp png_ptr)
+{
+    /* Obsolete, to be removed from libpng-1.4.0 */
+    return (png_ptr? 0L: 0L);
+}
+#endif /* ?PNG_1_0_X */
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* These functions were added to libpng 1.2.6 but not enabled
+* by default. They will be enabled in libpng-1.4.0 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_structp png_ptr)
+{
+    return (png_ptr? png_ptr->user_width_max : 0);
+}
+png_uint_32 PNGAPI
+png_get_user_height_max (png_structp png_ptr)
+{
+    return (png_ptr? png_ptr->user_height_max : 0);
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngmem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,641 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.2.41 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all memory allocation.  Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* If you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct.  The malloc and memset can be replaced
+   by a single call to calloc() if this is thought to improve performance. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Alternate version of png_create_struct, for use with user-defined malloc. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+      size = png_sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+      size = png_sizeof(png_struct);
+   else
+      return (png_get_copyright(NULL));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (malloc_fn != NULL)
+   {
+      png_struct dummy_struct;
+      png_structp png_ptr = &dummy_struct;
+      png_ptr->mem_ptr=mem_ptr;
+      struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
+   }
+   else
+#endif /* PNG_USER_MEM_SUPPORTED */
+   struct_ptr = (png_voidp)farmalloc(size);
+   if (struct_ptr != NULL)
+      png_memset(struct_ptr, 0, size);
+   return (struct_ptr);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+    png_voidp mem_ptr)
+{
+#endif
+   if (struct_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      if (free_fn != NULL)
+      {
+         png_struct dummy_struct;
+         png_structp png_ptr = &dummy_struct;
+         png_ptr->mem_ptr=mem_ptr;
+         (*(free_fn))(png_ptr, struct_ptr);
+         return;
+      }
+#endif /* PNG_USER_MEM_SUPPORTED */
+      farfree (struct_ptr);
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store its
+ * memory stuff).  zlib doesn't like this at all, so we have to
+ * detect and deal with it.  This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode.  This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+png_voidp /* PRIVATE */
+png_calloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+   ret = (png_malloc(png_ptr, size));
+   if (ret != NULL)
+      png_memset(ret,0,(png_size_t)size);
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->malloc_fn != NULL)
+      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+   else
+      ret = (png_malloc_default(png_ptr, size));
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+       png_error(png_ptr, "Out of memory!");
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+   {
+      png_warning(png_ptr, "Cannot Allocate > 64K");
+      ret = NULL;
+   }
+   else
+#endif
+
+   if (size != (size_t)size)
+      ret = NULL;
+   else if (size == (png_uint_32)65536L)
+   {
+      if (png_ptr->offset_table == NULL)
+      {
+         /* Try to see if we need to do any of this fancy stuff */
+         ret = farmalloc(size);
+         if (ret == NULL || ((png_size_t)ret & 0xffff))
+         {
+            int num_blocks;
+            png_uint_32 total_size;
+            png_bytep table;
+            int i;
+            png_byte huge * hptr;
+
+            if (ret != NULL)
+            {
+               farfree(ret);
+               ret = NULL;
+            }
+
+            if (png_ptr->zlib_window_bits > 14)
+               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+            else
+               num_blocks = 1;
+            if (png_ptr->zlib_mem_level >= 7)
+               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+            else
+               num_blocks++;
+
+            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+            table = farmalloc(total_size);
+
+            if (table == NULL)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr, "Out Of Memory."); /* Note "O", "M" */
+               else
+                  png_warning(png_ptr, "Out Of Memory.");
+#endif
+               return (NULL);
+            }
+
+            if ((png_size_t)table & 0xfff0)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr,
+                    "Farmalloc didn't return normalized pointer");
+               else
+                  png_warning(png_ptr,
+                    "Farmalloc didn't return normalized pointer");
+#endif
+               return (NULL);
+            }
+
+            png_ptr->offset_table = table;
+            png_ptr->offset_table_ptr = farmalloc(num_blocks *
+               png_sizeof(png_bytep));
+
+            if (png_ptr->offset_table_ptr == NULL)
+            {
+#ifndef PNG_USER_MEM_SUPPORTED
+               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+                  png_error(png_ptr, "Out Of memory."); /* Note "O", "m" */
+               else
+                  png_warning(png_ptr, "Out Of memory.");
+#endif
+               return (NULL);
+            }
+
+            hptr = (png_byte huge *)table;
+            if ((png_size_t)hptr & 0xf)
+            {
+               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
+            }
+            for (i = 0; i < num_blocks; i++)
+            {
+               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
+            }
+
+            png_ptr->offset_table_number = num_blocks;
+            png_ptr->offset_table_count = 0;
+            png_ptr->offset_table_count_free = 0;
+         }
+      }
+
+      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+      {
+#ifndef PNG_USER_MEM_SUPPORTED
+         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+            png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
+         else
+            png_warning(png_ptr, "Out of Memory.");
+#endif
+         return (NULL);
+      }
+
+      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+   }
+   else
+      ret = farmalloc(size);
+
+#ifndef PNG_USER_MEM_SUPPORTED
+   if (ret == NULL)
+   {
+      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+         png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+      else
+         png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
+   }
+#endif
+
+   return (ret);
+}
+
+/* Free a pointer allocated by png_malloc().  In the default
+ * configuration, png_ptr is not used, but is passed in case it
+ * is needed.  If ptr is NULL, return without taking any action.
+ */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->free_fn != NULL)
+   {
+      (*(png_ptr->free_fn))(png_ptr, ptr);
+      return;
+   }
+   else
+      png_free_default(png_ptr, ptr);
+}
+
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+   if (png_ptr->offset_table != NULL)
+   {
+      int i;
+
+      for (i = 0; i < png_ptr->offset_table_count; i++)
+      {
+         if (ptr == png_ptr->offset_table_ptr[i])
+         {
+            ptr = NULL;
+            png_ptr->offset_table_count_free++;
+            break;
+         }
+      }
+      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+      {
+         farfree(png_ptr->offset_table);
+         farfree(png_ptr->offset_table_ptr);
+         png_ptr->offset_table = NULL;
+         png_ptr->offset_table_ptr = NULL;
+      }
+   }
+
+   if (ptr != NULL)
+   {
+      farfree(ptr);
+   }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info.  The malloc and
+   memset can be replaced by a single call to calloc() if this is thought
+   to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Allocate memory for a png_struct or a png_info.  The malloc and
+   memset can be replaced by a single call to calloc() if this is thought
+   to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+      size = png_sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+      size = png_sizeof(png_struct);
+   else
+      return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (malloc_fn != NULL)
+   {
+      png_struct dummy_struct;
+      png_structp png_ptr = &dummy_struct;
+      png_ptr->mem_ptr=mem_ptr;
+      struct_ptr = (*(malloc_fn))(png_ptr, size);
+      if (struct_ptr != NULL)
+         png_memset(struct_ptr, 0, size);
+      return (struct_ptr);
+   }
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   struct_ptr = (png_voidp)farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   struct_ptr = (png_voidp)halloc(size, 1);
+# else
+   struct_ptr = (png_voidp)malloc(size);
+# endif
+#endif
+   if (struct_ptr != NULL)
+      png_memset(struct_ptr, 0, size);
+
+   return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+    png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+   if (struct_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      if (free_fn != NULL)
+      {
+         png_struct dummy_struct;
+         png_structp png_ptr = &dummy_struct;
+         png_ptr->mem_ptr=mem_ptr;
+         (*(free_fn))(png_ptr, struct_ptr);
+         return;
+      }
+#endif /* PNG_USER_MEM_SUPPORTED */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+      farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+      hfree(struct_ptr);
+# else
+      free(struct_ptr);
+# endif
+#endif
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information.  zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ */
+
+png_voidp PNGAPI
+png_calloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+   ret = (png_malloc(png_ptr, size));
+   if (ret != NULL)
+      png_memset(ret,0,(png_size_t)size);
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+   if (png_ptr->malloc_fn != NULL)
+      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+   else
+      ret = (png_malloc_default(png_ptr, size));
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+       png_error(png_ptr, "Out of Memory!");
+   return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+   if (png_ptr == NULL || size == 0)
+      return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+   {
+#ifndef PNG_USER_MEM_SUPPORTED
+      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+         png_error(png_ptr, "Cannot Allocate > 64K");
+      else
+#endif
+         return NULL;
+   }
+#endif
+
+   /* Check for overflow */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   if (size != (unsigned long)size)
+      ret = NULL;
+   else
+      ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   if (size != (unsigned long)size)
+      ret = NULL;
+   else
+      ret = halloc(size, 1);
+# else
+   if (size != (size_t)size)
+      ret = NULL;
+   else
+      ret = malloc((size_t)size);
+# endif
+#endif
+
+#ifndef PNG_USER_MEM_SUPPORTED
+   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+      png_error(png_ptr, "Out of Memory");
+#endif
+
+   return (ret);
+}
+
+/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
+ * without taking any action.
+ */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr->free_fn != NULL)
+   {
+      (*(png_ptr->free_fn))(png_ptr, ptr);
+      return;
+   }
+   else
+      png_free_default(png_ptr, ptr);
+}
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   hfree(ptr);
+# else
+   free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+#ifdef PNG_1_0_X
+#  define png_malloc_warn png_malloc
+#else
+/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
+ * function will set up png_malloc() to issue a png_warning and return NULL
+ * instead of issuing a png_error, if it fails to allocate the requested
+ * memory.
+ */
+png_voidp PNGAPI
+png_malloc_warn(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ptr;
+   png_uint_32 save_flags;
+   if (png_ptr == NULL)
+      return (NULL);
+
+   save_flags = png_ptr->flags;
+   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
+   png_ptr->flags=save_flags;
+   return(ptr);
+}
+#endif
+
+png_voidp PNGAPI
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr, "Overflow in png_memcpy_check.");
+
+   return(png_memcpy (s1, s2, size));
+}
+
+png_voidp PNGAPI
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr, "Overflow in png_memset_check.");
+
+   return (png_memset (s1, value, size));
+
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+  malloc_fn, png_free_ptr free_fn)
+{
+   if (png_ptr != NULL)
+   {
+      png_ptr->mem_ptr = mem_ptr;
+      png_ptr->malloc_fn = malloc_fn;
+      png_ptr->free_fn = free_fn;
+   }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+   return ((png_voidp)png_ptr->mem_ptr);
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngpread.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngpread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngpread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1774 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.2.44 [June 26, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* Push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_READ_iTXt_MODE  7
+#define PNG_ERROR_MODE      8
+
+void PNGAPI
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+   png_bytep buffer, png_size_t buffer_size)
+{
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+   while (png_ptr->buffer_size)
+   {
+      png_process_some_data(png_ptr, info_ptr);
+   }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr == NULL)
+      return;
+
+   switch (png_ptr->process_mode)
+   {
+      case PNG_READ_SIG_MODE:
+      {
+         png_push_read_sig(png_ptr, info_ptr);
+         break;
+      }
+
+      case PNG_READ_CHUNK_MODE:
+      {
+         png_push_read_chunk(png_ptr, info_ptr);
+         break;
+      }
+
+      case PNG_READ_IDAT_MODE:
+      {
+         png_push_read_IDAT(png_ptr);
+         break;
+      }
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+      case PNG_READ_tEXt_MODE:
+      {
+         png_push_read_tEXt(png_ptr, info_ptr);
+         break;
+      }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      case PNG_READ_zTXt_MODE:
+      {
+         png_push_read_zTXt(png_ptr, info_ptr);
+         break;
+      }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      case PNG_READ_iTXt_MODE:
+      {
+         png_push_read_iTXt(png_ptr, info_ptr);
+         break;
+      }
+
+#endif
+      case PNG_SKIP_MODE:
+      {
+         png_push_crc_finish(png_ptr);
+         break;
+      }
+
+      default:
+      {
+         png_ptr->buffer_size = 0;
+         break;
+      }
+   }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature.  It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+   png_size_t num_checked = png_ptr->sig_bytes,
+             num_to_check = 8 - num_checked;
+
+   if (png_ptr->buffer_size < num_to_check)
+   {
+      num_to_check = png_ptr->buffer_size;
+   }
+
+   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+      num_to_check);
+   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
+
+   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+   {
+      if (num_checked < 4 &&
+          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+         png_error(png_ptr, "Not a PNG file");
+      else
+         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+   }
+   else
+   {
+      if (png_ptr->sig_bytes >= 8)
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+      }
+   }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_CONST PNG_IHDR;
+      PNG_CONST PNG_IDAT;
+      PNG_CONST PNG_IEND;
+      PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+      PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+      PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+      PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+      PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+      PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+      PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+      PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+      PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+      PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+      PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+      PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+      PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+      PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+      PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+      PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+
+   /* First we make sure we have enough data for the 4 byte chunk name
+    * and the 4 byte chunk length before proceeding with decoding the
+    * chunk data.  To fully decode each of these chunks, we also make
+    * sure we have enough data in the buffer for the 4 byte CRC at the
+    * end of every chunk (except IDAT, which is handled separately).
+    */
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+   }
+
+   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+     if (png_ptr->mode & PNG_AFTER_IDAT)
+        png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+   {
+      if (png_ptr->push_length != 13)
+         png_error(png_ptr, "Invalid IHDR length");
+
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+      png_ptr->process_mode = PNG_READ_DONE_MODE;
+      png_push_have_end(png_ptr, info_ptr);
+   }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+         png_ptr->mode |= PNG_HAVE_IDAT;
+
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+
+      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_ptr->mode |= PNG_HAVE_PLTE;
+
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         if (!(png_ptr->mode & PNG_HAVE_IHDR))
+            png_error(png_ptr, "Missing IHDR before IDAT");
+
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                  !(png_ptr->mode & PNG_HAVE_PLTE))
+            png_error(png_ptr, "Missing PLTE before IDAT");
+      }
+   }
+
+#endif
+   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+   {
+      /* If we reach an IDAT chunk, this means we have read all of the
+       * header chunks, and we can start reading the image (or if this
+       * is called after the image has been read - we have an error).
+       */
+
+      if (!(png_ptr->mode & PNG_HAVE_IHDR))
+         png_error(png_ptr, "Missing IHDR before IDAT");
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+          !(png_ptr->mode & PNG_HAVE_PLTE))
+         png_error(png_ptr, "Missing PLTE before IDAT");
+
+      if (png_ptr->mode & PNG_HAVE_IDAT)
+      {
+         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+            if (png_ptr->push_length == 0)
+               return;
+
+         if (png_ptr->mode & PNG_AFTER_IDAT)
+            png_error(png_ptr, "Too many IDAT's found");
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+      png_ptr->mode |= PNG_HAVE_IDAT;
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+      png_push_have_info(png_ptr, info_ptr);
+      png_ptr->zstream.avail_out =
+          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+          png_ptr->iwidth) + 1;
+      png_ptr->zstream.next_out = png_ptr->row_buf;
+      return;
+   }
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+#endif
+   else
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+   png_ptr->process_mode = PNG_SKIP_MODE;
+   png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structp png_ptr)
+{
+   if (png_ptr->skip_length && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->skip_length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->skip_length)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+   }
+}
+
+void PNGAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+   png_bytep ptr;
+
+   if (png_ptr == NULL)
+      return;
+
+   ptr = buffer;
+   if (png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->save_buffer_size)
+         save_size = length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+      length -= save_size;
+      ptr += save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->current_buffer_size)
+         save_size = length;
+
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structp png_ptr)
+{
+   if (png_ptr->save_buffer_size)
+   {
+      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+      {
+         png_size_t i, istop;
+         png_bytep sp;
+         png_bytep dp;
+
+         istop = png_ptr->save_buffer_size;
+         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+            i < istop; i++, sp++, dp++)
+         {
+            *dp = *sp;
+         }
+      }
+   }
+   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+      png_ptr->save_buffer_max)
+   {
+      png_size_t new_max;
+      png_bytep old_buffer;
+
+      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+         (png_ptr->current_buffer_size + 256))
+      {
+        png_error(png_ptr, "Potential overflow of save_buffer");
+      }
+
+      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+      old_buffer = png_ptr->save_buffer;
+      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+         (png_uint_32)new_max);
+      if (png_ptr->save_buffer == NULL)
+      {
+        png_free(png_ptr, old_buffer);
+        png_error(png_ptr, "Insufficient memory for save_buffer");
+      }
+      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      png_free(png_ptr, old_buffer);
+      png_ptr->save_buffer_max = new_max;
+   }
+   if (png_ptr->current_buffer_size)
+   {
+      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+      png_ptr->current_buffer_size = 0;
+   }
+   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+   png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   png_ptr->current_buffer = buffer;
+   png_ptr->current_buffer_size = buffer_length;
+   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_CONST PNG_IDAT;
+#endif
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+            png_error(png_ptr, "Not enough compressed data");
+         return;
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+   }
+   if (png_ptr->idat_size && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+
+         /* Check for overflow */
+         if ((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->idat_size && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+
+         /* Check for overflow */
+         if ((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->idat_size)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_AFTER_IDAT;
+   }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   /* The caller checks for a non-zero buffer length. */
+   if (!(buffer_length > 0) || buffer == NULL)
+      png_error(png_ptr, "No IDAT data (internal error)");
+
+   /* This routine must process all the data it has been given
+    * before returning, calling the row callback as required to
+    * handle the uncompressed results.
+    */
+   png_ptr->zstream.next_in = buffer;
+   png_ptr->zstream.avail_in = (uInt)buffer_length;
+
+   /* Keep going until the decompressed data is all processed
+    * or the stream marked as finished.
+    */
+   while (png_ptr->zstream.avail_in > 0 &&
+	  !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+   {
+      int ret;
+
+      /* We have data for zlib, but we must check that zlib
+       * has somewhere to put the results.  It doesn't matter
+       * if we don't expect any results -- it may be the input
+       * data is just the LZ end code.
+       */
+      if (!(png_ptr->zstream.avail_out > 0))
+      {
+         png_ptr->zstream.avail_out =
+             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+             png_ptr->iwidth) + 1;
+         png_ptr->zstream.next_out = png_ptr->row_buf;
+      }
+
+      /* Using Z_SYNC_FLUSH here means that an unterminated
+       * LZ stream can still be handled (a stream with a missing
+       * end code), otherwise (Z_NO_FLUSH) a future zlib
+       * implementation might defer output and, therefore,
+       * change the current behavior.  (See comments in inflate.c
+       * for why this doesn't happen at present with zlib 1.2.5.)
+       */
+      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+
+      /* Check for any failure before proceeding. */
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+	 /* Terminate the decompression. */
+	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+
+         /* This may be a truncated stream (missing or
+	  * damaged end code).  Treat that as a warning.
+	  */
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+	     png_ptr->pass > 6)
+	    png_warning(png_ptr, "Truncated compressed data in IDAT");
+	 else
+	    png_error(png_ptr, "Decompression error in IDAT");
+
+	 /* Skip the check on unprocessed input */
+         return;
+      }
+
+      /* Did inflate output any data? */
+      if (png_ptr->zstream.next_out != png_ptr->row_buf)
+      {
+	 /* Is this unexpected data after the last row?
+	  * If it is, artificially terminate the LZ output
+	  * here.
+	  */
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+	     png_ptr->pass > 6)
+         {
+	    /* Extra data. */
+	    png_warning(png_ptr, "Extra compressed data in IDAT");
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+	    /* Do no more processing; skip the unprocessed
+	     * input check below.
+	     */
+            return;
+	 }
+
+	 /* Do we have a complete row? */
+	 if (png_ptr->zstream.avail_out == 0)
+	    png_push_process_row(png_ptr);
+      }
+
+      /* And check for the end of the stream. */
+      if (ret == Z_STREAM_END)
+	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+   }
+
+   /* All the data should have been processed, if anything
+    * is left at this point we have bytes of IDAT data
+    * after the zlib end code.
+    */
+   if (png_ptr->zstream.avail_in > 0)
+      png_warning(png_ptr, "Extra compression data");
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structp png_ptr)
+{
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+       png_ptr->row_info.width);
+
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+       (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+
+   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+      png_do_read_transformations(png_ptr);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Blow up interlaced rows to full size */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+/*       old interface (pre-1.0.9):
+         png_do_read_interlace(&(png_ptr->row_info),
+             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+         png_do_read_interlace(png_ptr);
+
+    switch (png_ptr->pass)
+    {
+         case 0:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
+            }
+
+            if (png_ptr->pass == 2) /* Pass 1 might be empty */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            if (png_ptr->pass == 4 && png_ptr->height <= 4)
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            if (png_ptr->pass == 6 && png_ptr->height <= 4)
+            {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+
+         case 1:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 2:
+         {
+            int i;
+
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 4) /* Pass 3 might be empty */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 3:
+         {
+            int i;
+
+            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 4) /* Skip top two generated rows */
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+
+            break;
+         }
+
+         case 4:
+         {
+            int i;
+
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 6) /* Pass 5 might be empty */
+            {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+
+         case 5:
+         {
+            int i;
+
+            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            if (png_ptr->pass == 6) /* Skip top generated row */
+            {
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+
+            break;
+         }
+         case 6:
+         {
+            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+            png_read_push_finish_row(png_ptr);
+
+            if (png_ptr->pass != 6)
+               break;
+
+                  png_push_have_row(png_ptr, png_bytep_NULL);
+            png_read_push_finish_row(png_ptr);
+         }
+      }
+   }
+   else
+#endif
+   {
+      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+      png_read_push_finish_row(png_ptr);
+   }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+   /* Height of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   */
+#endif
+
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0,
+         png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+             (png_ptr->pass == 3 && png_ptr->width < 3) ||
+             (png_ptr->pass == 5 && png_ptr->width < 2))
+           png_ptr->pass++;
+
+         if (png_ptr->pass > 7)
+            png_ptr->pass--;
+
+         if (png_ptr->pass >= 7)
+            break;
+
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         if (png_ptr->transformations & PNG_INTERLACE)
+            break;
+
+         png_ptr->num_rows = (png_ptr->height +
+            png_pass_yinc[png_ptr->pass] - 1 -
+            png_pass_ystart[png_ptr->pass]) /
+            png_pass_yinc[png_ptr->pass];
+
+      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+   }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+}
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place tEXt");
+         info_ptr = info_ptr; /* To quiet some compiler warnings */
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+      (png_uint_32)(length + 1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+
+      else
+         text_size = png_ptr->current_text_left;
+
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+      int ret;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#ifdef PNG_MAX_MALLOC_64K
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+
+      for (text = key; *text; text++)
+         /* Empty loop */ ;
+
+      if (text < key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+         (png_uint_32)png_sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+      text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = NULL;
+      text_ptr->lang_key = NULL;
+#endif
+      text_ptr->text = text;
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, key);
+      png_free(png_ptr, text_ptr);
+      png_ptr->current_text = NULL;
+
+      if (ret)
+        png_warning(png_ptr, "Insufficient memory to store text chunk.");
+   }
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place zTXt");
+         info_ptr = info_ptr; /* To quiet some compiler warnings */
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We can't handle zTXt chunks > 64K, since we don't have enough space
+    * to be able to store the uncompressed data.  Actually, the threshold
+    * is probably around 32K, but it isn't as definite as 64K is.
+    */
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+      png_push_crc_skip(png_ptr, length);
+      return;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+      (png_uint_32)(length + 1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+
+      else
+         text_size = png_ptr->current_text_left;
+
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+      int ret;
+      png_size_t text_size, key_size;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+      key = png_ptr->current_text;
+
+      for (text = key; *text; text++)
+         /* Empty loop */ ;
+
+      /* zTXt can't have zero text */
+      if (text >= key + png_ptr->current_text_size)
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      png_ptr->zstream.next_in = (png_bytep )text;
+      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+         (text - key));
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      key_size = text - key;
+      text_size = 0;
+      text = NULL;
+      ret = Z_STREAM_END;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+            png_ptr->current_text = NULL;
+            png_free(png_ptr, key);
+            png_free(png_ptr, text);
+            return;
+         }
+         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text = (png_charp)png_malloc(png_ptr,
+                     (png_uint_32)(png_ptr->zbuf_size
+                     - png_ptr->zstream.avail_out + key_size + 1));
+
+               png_memcpy(text + key_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+               png_memcpy(text, key, key_size);
+
+               text_size = key_size + png_ptr->zbuf_size -
+                  png_ptr->zstream.avail_out;
+
+               *(text + text_size) = '\0';
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, text_size +
+                  (png_uint_32)(png_ptr->zbuf_size 
+                  - png_ptr->zstream.avail_out + 1));
+
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = '\0';
+            }
+            if (ret != Z_STREAM_END)
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+         else
+         {
+            break;
+         }
+
+         if (ret == Z_STREAM_END)
+            break;
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      if (ret != Z_STREAM_END)
+      {
+         png_ptr->current_text = NULL;
+         png_free(png_ptr, key);
+         png_free(png_ptr, text);
+         return;
+      }
+
+      png_ptr->current_text = NULL;
+      png_free(png_ptr, key);
+      key = text;
+      text += key_size;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+          (png_uint_32)png_sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+      text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+      text_ptr->lang = NULL;
+      text_ptr->lang_key = NULL;
+#endif
+      text_ptr->text = text;
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, key);
+      png_free(png_ptr, text_ptr);
+
+      if (ret)
+        png_warning(png_ptr, "Insufficient memory to store text chunk.");
+   }
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+      {
+         png_error(png_ptr, "Out of place iTXt");
+         info_ptr = info_ptr; /* To quiet some compiler warnings */
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+   {
+      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+      (png_uint_32)(length + 1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+
+      else
+         text_size = png_ptr->current_text_left;
+
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp key;
+      int comp_flag;
+      png_charp lang;
+      png_charp lang_key;
+      png_charp text;
+      int ret;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#ifdef PNG_MAX_MALLOC_64K
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+
+      for (lang = key; *lang; lang++)
+         /* Empty loop */ ;
+
+      if (lang < key + png_ptr->current_text_size - 3)
+         lang++;
+
+      comp_flag = *lang++;
+      lang++;     /* Skip comp_type, always zero */
+
+      for (lang_key = lang; *lang_key; lang_key++)
+         /* Empty loop */ ;
+
+      lang_key++;        /* Skip NUL separator */
+
+      text=lang_key;
+
+      if (lang_key < key + png_ptr->current_text_size - 1)
+      {
+        for (; *text; text++)
+           /* Empty loop */ ;
+      }
+
+      if (text < key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr,
+         (png_uint_32)png_sizeof(png_text));
+
+      text_ptr->compression = comp_flag + 2;
+      text_ptr->key = key;
+      text_ptr->lang = lang;
+      text_ptr->lang_key = lang_key;
+      text_ptr->text = text;
+      text_ptr->text_length = 0;
+      text_ptr->itxt_length = png_strlen(text);
+
+      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+      png_ptr->current_text = NULL;
+
+      png_free(png_ptr, text_ptr);
+      if (ret)
+         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
+   }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
+ */
+void /* PRIVATE */
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
+   length)
+{
+   png_uint_32 skip = 0;
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+         PNG_HANDLE_CHUNK_ALWAYS
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+         && png_ptr->read_user_chunk_fn == NULL
+#endif
+         )
+#endif
+         png_chunk_error(png_ptr, "unknown critical chunk");
+
+      info_ptr = info_ptr; /* To quiet some compiler warnings */
+   }
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+   {
+#ifdef PNG_MAX_MALLOC_64K
+      if (length > (png_uint_32)65535L)
+      {
+          png_warning(png_ptr, "unknown chunk too large to fit in memory");
+          skip = length - (png_uint_32)65535L;
+          length = (png_uint_32)65535L;
+      }
+#endif
+      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
+                 (png_charp)png_ptr->chunk_name, 
+                 png_sizeof(png_ptr->unknown_chunk.name));
+      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
+        = '\0';
+
+      png_ptr->unknown_chunk.size = (png_size_t)length;
+
+      if (length == 0)
+         png_ptr->unknown_chunk.data = NULL;
+
+      else
+      {
+         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)length);
+         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+      }
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+      if (png_ptr->read_user_chunk_fn != NULL)
+      {
+         /* Callback to user unknown chunk handler */
+         int ret;
+         ret = (*(png_ptr->read_user_chunk_fn))
+           (png_ptr, &png_ptr->unknown_chunk);
+
+         if (ret < 0)
+            png_chunk_error(png_ptr, "error in user chunk");
+
+         if (ret == 0)
+         {
+            if (!(png_ptr->chunk_name[0] & 0x20))
+               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                    PNG_HANDLE_CHUNK_ALWAYS)
+                  png_chunk_error(png_ptr, "unknown critical chunk");
+            png_set_unknown_chunks(png_ptr, info_ptr,
+               &png_ptr->unknown_chunk, 1);
+         }
+      }
+
+      else
+#endif
+        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+      png_free(png_ptr, png_ptr->unknown_chunk.data);
+      png_ptr->unknown_chunk.data = NULL;
+   }
+
+   else
+#endif
+      skip=length;
+   png_push_crc_skip(png_ptr, skip);
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->info_fn != NULL)
+      (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->end_fn != NULL)
+      (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+   if (png_ptr->row_fn != NULL)
+      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+         (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row (png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_CONST int FARDATA png_pass_dsp_mask[7] =
+      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
+
+   if (png_ptr == NULL)
+      return;
+
+   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
+      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->info_fn = info_fn;
+   png_ptr->row_fn = row_fn;
+   png_ptr->end_fn = end_fn;
+
+   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+
+   return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngread.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1528 @@
+
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.2.44 [June 26, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory
+ * needed.
+ */
+png_structp PNGAPI
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#ifdef PNG_SETJMP_SUPPORTED
+   volatile
+#endif
+   png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+#endif
+
+   int i;
+
+   png_debug(1, "in png_create_read_struct");
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif
+   if (png_ptr == NULL)
+      return (NULL);
+
+   /* Added at libpng-1.2.6 */
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#  ifdef PNG_USER_CHUNK_CACHE_MAX
+   /* Added at libpng-1.2.43 and 1.4.0 */
+   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+#  endif
+#  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
+   /* Added at libpng-1.2.43 and 1.4.1 */
+   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+#  endif
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr,
+         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      return (NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#endif
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif
+
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   if (user_png_ver)
+   {
+      i = 0;
+      do
+      {
+         if (user_png_ver[i] != png_libpng_ver[i])
+            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+      } while (png_libpng_ver[i++]);
+    }
+    else
+         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+
+
+    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+    {
+       /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+       * we must recompile any applications that use any older library version.
+       * For versions after libpng 1.0, we will be compatible, so we need
+       * only check the first digit.
+       */
+      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+      {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+         char msg[80];
+         if (user_png_ver)
+         {
+           png_snprintf(msg, 80,
+              "Application was compiled with png.h from libpng-%.20s",
+              user_png_ver);
+           png_warning(png_ptr, msg);
+         }
+         png_snprintf(msg, 80,
+             "Application  is  running with png.c from libpng-%.20s",
+             png_libpng_ver);
+         png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+         png_ptr->flags = 0;
+#endif
+         png_error(png_ptr,
+            "Incompatible libpng version in application and library");
+      }
+   }
+
+   /* Initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+      switch (inflateInit(&png_ptr->zstream))
+      {
+         case Z_OK: /* Do nothing */ break;
+         case Z_MEM_ERROR:
+         case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error");
+            break;
+         case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
+            break;
+         default: png_error(png_ptr, "Unknown zlib error");
+      }
+
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then
+   encounter a png_error() will longjmp here.  Since the jmpbuf is
+   then meaningless we abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+       PNG_ABORT();
+   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#else
+   if (setjmp(png_ptr->jmpbuf))
+       PNG_ABORT();
+#endif
+#endif /* PNG_SETJMP_SUPPORTED */
+
+   return (png_ptr);
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Initialize PNG structure for reading, and allocate any memory needed.
+ * This interface is deprecated in favour of the png_create_read_struct(),
+ * and it will disappear as of libpng-1.3.0.
+ */
+#undef png_read_init
+void PNGAPI
+png_read_init(png_structp png_ptr)
+{
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+   if (png_ptr == NULL)
+      return;
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+   if (png_sizeof(png_struct) > png_struct_size ||
+      png_sizeof(png_info) > png_info_size)
+   {
+      char msg[80];
+      png_ptr->warning_fn = NULL;
+      if (user_png_ver)
+      {
+        png_snprintf(msg, 80,
+           "Application was compiled with png.h from libpng-%.20s",
+           user_png_ver);
+        png_warning(png_ptr, msg);
+      }
+      png_snprintf(msg, 80,
+         "Application  is  running with png.c from libpng-%.20s",
+         png_libpng_ver);
+      png_warning(png_ptr, msg);
+   }
+#endif
+   if (png_sizeof(png_struct) > png_struct_size)
+   {
+      png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+      png_ptr->flags = 0;
+#endif
+      png_error(png_ptr,
+      "The png struct allocated by the application for reading is"
+      " too small.");
+   }
+   if (png_sizeof(png_info) > png_info_size)
+   {
+      png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+      png_ptr->flags = 0;
+#endif
+      png_error(png_ptr,
+        "The info struct allocated by application for reading is"
+        " too small.");
+   }
+   png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+void PNGAPI
+png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp;  /* to save current jump buffer */
+#endif
+
+   int i = 0;
+
+   png_structp png_ptr=*ptr_ptr;
+
+   if (png_ptr == NULL)
+      return;
+
+   do
+   {
+      if (user_png_ver[i] != png_libpng_ver[i])
+      {
+#ifdef PNG_LEGACY_SUPPORTED
+        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+        png_ptr->warning_fn = NULL;
+        png_warning(png_ptr,
+         "Application uses deprecated png_read_init() and should be"
+         " recompiled.");
+        break;
+#endif
+      }
+   } while (png_libpng_ver[i++]);
+
+   png_debug(1, "in png_read_init_3");
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+   if (png_sizeof(png_struct) > png_struct_size)
+   {
+      png_destroy_struct(png_ptr);
+      *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+      png_ptr = *ptr_ptr;
+   }
+
+   /* Reset all variables to 0 */
+   png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+   /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+   /* Initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+   switch (inflateInit(&png_ptr->zstream))
+   {
+      case Z_OK: /* Do nothing */ break;
+      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
+          break;
+      default: png_error(png_ptr, "Unknown zlib error");
+   }
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data.  This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream.  You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here.  The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_info");
+ 
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+ 
+   /* If we haven't checked all of the PNG signature bytes, do so now. */
+   if (png_ptr->sig_bytes < 8)
+   {
+      png_size_t num_checked = png_ptr->sig_bytes,
+                 num_to_check = 8 - num_checked;
+
+      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+      png_ptr->sig_bytes = 8;
+
+      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+      {
+         if (num_checked < 4 &&
+             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+            png_error(png_ptr, "Not a PNG file");
+         else
+            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+      }
+      if (num_checked < 3)
+         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+   }
+
+   for (;;)
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_CONST PNG_IHDR;
+      PNG_CONST PNG_IDAT;
+      PNG_CONST PNG_IEND;
+      PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+      PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+      PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+      PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+      PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+      PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+      PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+      PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+      PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+      PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+      PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+      PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+      PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+      PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+      PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+      PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+      png_uint_32 length = png_read_chunk_header(png_ptr);
+      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
+
+      /* This should be a binary subdivision search or a hash for
+       * matching the chunk name rather than a linear search.
+       */
+      if (!png_memcmp(chunk_name, png_IDAT, 4))
+        if (png_ptr->mode & PNG_AFTER_IDAT)
+          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+      if (!png_memcmp(chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, chunk_name))
+      {
+         if (!png_memcmp(chunk_name, png_IDAT, 4))
+            png_ptr->mode |= PNG_HAVE_IDAT;
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+         else if (!png_memcmp(chunk_name, png_IDAT, 4))
+         {
+            if (!(png_ptr->mode & PNG_HAVE_IHDR))
+               png_error(png_ptr, "Missing IHDR before IDAT");
+            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                     !(png_ptr->mode & PNG_HAVE_PLTE))
+               png_error(png_ptr, "Missing PLTE before IDAT");
+            break;
+         }
+      }
+#endif
+      else if (!png_memcmp(chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+      else if (!png_memcmp(chunk_name, png_IDAT, 4))
+      {
+         if (!(png_ptr->mode & PNG_HAVE_IHDR))
+            png_error(png_ptr, "Missing IHDR before IDAT");
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                  !(png_ptr->mode & PNG_HAVE_PLTE))
+            png_error(png_ptr, "Missing PLTE before IDAT");
+
+         png_ptr->idat_size = length;
+         png_ptr->mode |= PNG_HAVE_IDAT;
+         break;
+      }
+#ifdef PNG_READ_bKGD_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_update_info");
+ 
+   if (png_ptr == NULL)
+      return;
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+   else
+      png_warning(png_ptr,
+      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
+
+   png_read_transform_info(png_ptr, info_ptr);
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place.  This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structp png_ptr)
+{
+   png_debug(1, "in png_start_read_image");
+ 
+   if (png_ptr == NULL)
+      return;
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void PNGAPI
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+   PNG_CONST PNG_IDAT;
+   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
+      0xff};
+   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+   int ret;
+ 
+   if (png_ptr == NULL)
+      return;
+ 
+   png_debug2(1, "in png_read_row (row %lu, pass %d)",
+      png_ptr->row_number, png_ptr->pass);
+
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+   /* Check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+    !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+   }
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* If interlaced and we do not need a new row, combine row and return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 0x07)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 4))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 3) != 2)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 2))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 1))
+            {
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "Invalid attempt to read row data");
+
+   png_ptr->zstream.next_out = png_ptr->row_buf;
+   png_ptr->zstream.avail_out =
+       (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+       png_ptr->iwidth) + 1);
+   do
+   {
+      if (!(png_ptr->zstream.avail_in))
+      {
+         while (!png_ptr->idat_size)
+         {
+            png_crc_finish(png_ptr, 0);
+
+            png_ptr->idat_size = png_read_chunk_header(png_ptr);
+            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+               png_error(png_ptr, "Not enough image data");
+         }
+         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_in = png_ptr->zbuf;
+         if (png_ptr->zbuf_size > png_ptr->idat_size)
+            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+         png_crc_read(png_ptr, png_ptr->zbuf,
+            (png_size_t)png_ptr->zstream.avail_in);
+         png_ptr->idat_size -= png_ptr->zstream.avail_in;
+      }
+      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+      if (ret == Z_STREAM_END)
+      {
+         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+            png_ptr->idat_size)
+            png_error(png_ptr, "Extra compressed data");
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         break;
+      }
+      if (ret != Z_OK)
+         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                   "Decompression error");
+
+   } while (png_ptr->zstream.avail_out);
+
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+       png_ptr->row_info.width);
+
+   if (png_ptr->row_buf[0])
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+      (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
+
+
+   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+      png_do_read_transformations(png_ptr);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Blow up interlaced rows to full size */
+   if (png_ptr->interlaced &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+         /* Old interface (pre-1.0.9):
+          * png_do_read_interlace(&(png_ptr->row_info),
+          *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+          */
+         png_do_read_interlace(png_ptr);
+
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row,
+            png_pass_dsp_mask[png_ptr->pass]);
+      if (row != NULL)
+         png_combine_row(png_ptr, row,
+            png_pass_mask[png_ptr->pass]);
+   }
+   else
+#endif
+   {
+      if (row != NULL)
+         png_combine_row(png_ptr, row, 0xff);
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row, 0xff);
+   }
+   png_read_finish_row(png_ptr);
+
+   if (png_ptr->read_row_fn != NULL)
+      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data.  If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass.  If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive.  If the image is displayed after each pass, it will
+ * appear to "sparkle" in.  "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available.  If you do not want this "chunky" display, you may pass
+ * NULL for display_row.  If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows.  In this case, you do not have to provide a display_row buffer
+ * also, but you may.  If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structp png_ptr, png_bytepp row,
+   png_bytepp display_row, png_uint_32 num_rows)
+{
+   png_uint_32 i;
+   png_bytepp rp;
+   png_bytepp dp;
+
+   png_debug(1, "in png_read_rows");
+ 
+   if (png_ptr == NULL)
+      return;
+   rp = row;
+   dp = display_row;
+   if (rp != NULL && dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp++;
+         png_bytep dptr = *dp++;
+
+         png_read_row(png_ptr, rptr, dptr);
+      }
+   else if (rp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp;
+         png_read_row(png_ptr, rptr, png_bytep_NULL);
+         rp++;
+      }
+   else if (dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep dptr = *dp;
+         png_read_row(png_ptr, png_bytep_NULL, dptr);
+         dp++;
+      }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image.  If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been.  You can
+ * only call this function once.  If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i, image_height;
+   int pass, j;
+   png_bytepp rp;
+
+   png_debug(1, "in png_read_image");
+ 
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   pass = png_set_interlace_handling(png_ptr);
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+        "Cannot read interlaced image -- interlace handler disabled.");
+   pass = 1;
+#endif
+
+
+   image_height=png_ptr->height;
+   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
+
+   for (j = 0; j < pass; j++)
+   {
+      rp = image;
+      for (i = 0; i < image_height; i++)
+      {
+         png_read_row(png_ptr, *rp, png_bytep_NULL);
+         rp++;
+      }
+   }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file.  Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_end");
+ 
+   if (png_ptr == NULL)
+      return;
+   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+   do
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_CONST PNG_IHDR;
+      PNG_CONST PNG_IDAT;
+      PNG_CONST PNG_IEND;
+      PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+      PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+      PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+      PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+      PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+      PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+      PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+      PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+      PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+      PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+      PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+      PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+      PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+      PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+      PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+      PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+      png_uint_32 length = png_read_chunk_header(png_ptr);
+      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
+
+      if (!png_memcmp(chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      else if (png_handle_as_unknown(png_ptr, chunk_name))
+      {
+         if (!png_memcmp(chunk_name, png_IDAT, 4))
+         {
+            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+               png_error(png_ptr, "Too many IDAT's found");
+         }
+         png_handle_unknown(png_ptr, info_ptr, length);
+         if (!png_memcmp(chunk_name, png_PLTE, 4))
+            png_ptr->mode |= PNG_HAVE_PLTE;
+      }
+#endif
+      else if (!png_memcmp(chunk_name, png_IDAT, 4))
+      {
+         /* Zero length IDATs are legal after the last IDAT has been
+          * read, but not after other chunks have been read.
+          */
+         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+            png_error(png_ptr, "Too many IDAT's found");
+         png_crc_finish(png_ptr, length);
+      }
+      else if (!png_memcmp(chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+#ifdef PNG_READ_bKGD_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+      else if (!png_memcmp(chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+   png_infopp end_info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn = NULL;
+   png_voidp mem_ptr = NULL;
+#endif
+
+   png_debug(1, "in png_destroy_read_struct");
+ 
+   if (png_ptr_ptr != NULL)
+      png_ptr = *png_ptr_ptr;
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+   mem_ptr = png_ptr->mem_ptr;
+#endif
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (end_info_ptr_ptr != NULL)
+      end_info_ptr = *end_info_ptr_ptr;
+
+   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+   if (info_ptr != NULL)
+   {
+#ifdef PNG_TEXT_SUPPORTED
+      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+          (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+
+   if (end_info_ptr != NULL)
+   {
+#ifdef PNG_READ_TEXT_SUPPORTED
+      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
+#endif
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)end_info_ptr);
+#endif
+      *end_info_ptr_ptr = NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+          (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      *png_ptr_ptr = NULL;
+   }
+}
+
+/* Free all memory used by the read (old method) */
+void /* PRIVATE */
+png_read_destroy(png_structp png_ptr, png_infop info_ptr,
+    png_infop end_info_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp;
+#endif
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+#endif
+
+   png_debug(1, "in png_read_destroy");
+ 
+   if (info_ptr != NULL)
+      png_info_destroy(png_ptr, info_ptr);
+
+   if (end_info_ptr != NULL)
+      png_info_destroy(png_ptr, end_info_ptr);
+
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->big_row_buf);
+   png_free(png_ptr, png_ptr->prev_row);
+   png_free(png_ptr, png_ptr->chunkdata);
+#ifdef PNG_READ_DITHER_SUPPORTED
+   png_free(png_ptr, png_ptr->palette_lookup);
+   png_free(png_ptr, png_ptr->dither_index);
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   png_free(png_ptr, png_ptr->gamma_from_1);
+   png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_PLTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_TRNS)
+      png_free(png_ptr, png_ptr->trans);
+   png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
+      png_free(png_ptr, png_ptr->trans);
+   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+#ifdef PNG_FREE_ME_SUPPORTED
+   if (png_ptr->free_me & PNG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+   png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
+   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if (png_ptr->gamma_16_table != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_table[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_table);
+   }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   if (png_ptr->gamma_16_from_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_from_1);
+   }
+   if (png_ptr->gamma_16_to_1 != NULL)
+   {
+      int i;
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+      }
+   png_free(png_ptr, png_ptr->gamma_16_to_1);
+   }
+#endif
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+   inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+#ifdef PNG_TEXT_SUPPORTED
+   png_free(png_ptr, png_ptr->current_text);
+#endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+   /* Save the important info out of the png_struct, in case it is
+    * being used again.
+    */
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
+
+   png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+   if (png_ptr == NULL)
+      return;
+   png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+                           int transforms,
+                           voidp params)
+{
+   int row;
+
+   if (png_ptr == NULL)
+      return;
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+   /* Invert the alpha channel from opacity to transparency
+    */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+   /* png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).
+    */
+   png_read_info(png_ptr, info_ptr);
+   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+      png_error(png_ptr, "Image is too high to process with png_read_png()");
+
+   /* -------------- image transformations start here ------------------- */
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+   /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_16)
+      png_set_strip_16(png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   /* Strip alpha bytes from the input data without combining with
+    * the background (not recommended).
+    */
+   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+      png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   if (transforms & PNG_TRANSFORM_PACKING)
+      png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing).
+    */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+      png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   /* Expand paletted colors into true RGB triplets
+    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+    * Expand paletted or RGB images with transparency to full alpha
+    * channels so the data will be available as RGBA quartets.
+    */
+   if (transforms & PNG_TRANSFORM_EXPAND)
+      if ((png_ptr->bit_depth < 8) ||
+          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+         png_set_expand(png_ptr);
+#endif
+
+   /* We don't handle background color or gamma transformation or dithering.
+    */
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+   /* Invert monochrome files to have 0 as white and 1 as black
+    */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+      png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   {
+      png_color_8p sig_bit;
+
+      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+      png_set_shift(png_ptr, sig_bit);
+   }
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+   /* Flip the RGB pixels to BGR (or RGBA to BGRA)
+    */
+   if (transforms & PNG_TRANSFORM_BGR)
+      png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
+    */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+       png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_SUPPORTED
+   /* Swap bytes of 16 bit files to least significant byte first
+    */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+      png_set_swap(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+   /* Invert the alpha channel from opacity to transparency
+    */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+       png_set_invert_alpha(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* Expand grayscale image to RGB
+    */
+   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
+       png_set_gray_to_rgb(png_ptr);
+#endif
+
+   /* We don't handle adding filler bytes */
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (i.e., you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+   if (info_ptr->row_pointers == NULL)
+   {
+      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+         info_ptr->height * png_sizeof(png_bytep));
+      png_memset(info_ptr->row_pointers, 0, info_ptr->height
+         * png_sizeof(png_bytep));
+
+#ifdef PNG_FREE_ME_SUPPORTED
+      info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+
+      for (row = 0; row < (int)info_ptr->height; row++)
+         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+            png_get_rowbytes(png_ptr, info_ptr));
+   }
+
+   png_read_image(png_ptr, info_ptr->row_pointers);
+   info_ptr->valid |= PNG_INFO_IDAT;
+
+   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+
+   transforms = transforms; /* Quiet compiler warnings */
+   params = params;
+
+}
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,180 @@
+
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all input.  Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method.  Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+/* Read the data from whatever input you are using.  The default routine
+ * reads from a file pointer.  Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered reads.  This should never be asked
+ * to read more then 64K on a 16 bit machine.
+ */
+void /* PRIVATE */
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_debug1(4, "reading %d bytes", (int)length);
+ 
+   if (png_ptr->read_data_fn != NULL)
+      (*(png_ptr->read_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL read function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual reading of data.  If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   if (png_ptr == NULL)
+      return;
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+#ifdef _WIN32_WCE
+   if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
+   check = (png_size_t)fread(data, (png_size_t)1, length,
+      (png_FILE_p)png_ptr->io_ptr);
+#endif
+
+   if (check != length)
+      png_error(png_ptr, "Read Error");
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   int check;
+   png_byte *n_data;
+   png_FILE_p io_ptr;
+
+   if (png_ptr == NULL)
+      return;
+   /* Check if data really is near. If so, use usual code. */
+   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)n_data == data)
+   {
+#ifdef _WIN32_WCE
+      if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check,
+          NULL) )
+         check = 0;
+#else
+      check = fread(n_data, 1, length, io_ptr);
+#endif
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t read, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         read = MIN(NEAR_BUF_SIZE, remaining);
+#ifdef _WIN32_WCE
+         if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+            err = 0;
+#else
+         err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
+         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+         if (err != read)
+            break;
+         else
+            check += err;
+         data += read;
+         remaining -= read;
+      }
+      while (remaining != 0);
+   }
+   if ((png_uint_32)check != (png_uint_32)length)
+      png_error(png_ptr, "read Error");
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+ * for libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr      - pointer to a png input data structure
+ * io_ptr       - pointer to user supplied structure containing info about
+ *                the input functions.  May be NULL.
+ * read_data_fn - pointer to a new input function that takes as its
+ *                arguments a pointer to a png_struct, a pointer to
+ *                a location where input data can be stored, and a 32-bit
+ *                unsigned int that is the number of bytes to be read.
+ *                To exit and output any fatal error messages the new write
+ *                function should call png_error(png_ptr, "Error msg").
+ *                May be NULL, in which case libpng's default function will
+ *                be used.
+ */
+void PNGAPI
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr read_data_fn)
+{
+   if (png_ptr == NULL)
+      return;
+   png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+   if (read_data_fn != NULL)
+      png_ptr->read_data_fn = read_data_fn;
+   else
+      png_ptr->read_data_fn = png_default_read_data;
+#else
+   png_ptr->read_data_fn = read_data_fn;
+#endif
+
+   /* It is an error to write to a read device */
+   if (png_ptr->write_data_fn != NULL)
+   {
+      png_ptr->write_data_fn = NULL;
+      png_warning(png_ptr,
+         "It's an error to set both read_data_fn and write_data_fn in the ");
+      png_warning(png_ptr,
+         "same structure.  Resetting write_data_fn to NULL.");
+   }
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* PNG_READ_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrtran.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrtran.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrtran.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4457 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+   png_debug(1, "in png_set_crc_action");
+ 
+   if (png_ptr == NULL)
+      return;
+
+   /* Tell libpng how we react to CRC errors in critical chunks */
+   switch (crit_action)
+   {
+      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
+         break;
+
+      case PNG_CRC_WARN_USE:                               /* Warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+         break;
+
+      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+                           PNG_FLAG_CRC_CRITICAL_IGNORE;
+         break;
+
+      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
+         png_warning(png_ptr,
+            "Can't discard critical data on CRC error.");
+      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
+
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         break;
+   }
+
+   /* Tell libpng how we react to CRC errors in ancillary chunks */
+   switch (ancil_action)
+   {
+      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
+         break;
+
+      case PNG_CRC_WARN_USE:                              /* Warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+         break;
+
+      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+
+      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+
+      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
+
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         break;
+   }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Handle alpha and tRNS via a background color */
+void PNGAPI
+png_set_background(png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma)
+{
+   png_debug(1, "in png_set_background");
+ 
+   if (png_ptr == NULL)
+      return;
+   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+   {
+      png_warning(png_ptr, "Application must supply a known background gamma");
+      return;
+   }
+
+   png_ptr->transformations |= PNG_BACKGROUND;
+   png_memcpy(&(png_ptr->background), background_color,
+      png_sizeof(png_color_16));
+   png_ptr->background_gamma = (float)background_gamma;
+   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+}
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Strip 16 bit depth files to 8 bit depth */
+void PNGAPI
+png_set_strip_16(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_16");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+void PNGAPI
+png_set_strip_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_alpha");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
+}
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* Dither file to 8 bit.  Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible.  If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number.  "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+   struct png_dsort_struct FAR * next;
+   png_byte left;
+   png_byte right;
+} png_dsort;
+typedef png_dsort FAR *       png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void PNGAPI
+png_set_dither(png_structp png_ptr, png_colorp palette,
+   int num_palette, int maximum_colors, png_uint_16p histogram,
+   int full_dither)
+{
+   png_debug(1, "in png_set_dither");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_DITHER;
+
+   if (!full_dither)
+   {
+      int i;
+
+      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)(num_palette * png_sizeof(png_byte)));
+      for (i = 0; i < num_palette; i++)
+         png_ptr->dither_index[i] = (png_byte)i;
+   }
+
+   if (num_palette > maximum_colors)
+   {
+      if (histogram != NULL)
+      {
+         /* This is easy enough, just throw out the least used colors.
+          * Perhaps not the best solution, but good enough.
+          */
+
+         int i;
+
+         /* Initialize an array to sort colors */
+         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof(png_byte)));
+
+         /* Initialize the dither_sort array */
+         for (i = 0; i < num_palette; i++)
+            png_ptr->dither_sort[i] = (png_byte)i;
+
+         /* Find the least used palette entries by starting a
+          * bubble sort, and running it until we have sorted
+          * out enough colors.  Note that we don't care about
+          * sorting all the colors, just finding which are
+          * least used.
+          */
+
+         for (i = num_palette - 1; i >= maximum_colors; i--)
+         {
+            int done; /* To stop early if the list is pre-sorted */
+            int j;
+
+            done = 1;
+            for (j = 0; j < i; j++)
+            {
+               if (histogram[png_ptr->dither_sort[j]]
+                   < histogram[png_ptr->dither_sort[j + 1]])
+               {
+                  png_byte t;
+
+                  t = png_ptr->dither_sort[j];
+                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
+                  png_ptr->dither_sort[j + 1] = t;
+                  done = 0;
+               }
+            }
+            if (done)
+               break;
+         }
+
+         /* Swap the palette around, and set up a table, if necessary */
+         if (full_dither)
+         {
+            int j = num_palette;
+
+            /* Put all the useful colors within the max, but don't
+             * move the others.
+             */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+               {
+                  do
+                     j--;
+                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+                  palette[i] = palette[j];
+               }
+            }
+         }
+         else
+         {
+            int j = num_palette;
+
+            /* Move all the used colors inside the max limit, and
+             * develop a translation table.
+             */
+            for (i = 0; i < maximum_colors; i++)
+            {
+               /* Only move the colors we need to */
+               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+               {
+                  png_color tmp_color;
+
+                  do
+                     j--;
+                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+
+                  tmp_color = palette[j];
+                  palette[j] = palette[i];
+                  palette[i] = tmp_color;
+                  /* Indicate where the color went */
+                  png_ptr->dither_index[j] = (png_byte)i;
+                  png_ptr->dither_index[i] = (png_byte)j;
+               }
+            }
+
+            /* Find closest color for those colors we are not using */
+            for (i = 0; i < num_palette; i++)
+            {
+               if ((int)png_ptr->dither_index[i] >= maximum_colors)
+               {
+                  int min_d, k, min_k, d_index;
+
+                  /* Find the closest color to one we threw out */
+                  d_index = png_ptr->dither_index[i];
+                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+                  for (k = 1, min_k = 0; k < maximum_colors; k++)
+                  {
+                     int d;
+
+                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+                     if (d < min_d)
+                     {
+                        min_d = d;
+                        min_k = k;
+                     }
+                  }
+                  /* Point to closest color */
+                  png_ptr->dither_index[i] = (png_byte)min_k;
+               }
+            }
+         }
+         png_free(png_ptr, png_ptr->dither_sort);
+         png_ptr->dither_sort = NULL;
+      }
+      else
+      {
+         /* This is much harder to do simply (and quickly).  Perhaps
+          * we need to go through a median cut routine, but those
+          * don't always behave themselves with only a few colors
+          * as input.  So we will just find the closest two colors,
+          * and throw out one of them (chosen somewhat randomly).
+          * [We don't understand this at all, so if someone wants to
+          *  work on improving it, be our guest - AED, GRP]
+          */
+         int i;
+         int max_d;
+         int num_new_palette;
+         png_dsortp t;
+         png_dsortpp hash;
+
+         t = NULL;
+
+         /* Initialize palette index arrays */
+         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof(png_byte)));
+         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * png_sizeof(png_byte)));
+
+         /* Initialize the sort array */
+         for (i = 0; i < num_palette; i++)
+         {
+            png_ptr->index_to_palette[i] = (png_byte)i;
+            png_ptr->palette_to_index[i] = (png_byte)i;
+         }
+
+         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+            png_sizeof(png_dsortp)));
+
+         num_new_palette = num_palette;
+
+         /* Initial wild guess at how far apart the farthest pixel
+          * pair we will be eliminating will be.  Larger
+          * numbers mean more areas will be allocated, Smaller
+          * numbers run the risk of not saving enough data, and
+          * having to do this all over again.
+          *
+          * I have not done extensive checking on this number.
+          */
+         max_d = 96;
+
+         while (num_new_palette > maximum_colors)
+         {
+            for (i = 0; i < num_new_palette - 1; i++)
+            {
+               int j;
+
+               for (j = i + 1; j < num_new_palette; j++)
+               {
+                  int d;
+
+                  d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+                  if (d <= max_d)
+                  {
+
+                     t = (png_dsortp)png_malloc_warn(png_ptr,
+                         (png_uint_32)(png_sizeof(png_dsort)));
+                     if (t == NULL)
+                         break;
+                     t->next = hash[d];
+                     t->left = (png_byte)i;
+                     t->right = (png_byte)j;
+                     hash[d] = t;
+                  }
+               }
+               if (t == NULL)
+                  break;
+            }
+
+            if (t != NULL)
+            for (i = 0; i <= max_d; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p;
+
+                  for (p = hash[i]; p; p = p->next)
+                  {
+                     if ((int)png_ptr->index_to_palette[p->left]
+                        < num_new_palette &&
+                        (int)png_ptr->index_to_palette[p->right]
+                        < num_new_palette)
+                     {
+                        int j, next_j;
+
+                        if (num_new_palette & 0x01)
+                        {
+                           j = p->left;
+                           next_j = p->right;
+                        }
+                        else
+                        {
+                           j = p->right;
+                           next_j = p->left;
+                        }
+
+                        num_new_palette--;
+                        palette[png_ptr->index_to_palette[j]]
+                          = palette[num_new_palette];
+                        if (!full_dither)
+                        {
+                           int k;
+
+                           for (k = 0; k < num_palette; k++)
+                           {
+                              if (png_ptr->dither_index[k] ==
+                                 png_ptr->index_to_palette[j])
+                                 png_ptr->dither_index[k] =
+                                    png_ptr->index_to_palette[next_j];
+                              if ((int)png_ptr->dither_index[k] ==
+                                 num_new_palette)
+                                 png_ptr->dither_index[k] =
+                                    png_ptr->index_to_palette[j];
+                           }
+                        }
+
+                        png_ptr->index_to_palette[png_ptr->palette_to_index
+                           [num_new_palette]] = png_ptr->index_to_palette[j];
+                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+                           = png_ptr->palette_to_index[num_new_palette];
+
+                        png_ptr->index_to_palette[j] =
+                            (png_byte)num_new_palette;
+                        png_ptr->palette_to_index[num_new_palette] =
+                            (png_byte)j;
+                     }
+                     if (num_new_palette <= maximum_colors)
+                        break;
+                  }
+                  if (num_new_palette <= maximum_colors)
+                     break;
+               }
+            }
+
+            for (i = 0; i < 769; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p = hash[i];
+                  while (p)
+                  {
+                     t = p->next;
+                     png_free(png_ptr, p);
+                     p = t;
+                  }
+               }
+               hash[i] = 0;
+            }
+            max_d += 96;
+         }
+         png_free(png_ptr, hash);
+         png_free(png_ptr, png_ptr->palette_to_index);
+         png_free(png_ptr, png_ptr->index_to_palette);
+         png_ptr->palette_to_index = NULL;
+         png_ptr->index_to_palette = NULL;
+      }
+      num_palette = maximum_colors;
+   }
+   if (png_ptr->palette == NULL)
+   {
+      png_ptr->palette = palette;
+   }
+   png_ptr->num_palette = (png_uint_16)num_palette;
+
+   if (full_dither)
+   {
+      int i;
+      png_bytep distance;
+      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+         PNG_DITHER_BLUE_BITS;
+      int num_red = (1 << PNG_DITHER_RED_BITS);
+      int num_green = (1 << PNG_DITHER_GREEN_BITS);
+      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
+      png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+      png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr,
+         (png_uint_32)(num_entries * png_sizeof(png_byte)));
+
+      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+         png_sizeof(png_byte)));
+      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
+
+      for (i = 0; i < num_palette; i++)
+      {
+         int ir, ig, ib;
+         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+         for (ir = 0; ir < num_red; ir++)
+         {
+            /* int dr = abs(ir - r); */
+            int dr = ((ir > r) ? ir - r : r - ir);
+            int index_r = (ir << (PNG_DITHER_BLUE_BITS +
+                PNG_DITHER_GREEN_BITS));
+
+            for (ig = 0; ig < num_green; ig++)
+            {
+               /* int dg = abs(ig - g); */
+               int dg = ((ig > g) ? ig - g : g - ig);
+               int dt = dr + dg;
+               int dm = ((dr > dg) ? dr : dg);
+               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+
+               for (ib = 0; ib < num_blue; ib++)
+               {
+                  int d_index = index_g | ib;
+                  /* int db = abs(ib - b); */
+                  int db = ((ib > b) ? ib - b : b - ib);
+                  int dmax = ((dm > db) ? dm : db);
+                  int d = dmax + dt + db;
+
+                  if (d < (int)distance[d_index])
+                  {
+                     distance[d_index] = (png_byte)d;
+                     png_ptr->palette_lookup[d_index] = (png_byte)i;
+                  }
+               }
+            }
+         }
+      }
+
+      png_free(png_ptr, distance);
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma.  We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ *
+ * We will turn off gamma transformation later if no semitransparent entries
+ * are present in the tRNS array for palette images.  We can't do it here
+ * because we don't necessarily have the tRNS chunk yet.
+ */
+void PNGAPI
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+   png_debug(1, "in png_set_gamma");
+
+   if (png_ptr == NULL)
+      return;
+
+   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
+       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+     png_ptr->transformations |= PNG_GAMMA;
+   png_ptr->gamma = (float)file_gamma;
+   png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+
+/* GRR 19990627:  the following three functions currently are identical
+ *  to png_set_expand().  However, it is entirely reasonable that someone
+ *  might wish to expand an indexed image to RGB but *not* expand a single,
+ *  fully transparent palette entry to a full alpha channel--perhaps instead
+ *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ *  the transparent color with a particular RGB value, or drop tRNS entirely.
+ *  IOW, a future version of the library may make the transformations flag
+ *  a bit more fine-grained, with separate bits for each of these three
+ *  functions.
+ *
+ *  More to the point, these functions make it obvious what libpng will be
+ *  doing, whereas "expand" can (and does) mean any number of things.
+ *
+ *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
+ *  to expand only the sample depth but not to expand the tRNS to alpha
+ *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_palette_to_rgb");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+
+#ifndef PNG_1_0_X
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= PNG_EXPAND;
+   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+/* Deprecated as of libpng-1.2.9 */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_gray_1_2_4_to_8");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_tRNS_to_alpha");
+
+   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+void PNGAPI
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_gray_to_rgb");
+
+   png_ptr->transformations |= PNG_GRAY_TO_RGB;
+   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Convert a RGB image to a grayscale of the same width.  This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+   double green)
+{
+   int red_fixed = (int)((float)red*100000.0 + 0.5);
+   int green_fixed = (int)((float)green*100000.0 + 0.5);
+   if (png_ptr == NULL)
+      return;
+   png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+   png_fixed_point red, png_fixed_point green)
+{
+   png_debug(1, "in png_set_rgb_to_gray");
+
+   if (png_ptr == NULL)
+      return;
+
+   switch(error_action)
+   {
+      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
+              break;
+
+      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+              break;
+
+      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+   }
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+      png_ptr->transformations |= PNG_EXPAND;
+#else
+   {
+      png_warning(png_ptr,
+        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
+      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
+   }
+#endif
+   {
+      png_uint_16 red_int, green_int;
+      if (red < 0 || green < 0)
+      {
+         red_int   =  6968; /* .212671 * 32768 + .5 */
+         green_int = 23434; /* .715160 * 32768 + .5 */
+      }
+      else if (red + green < 100000L)
+      {
+         red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+         green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
+      }
+      else
+      {
+         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+         red_int   =  6968;
+         green_int = 23434;
+      }
+      png_ptr->rgb_to_gray_red_coeff   = red_int;
+      png_ptr->rgb_to_gray_green_coeff = green_int;
+      png_ptr->rgb_to_gray_blue_coeff  =
+         (png_uint_16)(32768 - red_int - green_int);
+   }
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   read_user_transform_fn)
+{
+   png_debug(1, "in png_set_read_user_transform_fn");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+   if (read_user_transform_fn)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transforms");
+#endif
+}
+#endif
+
+/* Initialize everything needed for the read.  This includes modifying
+ * the palette.
+ */
+void /* PRIVATE */
+png_init_read_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_init_read_transformations");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+  if (png_ptr != NULL)
+#endif
+  {
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+    defined(PNG_READ_SHIFT_SUPPORTED) || \
+    defined(PNG_READ_GAMMA_SUPPORTED)
+   int color_type = png_ptr->color_type;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* Detect gray background and attempt to enable optimization
+    * for gray --> RGB case
+    *
+    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+    * background color might actually be gray yet not be flagged as such.
+    * This is not a problem for the current code, which uses
+    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+    * png_do_gray_to_rgb() transformation.
+    */
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+       !(color_type & PNG_COLOR_MASK_COLOR))
+   {
+          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+   } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
+              !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+              (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+              png_ptr->background.red == png_ptr->background.green &&
+              png_ptr->background.red == png_ptr->background.blue)
+   {
+          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+          png_ptr->background.gray = png_ptr->background.red;
+   }
+#endif
+
+   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+       (png_ptr->transformations & PNG_EXPAND))
+   {
+      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
+      {
+         /* Expand background and tRNS chunks */
+         switch (png_ptr->bit_depth)
+         {
+            case 1:
+               png_ptr->background.gray *= (png_uint_16)0xff;
+               png_ptr->background.red = png_ptr->background.green
+                 =  png_ptr->background.blue = png_ptr->background.gray;
+               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+               {
+                 png_ptr->trans_values.gray *= (png_uint_16)0xff;
+                 png_ptr->trans_values.red = png_ptr->trans_values.green
+                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+               }
+               break;
+
+            case 2:
+               png_ptr->background.gray *= (png_uint_16)0x55;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+               {
+                 png_ptr->trans_values.gray *= (png_uint_16)0x55;
+                 png_ptr->trans_values.red = png_ptr->trans_values.green
+                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+               }
+               break;
+
+            case 4:
+               png_ptr->background.gray *= (png_uint_16)0x11;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+               {
+                 png_ptr->trans_values.gray *= (png_uint_16)0x11;
+                 png_ptr->trans_values.red = png_ptr->trans_values.green
+                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+               }
+               break;
+
+            case 8:
+
+            case 16:
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+               break;
+         }
+      }
+      else if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_ptr->background.red   =
+            png_ptr->palette[png_ptr->background.index].red;
+         png_ptr->background.green =
+            png_ptr->palette[png_ptr->background.index].green;
+         png_ptr->background.blue  =
+            png_ptr->palette[png_ptr->background.index].blue;
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+        if (png_ptr->transformations & PNG_INVERT_ALPHA)
+        {
+#ifdef PNG_READ_EXPAND_SUPPORTED
+           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+#endif
+           {
+           /* Invert the alpha channel (in tRNS) unless the pixels are
+            * going to be expanded, in which case leave it for later
+            */
+              int i, istop;
+              istop=(int)png_ptr->num_trans;
+              for (i=0; i<istop; i++)
+                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
+           }
+        }
+#endif
+
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+
+   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
+       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
+         < PNG_GAMMA_THRESHOLD))
+   {
+    int i, k;
+    k=0;
+    for (i=0; i<png_ptr->num_trans; i++)
+    {
+      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
+        k=1; /* Partial transparency is present */
+    }
+    if (k == 0)
+      png_ptr->transformations &= ~PNG_GAMMA;
+   }
+
+   if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
+        png_ptr->gamma != 0.0)
+   {
+      png_build_gamma_table(png_ptr);
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+      if (png_ptr->transformations & PNG_BACKGROUND)
+      {
+         if (color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+           /* Could skip if no transparency */
+            png_color back, back_1;
+            png_colorp palette = png_ptr->palette;
+            int num_palette = png_ptr->num_palette;
+            int i;
+            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+            {
+               back.red = png_ptr->gamma_table[png_ptr->background.red];
+               back.green = png_ptr->gamma_table[png_ptr->background.green];
+               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+            }
+            else
+            {
+               double g, gs;
+
+               switch (png_ptr->background_gamma_type)
+               {
+                  case PNG_BACKGROUND_GAMMA_SCREEN:
+                     g = (png_ptr->screen_gamma);
+                     gs = 1.0;
+                     break;
+
+                  case PNG_BACKGROUND_GAMMA_FILE:
+                     g = 1.0 / (png_ptr->gamma);
+                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                     break;
+
+                  case PNG_BACKGROUND_GAMMA_UNIQUE:
+                     g = 1.0 / (png_ptr->background_gamma);
+                     gs = 1.0 / (png_ptr->background_gamma *
+                                 png_ptr->screen_gamma);
+                     break;
+                  default:
+                     g = 1.0;    /* back_1 */
+                     gs = 1.0;   /* back */
+               }
+
+               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+               {
+                  back.red   = (png_byte)png_ptr->background.red;
+                  back.green = (png_byte)png_ptr->background.green;
+                  back.blue  = (png_byte)png_ptr->background.blue;
+               }
+               else
+               {
+                  back.red = (png_byte)(pow(
+                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+                  back.green = (png_byte)(pow(
+                     (double)png_ptr->background.green/255, gs) * 255.0
+                         + .5);
+                  back.blue = (png_byte)(pow(
+                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+               }
+
+               back_1.red = (png_byte)(pow(
+                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
+               back_1.green = (png_byte)(pow(
+                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
+               back_1.blue = (png_byte)(pow(
+                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+            }
+            for (i = 0; i < num_palette; i++)
+            {
+               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+               {
+                  if (png_ptr->trans[i] == 0)
+                  {
+                     palette[i] = back;
+                  }
+                  else /* if (png_ptr->trans[i] != 0xff) */
+                  {
+                     png_byte v, w;
+
+                     v = png_ptr->gamma_to_1[palette[i].red];
+                     png_composite(w, v, png_ptr->trans[i], back_1.red);
+                     palette[i].red = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].green];
+                     png_composite(w, v, png_ptr->trans[i], back_1.green);
+                     palette[i].green = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].blue];
+                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
+                     palette[i].blue = png_ptr->gamma_from_1[w];
+                  }
+               }
+               else
+               {
+                  palette[i].red = png_ptr->gamma_table[palette[i].red];
+                  palette[i].green = png_ptr->gamma_table[palette[i].green];
+                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+               }
+            }
+            /* Prevent the transformations being done again, and make sure
+             * that the now spurious alpha channel is stripped - the code
+             * has just reduced background composition and gamma correction
+             * to a simple alpha channel strip.
+             */
+            png_ptr->transformations &= ~PNG_BACKGROUND;
+            png_ptr->transformations &= ~PNG_GAMMA;
+            png_ptr->transformations |= PNG_STRIP_ALPHA;
+         }
+         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+         else
+         /* color_type != PNG_COLOR_TYPE_PALETTE */
+         {
+            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+            double g = 1.0;
+            double gs = 1.0;
+
+            switch (png_ptr->background_gamma_type)
+            {
+               case PNG_BACKGROUND_GAMMA_SCREEN:
+                  g = (png_ptr->screen_gamma);
+                  gs = 1.0;
+                  break;
+
+               case PNG_BACKGROUND_GAMMA_FILE:
+                  g = 1.0 / (png_ptr->gamma);
+                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                  break;
+
+               case PNG_BACKGROUND_GAMMA_UNIQUE:
+                  g = 1.0 / (png_ptr->background_gamma);
+                  gs = 1.0 / (png_ptr->background_gamma *
+                     png_ptr->screen_gamma);
+                  break;
+            }
+
+            png_ptr->background_1.gray = (png_uint_16)(pow(
+               (double)png_ptr->background.gray / m, g) * m + .5);
+            png_ptr->background.gray = (png_uint_16)(pow(
+               (double)png_ptr->background.gray / m, gs) * m + .5);
+
+            if ((png_ptr->background.red != png_ptr->background.green) ||
+                (png_ptr->background.red != png_ptr->background.blue) ||
+                (png_ptr->background.red != png_ptr->background.gray))
+            {
+               /* RGB or RGBA with color background */
+               png_ptr->background_1.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, g) * m + .5);
+               png_ptr->background_1.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, g) * m + .5);
+               png_ptr->background_1.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, g) * m + .5);
+               png_ptr->background.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, gs) * m + .5);
+               png_ptr->background.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, gs) * m + .5);
+               png_ptr->background.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, gs) * m + .5);
+            }
+            else
+            {
+               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+               png_ptr->background_1.red = png_ptr->background_1.green
+                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
+               png_ptr->background.red = png_ptr->background.green
+                 = png_ptr->background.blue = png_ptr->background.gray;
+            }
+         }
+      }
+      else
+      /* Transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+      if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_colorp palette = png_ptr->palette;
+         int num_palette = png_ptr->num_palette;
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            palette[i].red = png_ptr->gamma_table[palette[i].red];
+            palette[i].green = png_ptr->gamma_table[palette[i].green];
+            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+         }
+
+         /* Done the gamma correction. */
+         png_ptr->transformations &= ~PNG_GAMMA;
+      }
+   }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   /* No GAMMA transformation */
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+       (color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      int i;
+      int istop = (int)png_ptr->num_trans;
+      png_color back;
+      png_colorp palette = png_ptr->palette;
+
+      back.red   = (png_byte)png_ptr->background.red;
+      back.green = (png_byte)png_ptr->background.green;
+      back.blue  = (png_byte)png_ptr->background.blue;
+
+      for (i = 0; i < istop; i++)
+      {
+         if (png_ptr->trans[i] == 0)
+         {
+            palette[i] = back;
+         }
+         else if (png_ptr->trans[i] != 0xff)
+         {
+            /* The png_composite() macro is defined in png.h */
+            png_composite(palette[i].red, palette[i].red,
+               png_ptr->trans[i], back.red);
+            png_composite(palette[i].green, palette[i].green,
+               png_ptr->trans[i], back.green);
+            png_composite(palette[i].blue, palette[i].blue,
+               png_ptr->trans[i], back.blue);
+         }
+      }
+
+      /* Handled alpha, still need to strip the channel. */
+      png_ptr->transformations &= ~PNG_BACKGROUND;
+      png_ptr->transformations |= PNG_STRIP_ALPHA;
+   }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SHIFT) &&
+      (color_type == PNG_COLOR_TYPE_PALETTE))
+   {
+      png_uint_16 i;
+      png_uint_16 istop = png_ptr->num_palette;
+      int sr = 8 - png_ptr->sig_bit.red;
+      int sg = 8 - png_ptr->sig_bit.green;
+      int sb = 8 - png_ptr->sig_bit.blue;
+
+      if (sr < 0 || sr > 8)
+         sr = 0;
+      if (sg < 0 || sg > 8)
+         sg = 0;
+      if (sb < 0 || sb > 8)
+         sb = 0;
+      for (i = 0; i < istop; i++)
+      {
+         png_ptr->palette[i].red >>= sr;
+         png_ptr->palette[i].green >>= sg;
+         png_ptr->palette[i].blue >>= sb;
+      }
+   }
+#endif  /* PNG_READ_SHIFT_SUPPORTED */
+ }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr)
+      return;
+#endif
+}
+
+/* Modify the info structure to reflect the transformations.  The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_transform_info");
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans &&
+              (png_ptr->transformations & PNG_EXPAND_tRNS))
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         else
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+         info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+      else
+      {
+         if (png_ptr->num_trans)
+         {
+            if (png_ptr->transformations & PNG_EXPAND_tRNS)
+              info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+         }
+         if (info_ptr->bit_depth < 8)
+            info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+   }
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+      info_ptr->num_trans = 0;
+      info_ptr->background = png_ptr->background;
+   }
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      info_ptr->gamma = png_ptr->gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+   }
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
+      info_ptr->bit_depth = 8;
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+      {
+         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+      }
+   }
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+      info_ptr->bit_depth = 8;
+#endif
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
+   if ((png_ptr->transformations & PNG_FILLER) &&
+       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+   {
+      info_ptr->channels++;
+      /* If adding a true alpha channel not just filler */
+#ifndef PNG_1_0_X
+      if (png_ptr->transformations & PNG_ADD_ALPHA)
+        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+   }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       if (info_ptr->bit_depth < png_ptr->user_transform_depth)
+         info_ptr->bit_depth = png_ptr->user_transform_depth;
+       if (info_ptr->channels < png_ptr->user_transform_channels)
+         info_ptr->channels = png_ptr->user_transform_channels;
+     }
+#endif
+
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+      info_ptr->bit_depth);
+
+   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
+
+#ifndef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr)
+      return;
+#endif
+}
+
+/* Transform the row.  The order of transformations is significant,
+ * and is very touchy.  If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_read_transformations");
+
+   if (png_ptr->row_buf == NULL)
+   {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+      char msg[50];
+
+      png_snprintf2(msg, 50,
+         "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
+         png_ptr->pass);
+      png_error(png_ptr, msg);
+#else
+      png_error(png_ptr, "NULL row buffer");
+#endif
+   }
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      /* Application has failed to call either png_read_start_image()
+       * or png_read_update_info() after setting transforms that expand
+       * pixels.  This check added to libpng-1.2.19
+       */
+#if (PNG_WARN_UNINITIALIZED_ROW==1)
+      png_error(png_ptr, "Uninitialized row");
+#else
+      png_warning(png_ptr, "Uninitialized row");
+#endif
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+      }
+      else
+      {
+         if (png_ptr->num_trans &&
+             (png_ptr->transformations & PNG_EXPAND_tRNS))
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               &(png_ptr->trans_values));
+         else
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               NULL);
+      }
+   }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+   {
+      int rgb_error =
+         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info),
+             png_ptr->row_buf + 1);
+      if (rgb_error)
+      {
+         png_ptr->rgb_to_gray_status=1;
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_WARN)
+            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_ERR)
+            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+      }
+   }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ *   In most cases, the "simple transparency" should be done prior to doing
+ *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ *   pixel is transparent.  You would also need to make sure that the
+ *   transparency information is upgraded to RGB.
+ *
+ *   To summarize, the current flow is:
+ *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ *                                   with background "in place" if transparent,
+ *                                   convert to RGB if necessary
+ *   - Gray + alpha -> composite with gray background and remove alpha bytes,
+ *                                   convert to RGB if necessary
+ *
+ *   To support RGB backgrounds for gray images we need:
+ *   - Gray + simple transparency -> convert to RGB + simple transparency,
+ *                                   compare 3 or 6 bytes and composite with
+ *                                   background "in place" if transparent
+ *                                   (3x compare/pixel compared to doing
+ *                                   composite with gray bkgrnd)
+ *   - Gray + alpha -> convert to RGB + alpha, composite with background and
+ *                                   remove alpha bytes (3x float
+ *                                   operations/pixel compared with composite
+ *                                   on gray background)
+ *
+ *  Greg's change will do this.  The reason it wasn't done before is for
+ *  performance, as this increases the per-pixel operations.  If we would check
+ *  in advance if the background was gray or RGB, and position the gray-to-RGB
+ *  transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* If gray -> RGB, do so now only if background is non-gray; else do later
+    * for performance reasons
+    */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+      ((png_ptr->num_trans != 0 ) ||
+      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->trans_values), &(png_ptr->background)
+#ifdef PNG_READ_GAMMA_SUPPORTED
+         , &(png_ptr->background_1),
+         png_ptr->gamma_table, png_ptr->gamma_from_1,
+         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+         png_ptr->gamma_shift
+#endif
+);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if ((png_ptr->transformations & PNG_GAMMA) &&
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+       !((png_ptr->transformations & PNG_BACKGROUND) &&
+       ((png_ptr->num_trans != 0) ||
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+          png_ptr->gamma_table, png_ptr->gamma_16_table,
+          png_ptr->gamma_shift);
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+   if (png_ptr->transformations & PNG_16_TO_8)
+      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->palette_lookup, png_ptr->dither_index);
+      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
+         png_error(png_ptr, "png_do_dither returned rowbytes=0");
+   }
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* If gray -> RGB, do so now only if we did not do so above */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+    {
+      if (png_ptr->read_user_transform_fn != NULL)
+         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+            (png_ptr,                    /* png_ptr */
+               &(png_ptr->row_info),     /* row_info: */
+               /*  png_uint_32 width;       width of row */
+               /*  png_uint_32 rowbytes;    number of bytes in row */
+               /*  png_byte color_type;     color type of pixels */
+               /*  png_byte bit_depth;      bit depth of samples */
+               /*  png_byte channels;       number of channels (1-4) */
+               /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+               png_ptr->row_buf + 1);    /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+      if (png_ptr->user_transform_depth)
+         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+      if (png_ptr->user_transform_channels)
+         png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+         png_ptr->row_info.channels);
+      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+         png_ptr->row_info.width);
+   }
+#endif
+
+}
+
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values.  Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_unpack");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+   if (row_info->bit_depth < 8)
+#endif
+   {
+      png_uint_32 i;
+      png_uint_32 row_width=row_info->width;
+
+      switch (row_info->bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x01);
+               if (shift == 7)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift++;
+
+               dp--;
+            }
+            break;
+         }
+
+         case 2:
+         {
+
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x03);
+               if (shift == 6)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift += 2;
+
+               dp--;
+            }
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)row_width - 1;
+            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+            for (i = 0; i < row_width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x0f);
+               if (shift == 4)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift = 4;
+
+               dp--;
+            }
+            break;
+         }
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_width * row_info->channels;
+   }
+}
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* Reverse the effects of png_do_shift.  This routine merely shifts the
+ * pixels back to their significant bits values.  Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+   png_debug(1, "in png_do_unshift");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift[4];
+      int channels = 0;
+      int c;
+      png_uint_16 value = 0;
+      png_uint_32 row_width = row_info->width;
+
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->red;
+         shift[channels++] = row_info->bit_depth - sig_bits->green;
+         shift[channels++] = row_info->bit_depth - sig_bits->blue;
+      }
+      else
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->gray;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+      }
+
+      for (c = 0; c < channels; c++)
+      {
+         if (shift[c] <= 0)
+            shift[c] = 0;
+         else
+            value = 1;
+      }
+
+      if (!value)
+         return;
+
+      switch (row_info->bit_depth)
+      {
+         case 2:
+         {
+            png_bytep bp;
+            png_uint_32 i;
+            png_uint_32 istop = row_info->rowbytes;
+
+            for (bp = row, i = 0; i < istop; i++)
+            {
+               *bp >>= 1;
+               *bp++ &= 0x55;
+            }
+            break;
+         }
+
+         case 4:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = row_info->rowbytes;
+            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+               (png_byte)((int)0xf >> shift[0]));
+
+            for (i = 0; i < istop; i++)
+            {
+               *bp >>= shift[0];
+               *bp++ &= mask;
+            }
+            break;
+         }
+
+         case 8:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = row_width * channels;
+
+            for (i = 0; i < istop; i++)
+            {
+               *bp++ >>= shift[i%channels];
+            }
+            break;
+         }
+
+         case 16:
+         {
+            png_bytep bp = row;
+            png_uint_32 i;
+            png_uint_32 istop = channels * row_width;
+
+            for (i = 0; i < istop; i++)
+            {
+               value = (png_uint_16)((*bp << 8) + *(bp + 1));
+               value >>= shift[i%channels];
+               *bp++ = (png_byte)(value >> 8);
+               *bp++ = (png_byte)(value & 0xff);
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Chop rows of bit depth 16 down to 8 */
+void /* PRIVATE */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_chop");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+   if (row_info->bit_depth == 16)
+#endif
+   {
+      png_bytep sp = row;
+      png_bytep dp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->width * row_info->channels;
+
+      for (i = 0; i<istop; i++, sp += 2, dp++)
+      {
+#ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+      /* This does a more accurate scaling of the 16-bit color
+       * value, rather than a simple low-byte truncation.
+       *
+       * What the ideal calculation should be:
+       *   *dp = (((((png_uint_32)(*sp) << 8) |
+       *          (png_uint_32)(*(sp + 1))) * 255 + 127)
+       *          / (png_uint_32)65535L;
+       *
+       * GRR: no, I think this is what it really should be:
+       *   *dp = (((((png_uint_32)(*sp) << 8) |
+       *           (png_uint_32)(*(sp + 1))) + 128L)
+       *           / (png_uint_32)257L;
+       *
+       * GRR: here's the exact calculation with shifts:
+       *   temp = (((png_uint_32)(*sp) << 8) |
+       *           (png_uint_32)(*(sp + 1))) + 128L;
+       *   *dp = (temp - (temp >> 8)) >> 8;
+       *
+       * Approximate calculation with shift/add instead of multiply/divide:
+       *   *dp = ((((png_uint_32)(*sp) << 8) |
+       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+       *
+       * What we actually do to avoid extra shifting and conversion:
+       */
+
+         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+       /* Simply discard the low order byte */
+         *dp = *sp;
+#endif
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_swap_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from RGBA to ARGB */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from RRGGBBAA to AARRGGBB */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from GA to AG */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from GGAA to AAGG */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_invert_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=3;
+               dp=sp;
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+
+/*             This does nothing:
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               We can replace it with:
+*/
+               sp-=6;
+               dp=sp;
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = *(--sp);
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp  = row + row_info->rowbytes;
+            png_bytep dp = sp;
+            png_uint_32 i;
+
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = (png_byte)(255 - *(--sp));
+               *(--dp) = (png_byte)(255 - *(--sp));
+/*
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+*/
+               sp-=2;
+               dp=sp;
+            }
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+   png_uint_32 filler, png_uint_32 flags)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+   png_byte lo_filler = (png_byte)(filler & 0xff);
+
+   png_debug(1, "in png_do_read_filler");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL  && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         /* This changes the data from G to GX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp =  sp + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+      /* This changes the data from G to XG */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         /* This changes the data from GG to GGXX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+         /* This changes the data from GG to XXGG */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+   } /* COLOR_TYPE == GRAY */
+   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         /* This changes the data from RGB to RGBX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp  + (png_size_t)row_width;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      /* This changes the data from RGB to XRGB */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 3;
+            png_bytep dp = sp + (png_size_t)row_width;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 4;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         /* This changes the data from RRGGBB to RRGGBBXX */
+         if (flags & PNG_FLAG_FILLER_AFTER)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 1; i < row_width; i++)
+            {
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+            *(--dp) = hi_filler;
+            *(--dp) = lo_filler;
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+         /* This changes the data from RRGGBB to XXRRGGBB */
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 6;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = hi_filler;
+               *(--dp) = lo_filler;
+            }
+            row_info->channels = 4;
+            row_info->pixel_depth = 64;
+            row_info->rowbytes = row_width * 8;
+         }
+      }
+   } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+   png_uint_32 i;
+   png_uint_32 row_width = row_info->width;
+
+   png_debug(1, "in png_do_gray_to_rgb");
+
+   if (row_info->bit_depth >= 8 &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + (png_size_t)row_width - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *(sp--);
+            }
+         }
+         else
+         {
+            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            for (i = 0; i < row_width; i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+            }
+         }
+      }
+      row_info->channels += (png_byte)2;
+      row_info->color_type |= PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+         row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+   }
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ at
+ * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
+ * New link:
+ * <http://www.poynton.com/notes/colour_and_gamma/>
+ * Charles Poynton poynton at poynton.com
+ *
+ *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ *  We approximate this with
+ *
+ *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
+ *
+ *  which can be expressed with integers as
+ *
+ *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ *  The calculation is to be done in a linear colorspace.
+ *
+ *  Other integer coefficents can be used via png_set_rgb_to_gray().
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+   png_uint_32 i;
+
+   png_uint_32 row_width = row_info->width;
+   int rgb_error = 0;
+
+   png_debug(1, "in png_do_rgb_to_gray");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+      (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
+
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (row_info->bit_depth == 8)
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
+                  if (red != green || red != blue)
+                  {
+                     rgb_error |= 1;
+                     *(dp++) = png_ptr->gamma_from_1[
+                       (rc*red + gc*green + bc*blue)>>15];
+                  }
+                  else
+                     *(dp++) = *(sp - 1);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = *(sp++);
+                  png_byte green = *(sp++);
+                  png_byte blue  = *(sp++);
+                  if (red != green || red != blue)
+                  {
+                     rgb_error |= 1;
+                     *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+                  }
+                  else
+                     *(dp++) = *(sp - 1);
+               }
+            }
+         }
+
+         else /* RGB bit_depth == 16 */
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_16_to_1 != NULL &&
+                png_ptr->gamma_16_from_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, w;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if (red == green && red == blue)
+                     w = red;
+                  else
+                  {
+                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
+                                  png_ptr->gamma_shift][red>>8];
+                     png_uint_16 green_1 =
+                         png_ptr->gamma_16_to_1[(green&0xff) >>
+                                  png_ptr->gamma_shift][green>>8];
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
+                                  png_ptr->gamma_shift][blue>>8];
+                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
+                                  + bc*blue_1)>>15);
+                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                         png_ptr->gamma_shift][gray16 >> 8];
+                     rgb_error |= 1;
+                  }
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, gray16;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if (red != green || red != blue)
+                     rgb_error |= 1;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
+               }
+            }
+         }
+      }
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
+                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
+                  if (red != green || red != blue)
+                     rgb_error |= 1;
+                  *(dp++) =  png_ptr->gamma_from_1
+                             [(rc*red + gc*green + bc*blue)>>15];
+                  *(dp++) = *(sp++);  /* alpha */
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_byte red   = *(sp++);
+                  png_byte green = *(sp++);
+                  png_byte blue  = *(sp++);
+                  if (red != green || red != blue)
+                     rgb_error |= 1;
+                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = *(sp++);  /* alpha */
+               }
+            }
+         }
+         else /* RGBA bit_depth == 16 */
+         {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+            if (png_ptr->gamma_16_to_1 != NULL &&
+                png_ptr->gamma_16_from_1 != NULL)
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, w;
+
+                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+                  if (red == green && red == blue)
+                     w = red;
+                  else
+                  {
+                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
+                         png_ptr->gamma_shift][red>>8];
+                     png_uint_16 green_1 =
+                         png_ptr->gamma_16_to_1[(green&0xff) >>
+                         png_ptr->gamma_shift][green>>8];
+                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
+                         png_ptr->gamma_shift][blue>>8];
+                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
+                         + gc * green_1 + bc * blue_1)>>15);
+                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                         png_ptr->gamma_shift][gray16 >> 8];
+                     rgb_error |= 1;
+                  }
+
+                  *(dp++) = (png_byte)((w>>8) & 0xff);
+                  *(dp++) = (png_byte)(w & 0xff);
+                  *(dp++) = *(sp++);  /* alpha */
+                  *(dp++) = *(sp++);
+               }
+            }
+            else
+#endif
+            {
+               png_bytep sp = row;
+               png_bytep dp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 red, green, blue, gray16;
+                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+                  if (red != green || red != blue)
+                     rgb_error |= 1;
+                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
+                  *(dp++) = (png_byte)(gray16 & 0xff);
+                  *(dp++) = *(sp++);  /* alpha */
+                  *(dp++) = *(sp++);
+               }
+            }
+         }
+      }
+   row_info->channels -= (png_byte)2;
+      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+         row_info->bit_depth);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+   }
+   return rgb_error;
+}
+#endif
+
+/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
+ * large of png_color.  This lets grayscale images be treated as
+ * paletted.  Most useful for gamma correction and simplification
+ * of code.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+   int num_palette;
+   int color_inc;
+   int i;
+   int v;
+
+   png_debug(1, "in png_do_build_grayscale_palette");
+
+   if (palette == NULL)
+      return;
+
+   switch (bit_depth)
+   {
+      case 1:
+         num_palette = 2;
+         color_inc = 0xff;
+         break;
+
+      case 2:
+         num_palette = 4;
+         color_inc = 0x55;
+         break;
+
+      case 4:
+         num_palette = 16;
+         color_inc = 0x11;
+         break;
+
+      case 8:
+         num_palette = 256;
+         color_inc = 1;
+         break;
+
+      default:
+         num_palette = 0;
+         color_inc = 0;
+         break;
+   }
+
+   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+   {
+      palette[i].red = (png_byte)v;
+      palette[i].green = (png_byte)v;
+      palette[i].blue = (png_byte)v;
+   }
+}
+
+/* This function is currently unused.  Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && \
+  defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void /* PRIVATE */
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+   int num_palette)
+{
+   png_debug(1, "in png_correct_palette");
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+    defined(PNG_READ_GAMMA_SUPPORTED) && \
+  defined(PNG_FLOATING_POINT_SUPPORTED)
+   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
+   {
+      png_color back, back_1;
+
+      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+      {
+         back.red = png_ptr->gamma_table[png_ptr->background.red];
+         back.green = png_ptr->gamma_table[png_ptr->background.green];
+         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+      }
+      else
+      {
+         double g;
+
+         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN
+             || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+         {
+            back.red = png_ptr->background.red;
+            back.green = png_ptr->background.green;
+            back.blue = png_ptr->background.blue;
+         }
+         else
+         {
+            back.red =
+               (png_byte)(pow((double)png_ptr->background.red/255, g) *
+                255.0 + 0.5);
+            back.green =
+               (png_byte)(pow((double)png_ptr->background.green/255, g) *
+                255.0 + 0.5);
+            back.blue =
+               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+                255.0 + 0.5);
+         }
+
+         g = 1.0 / png_ptr->background_gamma;
+
+         back_1.red =
+            (png_byte)(pow((double)png_ptr->background.red/255, g) *
+             255.0 + 0.5);
+         back_1.green =
+            (png_byte)(pow((double)png_ptr->background.green/255, g) *
+             255.0 + 0.5);
+         back_1.blue =
+            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+             255.0 + 0.5);
+      }
+
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_uint_32 i;
+
+         for (i = 0; i < (png_uint_32)num_palette; i++)
+         {
+            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+            {
+               palette[i] = back;
+            }
+            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+            {
+               png_byte v, w;
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+               png_composite(w, v, png_ptr->trans[i], back_1.red);
+               palette[i].red = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+               png_composite(w, v, png_ptr->trans[i], back_1.green);
+               palette[i].green = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+               png_composite(w, v, png_ptr->trans[i], back_1.blue);
+               palette[i].blue = png_ptr->gamma_from_1[w];
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+      else
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i] = back;
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+   }
+   else
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+      int i;
+
+      for (i = 0; i < num_palette; i++)
+      {
+         palette[i].red = png_ptr->gamma_table[palette[i].red];
+         palette[i].green = png_ptr->gamma_table[palette[i].green];
+         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+      }
+   }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   else
+#endif
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_color back;
+
+         back.red   = (png_byte)png_ptr->background.red;
+         back.green = (png_byte)png_ptr->background.green;
+         back.blue  = (png_byte)png_ptr->background.blue;
+
+         for (i = 0; i < (int)png_ptr->num_trans; i++)
+         {
+            if (png_ptr->trans[i] == 0)
+            {
+               palette[i].red = back.red;
+               palette[i].green = back.green;
+               palette[i].blue = back.blue;
+            }
+            else if (png_ptr->trans[i] != 0xff)
+            {
+               png_composite(palette[i].red, png_ptr->palette[i].red,
+                  png_ptr->trans[i], back.red);
+               png_composite(palette[i].green, png_ptr->palette[i].green,
+                  png_ptr->trans[i], back.green);
+               png_composite(palette[i].blue, png_ptr->palette[i].blue,
+                  png_ptr->trans[i], back.blue);
+            }
+         }
+      }
+      else /* Assume grayscale palette (what else could it be?) */
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (i == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i].red = (png_byte)png_ptr->background.red;
+               palette[i].green = (png_byte)png_ptr->background.green;
+               palette[i].blue = (png_byte)png_ptr->background.blue;
+            }
+         }
+      }
+   }
+#endif
+}
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0.  Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_background(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   , png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift
+#endif
+   )
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+   int shift;
+
+   png_debug(1, "in png_do_background");
+
+   if (background != NULL &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  sp = row;
+                  shift = 7;
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0x01)
+                        == trans_values->gray)
+                     {
+                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                        *sp |= (png_byte)(background->gray << shift);
+                     }
+                     if (!shift)
+                     {
+                        shift = 7;
+                        sp++;
+                     }
+                     else
+                        shift--;
+                  }
+                  break;
+               }
+
+               case 2:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        else
+                        {
+                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
+                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+                               (p << 4) | (p << 6)] >> 6) & 0x03);
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(g << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+                        else
+                           shift -= 2;
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 6;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x03)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 6;
+                           sp++;
+                        }
+                        else
+                           shift -= 2;
+                     }
+                  }
+                  break;
+               }
+
+               case 4:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        else
+                        {
+                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+                           png_byte g = (png_byte)((gamma_table[p |
+                             (p << 4)] >> 4) & 0x0f);
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(g << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+                        else
+                           shift -= 4;
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     shift = 4;
+                     for (i = 0; i < row_width; i++)
+                     {
+                        if ((png_uint_16)((*sp >> shift) & 0x0f)
+                            == trans_values->gray)
+                        {
+                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                           *sp |= (png_byte)(background->gray << shift);
+                        }
+                        if (!shift)
+                        {
+                           shift = 4;
+                           sp++;
+                        }
+                        else
+                           shift -= 4;
+                     }
+                  }
+                  break;
+               }
+
+               case 8:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_table != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                        else
+                        {
+                           *sp = gamma_table[*sp];
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                     }
+                  }
+                  break;
+               }
+
+               case 16:
+               {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                  if (gamma_16 != NULL)
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        if (v == trans_values->gray)
+                        {
+                           /* Background is already in screen gamma */
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                        else
+                        {
+                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                           *sp = (png_byte)((v >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(v & 0xff);
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     sp = row;
+                     for (i = 0; i < row_width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        if (v == trans_values->gray)
+                        {
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                     }
+                  }
+                  break;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        *sp = gamma_table[*sp];
+                        *(sp + 1) = gamma_table[*(sp + 1)];
+                        *(sp + 2) = gamma_table[*(sp + 2)];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 6)
+                  {
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 2, dp++)
+                  {
+                     png_uint_16 a = *(sp + 1);
+
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                     }
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->gray);
+                        *dp = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 2, dp++)
+                  {
+                     png_byte a = *(sp + 1);
+
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                     }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background_1->gray);
+                     }
+#else
+                     *dp = (png_byte)background->gray;
+#endif
+                  }
+               }
+            }
+            else /* if (png_ptr->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                     else if (a == 0)
+#else
+                     else
+#endif
+                     {
+                        /* Background is already in screen gamma */
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                     else
+                     {
+                        png_uint_16 g, v, w;
+
+                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(v, g, a, background_1->gray);
+                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+                        *dp = (png_byte)((w >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(w & 0xff);
+                     }
+#endif
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 2);
+                     }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                     else if (a == 0)
+#else
+                     else
+#endif
+                     {
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+                     else
+                     {
+                        png_uint_16 g, v;
+
+                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_composite_16(v, g, a, background_1->gray);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+#endif
+                  }
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                        *(dp + 1) = gamma_table[*(sp + 1)];
+                        *(dp + 2) = gamma_table[*(sp + 2)];
+                     }
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->red);
+                        *dp = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 1)];
+                        png_composite(w, v, a, background_1->green);
+                        *(dp + 1) = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 2)];
+                        png_composite(w, v, a, background_1->blue);
+                        *(dp + 2) = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a = *(sp + 3);
+
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                        *(dp + 1) = *(sp + 1);
+                        *(dp + 2) = *(sp + 2);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background->red);
+                        png_composite(*(dp + 1), *(sp + 1), a,
+                           background->green);
+                        png_composite(*(dp + 2), *(sp + 2), a,
+                           background->blue);
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                         << 8) + (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                     else if (a == 0)
+                     {
+                        /* Background is already in screen gamma */
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v, w, x;
+
+                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(w, v, a, background_1->red);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *dp = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        png_composite_16(w, v, a, background_1->green);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        png_composite_16(w, v, a, background_1->blue);
+                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(x & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  sp = row;
+                  dp = row;
+                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                        << 8) + (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 6);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v;
+
+                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                            + *(sp + 3));
+                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                            + *(sp + 5));
+
+                        png_composite_16(v, r, a, background->red);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        png_composite_16(v, g, a, background->green);
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        png_composite_16(v, b, a, background->blue);
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+      }
+
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+         row_info->channels--;
+         row_info->pixel_depth = (png_byte)(row_info->channels *
+            row_info->bit_depth);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Gamma correct the image, avoiding the alpha channel.  Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift.  Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift)
+{
+   png_bytep sp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_gamma");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp += 2;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            if (row_info->bit_depth == 2)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 4)
+               {
+                  int a = *sp & 0xc0;
+                  int b = *sp & 0x30;
+                  int c = *sp & 0x0c;
+                  int d = *sp & 0x03;
+
+                  *sp = (png_byte)(
+                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
+                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+                  sp++;
+               }
+            }
+
+            if (row_info->bit_depth == 4)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i += 2)
+               {
+                  int msb = *sp & 0xf0;
+                  int lsb = *sp & 0x0f;
+
+                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+                  sp++;
+               }
+            }
+
+            else if (row_info->bit_depth == 8)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+
+            else if (row_info->bit_depth == 16)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++)
+               {
+                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+   png_colorp palette, png_bytep trans, int num_trans)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand_palette");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (row_info->bit_depth < 8)
+      {
+         switch (row_info->bit_depth)
+         {
+            case 1:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 3);
+               dp = row + (png_size_t)row_width - 1;
+               shift = 7 - (int)((row_width + 7) & 0x07);
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((*sp >> shift) & 0x01)
+                     *dp = 1;
+                  else
+                     *dp = 0;
+                  if (shift == 7)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift++;
+
+                  dp--;
+               }
+               break;
+            }
+
+            case 2:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 2);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x03;
+                  *dp = (png_byte)value;
+                  if (shift == 6)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 2;
+
+                  dp--;
+               }
+               break;
+            }
+
+            case 4:
+            {
+               sp = row + (png_size_t)((row_width - 1) >> 1);
+               dp = row + (png_size_t)row_width - 1;
+               shift = (int)((row_width & 0x01) << 2);
+               for (i = 0; i < row_width; i++)
+               {
+                  value = (*sp >> shift) & 0x0f;
+                  *dp = (png_byte)value;
+                  if (shift == 4)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 4;
+
+                  dp--;
+               }
+               break;
+            }
+         }
+         row_info->bit_depth = 8;
+         row_info->pixel_depth = 8;
+         row_info->rowbytes = row_width;
+      }
+      switch (row_info->bit_depth)
+      {
+         case 8:
+         {
+            if (trans != NULL)
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 2) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((int)(*sp) >= num_trans)
+                     *dp-- = 0xff;
+                  else
+                     *dp-- = trans[*sp];
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 32;
+               row_info->rowbytes = row_width * 4;
+               row_info->color_type = 6;
+               row_info->channels = 4;
+            }
+            else
+            {
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width * 3) - 1;
+
+               for (i = 0; i < row_width; i++)
+               {
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 24;
+               row_info->rowbytes = row_width * 3;
+               row_info->color_type = 2;
+               row_info->channels = 3;
+            }
+            break;
+         }
+      }
+   }
+}
+
+/* If the bit depth < 8, it is expanded to 8.  Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_value)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_expand");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
+
+         if (row_info->bit_depth < 8)
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  gray = (png_uint_16)((gray&0x01)*0xff);
+                  sp = row + (png_size_t)((row_width - 1) >> 3);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = 7 - (int)((row_width + 7) & 0x07);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     if ((*sp >> shift) & 0x01)
+                        *dp = 0xff;
+                     else
+                        *dp = 0;
+                     if (shift == 7)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift++;
+
+                     dp--;
+                  }
+                  break;
+               }
+
+               case 2:
+               {
+                  gray = (png_uint_16)((gray&0x03)*0x55);
+                  sp = row + (png_size_t)((row_width - 1) >> 2);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x03;
+                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
+                        (value << 6));
+                     if (shift == 6)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift += 2;
+
+                     dp--;
+                  }
+                  break;
+               }
+
+               case 4:
+               {
+                  gray = (png_uint_16)((gray&0x0f)*0x11);
+                  sp = row + (png_size_t)((row_width - 1) >> 1);
+                  dp = row + (png_size_t)row_width - 1;
+                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+                  for (i = 0; i < row_width; i++)
+                  {
+                     value = (*sp >> shift) & 0x0f;
+                     *dp = (png_byte)(value | (value << 4));
+                     if (shift == 4)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift = 4;
+
+                     dp--;
+                  }
+                  break;
+               }
+            }
+
+            row_info->bit_depth = 8;
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_width;
+         }
+
+         if (trans_value != NULL)
+         {
+            if (row_info->bit_depth == 8)
+            {
+               gray = gray & 0xff;
+               sp = row + (png_size_t)row_width - 1;
+               dp = row + (png_size_t)(row_width << 1) - 1;
+               for (i = 0; i < row_width; i++)
+               {
+                  if (*sp == gray)
+                     *dp-- = 0;
+                  else
+                     *dp-- = 0xff;
+                  *dp-- = *sp--;
+               }
+            }
+
+            else if (row_info->bit_depth == 16)
+            {
+               png_byte gray_high = (gray >> 8) & 0xff;
+               png_byte gray_low = gray & 0xff;
+               sp = row + row_info->rowbytes - 1;
+               dp = row + (row_info->rowbytes << 1) - 1;
+               for (i = 0; i < row_width; i++)
+               {
+                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
+                  {
+                     *dp-- = 0;
+                     *dp-- = 0;
+                  }
+                  else
+                  {
+                     *dp-- = 0xff;
+                     *dp-- = 0xff;
+                  }
+                  *dp-- = *sp--;
+                  *dp-- = *sp--;
+               }
+            }
+
+            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+            row_info->channels = 2;
+            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+               row_width);
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            png_byte red = trans_value->red & 0xff;
+            png_byte green = trans_value->green & 0xff;
+            png_byte blue = trans_value->blue & 0xff;
+            sp = row + (png_size_t)row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 2) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+                  *dp-- = 0;
+               else
+                  *dp-- = 0xff;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         else if (row_info->bit_depth == 16)
+         {
+            png_byte red_high = (trans_value->red >> 8) & 0xff;
+            png_byte green_high = (trans_value->green >> 8) & 0xff;
+            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
+            png_byte red_low = trans_value->red & 0xff;
+            png_byte green_low = trans_value->green & 0xff;
+            png_byte blue_low = trans_value->blue & 0xff;
+            sp = row + row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_width << 3) - 1;
+            for (i = 0; i < row_width; i++)
+            {
+               if (*(sp - 5) == red_high &&
+                  *(sp - 4) == red_low &&
+                  *(sp - 3) == green_high &&
+                  *(sp - 2) == green_low &&
+                  *(sp - 1) == blue_high &&
+                  *(sp    ) == blue_low)
+               {
+                  *dp-- = 0;
+                  *dp-- = 0;
+               }
+               else
+               {
+                  *dp-- = 0xff;
+                  *dp-- = 0xff;
+               }
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         row_info->channels = 4;
+         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+   }
+}
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+void /* PRIVATE */
+png_do_dither(png_row_infop row_info, png_bytep row,
+    png_bytep palette_lookup, png_bytep dither_lookup)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   png_uint_32 row_width=row_info->width;
+
+   png_debug(1, "in png_do_dither");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+         palette_lookup && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+
+            /* This looks real messy, but the compiler will reduce
+             * it down to a reasonable formula.  For example, with
+             * 5 bits per color, we get:
+             * p = (((r >> 3) & 0x1f) << 10) |
+             *    (((g >> 3) & 0x1f) << 5) |
+             *    ((b >> 3) & 0x1f);
+             */
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+         palette_lookup != NULL && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+            sp++;
+
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+         dither_lookup && row_info->bit_depth == 8)
+      {
+         sp = row;
+         for (i = 0; i < row_width; i++, sp++)
+         {
+            *sp = dither_lookup[*sp];
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+static PNG_CONST int png_gamma_shift[] =
+   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
+
+/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future.  Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ *
+ * See the PNG extensions document for an integer algorithm for creating
+ * the gamma tables.  Maybe we will implement that here someday.
+ *
+ * We should only reach this point if
+ *
+ *      the file_gamma is known (i.e., the gAMA or sRGB chunk is present,
+ *      or the application has provided a file_gamma)
+ *
+ *   AND
+ *      {
+ *         the screen_gamma is known
+ *      OR
+ *
+ *         RGB_to_gray transformation is being performed
+ *      }
+ *
+ *   AND
+ *      {
+ *         the screen_gamma is different from the reciprocal of the
+ *         file_gamma by more than the specified threshold
+ *
+ *      OR
+ *
+ *         a background color has been specified and the file_gamma
+ *         and screen_gamma are not 1.0, within the specified threshold.
+ *      }
+ */
+
+void /* PRIVATE */
+png_build_gamma_table(png_structp png_ptr)
+{
+  png_debug(1, "in png_build_gamma_table");
+
+  if (png_ptr->bit_depth <= 8)
+  {
+     int i;
+     double g;
+
+     if (png_ptr->screen_gamma > .000001)
+        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+
+     else
+        g = 1.0;
+
+     png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+        (png_uint_32)256);
+
+     for (i = 0; i < 256; i++)
+     {
+        png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+           g) * 255.0 + .5);
+     }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+     if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
+     {
+
+        g = 1.0 / (png_ptr->gamma);
+
+        png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+           (png_uint_32)256);
+
+        for (i = 0; i < 256; i++)
+        {
+           png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+              g) * 255.0 + .5);
+        }
+
+
+        png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+           (png_uint_32)256);
+
+        if (png_ptr->screen_gamma > 0.000001)
+           g = 1.0 / png_ptr->screen_gamma;
+
+        else
+           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
+
+        for (i = 0; i < 256; i++)
+        {
+           png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+              g) * 255.0 + .5);
+
+        }
+     }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+  }
+  else
+  {
+     double g;
+     int i, j, shift, num;
+     int sig_bit;
+     png_uint_32 ig;
+
+     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+     {
+        sig_bit = (int)png_ptr->sig_bit.red;
+
+        if ((int)png_ptr->sig_bit.green > sig_bit)
+           sig_bit = png_ptr->sig_bit.green;
+
+        if ((int)png_ptr->sig_bit.blue > sig_bit)
+           sig_bit = png_ptr->sig_bit.blue;
+     }
+     else
+     {
+        sig_bit = (int)png_ptr->sig_bit.gray;
+     }
+
+     if (sig_bit > 0)
+        shift = 16 - sig_bit;
+
+     else
+        shift = 0;
+
+     if (png_ptr->transformations & PNG_16_TO_8)
+     {
+        if (shift < (16 - PNG_MAX_GAMMA_8))
+           shift = (16 - PNG_MAX_GAMMA_8);
+     }
+
+     if (shift > 8)
+        shift = 8;
+
+     if (shift < 0)
+        shift = 0;
+
+     png_ptr->gamma_shift = (png_byte)shift;
+
+     num = (1 << (8 - shift));
+
+     if (png_ptr->screen_gamma > .000001)
+        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+     else
+        g = 1.0;
+
+     png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr,
+        (png_uint_32)(num * png_sizeof(png_uint_16p)));
+
+     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
+     {
+        double fin, fout;
+        png_uint_32 last, max;
+
+        for (i = 0; i < num; i++)
+        {
+           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+              (png_uint_32)(256 * png_sizeof(png_uint_16)));
+        }
+
+        g = 1.0 / g;
+        last = 0;
+        for (i = 0; i < 256; i++)
+        {
+           fout = ((double)i + 0.5) / 256.0;
+           fin = pow(fout, g);
+           max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+           while (last <= max)
+           {
+              png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+                 [(int)(last >> (8 - shift))] = (png_uint_16)(
+                 (png_uint_16)i | ((png_uint_16)i << 8));
+              last++;
+           }
+        }
+        while (last < ((png_uint_32)num << 8))
+        {
+           png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+              [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+           last++;
+        }
+     }
+     else
+     {
+        for (i = 0; i < num; i++)
+        {
+           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+              (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+           ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+
+           for (j = 0; j < 256; j++)
+           {
+              png_ptr->gamma_16_table[i][j] =
+                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                    65535.0, g) * 65535.0 + .5);
+           }
+        }
+     }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+     if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+     {
+
+        g = 1.0 / (png_ptr->gamma);
+
+        png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr,
+           (png_uint_32)(num * png_sizeof(png_uint_16p )));
+
+        for (i = 0; i < num; i++)
+        {
+           png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+              (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+           ig = (((png_uint_32)i *
+              (png_uint_32)png_gamma_shift[shift]) >> 4);
+           for (j = 0; j < 256; j++)
+           {
+              png_ptr->gamma_16_to_1[i][j] =
+                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                    65535.0, g) * 65535.0 + .5);
+           }
+        }
+
+        if (png_ptr->screen_gamma > 0.000001)
+           g = 1.0 / png_ptr->screen_gamma;
+
+        else
+           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
+
+        png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr,
+           (png_uint_32)(num * png_sizeof(png_uint_16p)));
+
+        for (i = 0; i < num; i++)
+        {
+           png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+              (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+           ig = (((png_uint_32)i *
+              (png_uint_32)png_gamma_shift[shift]) >> 4);
+
+           for (j = 0; j < 256; j++)
+           {
+              png_ptr->gamma_16_from_1[i][j] =
+                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                    65535.0, g) * 65535.0 + .5);
+           }
+        }
+     }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+  }
+}
+#endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_intrapixel");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
+            *(rp  ) = (png_byte)((red >> 8) & 0xff);
+            *(rp+1) = (png_byte)(red & 0xff);
+            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp+5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrutil.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3382 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.2.44 [June 26, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
+#  define WIN32_WCE_OLD
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#  ifdef WIN32_WCE_OLD
+/* The strtod() function is not supported on WindowsCE */
+__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
+    char **endptr)
+{
+   double result = 0;
+   int len;
+   wchar_t *str, *end;
+
+   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+   str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
+   if ( NULL != str )
+   {
+      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+      result = wcstod(str, &end);
+      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
+      png_free(png_ptr, str);
+   }
+   return result;
+}
+#  else
+#    define png_strtod(p,a,b) strtod(a,b)
+#  endif
+#endif
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_structp png_ptr, png_bytep buf)
+{
+#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
+   png_uint_32 i = png_get_uint_32(buf);
+#else
+   /* Avoid an extra function call by inlining the result. */
+   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+      ((png_uint_32)(*(buf + 1)) << 16) +
+      ((png_uint_32)(*(buf + 2)) << 8) +
+      (png_uint_32)(*(buf + 3));
+#endif
+   if (i > PNG_UINT_31_MAX)
+     png_error(png_ptr, "PNG unsigned integer out of range.");
+   return (i);
+}
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 PNGAPI
+png_get_uint_32(png_bytep buf)
+{
+   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+      ((png_uint_32)(*(buf + 1)) << 16) +
+      ((png_uint_32)(*(buf + 2)) << 8) +
+      (png_uint_32)(*(buf + 3));
+
+   return (i);
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same.
+ */
+png_int_32 PNGAPI
+png_get_int_32(png_bytep buf)
+{
+   png_int_32 i = ((png_int_32)(*buf) << 24) +
+      ((png_int_32)(*(buf + 1)) << 16) +
+      ((png_int_32)(*(buf + 2)) << 8) +
+      (png_int_32)(*(buf + 3));
+
+   return (i);
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 PNGAPI
+png_get_uint_16(png_bytep buf)
+{
+   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+      (png_uint_16)(*(buf + 1)));
+
+   return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structp png_ptr)
+{
+   png_byte buf[8];
+   png_uint_32 length;
+
+   /* Read the length and the chunk name */
+   png_read_data(png_ptr, buf, 8);
+   length = png_get_uint_31(png_ptr, buf);
+
+   /* Put the chunk name into png_ptr->chunk_name */
+   png_memcpy(png_ptr->chunk_name, buf + 4, 4);
+
+   png_debug2(0, "Reading %s chunk, length = %lu",
+      png_ptr->chunk_name, length);
+
+   /* Reset the crc and run it over the chunk name */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
+
+   /* Check to see if chunk name is valid */
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+   return length;
+}
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+   if (png_ptr == NULL)
+      return;
+   png_read_data(png_ptr, buf, length);
+   png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC.  Depending on whether we
+ * are reading a ancillary or critical chunk, and how the program has set
+ * things up, we may calculate the CRC on the data and print a message.
+ * Returns '1' if there was a CRC error, '0' otherwise.
+ */
+int /* PRIVATE */
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+   png_size_t i;
+   png_size_t istop = png_ptr->zbuf_size;
+
+   for (i = (png_size_t)skip; i > istop; i -= istop)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+   }
+   if (i)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, i);
+   }
+
+   if (png_crc_error(png_ptr))
+   {
+      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
+          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
+          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+      else
+      {
+         png_chunk_error(png_ptr, "CRC error");
+      }
+      return (1);
+   }
+
+   return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+int /* PRIVATE */
+png_crc_error(png_structp png_ptr)
+{
+   png_byte crc_bytes[4];
+   png_uint_32 crc;
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   png_read_data(png_ptr, crc_bytes, 4);
+
+   if (need_crc)
+   {
+      crc = png_get_uint_32(crc_bytes);
+      return ((int)(crc != png_ptr->crc));
+   }
+   else
+      return (0);
+}
+
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED)
+static png_size_t
+png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
+        png_bytep output, png_size_t output_size)
+{
+   png_size_t count = 0;
+
+   png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
+   png_ptr->zstream.avail_in = size;
+
+   while (1)
+   {
+      int ret, avail;
+
+      /* Reset the output buffer each time round - we empty it
+       * after every inflate call.
+       */
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
+
+      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
+      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+
+      /* First copy/count any new output - but only if we didn't
+       * get an error code.
+       */
+      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
+      {
+         if (output != 0 && output_size > count)
+         {
+            int copy = output_size - count;
+            if (avail < copy) copy = avail;
+            png_memcpy(output + count, png_ptr->zbuf, copy);
+         }
+         count += avail;
+      }
+
+      if (ret == Z_OK)
+         continue;
+
+      /* Termination conditions - always reset the zstream, it
+       * must be left in inflateInit state.
+       */
+      png_ptr->zstream.avail_in = 0;
+      inflateReset(&png_ptr->zstream);
+
+      if (ret == Z_STREAM_END)
+         return count; /* NOTE: may be zero. */
+
+      /* Now handle the error codes - the API always returns 0
+       * and the error message is dumped into the uncompressed
+       * buffer if available.
+       */
+      {
+         PNG_CONST char *msg;
+         if (png_ptr->zstream.msg != 0)
+            msg = png_ptr->zstream.msg;
+         else
+         {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+            char umsg[52];
+
+            switch (ret)
+            {
+               case Z_BUF_ERROR:
+                  msg = "Buffer error in compressed datastream in %s chunk";
+                  break;
+               case Z_DATA_ERROR:
+                  msg = "Data error in compressed datastream in %s chunk";
+                  break;
+               default:
+                  msg = "Incomplete compressed datastream in %s chunk";
+                  break;
+            }
+
+            png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
+            msg = umsg;
+#else
+            msg = "Damaged compressed datastream in chunk other than IDAT";
+#endif
+         }
+
+         png_warning(png_ptr, msg);
+      }
+
+      /* 0 means an error - notice that this code simple ignores
+       * zero length compressed chunks as a result.
+       */
+      return 0;
+   }
+}
+
+/*
+ * Decompress trailing data in a chunk.  The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part.  What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+void /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+    png_size_t chunklength,
+    png_size_t prefix_size, png_size_t *newlength)
+{
+   /* The caller should guarantee this */
+   if (prefix_size > chunklength)
+   {
+      /* The recovery is to delete the chunk. */
+      png_warning(png_ptr, "invalid chunklength");
+      prefix_size = 0; /* To delete everything */
+   }
+
+   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_size_t expanded_size = png_inflate(png_ptr,
+                (png_bytep)(png_ptr->chunkdata + prefix_size),
+                chunklength - prefix_size,
+                0/*output*/, 0/*output size*/);
+
+      /* Now check the limits on this chunk - if the limit fails the
+       * compressed data will be removed, the prefix will remain.
+       */
+#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+      if (png_ptr->user_chunk_malloc_max &&
+          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
+#else
+#  ifdef PNG_USER_CHUNK_MALLOC_MAX
+      if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
+          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
+#  endif
+#endif
+         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
+
+      /* If the size is zero either there was an error and a message
+       * has already been output (warning) or the size really is zero
+       * and we have nothing to do - the code will exit through the
+       * error case below.
+       */
+#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
+    defined(PNG_USER_CHUNK_MALLOC_MAX)
+      else
+#endif
+      if (expanded_size > 0)
+      {
+         /* Success (maybe) - really uncompress the chunk. */
+         png_size_t new_size = 0;
+         png_charp text = png_malloc_warn(png_ptr,
+                        prefix_size + expanded_size + 1);
+
+         if (text != NULL)
+         {
+            png_memcpy(text, png_ptr->chunkdata, prefix_size);
+            new_size = png_inflate(png_ptr,
+                (png_bytep)(png_ptr->chunkdata + prefix_size),
+                chunklength - prefix_size,
+                (png_bytep)(text + prefix_size), expanded_size);
+            text[prefix_size + expanded_size] = 0; /* just in case */
+
+            if (new_size == expanded_size)
+            {
+               png_free(png_ptr, png_ptr->chunkdata);
+               png_ptr->chunkdata = text;
+               *newlength = prefix_size + expanded_size;
+               return; /* The success return! */
+            }
+
+            png_warning(png_ptr, "png_inflate logic error");
+            png_free(png_ptr, text);
+         }
+         else
+          png_warning(png_ptr, "Not enough memory to decompress chunk.");
+      }
+   }
+
+   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+   {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+      char umsg[50];
+
+      png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
+          comp_type);
+      png_warning(png_ptr, umsg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+      /* The recovery is to simply drop the data. */
+   }
+
+   /* Generic error return - leave the prefix, delete the compressed
+    * data, reallocate the chunkdata to remove the potentially large
+    * amount of compressed data.
+    */
+   {
+      png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
+      if (text != NULL)
+      {
+         if (prefix_size > 0)
+            png_memcpy(text, png_ptr->chunkdata, prefix_size);
+         png_free(png_ptr, png_ptr->chunkdata);
+         png_ptr->chunkdata = text;
+
+         /* This is an extra zero in the 'uncompressed' part. */
+         *(png_ptr->chunkdata + prefix_size) = 0x00;
+      }
+      /* Ignore a malloc error here - it is safe. */
+   }
+
+   *newlength = prefix_size;
+}
+#endif
+
+/* Read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[13];
+   png_uint_32 width, height;
+   int bit_depth, color_type, compression_type, filter_type;
+   int interlace_type;
+
+   png_debug(1, "in png_handle_IHDR");
+
+   if (png_ptr->mode & PNG_HAVE_IHDR)
+      png_error(png_ptr, "Out of place IHDR");
+
+   /* Check the length */
+   if (length != 13)
+      png_error(png_ptr, "Invalid IHDR chunk");
+
+   png_ptr->mode |= PNG_HAVE_IHDR;
+
+   png_crc_read(png_ptr, buf, 13);
+   png_crc_finish(png_ptr, 0);
+
+   width = png_get_uint_31(png_ptr, buf);
+   height = png_get_uint_31(png_ptr, buf + 4);
+   bit_depth = buf[8];
+   color_type = buf[9];
+   compression_type = buf[10];
+   filter_type = buf[11];
+   interlace_type = buf[12];
+
+   /* Set internal variables */
+   png_ptr->width = width;
+   png_ptr->height = height;
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->color_type = (png_byte)color_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+
+   /* Find number of channels */
+   switch (png_ptr->color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+      case PNG_COLOR_TYPE_PALETTE:
+         png_ptr->channels = 1;
+         break;
+
+      case PNG_COLOR_TYPE_RGB:
+         png_ptr->channels = 3;
+         break;
+
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         png_ptr->channels = 2;
+         break;
+
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         png_ptr->channels = 4;
+         break;
+   }
+
+   /* Set up other useful info */
+   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+   png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+   png_debug1(3, "channels = %d", png_ptr->channels);
+   png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+      color_type, interlace_type, compression_type, filter_type);
+}
+
+/* Read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_color palette[PNG_MAX_PALETTE_LENGTH];
+   int num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   png_colorp pal_ptr;
+#endif
+
+   png_debug(1, "in png_handle_PLTE");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before PLTE");
+
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid PLTE after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      png_error(png_ptr, "Duplicate PLTE chunk");
+
+   png_ptr->mode |= PNG_HAVE_PLTE;
+
+   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+   {
+      png_warning(png_ptr,
+        "Ignoring PLTE chunk in grayscale PNG");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#endif
+
+   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+   {
+      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+      {
+         png_warning(png_ptr, "Invalid palette chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      else
+      {
+         png_error(png_ptr, "Invalid palette chunk");
+      }
+   }
+
+   num = (int)length / 3;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      pal_ptr->red = buf[0];
+      pal_ptr->green = buf[1];
+      pal_ptr->blue = buf[2];
+   }
+#else
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      /* Don't depend upon png_color being any order */
+      palette[i].red = buf[0];
+      palette[i].green = buf[1];
+      palette[i].blue = buf[2];
+   }
+#endif
+
+   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+    * whatever the normal CRC configuration tells us.  However, if we
+    * have an RGB image, the PLTE can be considered ancillary, so
+    * we will act as though it is.
+    */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+   {
+      png_crc_finish(png_ptr, 0);
+   }
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
+   {
+      /* If we don't want to use the data from an ancillary chunk,
+         we have two options: an error abort, or a warning and we
+         ignore the data in this chunk (which should be OK, since
+         it's considered ancillary for a RGB or RGBA image). */
+      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+      {
+         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+         {
+            png_chunk_error(png_ptr, "CRC error");
+         }
+         else
+         {
+            png_chunk_warning(png_ptr, "CRC error");
+            return;
+         }
+      }
+      /* Otherwise, we (optionally) emit a warning and use the chunk. */
+      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+   }
+#endif
+
+   png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+      {
+         if (png_ptr->num_trans > (png_uint_16)num)
+         {
+            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+            png_ptr->num_trans = (png_uint_16)num;
+         }
+         if (info_ptr->num_trans > (png_uint_16)num)
+         {
+            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+            info_ptr->num_trans = (png_uint_16)num;
+         }
+      }
+   }
+#endif
+
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_IEND");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+   {
+      png_error(png_ptr, "No image in file");
+   }
+
+   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+   if (length != 0)
+   {
+      png_warning(png_ptr, "Incorrect IEND chunk length");
+   }
+   png_crc_finish(png_ptr, length);
+
+   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+}
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+void /* PRIVATE */
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float file_gamma;
+#endif
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_gAMA");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before gAMA");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid gAMA after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place gAMA chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+#ifdef PNG_READ_sRGB_SUPPORTED
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate gAMA chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 4)
+   {
+      png_warning(png_ptr, "Incorrect gAMA chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   igamma = (png_fixed_point)png_get_uint_32(buf);
+   /* Check for zero gamma */
+   if (igamma == 0)
+      {
+         png_warning(png_ptr,
+           "Ignoring gAMA chunk with gamma=0");
+         return;
+      }
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+         fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
+#endif
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   file_gamma = (float)igamma / (float)100000.0;
+#  ifdef PNG_READ_GAMMA_SUPPORTED
+     png_ptr->gamma = file_gamma;
+#  endif
+     png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+void /* PRIVATE */
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_sBIT");
+
+   buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sBIT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sBIT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+   {
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sBIT chunk");
+   }
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+   {
+      png_warning(png_ptr, "Duplicate sBIT chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 3;
+   else
+      truelen = (png_size_t)png_ptr->channels;
+
+   if (length != truelen || length > 4)
+   {
+      png_warning(png_ptr, "Incorrect sBIT chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[1];
+      png_ptr->sig_bit.blue = buf[2];
+      png_ptr->sig_bit.alpha = buf[3];
+   }
+   else
+   {
+      png_ptr->sig_bit.gray = buf[0];
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[0];
+      png_ptr->sig_bit.blue = buf[0];
+      png_ptr->sig_bit.alpha = buf[1];
+   }
+   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+void /* PRIVATE */
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[32];
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue;
+
+   png_uint_32 uint_x, uint_y;
+
+   png_debug(1, "in png_handle_cHRM");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before cHRM");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid cHRM after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Missing PLTE before cHRM");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
+#ifdef PNG_READ_sRGB_SUPPORTED
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate cHRM chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 32)
+   {
+      png_warning(png_ptr, "Incorrect cHRM chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 32);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   uint_x = png_get_uint_32(buf);
+   uint_y = png_get_uint_32(buf + 4);
+   int_x_white = (png_fixed_point)uint_x;
+   int_y_white = (png_fixed_point)uint_y;
+
+   uint_x = png_get_uint_32(buf + 8);
+   uint_y = png_get_uint_32(buf + 12);
+   int_x_red = (png_fixed_point)uint_x;
+   int_y_red = (png_fixed_point)uint_y;
+
+   uint_x = png_get_uint_32(buf + 16);
+   uint_y = png_get_uint_32(buf + 20);
+   int_x_green = (png_fixed_point)uint_x;
+   int_y_green = (png_fixed_point)uint_y;
+
+   uint_x = png_get_uint_32(buf + 24);
+   uint_y = png_get_uint_32(buf + 28);
+   int_x_blue = (png_fixed_point)uint_x;
+   int_y_blue = (png_fixed_point)uint_y;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   white_x = (float)int_x_white / (float)100000.0;
+   white_y = (float)int_y_white / (float)100000.0;
+   red_x   = (float)int_x_red   / (float)100000.0;
+   red_y   = (float)int_y_red   / (float)100000.0;
+   green_x = (float)int_x_green / (float)100000.0;
+   green_y = (float)int_y_green / (float)100000.0;
+   blue_x  = (float)int_x_blue  / (float)100000.0;
+   blue_y  = (float)int_y_blue  / (float)100000.0;
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
+      {
+      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
+          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
+          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
+          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
+          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
+          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
+         {
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+            fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
+               white_x, white_y, red_x, red_y);
+            fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
+               green_x, green_y, blue_x, blue_y);
+#else
+            fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+               (long)int_x_white, (long)int_y_white,
+               (long)int_x_red, (long)int_y_red);
+            fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+               (long)int_x_green, (long)int_y_green,
+               (long)int_x_blue, (long)int_y_blue);
+#endif
+#endif /* PNG_CONSOLE_IO_SUPPORTED */
+         }
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_cHRM(png_ptr, info_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+      int_y_green, int_x_blue, int_y_blue);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+void /* PRIVATE */
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   int intent;
+   png_byte buf[1];
+
+   png_debug(1, "in png_handle_sRGB");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sRGB");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sRGB after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sRGB chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+   {
+      png_warning(png_ptr, "Duplicate sRGB chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 1)
+   {
+      png_warning(png_ptr, "Incorrect sRGB chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 1);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   intent = buf[0];
+   /* Check for bad intent */
+   if (intent >= PNG_sRGB_INTENT_LAST)
+   {
+      png_warning(png_ptr, "Unknown sRGB intent");
+      return;
+   }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
+   {
+   png_fixed_point igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      igamma=info_ptr->int_gamma;
+#else
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
+#  endif
+#endif
+      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+         fprintf(stderr, "incorrect gamma=(%d/100000)\n",
+            (int)png_ptr->int_gamma);
+#  else
+#    ifdef PNG_FLOATING_POINT_SUPPORTED
+         fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
+#    endif
+#  endif
+#endif
+      }
+   }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
+          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
+         {
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+         }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_byte compression_type;
+   png_bytep pC;
+   png_charp profile;
+   png_uint_32 skip = 0;
+   png_uint_32 profile_size, profile_length;
+   png_size_t slength, prefix_length, data_length;
+
+   png_debug(1, "in png_handle_iCCP");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iCCP");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid iCCP after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place iCCP chunk");
+
+   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+   {
+      png_warning(png_ptr, "Duplicate iCCP chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00;
+
+   for (profile = png_ptr->chunkdata; *profile; profile++)
+      /* Empty loop to find end of name */ ;
+
+   ++profile;
+
+   /* There should be at least one zero (the compression type byte)
+    * following the separator, and we should be on it
+    */
+   if ( profile >= png_ptr->chunkdata + slength - 1)
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_warning(png_ptr, "Malformed iCCP chunk");
+      return;
+   }
+
+   /* Compression_type should always be zero */
+   compression_type = *profile++;
+   if (compression_type)
+   {
+      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
+                                 wrote nonzero) */
+   }
+
+   prefix_length = profile - png_ptr->chunkdata;
+   png_decompress_chunk(png_ptr, compression_type,
+     slength, prefix_length, &data_length);
+
+   profile_length = data_length - prefix_length;
+
+   if ( prefix_length > data_length || profile_length < 4)
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
+      return;
+   }
+
+   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
+   profile_size = ((*(pC    ))<<24) |
+                  ((*(pC + 1))<<16) |
+                  ((*(pC + 2))<< 8) |
+                  ((*(pC + 3))    );
+
+   if (profile_size < profile_length)
+      profile_length = profile_size;
+
+   if (profile_size > profile_length)
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
+      return;
+   }
+
+   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
+     compression_type, png_ptr->chunkdata + prefix_length, profile_length);
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_bytep entry_start;
+   png_sPLT_t new_palette;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   png_sPLT_entryp pp;
+#endif
+   int data_length, entry_size, i;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sPLT");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for sPLT");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sPLT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sPLT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00;
+
+   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
+       entry_start++)
+      /* Empty loop to find end of name */ ;
+   ++entry_start;
+
+   /* A sample depth should follow the separator, and we should be on it  */
+   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_warning(png_ptr, "malformed sPLT chunk");
+      return;
+   }
+
+   new_palette.depth = *entry_start++;
+   entry_size = (new_palette.depth == 8 ? 6 : 10);
+   data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
+
+   /* Integrity-check the data length */
+   if (data_length % entry_size)
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_warning(png_ptr, "sPLT chunk has bad length");
+      return;
+   }
+
+   new_palette.nentries = (png_int_32) ( data_length / entry_size);
+   if ((png_uint_32) new_palette.nentries >
+       (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
+   {
+       png_warning(png_ptr, "sPLT chunk too long");
+       return;
+   }
+   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
+   if (new_palette.entries == NULL)
+   {
+       png_warning(png_ptr, "sPLT chunk requires too much memory");
+       return;
+   }
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+      pp = new_palette.entries + i;
+
+      if (new_palette.depth == 8)
+      {
+          pp->red = *entry_start++;
+          pp->green = *entry_start++;
+          pp->blue = *entry_start++;
+          pp->alpha = *entry_start++;
+      }
+      else
+      {
+          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp->green = png_get_uint_16(entry_start); entry_start += 2;
+          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#else
+   pp = new_palette.entries;
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+
+      if (new_palette.depth == 8)
+      {
+          pp[i].red   = *entry_start++;
+          pp[i].green = *entry_start++;
+          pp[i].blue  = *entry_start++;
+          pp[i].alpha = *entry_start++;
+      }
+      else
+      {
+          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+#endif
+
+   /* Discard all chunk data except the name and stash that */
+   new_palette.name = png_ptr->chunkdata;
+
+   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+   png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+void /* PRIVATE */
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_tRNS");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tRNS");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid tRNS after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+   {
+      png_warning(png_ptr, "Duplicate tRNS chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_byte buf[2];
+
+      if (length != 2)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, 2);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.gray = png_get_uint_16(buf);
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_byte buf[6];
+
+      if (length != 6)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      png_crc_read(png_ptr, buf, (png_size_t)length);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.red = png_get_uint_16(buf);
+      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
+      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (!(png_ptr->mode & PNG_HAVE_PLTE))
+      {
+         /* Should be an error, but we can cope with it. */
+         png_warning(png_ptr, "Missing PLTE before tRNS");
+      }
+      if (length > (png_uint_32)png_ptr->num_palette ||
+          length > PNG_MAX_PALETTE_LENGTH)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (length == 0)
+      {
+         png_warning(png_ptr, "Zero length tRNS chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      png_crc_read(png_ptr, readbuf, (png_size_t)length);
+      png_ptr->num_trans = (png_uint_16)length;
+   }
+   else
+   {
+      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_ptr->num_trans = 0;
+      return;
+   }
+
+   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+      &(png_ptr->trans_values));
+}
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+void /* PRIVATE */
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[6];
+
+   png_debug(1, "in png_handle_bKGD");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before bKGD");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid bKGD after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+            !(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before bKGD");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+   {
+      png_warning(png_ptr, "Duplicate bKGD chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 1;
+   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      truelen = 6;
+   else
+      truelen = 2;
+
+   if (length != truelen)
+   {
+      png_warning(png_ptr, "Incorrect bKGD chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   /* We convert the index value into RGB components so that we can allow
+    * arbitrary RGB values for background when we have transparency, and
+    * so it is easy to determine the RGB values of the background color
+    * from the info_ptr struct. */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      png_ptr->background.index = buf[0];
+      if (info_ptr && info_ptr->num_palette)
+      {
+          if (buf[0] >= info_ptr->num_palette)
+          {
+             png_warning(png_ptr, "Incorrect bKGD chunk index value");
+             return;
+          }
+          png_ptr->background.red =
+             (png_uint_16)png_ptr->palette[buf[0]].red;
+          png_ptr->background.green =
+             (png_uint_16)png_ptr->palette[buf[0]].green;
+          png_ptr->background.blue =
+             (png_uint_16)png_ptr->palette[buf[0]].blue;
+      }
+   }
+   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+   {
+      png_ptr->background.red =
+      png_ptr->background.green =
+      png_ptr->background.blue =
+      png_ptr->background.gray = png_get_uint_16(buf);
+   }
+   else
+   {
+      png_ptr->background.red = png_get_uint_16(buf);
+      png_ptr->background.green = png_get_uint_16(buf + 2);
+      png_ptr->background.blue = png_get_uint_16(buf + 4);
+   }
+
+   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+void /* PRIVATE */
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   unsigned int num, i;
+   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+   png_debug(1, "in png_handle_hIST");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before hIST");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid hIST after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before hIST");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+   {
+      png_warning(png_ptr, "Duplicate hIST chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   num = length / 2 ;
+   if (num != (unsigned int) png_ptr->num_palette || num >
+      (unsigned int) PNG_MAX_PALETTE_LENGTH)
+   {
+      png_warning(png_ptr, "Incorrect hIST chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[2];
+
+      png_crc_read(png_ptr, buf, 2);
+      readbuf[i] = png_get_uint_16(buf);
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+void /* PRIVATE */
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_uint_32 res_x, res_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_pHYs");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pHYs");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pHYs after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_warning(png_ptr, "Duplicate pHYs chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect pHYs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   res_x = png_get_uint_32(buf);
+   res_y = png_get_uint_32(buf + 4);
+   unit_type = buf[8];
+   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+void /* PRIVATE */
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_int_32 offset_x, offset_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_oFFs");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before oFFs");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid oFFs after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_warning(png_ptr, "Duplicate oFFs chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect oFFs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   offset_x = png_get_int_32(buf);
+   offset_y = png_get_int_32(buf + 4);
+   unit_type = buf[8];
+   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+/* Read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_int_32 X0, X1;
+   png_byte type, nparams;
+   png_charp buf, units, endptr;
+   png_charpp params;
+   png_size_t slength;
+   int i;
+
+   png_debug(1, "in png_handle_pCAL");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+   {
+      png_warning(png_ptr, "Duplicate pCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
+      length + 1);
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (png_ptr->chunkdata == NULL)
+     {
+       png_warning(png_ptr, "No memory for pCAL purpose.");
+       return;
+     }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
+
+   png_debug(3, "Finding end of pCAL purpose string");
+   for (buf = png_ptr->chunkdata; *buf; buf++)
+      /* Empty loop */ ;
+
+   endptr = png_ptr->chunkdata + slength;
+
+   /* We need to have at least 12 bytes after the purpose string
+      in order to get the parameter information. */
+   if (endptr <= buf + 12)
+   {
+      png_warning(png_ptr, "Invalid pCAL data");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
+   X0 = png_get_int_32((png_bytep)buf+1);
+   X1 = png_get_int_32((png_bytep)buf+5);
+   type = buf[9];
+   nparams = buf[10];
+   units = buf + 11;
+
+   png_debug(3, "Checking pCAL equation type and number of parameters");
+   /* Check that we have the right number of parameters for known
+      equation types. */
+   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+   {
+      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+   else if (type >= PNG_EQUATION_LAST)
+   {
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+   }
+
+   for (buf = units; *buf; buf++)
+      /* Empty loop to move past the units string. */ ;
+
+   png_debug(3, "Allocating pCAL parameters array");
+   params = (png_charpp)png_malloc_warn(png_ptr,
+      (png_uint_32)(nparams * png_sizeof(png_charp))) ;
+   if (params == NULL)
+     {
+       png_free(png_ptr, png_ptr->chunkdata);
+       png_ptr->chunkdata = NULL;
+       png_warning(png_ptr, "No memory for pCAL params.");
+       return;
+     }
+
+   /* Get pointers to the start of each parameter string. */
+   for (i = 0; i < (int)nparams; i++)
+   {
+      buf++; /* Skip the null string terminator from previous parameter. */
+
+      png_debug1(3, "Reading pCAL parameter %d", i);
+      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
+         /* Empty loop to move past each parameter string */ ;
+
+      /* Make sure we haven't run out of data yet */
+      if (buf > endptr)
+      {
+         png_warning(png_ptr, "Invalid pCAL data");
+         png_free(png_ptr, png_ptr->chunkdata);
+         png_ptr->chunkdata = NULL;
+         png_free(png_ptr, params);
+         return;
+      }
+   }
+
+   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
+      units, params);
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+   png_free(png_ptr, params);
+}
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+/* Read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   double width, height;
+   png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_charp swidth, sheight;
+#endif
+#endif
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sCAL");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+   {
+      png_warning(png_ptr, "Duplicate sCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
+      length + 1);
+   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (png_ptr->chunkdata == NULL)
+   {
+      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
+
+   ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   width = png_strtod(png_ptr, ep, &vp);
+   if (*vp)
+   {
+      png_warning(png_ptr, "malformed width string in sCAL chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+   if (swidth == NULL)
+   {
+      png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+   for (ep = png_ptr->chunkdata; *ep; ep++)
+      /* Empty loop */ ;
+   ep++;
+
+   if (png_ptr->chunkdata + slength < ep)
+   {
+      png_warning(png_ptr, "Truncated sCAL chunk");
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+#endif
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   height = png_strtod(png_ptr, ep, &vp);
+   if (*vp)
+   {
+      png_warning(png_ptr, "malformed height string in sCAL chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+#endif
+      return;
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+   if (sheight == NULL)
+   {
+      png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+#endif
+      return;
+   }
+   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+   if (png_ptr->chunkdata + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      || width <= 0. || height <= 0.
+#endif
+      )
+   {
+      png_warning(png_ptr, "Invalid sCAL data");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+      png_free(png_ptr, swidth);
+      png_free(png_ptr, sheight);
+#endif
+      return;
+   }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
+#endif
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+   png_free(png_ptr, swidth);
+   png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+void /* PRIVATE */
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[7];
+   png_time mod_time;
+
+   png_debug(1, "in png_handle_tIME");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Out of place tIME chunk");
+   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+   {
+      png_warning(png_ptr, "Duplicate tIME chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   if (length != 7)
+   {
+      png_warning(png_ptr, "Incorrect tIME chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 7);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   mod_time.second = buf[6];
+   mod_time.minute = buf[5];
+   mod_time.hour = buf[4];
+   mod_time.day = buf[3];
+   mod_time.month = buf[2];
+   mod_time.year = png_get_uint_16(buf);
+
+   png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp key;
+   png_charp text;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+   int ret;
+
+   png_debug(1, "in png_handle_tEXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for tEXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tEXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+
+   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (png_ptr->chunkdata == NULL)
+   {
+     png_warning(png_ptr, "No memory to process text chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   key = png_ptr->chunkdata;
+
+   key[slength] = 0x00;
+
+   for (text = key; *text; text++)
+      /* Empty loop to find end of key */ ;
+
+   if (text != key + slength)
+      text++;
+
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+      (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr, "Not enough memory to process text chunk.");
+     png_free(png_ptr, png_ptr->chunkdata);
+     png_ptr->chunkdata = NULL;
+     return;
+   }
+   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
+   text_ptr->text = text;
+   text_ptr->text_length = png_strlen(text);
+
+   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+   png_free(png_ptr, text_ptr);
+   if (ret)
+     png_warning(png_ptr, "Insufficient memory to process text chunk.");
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp text;
+   int comp_type;
+   int ret;
+   png_size_t slength, prefix_len, data_len;
+
+   png_debug(1, "in png_handle_zTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for zTXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before zTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (png_ptr->chunkdata == NULL)
+   {
+     png_warning(png_ptr, "Out of memory processing zTXt chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00;
+
+   for (text = png_ptr->chunkdata; *text; text++)
+      /* Empty loop */ ;
+
+   /* zTXt must have some text after the chunkdataword */
+   if (text >= png_ptr->chunkdata + slength - 2)
+   {
+      png_warning(png_ptr, "Truncated zTXt chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+   else
+   {
+       comp_type = *(++text);
+       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+       {
+          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+          comp_type = PNG_TEXT_COMPRESSION_zTXt;
+       }
+       text++;        /* Skip the compression_method byte */
+   }
+   prefix_len = text - png_ptr->chunkdata;
+
+   png_decompress_chunk(png_ptr, comp_type,
+     (png_size_t)length, prefix_len, &data_len);
+
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+      (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
+     png_free(png_ptr, png_ptr->chunkdata);
+     png_ptr->chunkdata = NULL;
+     return;
+   }
+   text_ptr->compression = comp_type;
+   text_ptr->key = png_ptr->chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+   text_ptr->lang = NULL;
+   text_ptr->lang_key = NULL;
+   text_ptr->itxt_length = 0;
+#endif
+   text_ptr->text = png_ptr->chunkdata + prefix_len;
+   text_ptr->text_length = data_len;
+
+   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+   if (ret)
+     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp key, lang, text, lang_key;
+   int comp_flag;
+   int comp_type = 0;
+   int ret;
+   png_size_t slength, prefix_len, data_len;
+
+   png_debug(1, "in png_handle_iTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for iTXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+   if (png_ptr->chunkdata == NULL)
+   {
+     png_warning(png_ptr, "No memory to process iTXt chunk.");
+     return;
+   }
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   png_ptr->chunkdata[slength] = 0x00;
+
+   for (lang = png_ptr->chunkdata; *lang; lang++)
+      /* Empty loop */ ;
+   lang++;        /* Skip NUL separator */
+
+   /* iTXt must have a language tag (possibly empty), two compression bytes,
+    * translated keyword (possibly empty), and possibly some text after the
+    * keyword
+    */
+
+   if (lang >= png_ptr->chunkdata + slength - 3)
+   {
+      png_warning(png_ptr, "Truncated iTXt chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+   else
+   {
+       comp_flag = *lang++;
+       comp_type = *lang++;
+   }
+
+   for (lang_key = lang; *lang_key; lang_key++)
+      /* Empty loop */ ;
+   lang_key++;        /* Skip NUL separator */
+
+   if (lang_key >= png_ptr->chunkdata + slength)
+   {
+      png_warning(png_ptr, "Truncated iTXt chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   for (text = lang_key; *text; text++)
+      /* Empty loop */ ;
+   text++;        /* Skip NUL separator */
+   if (text >= png_ptr->chunkdata + slength)
+   {
+      png_warning(png_ptr, "Malformed iTXt chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      return;
+   }
+
+   prefix_len = text - png_ptr->chunkdata;
+
+   key=png_ptr->chunkdata;
+   if (comp_flag)
+       png_decompress_chunk(png_ptr, comp_type,
+         (size_t)length, prefix_len, &data_len);
+   else
+       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
+   text_ptr = (png_textp)png_malloc_warn(png_ptr,
+      (png_uint_32)png_sizeof(png_text));
+   if (text_ptr == NULL)
+   {
+     png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
+     png_free(png_ptr, png_ptr->chunkdata);
+     png_ptr->chunkdata = NULL;
+     return;
+   }
+   text_ptr->compression = (int)comp_flag + 1;
+   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
+   text_ptr->lang = png_ptr->chunkdata + (lang - key);
+   text_ptr->itxt_length = data_len;
+   text_ptr->text_length = 0;
+   text_ptr->key = png_ptr->chunkdata;
+   text_ptr->text = png_ptr->chunkdata + prefix_len;
+
+   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, png_ptr->chunkdata);
+   png_ptr->chunkdata = NULL;
+   if (ret)
+     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+}
+#endif
+
+/* This function is called when we haven't found a handler for a
+   chunk.  If there isn't a problem with the chunk itself (ie bad
+   chunk name, CRC, or a critical chunk), the chunk is silently ignored
+   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+   case it will be saved away to be written out later. */
+void /* PRIVATE */
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_uint_32 skip = 0;
+
+   png_debug(1, "in png_handle_unknown");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_CONST PNG_IDAT;
+#endif
+      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
+         png_ptr->mode |= PNG_AFTER_IDAT;
+   }
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+           PNG_HANDLE_CHUNK_ALWAYS
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+           && png_ptr->read_user_chunk_fn == NULL
+#endif
+        )
+#endif
+          png_chunk_error(png_ptr, "unknown critical chunk");
+   }
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+       || (png_ptr->read_user_chunk_fn != NULL)
+#endif
+        )
+   {
+#ifdef PNG_MAX_MALLOC_64K
+       if (length > (png_uint_32)65535L)
+       {
+           png_warning(png_ptr, "unknown chunk too large to fit in memory");
+           skip = length - (png_uint_32)65535L;
+           length = (png_uint_32)65535L;
+       }
+#endif
+       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
+                  (png_charp)png_ptr->chunk_name,
+                  png_sizeof(png_ptr->unknown_chunk.name));
+       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
+           = '\0';
+       png_ptr->unknown_chunk.size = (png_size_t)length;
+       if (length == 0)
+         png_ptr->unknown_chunk.data = NULL;
+       else
+       {
+         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
+         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+       }
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+       if (png_ptr->read_user_chunk_fn != NULL)
+       {
+          /* Callback to user unknown chunk handler */
+          int ret;
+          ret = (*(png_ptr->read_user_chunk_fn))
+            (png_ptr, &png_ptr->unknown_chunk);
+          if (ret < 0)
+             png_chunk_error(png_ptr, "error in user chunk");
+          if (ret == 0)
+          {
+             if (!(png_ptr->chunk_name[0] & 0x20))
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+                     PNG_HANDLE_CHUNK_ALWAYS)
+#endif
+                   png_chunk_error(png_ptr, "unknown critical chunk");
+             png_set_unknown_chunks(png_ptr, info_ptr,
+               &png_ptr->unknown_chunk, 1);
+          }
+       }
+       else
+#endif
+       png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+       png_free(png_ptr, png_ptr->unknown_chunk.data);
+       png_ptr->unknown_chunk.data = NULL;
+   }
+   else
+#endif
+      skip = length;
+
+   png_crc_finish(png_ptr, skip);
+
+#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
+   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+#endif
+}
+
+/* This function is called to verify that a chunk name is valid.
+   This function can't have the "critical chunk check" incorporated
+   into it, since in the future we will need to be able to call user
+   functions to handle unknown critical chunks after we check that
+   the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+   png_debug(1, "in png_check_chunk_name");
+   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+   {
+      png_chunk_error(png_ptr, "invalid chunk type");
+   }
+}
+
+/* Combines the row recently read in with the existing pixels in the
+   row.  This routine takes care of alpha and transparency if requested.
+   This routine also handles the two methods of progressive display
+   of interlaced images, depending on the mask value.
+   The mask value describes which pixels are to be combined with
+   the row.  The pattern always repeats every 8 pixels, so just 8
+   bits are needed.  A one indicates the pixel is to be combined,
+   a zero indicates the pixel is to be skipped.  This is in addition
+   to any alpha or transparency value associated with the pixel.  If
+   you want all pixels to be combined, pass 0xff (255) in mask.  */
+
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int mask)
+{
+   png_debug(1, "in png_combine_row");
+   if (mask == 0xff)
+   {
+      png_memcpy(row, png_ptr->row_buf + 1,
+         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
+   }
+   else
+   {
+      switch (png_ptr->row_info.pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_inc, s_start, s_end;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+            else
+#endif
+            {
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  int value;
+
+                  value = (*sp >> shift) & 0x01;
+                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_start, s_end, s_inc;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            int value;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+            else
+#endif
+            {
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0x03;
+                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            int s_start, s_end, s_inc;
+            int m = 0x80;
+            int shift;
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            int value;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+            else
+#endif
+            {
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            shift = s_start;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0xf;
+                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         default:
+         {
+            png_bytep sp = png_ptr->row_buf + 1;
+            png_bytep dp = row;
+            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+            png_uint_32 i;
+            png_uint_32 row_width = png_ptr->width;
+            png_byte m = 0x80;
+
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (m & mask)
+               {
+                  png_memcpy(dp, sp, pixel_bytes);
+               }
+
+               sp += pixel_bytes;
+               dp += pixel_bytes;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+      }
+   }
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* OLD pre-1.0.9 interface:
+void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+   png_uint_32 transformations)
+ */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+   png_row_infop row_info = &(png_ptr->row_info);
+   png_bytep row = png_ptr->row_buf + 1;
+   int pass = png_ptr->pass;
+   png_uint_32 transformations = png_ptr->transformations;
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   /* Offset to next interlace block */
+   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   png_debug(1, "in png_do_read_interlace");
+   if (row != NULL && row_info != NULL)
+   {
+      png_uint_32 final_width;
+
+      final_width = row_info->width * png_pass_inc[pass];
+
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_byte v;
+            png_uint_32 i;
+            int j;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (transformations & PNG_PACKSWAP)
+            {
+                sshift = (int)((row_info->width + 7) & 0x07);
+                dshift = (int)((final_width + 7) & 0x07);
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+            else
+#endif
+            {
+                sshift = 7 - (int)((row_info->width + 7) & 0x07);
+                dshift = 7 - (int)((final_width + 7) & 0x07);
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               v = (png_byte)((*sp >> sshift) & 0x01);
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+               dshift = (int)(((final_width + 3) & 0x03) << 1);
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+            else
+#endif
+            {
+               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v;
+               int j;
+
+               v = (png_byte)((*sp >> sshift) & 0x03);
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_uint_32 i;
+            int jstop = png_pass_inc[pass];
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+               dshift = (int)(((final_width + 1) & 0x01) << 2);
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            else
+#endif
+            {
+               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
+               int j;
+
+               for (j = 0; j < jstop; j++)
+               {
+                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         default:
+         {
+            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+            png_bytep sp = row + (png_size_t)(row_info->width - 1)
+                * pixel_bytes;
+            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+            int jstop = png_pass_inc[pass];
+            png_uint_32 i;
+
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte v[8];
+               int j;
+
+               png_memcpy(v, sp, pixel_bytes);
+               for (j = 0; j < jstop; j++)
+               {
+                  png_memcpy(dp, v, pixel_bytes);
+                  dp -= pixel_bytes;
+               }
+               sp -= pixel_bytes;
+            }
+            break;
+         }
+      }
+      row_info->width = final_width;
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
+   }
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
+   transformations = transformations; /* Silence compiler warning */
+#endif
+}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+   png_bytep prev_row, int filter)
+{
+   png_debug(1, "in png_read_filter_row");
+   png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
+   switch (filter)
+   {
+      case PNG_FILTER_VALUE_NONE:
+         break;
+      case PNG_FILTER_VALUE_SUB:
+      {
+         png_uint_32 i;
+         png_uint_32 istop = row_info->rowbytes;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_bytep rp = row + bpp;
+         png_bytep lp = row;
+
+         for (i = bpp; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_UP:
+      {
+         png_uint_32 i;
+         png_uint_32 istop = row_info->rowbytes;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+
+         for (i = 0; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_AVG:
+      {
+         png_uint_32 i;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+         png_bytep lp = row;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_uint_32 istop = row_info->rowbytes - bpp;
+
+         for (i = 0; i < bpp; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               ((int)(*pp++) / 2 )) & 0xff);
+            rp++;
+         }
+
+         for (i = 0; i < istop; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               (int)(*pp++ + *lp++) / 2 ) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_PAETH:
+      {
+         png_uint_32 i;
+         png_bytep rp = row;
+         png_bytep pp = prev_row;
+         png_bytep lp = row;
+         png_bytep cp = prev_row;
+         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_uint_32 istop=row_info->rowbytes - bpp;
+
+         for (i = 0; i < bpp; i++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+            rp++;
+         }
+
+         for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
+         {
+            int a, b, c, pa, pb, pc, p;
+
+            a = *lp++;
+            b = *pp++;
+            c = *cp++;
+
+            p = b - c;
+            pc = a - c;
+
+#ifdef PNG_USE_ABS
+            pa = abs(p);
+            pb = abs(pc);
+            pc = abs(p + pc);
+#else
+            pa = p < 0 ? -p : p;
+            pb = pc < 0 ? -pc : pc;
+            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+            /*
+               if (pa <= pb && pa <= pc)
+                  p = a;
+               else if (pb <= pc)
+                  p = b;
+               else
+                  p = c;
+             */
+
+            p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
+
+            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+            rp++;
+         }
+         break;
+      }
+      default:
+         png_warning(png_ptr, "Ignoring bad adaptive filter type");
+         *row = 0;
+         break;
+   }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void /* PRIVATE */
+png_read_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+   png_debug(1, "in png_read_finish_row");
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0,
+         png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if (png_ptr->pass >= 7)
+            break;
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         if (!(png_ptr->transformations & PNG_INTERLACE))
+         {
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (!(png_ptr->num_rows))
+               continue;
+         }
+         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
+            break;
+      } while (png_ptr->iwidth == 0);
+
+      if (png_ptr->pass < 7)
+         return;
+   }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+   {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_CONST PNG_IDAT;
+#endif
+      char extra;
+      int ret;
+
+      png_ptr->zstream.next_out = (Byte *)&extra;
+      png_ptr->zstream.avail_out = (uInt)1;
+      for (;;)
+      {
+         if (!(png_ptr->zstream.avail_in))
+         {
+            while (!png_ptr->idat_size)
+            {
+               png_byte chunk_length[4];
+
+               png_crc_finish(png_ptr, 0);
+
+               png_read_data(png_ptr, chunk_length, 4);
+               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
+               png_reset_crc(png_ptr);
+               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+                  png_error(png_ptr, "Not enough image data");
+
+            }
+            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_in = png_ptr->zbuf;
+            if (png_ptr->zbuf_size > png_ptr->idat_size)
+               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+            png_ptr->idat_size -= png_ptr->zstream.avail_in;
+         }
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret == Z_STREAM_END)
+         {
+            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+               png_ptr->idat_size)
+               png_warning(png_ptr, "Extra compressed data.");
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+         if (ret != Z_OK)
+            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                      "Decompression Error");
+
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_warning(png_ptr, "Extra compressed data.");
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+
+      }
+      png_ptr->zstream.avail_out = 0;
+   }
+
+   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+      png_warning(png_ptr, "Extra compression data.");
+
+   inflateReset(&png_ptr->zstream);
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+void /* PRIVATE */
+png_read_start_row(png_structp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   int max_pixel_depth;
+   png_size_t row_bytes;
+
+   png_debug(1, "in png_read_start_row");
+   png_ptr->zstream.avail_in = 0;
+   png_init_read_transformations(png_ptr);
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+      else
+         png_ptr->num_rows = png_ptr->height;
+
+      png_ptr->iwidth = (png_ptr->width +
+         png_pass_inc[png_ptr->pass] - 1 -
+         png_pass_start[png_ptr->pass]) /
+         png_pass_inc[png_ptr->pass];
+   }
+   else
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->iwidth = png_ptr->width;
+   }
+   max_pixel_depth = png_ptr->pixel_depth;
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+      max_pixel_depth = 8;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 24;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth < 8)
+            max_pixel_depth = 8;
+         if (png_ptr->num_trans)
+            max_pixel_depth *= 2;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (png_ptr->num_trans)
+         {
+            max_pixel_depth *= 4;
+            max_pixel_depth /= 3;
+         }
+      }
+   }
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   if (png_ptr->transformations & (PNG_FILLER))
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         max_pixel_depth = 32;
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth <= 8)
+            max_pixel_depth = 16;
+         else
+            max_pixel_depth = 32;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (max_pixel_depth <= 32)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 64;
+      }
+   }
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+   {
+      if (
+#ifdef PNG_READ_EXPAND_SUPPORTED
+        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#ifdef PNG_READ_FILLER_SUPPORTED
+        (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (max_pixel_depth <= 16)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 64;
+      }
+      else
+      {
+         if (max_pixel_depth <= 8)
+           {
+             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+               max_pixel_depth = 32;
+             else
+               max_pixel_depth = 24;
+           }
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            max_pixel_depth = 64;
+         else
+            max_pixel_depth = 48;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       int user_pixel_depth = png_ptr->user_transform_depth*
+         png_ptr->user_transform_channels;
+       if (user_pixel_depth > max_pixel_depth)
+         max_pixel_depth=user_pixel_depth;
+     }
+#endif
+
+   /* Align the width on the next larger 8 pixels.  Mainly used
+    * for interlacing
+    */
+   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+   /* Calculate the maximum bytes needed, adding a byte and a pixel
+    * for safety's sake
+    */
+   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
+      1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+   if (row_bytes > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+
+   if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
+   {
+     png_free(png_ptr, png_ptr->big_row_buf);
+     if (png_ptr->interlaced)
+        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+            row_bytes + 64);
+     else
+        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
+            row_bytes + 64);
+     png_ptr->old_big_row_buf_size = row_bytes + 64;
+
+     /* Use 32 bytes of padding before and after row_buf. */
+     png_ptr->row_buf = png_ptr->big_row_buf + 32;
+     png_ptr->old_big_row_buf_size = row_bytes + 64;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+   if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
+      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
+
+   if (row_bytes + 1 > png_ptr->old_prev_row_size)
+   {
+      png_free(png_ptr, png_ptr->prev_row);
+      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+        row_bytes + 1));
+      png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
+      png_ptr->old_prev_row_size = row_bytes + 1;
+   }
+
+   png_ptr->rowbytes = row_bytes;
+
+   png_debug1(3, "width = %lu,", png_ptr->width);
+   png_debug1(3, "height = %lu,", png_ptr->height);
+   png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
+   png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
+   png_debug1(3, "irowbytes = %lu",
+       PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+
+   png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+#endif /* PNG_READ_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngset.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngset.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngset.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1226 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file.  This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#ifdef PNG_bKGD_SUPPORTED
+void PNGAPI
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+   png_debug1(1, "in %s storage function", "bKGD");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
+   info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double white_x, double white_y, double red_x, double red_y,
+   double green_x, double green_y, double blue_x, double blue_y)
+{
+   png_debug1(1, "in %s storage function", "cHRM");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_white = (float)white_x;
+   info_ptr->y_white = (float)white_y;
+   info_ptr->x_red   = (float)red_x;
+   info_ptr->y_red   = (float)red_y;
+   info_ptr->x_green = (float)green_x;
+   info_ptr->y_green = (float)green_y;
+   info_ptr->x_blue  = (float)blue_x;
+   info_ptr->y_blue  = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+   info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+   info_ptr->int_x_red   = (png_fixed_point)(  red_x*100000.+0.5);
+   info_ptr->int_y_red   = (png_fixed_point)(  red_y*100000.+0.5);
+   info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+   info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+   info_ptr->int_x_blue  = (png_fixed_point)( blue_x*100000.+0.5);
+   info_ptr->int_y_blue  = (png_fixed_point)( blue_y*100000.+0.5);
+#endif
+   info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif /* PNG_FLOATING_POINT_SUPPORTED */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+   png_fixed_point blue_x, png_fixed_point blue_y)
+{
+   png_debug1(1, "in %s storage function", "cHRM fixed");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+   if (png_check_cHRM_fixed(png_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
+#endif
+   {
+      info_ptr->int_x_white = white_x;
+      info_ptr->int_y_white = white_y;
+      info_ptr->int_x_red   = red_x;
+      info_ptr->int_y_red   = red_y;
+      info_ptr->int_x_green = green_x;
+      info_ptr->int_y_green = green_y;
+      info_ptr->int_x_blue  = blue_x;
+      info_ptr->int_y_blue  = blue_y;
+#ifdef  PNG_FLOATING_POINT_SUPPORTED
+      info_ptr->x_white = (float)(white_x/100000.);
+      info_ptr->y_white = (float)(white_y/100000.);
+      info_ptr->x_red   = (float)(  red_x/100000.);
+      info_ptr->y_red   = (float)(  red_y/100000.);
+      info_ptr->x_green = (float)(green_x/100000.);
+      info_ptr->y_green = (float)(green_y/100000.);
+      info_ptr->x_blue  = (float)( blue_x/100000.);
+      info_ptr->y_blue  = (float)( blue_y/100000.);
+#endif
+      info_ptr->valid |= PNG_INFO_cHRM;
+   }
+}
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_cHRM_SUPPORTED */
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+   double png_gamma;
+
+   png_debug1(1, "in %s storage function", "gAMA");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Check for overflow */
+   if (file_gamma > 21474.83)
+   {
+      png_warning(png_ptr, "Limiting gamma to 21474.83");
+      png_gamma=21474.83;
+   }
+   else
+      png_gamma = file_gamma;
+   info_ptr->gamma = (float)png_gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = (int)(png_gamma*100000.+.5);
+#endif
+   info_ptr->valid |= PNG_INFO_gAMA;
+   if (png_gamma == 0.0)
+      png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+   int_gamma)
+{
+   png_fixed_point png_gamma;
+
+   png_debug1(1, "in %s storage function", "gAMA");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX)
+   {
+      png_warning(png_ptr, "Limiting gamma to 21474.83");
+      png_gamma=PNG_UINT_31_MAX;
+   }
+   else
+   {
+      if (int_gamma < 0)
+      {
+         png_warning(png_ptr, "Setting negative gamma to zero");
+         png_gamma = 0;
+      }
+      else
+         png_gamma = int_gamma;
+   }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   info_ptr->gamma = (float)(png_gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   info_ptr->int_gamma = png_gamma;
+#endif
+   info_ptr->valid |= PNG_INFO_gAMA;
+   if (png_gamma == 0)
+      png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+void PNGAPI
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function", "hIST");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->num_palette == 0 || info_ptr->num_palette
+       > PNG_MAX_PALETTE_LENGTH)
+   {
+      png_warning(png_ptr,
+         "Invalid palette size, hIST allocation skipped.");
+      return;
+   }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
+    * version 1.2.1
+    */
+   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
+      (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)));
+   if (png_ptr->hist == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
+      return;
+   }
+
+   for (i = 0; i < info_ptr->num_palette; i++)
+      png_ptr->hist[i] = hist[i];
+   info_ptr->hist = png_ptr->hist;
+   info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_HIST;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)
+{
+   png_debug1(1, "in %s storage function", "IHDR");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->width = width;
+   info_ptr->height = height;
+   info_ptr->bit_depth = (png_byte)bit_depth;
+   info_ptr->color_type = (png_byte)color_type;
+   info_ptr->compression_type = (png_byte)compression_type;
+   info_ptr->filter_type = (png_byte)filter_type;
+   info_ptr->interlace_type = (png_byte)interlace_type;
+
+   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+       info_ptr->compression_type, info_ptr->filter_type);
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+   /* Check for potential overflow */
+   if (width > (PNG_UINT_32_MAX
+                 >> 3)      /* 8-byte RGBA pixels */
+                 - 64       /* bigrowbuf hack */
+                 - 1        /* filter byte */
+                 - 7*8      /* rounding of width to multiple of 8 pixels */
+                 - 8)       /* extra max_pixel_depth pad */
+      info_ptr->rowbytes = (png_size_t)0;
+   else
+      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+void PNGAPI
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function", "oFFs");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_offset = offset_x;
+   info_ptr->y_offset = offset_y;
+   info_ptr->offset_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+void PNGAPI
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params)
+{
+   png_uint_32 length;
+   int i;
+
+   png_debug1(1, "in %s storage function", "pCAL");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   length = png_strlen(purpose) + 1;
+   png_debug1(3, "allocating purpose for info (%lu bytes)",
+     (unsigned long)length);
+   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->pcal_purpose == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
+      return;
+   }
+   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+   png_debug(3, "storing X0, X1, type, and nparams in info");
+   info_ptr->pcal_X0 = X0;
+   info_ptr->pcal_X1 = X1;
+   info_ptr->pcal_type = (png_byte)type;
+   info_ptr->pcal_nparams = (png_byte)nparams;
+
+   length = png_strlen(units) + 1;
+   png_debug1(3, "allocating units for info (%lu bytes)",
+     (unsigned long)length);
+   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->pcal_units == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL units.");
+      return;
+   }
+   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
+      (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
+   if (info_ptr->pcal_params == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for pCAL params.");
+      return;
+   }
+
+   png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
+
+   for (i = 0; i < nparams; i++)
+   {
+      length = png_strlen(params[i]) + 1;
+      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
+        (unsigned long)length);
+      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+      if (info_ptr->pcal_params[i] == NULL)
+      {
+         png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
+         return;
+      }
+      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+   }
+
+   info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+             int unit, double width, double height)
+{
+   png_debug1(1, "in %s storage function", "sCAL");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+   info_ptr->scal_pixel_width = width;
+   info_ptr->scal_pixel_height = height;
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+             int unit, png_charp swidth, png_charp sheight)
+{
+   png_uint_32 length;
+
+   png_debug1(1, "in %s storage function", "sCAL");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->scal_unit = (png_byte)unit;
+
+   length = png_strlen(swidth) + 1;
+   png_debug1(3, "allocating unit for info (%u bytes)",
+      (unsigned int)length);
+   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->scal_s_width == NULL)
+   {
+      png_warning(png_ptr,
+         "Memory allocation failed while processing sCAL.");
+      return;
+   }
+   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+   length = png_strlen(sheight) + 1;
+   png_debug1(3, "allocating unit for info (%u bytes)",
+      (unsigned int)length);
+   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
+   if (info_ptr->scal_s_height == NULL)
+   {
+      png_free (png_ptr, info_ptr->scal_s_width);
+      info_ptr->scal_s_width = NULL;
+      png_warning(png_ptr,
+         "Memory allocation failed while processing sCAL.");
+      return;
+   }
+   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+   info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+void PNGAPI
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function", "pHYs");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_pixels_per_unit = res_x;
+   info_ptr->y_pixels_per_unit = res_y;
+   info_ptr->phys_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+   png_colorp palette, int num_palette)
+{
+
+   png_debug1(1, "in %s storage function", "PLTE");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         png_error(png_ptr, "Invalid palette length");
+      else
+      {
+         png_warning(png_ptr, "Invalid palette length");
+         return;
+      }
+   }
+
+   /* It may not actually be necessary to set png_ptr->palette here;
+    * we do it for backward compatibility with the way the png_handle_tRNS
+    * function used to do the allocation.
+    */
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+
+   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+    * of num_palette entries, in case of an invalid PNG file that has
+    * too-large sample values.
+    */
+   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
+      PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
+   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
+   info_ptr->palette = png_ptr->palette;
+   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+   png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
+   info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+void PNGAPI
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+   png_color_8p sig_bit)
+{
+   png_debug1(1, "in %s storage function", "sBIT");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
+   info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void PNGAPI
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+   png_debug1(1, "in %s storage function", "sRGB");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->srgb_intent = (png_byte)intent;
+   info_ptr->valid |= PNG_INFO_sRGB;
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+   int intent)
+{
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float file_gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_fixed_point int_file_gamma;
+#endif
+#endif
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+      int_green_y, int_blue_x, int_blue_y;
+#endif
+   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_set_sRGB(png_ptr, info_ptr, intent);
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   file_gamma = (float).45455;
+   png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   int_file_gamma = 45455L;
+   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+   int_white_x = 31270L;
+   int_white_y = 32900L;
+   int_red_x   = 64000L;
+   int_red_y   = 33000L;
+   int_green_x = 30000L;
+   int_green_y = 60000L;
+   int_blue_x  = 15000L;
+   int_blue_y  =  6000L;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   white_x = (float).3127;
+   white_y = (float).3290;
+   red_x   = (float).64;
+   red_y   = (float).33;
+   green_x = (float).30;
+   green_y = (float).60;
+   blue_x  = (float).15;
+   blue_y  = (float).06;
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   png_set_cHRM_fixed(png_ptr, info_ptr,
+       int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+       int_green_y, int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_cHRM(png_ptr, info_ptr,
+       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif /* cHRM */
+}
+#endif /* sRGB */
+
+
+#ifdef PNG_iCCP_SUPPORTED
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charp name, int compression_type,
+             png_charp profile, png_uint_32 proflen)
+{
+   png_charp new_iccp_name;
+   png_charp new_iccp_profile;
+   png_uint_32 length;
+
+   png_debug1(1, "in %s storage function", "iCCP");
+
+   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+      return;
+
+   length = png_strlen(name)+1;
+   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
+   if (new_iccp_name == NULL)
+   {
+        png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
+      return;
+   }
+   png_memcpy(new_iccp_name, name, length);
+   new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
+   if (new_iccp_profile == NULL)
+   {
+      png_free (png_ptr, new_iccp_name);
+      png_warning(png_ptr,
+          "Insufficient memory to process iCCP profile.");
+      return;
+   }
+   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+   info_ptr->iccp_proflen = proflen;
+   info_ptr->iccp_name = new_iccp_name;
+   info_ptr->iccp_profile = new_iccp_profile;
+   /* Compression is always zero but is here so the API and info structure
+    * does not have to change if we introduce multiple compression types
+    */
+   info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_ICCP;
+#endif
+   info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+void PNGAPI
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+             int num_text)
+{
+   int ret;
+   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+   if (ret)
+      png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+               int num_text)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
+      png_ptr->chunk_name[0] == '\0') ?
+      "text" : (png_const_charp)png_ptr->chunk_name));
+
+   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+      return(0);
+
+   /* Make sure we have enough space in the "text" array in info_struct
+    * to hold all of the incoming text_ptr objects.
+    */
+   if (info_ptr->num_text + num_text > info_ptr->max_text)
+   {
+      if (info_ptr->text != NULL)
+      {
+         png_textp old_text;
+         int old_max;
+
+         old_max = info_ptr->max_text;
+         info_ptr->max_text = info_ptr->num_text + num_text + 8;
+         old_text = info_ptr->text;
+         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+            (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
+         if (info_ptr->text == NULL)
+         {
+            png_free(png_ptr, old_text);
+            return(1);
+         }
+         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+            png_sizeof(png_text)));
+         png_free(png_ptr, old_text);
+      }
+      else
+      {
+         info_ptr->max_text = num_text + 8;
+         info_ptr->num_text = 0;
+         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+            (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
+         if (info_ptr->text == NULL)
+            return(1);
+#ifdef PNG_FREE_ME_SUPPORTED
+         info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
+      }
+      png_debug1(3, "allocated %d entries for info_ptr->text",
+         info_ptr->max_text);
+   }
+   for (i = 0; i < num_text; i++)
+   {
+      png_size_t text_length, key_len;
+      png_size_t lang_len, lang_key_len;
+      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+      if (text_ptr[i].key == NULL)
+          continue;
+
+      key_len = png_strlen(text_ptr[i].key);
+
+      if (text_ptr[i].compression <= 0)
+      {
+         lang_len = 0;
+         lang_key_len = 0;
+      }
+
+      else
+#ifdef PNG_iTXt_SUPPORTED
+      {
+         /* Set iTXt data */
+
+         if (text_ptr[i].lang != NULL)
+            lang_len = png_strlen(text_ptr[i].lang);
+         else
+            lang_len = 0;
+         if (text_ptr[i].lang_key != NULL)
+            lang_key_len = png_strlen(text_ptr[i].lang_key);
+         else
+            lang_key_len = 0;
+      }
+#else /* PNG_iTXt_SUPPORTED */
+      {
+         png_warning(png_ptr, "iTXt chunk not supported.");
+         continue;
+      }
+#endif
+
+      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+      {
+         text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+         if (text_ptr[i].compression > 0)
+            textp->compression = PNG_ITXT_COMPRESSION_NONE;
+         else
+#endif
+            textp->compression = PNG_TEXT_COMPRESSION_NONE;
+      }
+
+      else
+      {
+         text_length = png_strlen(text_ptr[i].text);
+         textp->compression = text_ptr[i].compression;
+      }
+
+      textp->key = (png_charp)png_malloc_warn(png_ptr,
+         (png_uint_32)
+         (key_len + text_length + lang_len + lang_key_len + 4));
+      if (textp->key == NULL)
+         return(1);
+      png_debug2(2, "Allocated %lu bytes at %x in png_set_text",
+                 (png_uint_32)
+                 (key_len + lang_len + lang_key_len + text_length + 4),
+                 (int)textp->key);
+
+      png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
+      *(textp->key + key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+      if (text_ptr[i].compression > 0)
+      {
+         textp->lang = textp->key + key_len + 1;
+         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+         *(textp->lang + lang_len) = '\0';
+         textp->lang_key = textp->lang + lang_len + 1;
+         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+         *(textp->lang_key + lang_key_len) = '\0';
+         textp->text = textp->lang_key + lang_key_len + 1;
+      }
+      else
+#endif
+      {
+#ifdef PNG_iTXt_SUPPORTED
+         textp->lang=NULL;
+         textp->lang_key=NULL;
+#endif
+         textp->text = textp->key + key_len + 1;
+      }
+      if (text_length)
+         png_memcpy(textp->text, text_ptr[i].text,
+            (png_size_t)(text_length));
+      *(textp->text + text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+      if (textp->compression > 0)
+      {
+         textp->text_length = 0;
+         textp->itxt_length = text_length;
+      }
+      else
+#endif
+
+      {
+         textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+         textp->itxt_length = 0;
+#endif
+      }
+      info_ptr->num_text++;
+      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
+   }
+   return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+void PNGAPI
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+   png_debug1(1, "in %s storage function", "tIME");
+
+   if (png_ptr == NULL || info_ptr == NULL ||
+       (png_ptr->mode & PNG_WROTE_tIME))
+      return;
+
+   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
+   info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+void PNGAPI
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+   png_debug1(1, "in %s storage function", "tRNS");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (trans != NULL)
+   {
+       /* It may not actually be necessary to set png_ptr->trans here;
+        * we do it for backward compatibility with the way the png_handle_tRNS
+        * function used to do the allocation.
+        */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+
+       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+       png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
+           (png_uint_32)PNG_MAX_PALETTE_LENGTH);
+       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+          png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
+   }
+
+   if (trans_values != NULL)
+   {
+      int sample_max = (1 << info_ptr->bit_depth);
+      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+          (int)trans_values->gray > sample_max) ||
+          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+          ((int)trans_values->red > sample_max ||
+          (int)trans_values->green > sample_max ||
+          (int)trans_values->blue > sample_max)))
+         png_warning(png_ptr,
+            "tRNS chunk has out-of-range samples for bit_depth");
+      png_memcpy(&(info_ptr->trans_values), trans_values,
+         png_sizeof(png_color_16));
+      if (num_trans == 0)
+         num_trans = 1;
+   }
+
+   info_ptr->num_trans = (png_uint_16)num_trans;
+   if (num_trans != 0)
+   {
+      info_ptr->valid |= PNG_INFO_tRNS;
+#ifdef PNG_FREE_ME_SUPPORTED
+      info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+      png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
+   }
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+             png_infop info_ptr, png_sPLT_tp entries, int nentries)
+/*
+ *  entries        - array of png_sPLT_t structures
+ *                   to be added to the list of palettes
+ *                   in the info structure.
+ *  nentries       - number of palette structures to be
+ *                   added.
+ */
+{
+   png_sPLT_tp np;
+   int i;
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
+       (info_ptr->splt_palettes_num + nentries) *
+        (png_uint_32)png_sizeof(png_sPLT_t));
+   if (np == NULL)
+   {
+      png_warning(png_ptr, "No memory for sPLT palettes.");
+      return;
+   }
+
+   png_memcpy(np, info_ptr->splt_palettes,
+       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
+   png_free(png_ptr, info_ptr->splt_palettes);
+   info_ptr->splt_palettes=NULL;
+
+   for (i = 0; i < nentries; i++)
+   {
+      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+      png_sPLT_tp from = entries + i;
+      png_uint_32 length;
+
+      length = png_strlen(from->name) + 1;
+      to->name = (png_charp)png_malloc_warn(png_ptr, length);
+      if (to->name == NULL)
+      {
+         png_warning(png_ptr,
+           "Out of memory while processing sPLT chunk");
+         continue;
+      }
+      png_memcpy(to->name, from->name, length);
+      to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+          (png_uint_32)(from->nentries * png_sizeof(png_sPLT_entry)));
+      if (to->entries == NULL)
+      {
+         png_warning(png_ptr,
+           "Out of memory while processing sPLT chunk");
+         png_free(png_ptr, to->name);
+         to->name = NULL;
+         continue;
+      }
+      png_memcpy(to->entries, from->entries,
+          from->nentries * png_sizeof(png_sPLT_entry));
+      to->nentries = from->nentries;
+      to->depth = from->depth;
+   }
+
+   info_ptr->splt_palettes = np;
+   info_ptr->splt_palettes_num += nentries;
+   info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+   png_unknown_chunkp np;
+   int i;
+
+   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+      return;
+
+   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
+       (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) *
+       png_sizeof(png_unknown_chunk)));
+   if (np == NULL)
+   {
+      png_warning(png_ptr,
+          "Out of memory while processing unknown chunk.");
+      return;
+   }
+
+   png_memcpy(np, info_ptr->unknown_chunks,
+       info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
+   png_free(png_ptr, info_ptr->unknown_chunks);
+   info_ptr->unknown_chunks = NULL;
+
+   for (i = 0; i < num_unknowns; i++)
+   {
+      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+      png_unknown_chunkp from = unknowns + i;
+
+      png_memcpy((png_charp)to->name, (png_charp)from->name,
+          png_sizeof(from->name));
+      to->name[png_sizeof(to->name)-1] = '\0';
+      to->size = from->size;
+      /* Note our location in the read or write sequence */
+      to->location = (png_byte)(png_ptr->mode & 0xff);
+
+      if (from->size == 0)
+         to->data=NULL;
+      else
+      {
+         to->data = (png_bytep)png_malloc_warn(png_ptr,
+           (png_uint_32)from->size);
+         if (to->data == NULL)
+         {
+            png_warning(png_ptr,
+             "Out of memory while processing unknown chunk.");
+            to->size = 0;
+         }
+         else
+            png_memcpy(to->data, from->data, from->size);
+      }
+   }
+
+   info_ptr->unknown_chunks = np;
+   info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+   info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+   int chunk, int location)
+{
+   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+       (int)info_ptr->unknown_chunks_num)
+      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+   /* This function is deprecated in favor of png_permit_mng_features()
+      and will be removed from libpng-1.3.0 */
+
+   png_debug(1, "in png_permit_empty_plte, DEPRECATED.");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->mng_features_permitted = (png_byte)
+     ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) |
+     ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+   png_debug(1, "in png_permit_mng_features");
+
+   if (png_ptr == NULL)
+      return (png_uint_32)0;
+   png_ptr->mng_features_permitted =
+     (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+   return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+   chunk_list, int num_chunks)
+{
+   png_bytep new_list, p;
+   int i, old_num_chunks;
+   if (png_ptr == NULL)
+      return;
+   if (num_chunks == 0)
+   {
+      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
+         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+      else
+         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
+         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      else
+         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+      return;
+   }
+   if (chunk_list == NULL)
+      return;
+   old_num_chunks = png_ptr->num_chunk_list;
+   new_list=(png_bytep)png_malloc(png_ptr,
+      (png_uint_32)
+       (5*(num_chunks + old_num_chunks)));
+   if (png_ptr->chunk_list != NULL)
+   {
+      png_memcpy(new_list, png_ptr->chunk_list,
+          (png_size_t)(5*old_num_chunks));
+      png_free(png_ptr, png_ptr->chunk_list);
+      png_ptr->chunk_list=NULL;
+   }
+   png_memcpy(new_list + 5*old_num_chunks, chunk_list,
+       (png_size_t)(5*num_chunks));
+   for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
+      *p=(png_byte)keep;
+   png_ptr->num_chunk_list = old_num_chunks + num_chunks;
+   png_ptr->chunk_list = new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+   png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+   png_user_chunk_ptr read_user_chunk_fn)
+{
+   png_debug(1, "in png_set_read_user_chunk_fn");
+
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+   png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+   png_debug1(1, "in %s storage function", "rows");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+   info_ptr->row_pointers = row_pointers;
+   if (row_pointers)
+      info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr,
+    png_uint_32 size)
+{
+    if (png_ptr == NULL)
+       return;
+    png_free(png_ptr, png_ptr->zbuf);
+    png_ptr->zbuf_size = (png_size_t)size;
+    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+    png_ptr->zstream.next_out = png_ptr->zbuf;
+    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
+{
+   if (png_ptr && info_ptr)
+      info_ptr->valid &= ~mask;
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* Function was added to libpng 1.2.0 and should always exist by default */
+void PNGAPI
+png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+    if (png_ptr != NULL)
+    png_ptr->asm_flags = 0;
+    asm_flags = asm_flags; /* Quiet the compiler */
+}
+
+/* This function was added to libpng 1.2.0 */
+void PNGAPI
+png_set_mmx_thresholds (png_structp png_ptr,
+                        png_byte mmx_bitdepth_threshold,
+                        png_uint_32 mmx_rowbytes_threshold)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+    if (png_ptr == NULL)
+       return;
+    /* Quiet the compiler */
+    mmx_bitdepth_threshold = mmx_bitdepth_threshold;
+    mmx_rowbytes_threshold = mmx_rowbytes_threshold;
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* This function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
+    png_uint_32 user_height_max)
+{
+   /* Images with dimensions larger than these limits will be
+    * rejected by png_set_IHDR().  To accept any PNG datastream
+    * regardless of dimensions, set both limits to 0x7ffffffL.
+    */
+   if (png_ptr == NULL)
+      return;
+   png_ptr->user_width_max = user_width_max;
+   png_ptr->user_height_max = user_height_max;
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_set_benign_errors(png_structp png_ptr, int allowed)
+{
+   png_debug(1, "in png_set_benign_errors");
+
+   if (allowed)
+      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+   else
+      png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
+}
+#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
+#endif /* ?PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1705 @@
+
+/* pngtest.c - a simple test program to test libpng
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This program reads in a PNG image, writes it out again, and then
+ * compares the two files.  If the files are identical, this shows that
+ * the basic chunk handling, filtering, and (de)compression code is working
+ * properly.  It does not currently test all of the transforms, although
+ * it probably should.
+ *
+ * The program will report "FAIL" in certain legitimate cases:
+ * 1) when the compression level or filter selection method is changed.
+ * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
+ * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
+ *    exist in the input file.
+ * 4) others not listed here...
+ * In these cases, it is best to check with another tool such as "pngcheck"
+ * to see what the differences between the two files are.
+ *
+ * If a filename is given on the command-line, then this file is used
+ * for the input, rather than the default "pngtest.png".  This allows
+ * testing a wide variety of files easily.  You can also test a number
+ * of files at once by typing "pngtest -m file1.png file2.png ..."
+ */
+
+#define PNG_PEDANTIC_WARNINGS
+#include "png.h"
+
+#ifdef _WIN32_WCE
+#  if _WIN32_WCE < 211
+     __error__ (f|w)printf functions are not supported on old WindowsCE.;
+#  endif
+#  include <windows.h>
+#  include <stdlib.h>
+#  define READFILE(file, data, length, check) \
+     if (ReadFile(file, data, length, &check, NULL)) check = 0
+#  define WRITEFILE(file, data, length, check)) \
+     if (WriteFile(file, data, length, &check, NULL)) check = 0
+#  define FCLOSE(file) CloseHandle(file)
+#else
+#  include <stdio.h>
+#  include <stdlib.h>
+#  define READFILE(file, data, length, check) \
+     check=(png_size_t)fread(data, (png_size_t)1, length, file)
+#  define WRITEFILE(file, data, length, check) \
+     check=(png_size_t)fwrite(data, (png_size_t)1, length, file)
+#  define FCLOSE(file) fclose(file)
+#endif
+
+#ifndef PNG_STDIO_SUPPORTED
+#  ifdef _WIN32_WCE
+     typedef HANDLE                png_FILE_p;
+#  else
+     typedef FILE                * png_FILE_p;
+#  endif
+#endif
+
+/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
+#ifndef PNG_DEBUG
+#  define PNG_DEBUG 0
+#endif
+
+#if !PNG_DEBUG
+#  define SINGLE_ROWBUF_ALLOC  /* Makes buffer overruns easier to nail */
+#endif
+
+/* Turn on CPU timing
+#define PNGTEST_TIMING
+*/
+
+#ifndef PNG_FLOATING_POINT_SUPPORTED
+#undef PNGTEST_TIMING
+#endif
+
+#ifdef PNGTEST_TIMING
+static float t_start, t_stop, t_decode, t_encode, t_misc;
+#include <time.h>
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+#define PNG_tIME_STRING_LENGTH 29
+static int tIME_chunk_present = 0;
+static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
+#endif
+
+static int verbose = 0;
+
+int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
+
+#ifdef __TURBOC__
+#include <mem.h>
+#endif
+
+/* Defined so I can write to a file on gui/windowing platforms */
+/*  #define STDERR stderr  */
+#define STDERR stdout   /* For DOS */
+
+/* In case a system header (e.g., on AIX) defined jmpbuf */
+#ifdef jmpbuf
+#  undef jmpbuf
+#endif
+
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) png_ptr->jmpbuf
+#endif
+
+/* Example of using row callbacks to make a simple progress meter */
+static int status_pass = 1;
+static int status_dots_requested = 0;
+static int status_dots = 1;
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+   if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
+      return;
+   if (status_pass != pass)
+   {
+      fprintf(stdout, "\n Pass %d: ", pass);
+      status_pass = pass;
+      status_dots = 31;
+   }
+   status_dots--;
+   if (status_dots == 0)
+   {
+      fprintf(stdout, "\n         ");
+      status_dots=30;
+   }
+   fprintf(stdout, "r");
+}
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+   if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
+      return;
+   fprintf(stdout, "w");
+}
+
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+/* Example of using user transform callback (we don't transform anything,
+ * but merely examine the row filters.  We set this to 256 rather than
+ * 5 in case illegal filter values are present.)
+ */
+static png_uint_32 filters_used[256];
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+   if (png_ptr != NULL && row_info != NULL)
+      ++filters_used[*(data - 1)];
+}
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+/* Example of using user transform callback (we don't transform anything,
+ * but merely count the zero samples)
+ */
+
+static png_uint_32 zero_samples;
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+   png_bytep dp = data;
+   if (png_ptr == NULL)return;
+
+   /* Contents of row_info:
+    *  png_uint_32 width      width of row
+    *  png_uint_32 rowbytes   number of bytes in row
+    *  png_byte color_type    color type of pixels
+    *  png_byte bit_depth     bit depth of samples
+    *  png_byte channels      number of channels (1-4)
+    *  png_byte pixel_depth   bits per pixel (depth*channels)
+    */
+
+    /* Counts the number of zero samples (or zero pixels if color_type is 3 */
+
+    if (row_info->color_type == 0 || row_info->color_type == 3)
+    {
+       int pos = 0;
+       png_uint_32 n, nstop;
+       for (n = 0, nstop=row_info->width; n<nstop; n++)
+       {
+          if (row_info->bit_depth == 1)
+          {
+             if (((*dp << pos++ ) & 0x80) == 0)
+                zero_samples++;
+             if (pos == 8)
+             {
+                pos = 0;
+                dp++;
+             }
+          }
+          if (row_info->bit_depth == 2)
+          {
+             if (((*dp << (pos+=2)) & 0xc0) == 0)
+                zero_samples++;
+             if (pos == 8)
+             {
+                pos = 0;
+                dp++;
+             }
+          }
+          if (row_info->bit_depth == 4)
+          {
+             if (((*dp << (pos+=4)) & 0xf0) == 0)
+                zero_samples++;
+             if (pos == 8)
+             {
+                pos = 0;
+                dp++;
+             }
+          }
+          if (row_info->bit_depth == 8)
+             if (*dp++ == 0)
+                zero_samples++;
+          if (row_info->bit_depth == 16)
+          {
+             if ((*dp | *(dp+1)) == 0)
+                zero_samples++;
+             dp+=2;
+          }
+       }
+    }
+    else /* Other color types */
+    {
+       png_uint_32 n, nstop;
+       int channel;
+       int color_channels = row_info->channels;
+       if (row_info->color_type > 3)color_channels--;
+
+       for (n = 0, nstop=row_info->width; n<nstop; n++)
+       {
+          for (channel = 0; channel < color_channels; channel++)
+          {
+             if (row_info->bit_depth == 8)
+                if (*dp++ == 0)
+                   zero_samples++;
+             if (row_info->bit_depth == 16)
+             {
+                if ((*dp | *(dp+1)) == 0)
+                   zero_samples++;
+                dp+=2;
+             }
+          }
+          if (row_info->color_type > 3)
+          {
+             dp++;
+             if (row_info->bit_depth == 16)
+                dp++;
+          }
+       }
+    }
+}
+#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+
+static int wrote_question = 0;
+
+#ifndef PNG_STDIO_SUPPORTED
+/* START of code to validate stdio-free compilation */
+/* These copies of the default read/write functions come from pngrio.c and
+ * pngwio.c.  They allow "don't include stdio" testing of the library.
+ * This is the function that does the actual reading of data.  If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check = 0;
+   png_voidp io_ptr;
+
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+   io_ptr = png_get_io_ptr(png_ptr);
+   if (io_ptr != NULL)
+   {
+      READFILE((png_FILE_p)io_ptr, data, length, check);
+   }
+
+   if (check != length)
+   {
+      png_error(png_ptr, "Read Error!");
+   }
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   int check;
+   png_byte *n_data;
+   png_FILE_p io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)n_data == data)
+   {
+      READFILE(io_ptr, n_data, length, check);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t read, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         read = MIN(NEAR_BUF_SIZE, remaining);
+         READFILE(io_ptr, buf, 1, err);
+         png_memcpy(data, buf, read); /* Copy far buffer to near buffer */
+         if (err != read)
+            break;
+         else
+            check += err;
+         data += read;
+         remaining -= read;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+      png_error(png_ptr, "read Error");
+}
+#endif /* USE_FAR_KEYWORD */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+static void
+pngtest_flush(png_structp png_ptr)
+{
+   /* Do nothing; fflush() is said to be just a waste of energy. */
+   png_ptr = png_ptr;  /* Stifle compiler warning */
+}
+#endif
+
+/* This is the function that does the actual writing of data.  If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+
+   WRITEFILE((png_FILE_p)png_ptr->io_ptr,  data, length, check);
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
+   png_FILE_p io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)near_data == data)
+   {
+      WRITEFILE(io_ptr, near_data, length, check);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t written, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         written = MIN(NEAR_BUF_SIZE, remaining);
+         png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
+         WRITEFILE(io_ptr, buf, written, err);
+         if (err != written)
+            break;
+         else
+            check += err;
+         data += written;
+         remaining -= written;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+#endif /* USE_FAR_KEYWORD */
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void
+pngtest_warning(png_structp png_ptr, png_const_charp message)
+{
+   PNG_CONST char *name = "UNKNOWN (ERROR!)";
+   char *test;
+   test = png_get_error_ptr(png_ptr);
+   if (test == NULL)
+     fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+   else
+     fprintf(STDERR, "%s: libpng warning: %s\n", test, message);
+}
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void
+pngtest_error(png_structp png_ptr, png_const_charp message)
+{
+   pngtest_warning(png_ptr, message);
+   /* We can return because png_error calls the default handler, which is
+    * actually OK in this case.
+    */
+}
+#endif /* !PNG_STDIO_SUPPORTED */
+/* END of code to validate stdio-free compilation */
+
+/* START of code to validate memory allocation and deallocation */
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information.  zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * This piece of code can be compiled to validate max 64K allocations
+ * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
+ */
+typedef struct memory_information
+{
+   png_uint_32               size;
+   png_voidp                 pointer;
+   struct memory_information FAR *next;
+} memory_information;
+typedef memory_information FAR *memory_infop;
+
+static memory_infop pinformation = NULL;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+static int total_allocation = 0;
+static int num_allocations = 0;
+
+png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
+void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
+
+png_voidp
+png_debug_malloc(png_structp png_ptr, png_uint_32 size)
+{
+
+   /* png_malloc has already tested for NULL; png_create_struct calls
+    * png_debug_malloc directly, with png_ptr == NULL which is OK
+    */
+
+   if (size == 0)
+      return (NULL);
+
+   /* This calls the library allocator twice, once to get the requested
+      buffer and once to get a new free list entry. */
+   {
+      /* Disable malloc_fn and free_fn */
+      memory_infop pinfo;
+      png_set_mem_fn(png_ptr, NULL, NULL, NULL);
+      pinfo = (memory_infop)png_malloc(png_ptr,
+         (png_uint_32)png_sizeof(*pinfo));
+      pinfo->size = size;
+      current_allocation += size;
+      total_allocation += size;
+      num_allocations ++;
+      if (current_allocation > maximum_allocation)
+         maximum_allocation = current_allocation;
+      pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
+      /* Restore malloc_fn and free_fn */
+      png_set_mem_fn(png_ptr,
+          png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
+          (png_free_ptr)png_debug_free);
+      if (size != 0 && pinfo->pointer == NULL)
+      {
+         current_allocation -= size;
+         total_allocation -= size;
+         png_error(png_ptr,
+           "out of memory in pngtest->png_debug_malloc.");
+      }
+      pinfo->next = pinformation;
+      pinformation = pinfo;
+      /* Make sure the caller isn't assuming zeroed memory. */
+      png_memset(pinfo->pointer, 0xdd, pinfo->size);
+      if (verbose)
+         printf("png_malloc %lu bytes at %x\n", (unsigned long)size,
+            pinfo->pointer);
+      return (png_voidp)(pinfo->pointer);
+   }
+}
+
+/* Free a pointer.  It is removed from the list at the same time. */
+void
+png_debug_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL)
+      fprintf(STDERR, "NULL pointer to png_debug_free.\n");
+   if (ptr == 0)
+   {
+#if 0 /* This happens all the time. */
+      fprintf(STDERR, "WARNING: freeing NULL pointer\n");
+#endif
+      return;
+   }
+
+   /* Unlink the element from the list. */
+   {
+      memory_infop FAR *ppinfo = &pinformation;
+      for (;;)
+      {
+         memory_infop pinfo = *ppinfo;
+         if (pinfo->pointer == ptr)
+         {
+            *ppinfo = pinfo->next;
+            current_allocation -= pinfo->size;
+            if (current_allocation < 0)
+               fprintf(STDERR, "Duplicate free of memory\n");
+            /* We must free the list element too, but first kill
+               the memory that is to be freed. */
+            png_memset(ptr, 0x55, pinfo->size);
+            png_free_default(png_ptr, pinfo);
+            pinfo = NULL;
+            break;
+         }
+         if (pinfo->next == NULL)
+         {
+            fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
+            break;
+         }
+         ppinfo = &pinfo->next;
+      }
+   }
+
+   /* Finally free the data. */
+   if (verbose)
+      printf("Freeing %x\n", ptr);
+   png_free_default(png_ptr, ptr);
+   ptr = NULL;
+}
+#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
+/* END of code to test memory allocation/deallocation */
+
+
+/* Demonstration of user chunk support of the sTER and vpAg chunks */
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+
+/* (sTER is a public chunk not yet known by libpng.  vpAg is a private
+chunk used in ImageMagick to store "virtual page" size).  */
+
+static png_uint_32 user_chunk_data[4];
+
+    /* 0: sTER mode + 1
+     * 1: vpAg width
+     * 2: vpAg height
+     * 3: vpAg units
+     */
+
+static int read_user_chunk_callback(png_struct *png_ptr,
+   png_unknown_chunkp chunk)
+{
+   png_uint_32
+     *my_user_chunk_data;
+
+   /* Return one of the following:
+    *    return (-n);  chunk had an error
+    *    return (0);  did not recognize
+    *    return (n);  success
+    *
+    * The unknown chunk structure contains the chunk data:
+    * png_byte name[5];
+    * png_byte *data;
+    * png_size_t size;
+    *
+    * Note that libpng has already taken care of the CRC handling.
+    */
+
+   if (chunk->name[0] == 115 && chunk->name[1] ==  84 &&     /* s  T */
+       chunk->name[2] ==  69 && chunk->name[3] ==  82)       /* E  R */
+      {
+         /* Found sTER chunk */
+         if (chunk->size != 1)
+            return (-1); /* Error return */
+         if (chunk->data[0] != 0 && chunk->data[0] != 1)
+            return (-1);  /* Invalid mode */
+         my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
+         my_user_chunk_data[0]=chunk->data[0]+1;
+         return (1);
+      }
+
+   if (chunk->name[0] != 118 || chunk->name[1] != 112 ||    /* v  p */
+       chunk->name[2] !=  65 || chunk->name[3] != 103)      /* A  g */
+      return (0); /* Did not recognize */
+
+   /* Found ImageMagick vpAg chunk */
+
+   if (chunk->size != 9)
+      return (-1); /* Error return */
+
+   my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
+
+   my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data);
+   my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4);
+   my_user_chunk_data[3]=(png_uint_32)chunk->data[8];
+
+   return (1);
+
+}
+#endif
+/* END of code to demonstrate user chunk support */
+
+/* Test one file */
+int
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+{
+   static png_FILE_p fpin;
+   static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
+   png_structp read_ptr;
+   png_infop read_info_ptr, end_info_ptr;
+#ifdef PNG_WRITE_SUPPORTED
+   png_structp write_ptr;
+   png_infop write_info_ptr;
+   png_infop write_end_info_ptr;
+#else
+   png_structp write_ptr = NULL;
+   png_infop write_info_ptr = NULL;
+   png_infop write_end_info_ptr = NULL;
+#endif
+   png_bytep row_buf;
+   png_uint_32 y;
+   png_uint_32 width, height;
+   int num_pass, pass;
+   int bit_depth, color_type;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+#endif
+
+#ifdef _WIN32_WCE
+   TCHAR path[MAX_PATH];
+#endif
+   char inbuf[256], outbuf[256];
+
+   row_buf = NULL;
+
+#ifdef _WIN32_WCE
+   MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+   if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0,
+       NULL)) == INVALID_HANDLE_VALUE)
+#else
+   if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+   {
+      fprintf(STDERR, "Could not find input file %s\n", inname);
+      return (1);
+   }
+
+#ifdef _WIN32_WCE
+   MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+   if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+       0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+   if ((fpout = fopen(outname, "wb")) == NULL)
+#endif
+   {
+      fprintf(STDERR, "Could not open output file %s\n", outname);
+      FCLOSE(fpin);
+      return (1);
+   }
+
+   png_debug(0, "Allocating read and write structures");
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+   read_ptr =
+      png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+   read_ptr =
+      png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+      png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+#ifndef PNG_STDIO_SUPPORTED
+   png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
+       pngtest_warning);
+#endif
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+   user_chunk_data[0] = 0;
+   user_chunk_data[1] = 0;
+   user_chunk_data[2] = 0;
+   user_chunk_data[3] = 0;
+   png_set_read_user_chunk_fn(read_ptr, user_chunk_data,
+     read_user_chunk_callback);
+
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+   write_ptr =
+      png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+   write_ptr =
+      png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+      png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+#ifndef PNG_STDIO_SUPPORTED
+   png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
+       pngtest_warning);
+#endif
+#endif
+   png_debug(0, "Allocating read_info, write_info and end_info structures");
+   read_info_ptr = png_create_info_struct(read_ptr);
+   end_info_ptr = png_create_info_struct(read_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+   write_info_ptr = png_create_info_struct(write_ptr);
+   write_end_info_ptr = png_create_info_struct(write_ptr);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   png_debug(0, "Setting jmpbuf for read struct");
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_jmpbuf(read_ptr)))
+#endif
+   {
+      fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
+      png_free(read_ptr, row_buf);
+      row_buf = NULL;
+      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+      png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+      FCLOSE(fpin);
+      FCLOSE(fpout);
+      return (1);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_jmpbuf(read_ptr), jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+   png_debug(0, "Setting jmpbuf for write struct");
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_jmpbuf(write_ptr)))
+#endif
+   {
+      fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+      png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+      FCLOSE(fpin);
+      FCLOSE(fpout);
+      return (1);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_jmpbuf(write_ptr), jmpbuf, png_sizeof(jmp_buf));
+#endif
+#endif
+#endif
+
+   png_debug(0, "Initializing input and output streams");
+#ifdef PNG_STDIO_SUPPORTED
+   png_init_io(read_ptr, fpin);
+#  ifdef PNG_WRITE_SUPPORTED
+   png_init_io(write_ptr, fpout);
+#  endif
+#else
+   png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
+#  ifdef PNG_WRITE_SUPPORTED
+   png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
+#    ifdef PNG_WRITE_FLUSH_SUPPORTED
+      pngtest_flush);
+#    else
+      NULL);
+#    endif
+#  endif
+#endif
+   if (status_dots_requested == 1)
+   {
+#ifdef PNG_WRITE_SUPPORTED
+      png_set_write_status_fn(write_ptr, write_row_callback);
+#endif
+      png_set_read_status_fn(read_ptr, read_row_callback);
+   }
+   else
+   {
+#ifdef PNG_WRITE_SUPPORTED
+      png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
+#endif
+      png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
+   }
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   {
+      int i;
+      for (i = 0; i<256; i++)
+         filters_used[i] = 0;
+      png_set_read_user_transform_fn(read_ptr, count_filters);
+   }
+#endif
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   zero_samples = 0;
+   png_set_write_user_transform_fn(write_ptr, count_zero_samples);
+#endif
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_HANDLE_CHUNK_ALWAYS
+#    define PNG_HANDLE_CHUNK_ALWAYS       3
+#  endif
+   png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
+      png_bytep_NULL, 0);
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#  ifndef PNG_HANDLE_CHUNK_IF_SAFE
+#    define PNG_HANDLE_CHUNK_IF_SAFE      2
+#  endif
+   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
+      png_bytep_NULL, 0);
+#endif
+
+   png_debug(0, "Reading info struct");
+   png_read_info(read_ptr, read_info_ptr);
+
+   png_debug(0, "Transferring info struct");
+   {
+      int interlace_type, compression_type, filter_type;
+
+      if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
+          &color_type, &interlace_type, &compression_type, &filter_type))
+      {
+         png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+            color_type, interlace_type, compression_type, filter_type);
+#else
+            color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#endif
+      }
+   }
+#ifdef PNG_FIXED_POINT_SUPPORTED
+#ifdef PNG_cHRM_SUPPORTED
+   {
+      png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+         blue_y;
+      if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
+         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y))
+      {
+         png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
+            red_y, green_x, green_y, blue_x, blue_y);
+      }
+   }
+#endif
+#ifdef PNG_gAMA_SUPPORTED
+   {
+      png_fixed_point gamma;
+
+      if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
+         png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
+   }
+#endif
+#else /* Use floating point versions */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#ifdef PNG_cHRM_SUPPORTED
+   {
+      double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+         blue_y;
+      if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+         &red_y, &green_x, &green_y, &blue_x, &blue_y))
+      {
+         png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
+            red_y, green_x, green_y, blue_x, blue_y);
+      }
+   }
+#endif
+#ifdef PNG_gAMA_SUPPORTED
+   {
+      double gamma;
+
+      if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
+         png_set_gAMA(write_ptr, write_info_ptr, gamma);
+   }
+#endif
+#endif /* Floating point */
+#endif /* Fixed point */
+#ifdef PNG_iCCP_SUPPORTED
+   {
+      png_charp name;
+      png_charp profile;
+      png_uint_32 proflen;
+      int compression_type;
+
+      if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
+                      &profile, &proflen))
+      {
+         png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
+                      profile, proflen);
+      }
+   }
+#endif
+#ifdef PNG_sRGB_SUPPORTED
+   {
+      int intent;
+
+      if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
+         png_set_sRGB(write_ptr, write_info_ptr, intent);
+   }
+#endif
+   {
+      png_colorp palette;
+      int num_palette;
+
+      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
+         png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
+   }
+#ifdef PNG_bKGD_SUPPORTED
+   {
+      png_color_16p background;
+
+      if (png_get_bKGD(read_ptr, read_info_ptr, &background))
+      {
+         png_set_bKGD(write_ptr, write_info_ptr, background);
+      }
+   }
+#endif
+#ifdef PNG_hIST_SUPPORTED
+   {
+      png_uint_16p hist;
+
+      if (png_get_hIST(read_ptr, read_info_ptr, &hist))
+         png_set_hIST(write_ptr, write_info_ptr, hist);
+   }
+#endif
+#ifdef PNG_oFFs_SUPPORTED
+   {
+      png_int_32 offset_x, offset_y;
+      int unit_type;
+
+      if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
+          &unit_type))
+      {
+         png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+      }
+   }
+#endif
+#ifdef PNG_pCAL_SUPPORTED
+   {
+      png_charp purpose, units;
+      png_charpp params;
+      png_int_32 X0, X1;
+      int type, nparams;
+
+      if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
+         &nparams, &units, &params))
+      {
+         png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
+            nparams, units, params);
+      }
+   }
+#endif
+#ifdef PNG_pHYs_SUPPORTED
+   {
+      png_uint_32 res_x, res_y;
+      int unit_type;
+
+      if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
+         png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
+   }
+#endif
+#ifdef PNG_sBIT_SUPPORTED
+   {
+      png_color_8p sig_bit;
+
+      if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
+         png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
+   }
+#endif
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   {
+      int unit;
+      double scal_width, scal_height;
+
+      if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
+         &scal_height))
+      {
+         png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+      }
+   }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+   {
+      int unit;
+      png_charp scal_width, scal_height;
+
+      if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
+          &scal_height))
+      {
+         png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
+             scal_height);
+      }
+   }
+#endif
+#endif
+#endif
+#ifdef PNG_TEXT_SUPPORTED
+   {
+      png_textp text_ptr;
+      int num_text;
+
+      if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
+      {
+         png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
+         png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
+      }
+   }
+#endif
+#ifdef PNG_tIME_SUPPORTED
+   {
+      png_timep mod_time;
+
+      if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
+      {
+         png_set_tIME(write_ptr, write_info_ptr, mod_time);
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+         /* We have to use png_memcpy instead of "=" because the string
+          * pointed to by png_convert_to_rfc1123() gets free'ed before
+          * we use it.
+          */
+         png_memcpy(tIME_string,
+                    png_convert_to_rfc1123(read_ptr, mod_time),
+                    png_sizeof(tIME_string));
+         tIME_string[png_sizeof(tIME_string) - 1] = '\0';
+         tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+      }
+   }
+#endif
+#ifdef PNG_tRNS_SUPPORTED
+   {
+      png_bytep trans;
+      int num_trans;
+      png_color_16p trans_values;
+
+      if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
+         &trans_values))
+      {
+         int sample_max = (1 << bit_depth);
+         /* libpng doesn't reject a tRNS chunk with out-of-range samples */
+         if (!((color_type == PNG_COLOR_TYPE_GRAY &&
+             (int)trans_values->gray > sample_max) ||
+             (color_type == PNG_COLOR_TYPE_RGB &&
+             ((int)trans_values->red > sample_max ||
+             (int)trans_values->green > sample_max ||
+             (int)trans_values->blue > sample_max))))
+            png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
+               trans_values);
+      }
+   }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   {
+      png_unknown_chunkp unknowns;
+      int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
+         &unknowns);
+      if (num_unknowns)
+      {
+         png_size_t i;
+         png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
+           num_unknowns);
+         /* Copy the locations from the read_info_ptr.  The automatically
+          * generated locations in write_info_ptr are wrong because we
+          * haven't written anything yet.
+          */
+         for (i = 0; i < (png_size_t)num_unknowns; i++)
+           png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
+             unknowns[i].location);
+      }
+   }
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+   png_debug(0, "Writing info struct");
+
+/* If we wanted, we could write info in two steps:
+ * png_write_info_before_PLTE(write_ptr, write_info_ptr);
+ */
+   png_write_info(write_ptr, write_info_ptr);
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+   if (user_chunk_data[0] != 0)
+   {
+      png_byte png_sTER[5] = {115,  84,  69,  82, '\0'};
+
+      unsigned char
+        ster_chunk_data[1];
+
+      if (verbose)
+         fprintf(STDERR, "\n stereo mode = %lu\n",
+           (unsigned long)(user_chunk_data[0] - 1));
+      ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1);
+      png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1);
+   }
+   if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
+   {
+      png_byte png_vpAg[5] = {118, 112,  65, 103, '\0'};
+
+      unsigned char
+        vpag_chunk_data[9];
+
+      if (verbose)
+         fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n",
+           (unsigned long)user_chunk_data[1],
+           (unsigned long)user_chunk_data[2],
+           (unsigned long)user_chunk_data[3]);
+      png_save_uint_32(vpag_chunk_data, user_chunk_data[1]);
+      png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]);
+      vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff);
+      png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9);
+   }
+
+#endif
+#endif
+
+#ifdef SINGLE_ROWBUF_ALLOC
+   png_debug(0, "Allocating row buffer...");
+   row_buf = (png_bytep)png_malloc(read_ptr,
+      png_get_rowbytes(read_ptr, read_info_ptr));
+   png_debug1(0, "0x%08lx", (unsigned long)row_buf);
+#endif /* SINGLE_ROWBUF_ALLOC */
+   png_debug(0, "Writing row data");
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+  defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   num_pass = png_set_interlace_handling(read_ptr);
+#  ifdef PNG_WRITE_SUPPORTED
+   png_set_interlace_handling(write_ptr);
+#  endif
+#else
+   num_pass = 1;
+#endif
+
+#ifdef PNGTEST_TIMING
+   t_stop = (float)clock();
+   t_misc += (t_stop - t_start);
+   t_start = t_stop;
+#endif
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      png_debug1(0, "Writing row data for pass %d", pass);
+      for (y = 0; y < height; y++)
+      {
+#ifndef SINGLE_ROWBUF_ALLOC
+         png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y);
+         row_buf = (png_bytep)png_malloc(read_ptr,
+            png_get_rowbytes(read_ptr, read_info_ptr));
+         png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf,
+            png_get_rowbytes(read_ptr, read_info_ptr));
+#endif /* !SINGLE_ROWBUF_ALLOC */
+         png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNGTEST_TIMING
+         t_stop = (float)clock();
+         t_decode += (t_stop - t_start);
+         t_start = t_stop;
+#endif
+         png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
+#ifdef PNGTEST_TIMING
+         t_stop = (float)clock();
+         t_encode += (t_stop - t_start);
+         t_start = t_stop;
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef SINGLE_ROWBUF_ALLOC
+         png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y);
+         png_free(read_ptr, row_buf);
+         row_buf = NULL;
+#endif /* !SINGLE_ROWBUF_ALLOC */
+      }
+   }
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+
+   png_debug(0, "Reading and writing end_info data");
+
+   png_read_end(read_ptr, end_info_ptr);
+#ifdef PNG_TEXT_SUPPORTED
+   {
+      png_textp text_ptr;
+      int num_text;
+
+      if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
+      {
+         png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
+         png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
+      }
+   }
+#endif
+#ifdef PNG_tIME_SUPPORTED
+   {
+      png_timep mod_time;
+
+      if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
+      {
+         png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+         /* We have to use png_memcpy instead of "=" because the string
+            pointed to by png_convert_to_rfc1123() gets free'ed before
+            we use it */
+         png_memcpy(tIME_string,
+                    png_convert_to_rfc1123(read_ptr, mod_time),
+                    png_sizeof(tIME_string));
+         tIME_string[png_sizeof(tIME_string) - 1] = '\0';
+         tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+      }
+   }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   {
+      png_unknown_chunkp unknowns;
+      int num_unknowns;
+      num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
+         &unknowns);
+      if (num_unknowns)
+      {
+         png_size_t i;
+         png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
+           num_unknowns);
+         /* Copy the locations from the read_info_ptr.  The automatically
+          * generated locations in write_end_info_ptr are wrong because we
+          * haven't written the end_info yet.
+          */
+         for (i = 0; i < (png_size_t)num_unknowns; i++)
+           png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+             unknowns[i].location);
+      }
+   }
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+   png_write_end(write_ptr, write_end_info_ptr);
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+   if (verbose)
+   {
+      png_uint_32 iwidth, iheight;
+      iwidth = png_get_image_width(write_ptr, write_info_ptr);
+      iheight = png_get_image_height(write_ptr, write_info_ptr);
+      fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
+         (unsigned long)iwidth, (unsigned long)iheight);
+   }
+#endif
+
+   png_debug(0, "Destroying data structs");
+#ifdef SINGLE_ROWBUF_ALLOC
+   png_debug(1, "destroying row_buf for read_ptr");
+   png_free(read_ptr, row_buf);
+   row_buf = NULL;
+#endif /* SINGLE_ROWBUF_ALLOC */
+   png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr");
+   png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+   png_debug(1, "destroying write_end_info_ptr");
+   png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+   png_debug(1, "destroying write_ptr, write_info_ptr");
+   png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+   png_debug(0, "Destruction complete.");
+
+   FCLOSE(fpin);
+   FCLOSE(fpout);
+
+   png_debug(0, "Opening files for comparison");
+#ifdef _WIN32_WCE
+   MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+   if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+       0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+   if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+   {
+      fprintf(STDERR, "Could not find file %s\n", inname);
+      return (1);
+   }
+
+#ifdef _WIN32_WCE
+   MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+   if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+       0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+   if ((fpout = fopen(outname, "rb")) == NULL)
+#endif
+   {
+      fprintf(STDERR, "Could not find file %s\n", outname);
+      FCLOSE(fpin);
+      return (1);
+   }
+
+   for (;;)
+   {
+      png_size_t num_in, num_out;
+
+         READFILE(fpin, inbuf, 1, num_in);
+         READFILE(fpout, outbuf, 1, num_out);
+
+      if (num_in != num_out)
+      {
+         fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
+                 inname, outname);
+         if (wrote_question == 0)
+         {
+            fprintf(STDERR,
+         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
+              inname, PNG_ZBUF_SIZE);
+            fprintf(STDERR,
+              "\n   filtering heuristic (libpng default), compression");
+            fprintf(STDERR,
+              " level (zlib default),\n   and zlib version (%s)?\n\n",
+              ZLIB_VERSION);
+            wrote_question = 1;
+         }
+         FCLOSE(fpin);
+         FCLOSE(fpout);
+         return (0);
+      }
+
+      if (!num_in)
+         break;
+
+      if (png_memcmp(inbuf, outbuf, num_in))
+      {
+         fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
+         if (wrote_question == 0)
+         {
+            fprintf(STDERR,
+         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
+                 inname, PNG_ZBUF_SIZE);
+            fprintf(STDERR,
+              "\n   filtering heuristic (libpng default), compression");
+            fprintf(STDERR,
+              " level (zlib default),\n   and zlib version (%s)?\n\n",
+              ZLIB_VERSION);
+            wrote_question = 1;
+         }
+         FCLOSE(fpin);
+         FCLOSE(fpout);
+         return (0);
+      }
+   }
+
+   FCLOSE(fpin);
+   FCLOSE(fpout);
+
+   return (0);
+}
+
+/* Input and output filenames */
+#ifdef RISCOS
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
+#else
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
+#endif
+
+int
+main(int argc, char *argv[])
+{
+   int multiple = 0;
+   int ierror = 0;
+
+   fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
+   fprintf(STDERR, "   with zlib   version %s\n", ZLIB_VERSION);
+   fprintf(STDERR, "%s", png_get_copyright(NULL));
+   /* Show the version of libpng used in building the library */
+   fprintf(STDERR, " library (%lu):%s",
+      (unsigned long)png_access_version_number(),
+      png_get_header_version(NULL));
+   /* Show the version of libpng used in building the application */
+   fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
+      PNG_HEADER_VERSION_STRING);
+   fprintf(STDERR, " sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n",
+                    (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
+
+   /* Do some consistency checking on the memory allocation settings, I'm
+    * not sure this matters, but it is nice to know, the first of these
+    * tests should be impossible because of the way the macros are set
+    * in pngconf.h
+    */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+      fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
+#endif
+   /* I think the following can happen. */
+#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
+      fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
+#endif
+
+   if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
+   {
+      fprintf(STDERR,
+         "Warning: versions are different between png.h and png.c\n");
+      fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+      fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
+      ++ierror;
+   }
+
+   if (argc > 1)
+   {
+      if (strcmp(argv[1], "-m") == 0)
+      {
+         multiple = 1;
+         status_dots_requested = 0;
+      }
+      else if (strcmp(argv[1], "-mv") == 0 ||
+               strcmp(argv[1], "-vm") == 0 )
+      {
+         multiple = 1;
+         verbose = 1;
+         status_dots_requested = 1;
+      }
+      else if (strcmp(argv[1], "-v") == 0)
+      {
+         verbose = 1;
+         status_dots_requested = 1;
+         inname = argv[2];
+      }
+      else
+      {
+         inname = argv[1];
+         status_dots_requested = 0;
+      }
+   }
+
+   if (!multiple && argc == 3 + verbose)
+     outname = argv[2 + verbose];
+
+   if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
+   {
+     fprintf(STDERR,
+       "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+        argv[0], argv[0]);
+     fprintf(STDERR,
+       "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
+     fprintf(STDERR,
+       "  with -m %s is used as a temporary file\n", outname);
+     exit(1);
+   }
+
+   if (multiple)
+   {
+      int i;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+      int allocation_now = current_allocation;
+#endif
+      for (i=2; i<argc; ++i)
+      {
+         int kerror;
+         fprintf(STDERR, "\n Testing %s:", argv[i]);
+         kerror = test_one_file(argv[i], outname);
+         if (kerror == 0)
+         {
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+            int k;
+#endif
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+            fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+               (unsigned long)zero_samples);
+#else
+            fprintf(STDERR, " PASS\n");
+#endif
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+            for (k = 0; k<256; k++)
+               if (filters_used[k])
+                  fprintf(STDERR, " Filter %d was used %lu times\n",
+                     k, (unsigned long)filters_used[k]);
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+         if (tIME_chunk_present != 0)
+            fprintf(STDERR, " tIME = %s\n", tIME_string);
+         tIME_chunk_present = 0;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+         }
+         else
+         {
+            fprintf(STDERR, " FAIL\n");
+            ierror += kerror;
+         }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+         if (allocation_now != current_allocation)
+            fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+               current_allocation - allocation_now);
+         if (current_allocation != 0)
+         {
+            memory_infop pinfo = pinformation;
+
+            fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+               current_allocation);
+            while (pinfo != NULL)
+            {
+               fprintf(STDERR, " %lu bytes at %x\n",
+                 (unsigned long)pinfo->size,
+                 (unsigned int) pinfo->pointer);
+               pinfo = pinfo->next;
+            }
+         }
+#endif
+      }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+         fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+            current_allocation);
+         fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+            maximum_allocation);
+         fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
+            total_allocation);
+         fprintf(STDERR, "     Number of allocations: %10d\n",
+            num_allocations);
+#endif
+   }
+   else
+   {
+      int i;
+      for (i = 0; i<3; ++i)
+      {
+         int kerror;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+         int allocation_now = current_allocation;
+#endif
+         if (i == 1) status_dots_requested = 1;
+         else if (verbose == 0)status_dots_requested = 0;
+         if (i == 0 || verbose == 1 || ierror != 0)
+            fprintf(STDERR, "\n Testing %s:", inname);
+         kerror = test_one_file(inname, outname);
+         if (kerror == 0)
+         {
+            if (verbose == 1 || i == 2)
+            {
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+                int k;
+#endif
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+                fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+                   (unsigned long)zero_samples);
+#else
+                fprintf(STDERR, " PASS\n");
+#endif
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+                for (k = 0; k<256; k++)
+                   if (filters_used[k])
+                      fprintf(STDERR, " Filter %d was used %lu times\n",
+                         k, (unsigned long)filters_used[k]);
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+             if (tIME_chunk_present != 0)
+                fprintf(STDERR, " tIME = %s\n", tIME_string);
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+            }
+         }
+         else
+         {
+            if (verbose == 0 && i != 2)
+               fprintf(STDERR, "\n Testing %s:", inname);
+            fprintf(STDERR, " FAIL\n");
+            ierror += kerror;
+         }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+         if (allocation_now != current_allocation)
+             fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+               current_allocation - allocation_now);
+         if (current_allocation != 0)
+         {
+             memory_infop pinfo = pinformation;
+
+             fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+                current_allocation);
+             while (pinfo != NULL)
+             {
+                fprintf(STDERR, " %lu bytes at %x\n",
+                   (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
+                pinfo = pinfo->next;
+             }
+          }
+#endif
+       }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+       fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+          current_allocation);
+       fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+          maximum_allocation);
+       fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
+          total_allocation);
+       fprintf(STDERR, "     Number of allocations: %10d\n",
+            num_allocations);
+#endif
+   }
+
+#ifdef PNGTEST_TIMING
+   t_stop = (float)clock();
+   t_misc += (t_stop - t_start);
+   t_start = t_stop;
+   fprintf(STDERR, " CPU time used = %.3f seconds",
+      (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+   fprintf(STDERR, " (decoding %.3f,\n",
+      t_decode/(float)CLOCKS_PER_SEC);
+   fprintf(STDERR, "        encoding %.3f ,",
+      t_encode/(float)CLOCKS_PER_SEC);
+   fprintf(STDERR, " other %.3f seconds)\n\n",
+      t_misc/(float)CLOCKS_PER_SEC);
+#endif
+
+   if (ierror == 0)
+      fprintf(STDERR, " libpng passes test\n");
+   else
+      fprintf(STDERR, " libpng FAILS test\n");
+   return (int)(ierror != 0);
+}
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_44 your_png_h_is_not_version_1_2_44;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtrans.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtrans.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngtrans.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,699 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.2.41 [December 3, 2009]
+ * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_bgr");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap");
+
+   if (png_ptr == NULL)
+      return;
+   if (png_ptr->bit_depth == 16)
+      png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packing");
+
+   if (png_ptr == NULL)
+      return;
+   if (png_ptr->bit_depth < 8)
+   {
+      png_ptr->transformations |= PNG_PACK;
+      png_ptr->usr_bit_depth = 8;
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packswap");
+
+   if (png_ptr == NULL)
+      return;
+   if (png_ptr->bit_depth < 8)
+      png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+   png_debug(1, "in png_set_shift");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_SHIFT;
+   png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_interlace handling");
+
+   if (png_ptr && png_ptr->interlaced)
+   {
+      png_ptr->transformations |= PNG_INTERLACE;
+      return (7);
+   }
+
+   return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_filler");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_FILLER;
+#ifdef PNG_LEGACY_SUPPORTED
+   png_ptr->filler = (png_byte)filler;
+#else
+   png_ptr->filler = (png_uint_16)filler;
+#endif
+   if (filler_loc == PNG_FILLER_AFTER)
+      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+   else
+      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+   /* This should probably go in the "do_read_filler" routine.
+    * I attempted to do that in libpng-1.0.1a but that caused problems
+    * so I restored it in libpng-1.0.2a
+   */
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_ptr->usr_channels = 4;
+   }
+
+   /* Also I added this in libpng-1.0.2a (what happens when we expand
+    * a less-than-8-bit grayscale to GA? */
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
+   {
+      png_ptr->usr_channels = 2;
+   }
+}
+
+#ifndef PNG_1_0_X
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_add_alpha");
+
+   if (png_ptr == NULL)
+      return;
+   png_set_filler(png_ptr, filler, filler_loc);
+   png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+#endif
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap_alpha");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_alpha");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_mono");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* Invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_invert");
+
+  /* This test removed from libpng version 1.0.13 and 1.2.0:
+   *   if (row_info->bit_depth == 1 &&
+   */
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row == NULL || row_info == NULL)
+     return;
+#endif
+   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i++)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp++;
+      }
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 8)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i+=2)
+      {
+         *rp = (png_byte)(~(*rp));
+         rp+=2;
+      }
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+      row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop = row_info->rowbytes;
+
+      for (i = 0; i < istop; i+=4)
+      {
+         *rp = (png_byte)(~(*rp));
+         *(rp+1) = (png_byte)(~(*(rp+1)));
+         rp+=4;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_swap");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth == 16)
+   {
+      png_bytep rp = row;
+      png_uint_32 i;
+      png_uint_32 istop= row_info->width * row_info->channels;
+
+      for (i = 0; i < istop; i++, rp += 2)
+      {
+         png_byte t = *rp;
+         *rp = *(rp + 1);
+         *(rp + 1) = t;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* Swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_packswap");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth < 8)
+   {
+      png_bytep rp, end, table;
+
+      end = row + row_info->rowbytes;
+
+      if (row_info->bit_depth == 1)
+         table = (png_bytep)onebppswaptable;
+      else if (row_info->bit_depth == 2)
+         table = (png_bytep)twobppswaptable;
+      else if (row_info->bit_depth == 4)
+         table = (png_bytep)fourbppswaptable;
+      else
+         return;
+
+      for (rp = row; rp < end; rp++)
+         *rp = table[*rp];
+   }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* Remove filler or alpha byte(s) */
+void /* PRIVATE */
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+   png_debug(1, "in png_do_strip_filler");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      png_bytep sp=row;
+      png_bytep dp=row;
+      png_uint_32 row_width=row_info->width;
+      png_uint_32 i;
+
+      if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
+          (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+          (flags & PNG_FLAG_STRIP_ALPHA))) &&
+          row_info->channels == 4)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from RGBX or RGBA to RGB */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               dp+=3; sp+=4;
+               for (i = 1; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XRGB or ARGB to RGB */
+            else
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 24;
+            row_info->rowbytes = row_width * 3;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+               sp += 8; dp += 6;
+               for (i = 1; i < row_width; i++)
+               {
+                  /* This could be (although png_memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+               for (i = 0; i < row_width; i++)
+               {
+                  /* This could be (although png_memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+
+                  sp+=2;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 48;
+            row_info->rowbytes = row_width * 6;
+         }
+         row_info->channels = 3;
+      }
+      else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
+         (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+         (flags & PNG_FLAG_STRIP_ALPHA))) &&
+          row_info->channels == 2)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from GX or GA to G */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XG or AG to G */
+            else
+            {
+               for (i = 0; i < row_width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_width;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               /* This converts from GGXX or GGAA to GG */
+               sp += 4; dp += 2;
+               for (i = 1; i < row_width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               /* This converts from XXGG or AAGG to GG */
+               for (i = 0; i < row_width; i++)
+               {
+                  sp += 2;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_width * 2;
+         }
+         row_info->channels = 1;
+      }
+      if (flags & PNG_FLAG_STRIP_ALPHA)
+        row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+   }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_bgr");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 3)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 4)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 6)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_width; i++, rp += 8)
+            {
+               png_byte save = *rp;
+               *rp = *(rp + 4);
+               *(rp + 4) = save;
+               save = *(rp + 1);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 5) = save;
+            }
+         }
+      }
+   }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_LEGACY_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+   user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+   png_debug(1, "in png_set_user_transform_info");
+
+   if (png_ptr == NULL)
+      return;
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+   png_ptr->user_transform_ptr = user_transform_ptr;
+   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+   if (user_transform_ptr || user_transform_depth || user_transform_channels)
+      png_warning(png_ptr,
+        "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions.  The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+   if (png_ptr == NULL)
+      return (NULL);
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+   return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+   return (NULL);
+#endif
+}
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngvcrd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngvcrd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngvcrd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1 @@
+/* pnggvrd.c was removed from libpng-1.2.20. */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,260 @@
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.2.41 [December 3, 2009]
+ * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all output.  Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods.  Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using.  The default routine
+ * writes to a file pointer.  Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered writes.  This should never be asked
+ * to write more than 64K on a 16 bit machine.
+ */
+
+void /* PRIVATE */
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   if (png_ptr->write_data_fn != NULL )
+      (*(png_ptr->write_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL write function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual writing of data.  If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+
+   if (png_ptr == NULL)
+      return;
+#ifdef _WIN32_WCE
+   if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+      check = 0;
+#else
+   check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
+   if (check != length)
+      png_error(png_ptr, "Write Error");
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+ * can't handle far buffers in the medium and small models, we have to copy
+ * the data.
+ */
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
+   png_FILE_p io_ptr;
+
+   if (png_ptr == NULL)
+      return;
+   /* Check if data really is near. If so, use usual code. */
+   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)near_data == data)
+   {
+#ifdef _WIN32_WCE
+      if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+         check = 0;
+#else
+      check = fwrite(near_data, 1, length, io_ptr);
+#endif
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t written, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         written = MIN(NEAR_BUF_SIZE, remaining);
+         png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
+#ifdef _WIN32_WCE
+         if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+            err = 0;
+#else
+         err = fwrite(buf, 1, written, io_ptr);
+#endif
+         if (err != written)
+            break;
+
+         else
+            check += err;
+
+         data += written;
+         remaining -= written;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+      png_error(png_ptr, "Write Error");
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+ * to disk).  After png_flush is called, there should be no data pending
+ * writing in any buffers.
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+void /* PRIVATE */
+png_flush(png_structp png_ptr)
+{
+   if (png_ptr->output_flush_fn != NULL)
+      (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+void PNGAPI
+png_default_flush(png_structp png_ptr)
+{
+#ifndef _WIN32_WCE
+   png_FILE_p io_ptr;
+#endif
+   if (png_ptr == NULL)
+      return;
+#ifndef _WIN32_WCE
+   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+   fflush(io_ptr);
+#endif
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ * libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr       - pointer to a png output data structure
+ * io_ptr        - pointer to user supplied structure containing info about
+ *                 the output functions.  May be NULL.
+ * write_data_fn - pointer to a new output function that takes as its
+ *                 arguments a pointer to a png_struct, a pointer to
+ *                 data to be written, and a 32-bit unsigned int that is
+ *                 the number of bytes to be written.  The new write
+ *                 function should call png_error(png_ptr, "Error msg")
+ *                 to exit and output any fatal error messages.  May be
+ *                 NULL, in which case libpng's default function will
+ *                 be used.
+ * flush_data_fn - pointer to a new flush function that takes as its
+ *                 arguments a pointer to a png_struct.  After a call to
+ *                 the flush function, there should be no data in any buffers
+ *                 or pending transmission.  If the output method doesn't do
+ *                 any buffering of output, a function prototype must still be
+ *                 supplied although it doesn't have to do anything.  If
+ *                 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ *                 time, output_flush_fn will be ignored, although it must be
+ *                 supplied for compatibility.  May be NULL, in which case
+ *                 libpng's default function will be used, if
+ *                 PNG_WRITE_FLUSH_SUPPORTED is defined.  This is not
+ *                 a good idea if io_ptr does not point to a standard
+ *                 *FILE structure.
+ */
+void PNGAPI
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+   if (write_data_fn != NULL)
+      png_ptr->write_data_fn = write_data_fn;
+
+   else
+      png_ptr->write_data_fn = png_default_write_data;
+#else
+   png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+   if (output_flush_fn != NULL)
+      png_ptr->output_flush_fn = output_flush_fn;
+
+   else
+      png_ptr->output_flush_fn = png_default_flush;
+#else
+   png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+   /* It is an error to read while writing a png file */
+   if (png_ptr->read_data_fn != NULL)
+   {
+      png_ptr->read_data_fn = NULL;
+      png_warning(png_ptr,
+         "Attempted to set both read_data_fn and write_data_fn in");
+      png_warning(png_ptr,
+         "the same structure.  Resetting read_data_fn to NULL.");
+   }
+}
+
+#ifdef USE_FAR_KEYWORD
+#ifdef _MSC_VER
+void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
+{
+   void *near_ptr;
+   void FAR *far_ptr;
+   FP_OFF(near_ptr) = FP_OFF(ptr);
+   far_ptr = (void FAR *)near_ptr;
+
+   if (check != 0)
+      if (FP_SEG(ptr) != FP_SEG(far_ptr))
+         png_error(png_ptr, "segment lost in conversion");
+
+   return(near_ptr);
+}
+#  else
+void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
+{
+   void *near_ptr;
+   void FAR *far_ptr;
+   near_ptr = (void FAR *)ptr;
+   far_ptr = (void FAR *)near_ptr;
+
+   if (check != 0)
+      if (far_ptr != ptr)
+         png_error(png_ptr, "segment lost in conversion");
+
+   return(near_ptr);
+}
+#   endif
+#   endif
+#endif /* PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwrite.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1592 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.2.42 [January 3, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Get internal access to png.h */
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Writes all the PNG information.  This is the suggested way to use the
+ * library.  If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here.  If you want the chunk written
+ * after the image data, put it in png_write_end().  I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file.  If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_write_info_before_PLTE");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+   {
+   /* Write PNG signature */
+   png_write_sig(png_ptr);
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
+      (png_ptr->mng_features_permitted))
+   {
+      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+      png_ptr->mng_features_permitted = 0;
+   }
+#endif
+   /* Write IHDR information. */
+   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+      info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+      info_ptr->filter_type,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+      info_ptr->interlace_type);
+#else
+      0);
+#endif
+   /* The rest of these check to see if the valid field has the appropriate
+    * flag set, and if it does, writes the chunk.
+    */
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_gAMA)
+   {
+#  ifdef PNG_FLOATING_POINT_SUPPORTED
+      png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+#  endif
+#endif
+   }
+#endif
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_iCCP)
+      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+                     info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_sBIT)
+      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_cHRM)
+   {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+      png_write_cHRM(png_ptr,
+         info_ptr->x_white, info_ptr->y_white,
+         info_ptr->x_red, info_ptr->y_red,
+         info_ptr->x_green, info_ptr->y_green,
+         info_ptr->x_blue, info_ptr->y_blue);
+#else
+#  ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_cHRM_fixed(png_ptr,
+         info_ptr->int_x_white, info_ptr->int_y_white,
+         info_ptr->int_x_red, info_ptr->int_y_red,
+         info_ptr->int_x_green, info_ptr->int_y_green,
+         info_ptr->int_x_blue, info_ptr->int_y_blue);
+#  endif
+#endif
+   }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   if (info_ptr->unknown_chunks_num)
+   {
+      png_unknown_chunk *up;
+
+      png_debug(5, "writing extra chunks");
+
+      for (up = info_ptr->unknown_chunks;
+           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+           up++)
+      {
+         int keep = png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && !(up->location & PNG_HAVE_PLTE) &&
+            !(up->location & PNG_HAVE_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            if (up->size == 0)
+               png_warning(png_ptr, "Writing zero-length unknown chunk");
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+      }
+   }
+#endif
+      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+   }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_write_info_before_PLTE(png_ptr, info_ptr);
+
+   if (info_ptr->valid & PNG_INFO_PLTE)
+      png_write_PLTE(png_ptr, info_ptr->palette,
+         (png_uint_32)info_ptr->num_palette);
+   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      png_error(png_ptr, "Valid palette required for paletted images");
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_tRNS)
+   {
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+      /* Invert the alpha channel (in tRNS) */
+      if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+         info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         int j;
+         for (j = 0; j<(int)info_ptr->num_trans; j++)
+            info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
+      }
+#endif
+      png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+         info_ptr->num_trans, info_ptr->color_type);
+   }
+#endif
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_bKGD)
+      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#ifdef PNG_WRITE_hIST_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_hIST)
+      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_oFFs)
+      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+         info_ptr->offset_unit_type);
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_pCAL)
+      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+         info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+         info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_sCAL)
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+      png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else /* !FLOATING_POINT */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+      png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+          info_ptr->scal_s_width, info_ptr->scal_s_height);
+#endif /* FIXED_POINT */
+#endif /* FLOATING_POINT */
+#else  /* !WRITE_sCAL */
+      png_warning(png_ptr,
+          "png_write_sCAL not supported; sCAL chunk not written.");
+#endif /* WRITE_sCAL */
+#endif /* sCAL */
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_pHYs)
+      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+         info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif /* pHYs */
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_tIME)
+   {
+      png_write_tIME(png_ptr, &(info_ptr->mod_time));
+      png_ptr->mode |= PNG_WROTE_tIME;
+   }
+#endif /* tIME */
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_sPLT)
+     for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+       png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif /* sPLT */
+
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+   /* Check to see if we need to write text chunks */
+   for (i = 0; i < info_ptr->num_text; i++)
+   {
+      png_debug2(2, "Writing header text chunk %d, type %d", i,
+         info_ptr->text[i].compression);
+      /* An internationalized chunk? */
+      if (info_ptr->text[i].compression > 0)
+      {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+          /* Write international chunk */
+          png_write_iTXt(png_ptr,
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].lang_key,
+                         info_ptr->text[i].text);
+#else
+          png_warning(png_ptr, "Unable to write international text");
+#endif
+          /* Mark this chunk as written */
+          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
+      /* If we want a compressed text chunk */
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+      {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+         /* Write compressed chunk */
+         png_write_zTXt(png_ptr, info_ptr->text[i].key,
+            info_ptr->text[i].text, 0,
+            info_ptr->text[i].compression);
+#else
+         png_warning(png_ptr, "Unable to write compressed text");
+#endif
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+      }
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+      {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+         /* Write uncompressed chunk */
+         png_write_tEXt(png_ptr, info_ptr->text[i].key,
+                         info_ptr->text[i].text,
+                         0);
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+         /* Can't get here */
+         png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+      }
+   }
+#endif /* tEXt */
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   if (info_ptr->unknown_chunks_num)
+   {
+      png_unknown_chunk *up;
+
+      png_debug(5, "writing extra chunks");
+
+      for (up = info_ptr->unknown_chunks;
+           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+           up++)
+      {
+         int keep = png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_HAVE_PLTE) &&
+            !(up->location & PNG_HAVE_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+      }
+   }
+#endif
+}
+
+/* Writes the end of the PNG file.  If you don't want to write comments or
+ * time information, you can pass NULL for info.  If you already wrote these
+ * in png_write_info(), do not write them again here.  If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_write_end");
+
+   if (png_ptr == NULL)
+      return;
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "No IDATs written into file");
+
+   /* See if user wants us to write information chunks */
+   if (info_ptr != NULL)
+   {
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+      int i; /* local index variable */
+#endif
+#ifdef PNG_WRITE_tIME_SUPPORTED
+      /* Check to see if user has supplied a time chunk */
+      if ((info_ptr->valid & PNG_INFO_tIME) &&
+         !(png_ptr->mode & PNG_WROTE_tIME))
+         png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+      /* Loop through comment chunks */
+      for (i = 0; i < info_ptr->num_text; i++)
+      {
+         png_debug2(2, "Writing trailer text chunk %d, type %d", i,
+            info_ptr->text[i].compression);
+         /* An internationalized chunk? */
+         if (info_ptr->text[i].compression > 0)
+         {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+            /* Write international chunk */
+            png_write_iTXt(png_ptr,
+                        info_ptr->text[i].compression,
+                        info_ptr->text[i].key,
+                        info_ptr->text[i].lang,
+                        info_ptr->text[i].lang_key,
+                        info_ptr->text[i].text);
+#else
+            png_warning(png_ptr, "Unable to write international text");
+#endif
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+         else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+         {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+            /* Write compressed chunk */
+            png_write_zTXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, 0,
+               info_ptr->text[i].compression);
+#else
+            png_warning(png_ptr, "Unable to write compressed text");
+#endif
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+         }
+         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+         {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+            /* Write uncompressed chunk */
+            png_write_tEXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, 0);
+#else
+            png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+      }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+   if (info_ptr->unknown_chunks_num)
+   {
+      png_unknown_chunk *up;
+
+      png_debug(5, "writing extra chunks");
+
+      for (up = info_ptr->unknown_chunks;
+           up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+           up++)
+      {
+         int keep = png_handle_as_unknown(png_ptr, up->name);
+         if (keep != PNG_HANDLE_CHUNK_NEVER &&
+            up->location && (up->location & PNG_AFTER_IDAT) &&
+            ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+            (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+         {
+            png_write_chunk(png_ptr, up->name, up->data, up->size);
+         }
+      }
+   }
+#endif
+   }
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+
+   /* Write end of PNG file */
+   png_write_IEND(png_ptr);
+   /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
+    * and restored again in libpng-1.2.30, may cause some applications that
+    * do not set png_ptr->output_flush_fn to crash.  If your application
+    * experiences a problem, please try building libpng with
+    * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
+    * png-mng-implement at lists.sf.net .
+    */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#  ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
+   png_flush(png_ptr);
+#  endif
+#endif
+}
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* "tm" structure is not supported on WindowsCE */
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+   png_debug(1, "in png_convert_from_struct_tm");
+
+   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+   ptime->month = (png_byte)(ttime->tm_mon + 1);
+   ptime->day = (png_byte)ttime->tm_mday;
+   ptime->hour = (png_byte)ttime->tm_hour;
+   ptime->minute = (png_byte)ttime->tm_min;
+   ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+   struct tm *tbuf;
+
+   png_debug(1, "in png_convert_from_time_t");
+
+   tbuf = gmtime(&ttime);
+   png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+#ifdef PNG_SETJMP_SUPPORTED
+   volatile
+#endif
+   png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+#endif
+   int i;
+
+   png_debug(1, "in png_create_write_struct");
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif /* PNG_USER_MEM_SUPPORTED */
+   if (png_ptr == NULL)
+      return (NULL);
+
+   /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_ptr->zbuf = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr,
+         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      return (NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   if (user_png_ver)
+   {
+      i = 0;
+      do
+      {
+         if (user_png_ver[i] != png_libpng_ver[i])
+            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+      } while (png_libpng_ver[i++]);
+   }
+
+   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+   {
+     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+      * we must recompile any applications that use any older library version.
+      * For versions after libpng 1.0, we will be compatible, so we need
+      * only check the first digit.
+      */
+     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+     {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+        char msg[80];
+        if (user_png_ver)
+        {
+           png_snprintf(msg, 80,
+              "Application was compiled with png.h from libpng-%.20s",
+              user_png_ver);
+           png_warning(png_ptr, msg);
+        }
+        png_snprintf(msg, 80,
+           "Application  is  running with png.c from libpng-%.20s",
+           png_libpng_ver);
+        png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+        png_ptr->flags = 0;
+#endif
+        png_error(png_ptr,
+           "Incompatible libpng version in application and library");
+     }
+   }
+
+   /* Initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+
+   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+      png_flush_ptr_NULL);
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, png_doublep_NULL, png_doublep_NULL);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Applications that neglect to set up their own setjmp() and then
+    * encounter a png_error() will longjmp here.  Since the jmpbuf is
+    * then meaningless we abort instead of returning.
+    */
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+      PNG_ABORT();
+   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#else
+   if (setjmp(png_ptr->jmpbuf))
+      PNG_ABORT();
+#endif
+#endif
+   return (png_ptr);
+}
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Deprecated. */
+#undef png_write_init
+void PNGAPI
+png_write_init(png_structp png_ptr)
+{
+   /* We only come here via pre-1.0.7-compiled applications */
+   png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size, png_size_t png_info_size)
+{
+   /* We only come here via pre-1.0.12-compiled applications */
+   if (png_ptr == NULL) return;
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+   if (png_sizeof(png_struct) > png_struct_size ||
+      png_sizeof(png_info) > png_info_size)
+   {
+      char msg[80];
+      png_ptr->warning_fn = NULL;
+      if (user_png_ver)
+      {
+         png_snprintf(msg, 80,
+            "Application was compiled with png.h from libpng-%.20s",
+            user_png_ver);
+         png_warning(png_ptr, msg);
+      }
+      png_snprintf(msg, 80,
+         "Application  is  running with png.c from libpng-%.20s",
+         png_libpng_ver);
+      png_warning(png_ptr, msg);
+   }
+#endif
+   if (png_sizeof(png_struct) > png_struct_size)
+   {
+      png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+      png_ptr->flags = 0;
+#endif
+      png_error(png_ptr,
+      "The png struct allocated by the application for writing is"
+      " too small.");
+   }
+   if (png_sizeof(png_info) > png_info_size)
+   {
+      png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+      png_ptr->flags = 0;
+#endif
+      png_error(png_ptr,
+      "The info struct allocated by the application for writing is"
+      " too small.");
+   }
+   png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+
+void PNGAPI
+png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+   png_size_t png_struct_size)
+{
+   png_structp png_ptr = *ptr_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+   int i = 0;
+
+   if (png_ptr == NULL)
+      return;
+
+   do
+   {
+      if (user_png_ver[i] != png_libpng_ver[i])
+      {
+#ifdef PNG_LEGACY_SUPPORTED
+         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+         png_ptr->warning_fn = NULL;
+         png_warning(png_ptr,
+ "Application uses deprecated png_write_init() and should be recompiled.");
+#endif
+      }
+   } while (png_libpng_ver[i++]);
+
+   png_debug(1, "in png_write_init_3");
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+   if (png_sizeof(png_struct) > png_struct_size)
+   {
+      png_destroy_struct(png_ptr);
+      png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+      *ptr_ptr = png_ptr;
+   }
+
+   /* Reset all variables to 0 */
+   png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+   /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+   png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+      png_flush_ptr_NULL);
+
+   /* Initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, png_doublep_NULL, png_doublep_NULL);
+#endif
+}
+
+/* Write a few rows of image data.  If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structp png_ptr, png_bytepp row,
+   png_uint_32 num_rows)
+{
+   png_uint_32 i; /* row counter */
+   png_bytepp rp; /* row pointer */
+
+   png_debug(1, "in png_write_rows");
+
+   if (png_ptr == NULL)
+      return;
+
+   /* Loop through the rows */
+   for (i = 0, rp = row; i < num_rows; i++, rp++)
+   {
+      png_write_row(png_ptr, *rp);
+   }
+}
+
+/* Write the image.  You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i; /* row index */
+   int pass, num_pass; /* pass variables */
+   png_bytepp rp; /* points to current row */
+
+   if (png_ptr == NULL)
+      return;
+
+   png_debug(1, "in png_write_image");
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Initialize interlace handling.  If image is not interlaced,
+    * this will set pass to 1
+    */
+   num_pass = png_set_interlace_handling(png_ptr);
+#else
+   num_pass = 1;
+#endif
+   /* Loop through passes */
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      /* Loop through image */
+      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+      {
+         png_write_row(png_ptr, *rp);
+      }
+   }
+}
+
+/* Called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+   if (png_ptr == NULL)
+      return;
+
+   png_debug2(1, "in png_write_row (row %ld, pass %d)",
+      png_ptr->row_number, png_ptr->pass);
+
+   /* Initialize transformations and other stuff if first time */
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+      /* Make sure we wrote the header info */
+      if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+         png_error(png_ptr,
+            "png_write_info was never called before png_write_row.");
+
+      /* Check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+      if (png_ptr->transformations & PNG_INVERT_MONO)
+         png_warning(png_ptr,
+             "PNG_WRITE_INVERT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+      if (png_ptr->transformations & PNG_FILLER)
+         png_warning(png_ptr,
+             "PNG_WRITE_FILLER_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+    defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (png_ptr->transformations & PNG_PACKSWAP)
+         png_warning(png_ptr,
+             "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+      if (png_ptr->transformations & PNG_PACK)
+         png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+      if (png_ptr->transformations & PNG_SHIFT)
+         png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+      if (png_ptr->transformations & PNG_BGR)
+         png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+      if (png_ptr->transformations & PNG_SWAP_BYTES)
+         png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
+#endif
+
+      png_write_start_row(png_ptr);
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced and not interested in row, return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 0x07)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 0x07) != 4)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 0x03) != 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 0x01))
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   /* Set up row info for transformations */
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->usr_width;
+   png_ptr->row_info.channels = png_ptr->usr_channels;
+   png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+   png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+      png_ptr->row_info.channels);
+
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+      png_ptr->row_info.width);
+
+   png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type);
+   png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width);
+   png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels);
+   png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth);
+   png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth);
+   png_debug1(3, "row_info->rowbytes = %lu", png_ptr->row_info.rowbytes);
+
+   /* Copy user's row into buffer, leaving room for filter byte. */
+   png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+      png_ptr->row_info.rowbytes);
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Handle interlacing */
+   if (png_ptr->interlaced && png_ptr->pass < 6 &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      png_do_write_interlace(&(png_ptr->row_info),
+         png_ptr->row_buf + 1, png_ptr->pass);
+      /* This should always get caught above, but still ... */
+      if (!(png_ptr->row_info.width))
+      {
+         png_write_finish_row(png_ptr);
+         return;
+      }
+   }
+#endif
+
+   /* Handle other transformations */
+   if (png_ptr->transformations)
+      png_do_write_transformations(png_ptr);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+   {
+      /* Intrapixel differencing */
+      png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+   }
+#endif
+
+   /* Find a filter if necessary, filter the row and write it out. */
+   png_write_find_filter(png_ptr, &(png_ptr->row_info));
+
+   if (png_ptr->write_row_fn != NULL)
+      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structp png_ptr, int nrows)
+{
+   png_debug(1, "in png_set_flush");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* Flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structp png_ptr)
+{
+   int wrote_IDAT;
+
+   png_debug(1, "in png_write_flush");
+
+   if (png_ptr == NULL)
+      return;
+   /* We have already written out all of the data */
+   if (png_ptr->row_number >= png_ptr->num_rows)
+      return;
+
+   do
+   {
+      int ret;
+
+      /* Compress the data */
+      ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+      wrote_IDAT = 0;
+
+      /* Check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* Write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf,
+                        png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         wrote_IDAT = 1;
+      }
+   } while(wrote_IDAT == 1);
+
+   /* If there is any data left to be output, write it into a new IDAT */
+   if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+   {
+      /* Write the IDAT and reset the zlib output buffer */
+      png_write_IDAT(png_ptr, png_ptr->zbuf,
+                     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   }
+   png_ptr->flush_rows = 0;
+   png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* Free all memory used by the write */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn = NULL;
+   png_voidp mem_ptr = NULL;
+#endif
+
+   png_debug(1, "in png_destroy_write_struct");
+
+   if (png_ptr_ptr != NULL)
+   {
+      png_ptr = *png_ptr_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+      free_fn = png_ptr->free_fn;
+      mem_ptr = png_ptr->mem_ptr;
+#endif
+   }
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   if (png_ptr != NULL)
+   {
+      free_fn = png_ptr->free_fn;
+      mem_ptr = png_ptr->mem_ptr;
+   }
+#endif
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      if (png_ptr != NULL)
+      {
+        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+        if (png_ptr->num_chunk_list)
+        {
+           png_free(png_ptr, png_ptr->chunk_list);
+           png_ptr->chunk_list = NULL;
+           png_ptr->num_chunk_list = 0;
+        }
+#endif
+      }
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)info_ptr);
+#endif
+      *info_ptr_ptr = NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+      png_write_destroy(png_ptr);
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+         (png_voidp)mem_ptr);
+#else
+      png_destroy_struct((png_voidp)png_ptr);
+#endif
+      *png_ptr_ptr = NULL;
+   }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void /* PRIVATE */
+png_write_destroy(png_structp png_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+   jmp_buf tmp_jmp; /* Save jump buffer */
+#endif
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+#endif
+
+   png_debug(1, "in png_write_destroy");
+
+   /* Free any memory zlib uses */
+   deflateEnd(&png_ptr->zstream);
+
+   /* Free our memory.  png_free checks NULL for us. */
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->row_buf);
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   png_free(png_ptr, png_ptr->prev_row);
+   png_free(png_ptr, png_ptr->sub_row);
+   png_free(png_ptr, png_ptr->up_row);
+   png_free(png_ptr, png_ptr->avg_row);
+   png_free(png_ptr, png_ptr->paeth_row);
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   png_free(png_ptr, png_ptr->prev_filters);
+   png_free(png_ptr, png_ptr->filter_weights);
+   png_free(png_ptr, png_ptr->inv_filter_weights);
+   png_free(png_ptr, png_ptr->filter_costs);
+   png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Reset structure */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
+
+   png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+   png_debug(1, "in png_set_filter");
+
+   if (png_ptr == NULL)
+      return;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      (method == PNG_INTRAPIXEL_DIFFERENCING))
+         method = PNG_FILTER_TYPE_BASE;
+#endif
+   if (method == PNG_FILTER_TYPE_BASE)
+   {
+      switch (filters & (PNG_ALL_FILTERS | 0x07))
+      {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         case 5:
+         case 6:
+         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+         case PNG_FILTER_VALUE_NONE:
+              png_ptr->do_filter = PNG_FILTER_NONE; break;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         case PNG_FILTER_VALUE_SUB:
+              png_ptr->do_filter = PNG_FILTER_SUB; break;
+         case PNG_FILTER_VALUE_UP:
+              png_ptr->do_filter = PNG_FILTER_UP; break;
+         case PNG_FILTER_VALUE_AVG:
+              png_ptr->do_filter = PNG_FILTER_AVG; break;
+         case PNG_FILTER_VALUE_PAETH:
+              png_ptr->do_filter = PNG_FILTER_PAETH; break;
+         default: png_ptr->do_filter = (png_byte)filters; break;
+#else
+         default: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+      }
+
+      /* If we have allocated the row_buf, this means we have already started
+       * with the image and we should have allocated all of the filter buffers
+       * that have been selected.  If prev_row isn't already allocated, then
+       * it is too late to start using the filters that need it, since we
+       * will be missing the data in the previous row.  If an application
+       * wants to start and stop using particular filters during compression,
+       * it should start out with all of the filters, and then add and
+       * remove them after the start of compression.
+       */
+      if (png_ptr->row_buf != NULL)
+      {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+         if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+         {
+            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+              (png_ptr->rowbytes + 1));
+            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Up filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_UP;
+            }
+            else
+            {
+               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Average filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_AVG;
+            }
+            else
+            {
+               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+            }
+         }
+
+         if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+             png_ptr->paeth_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Paeth filter after starting");
+               png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+            }
+            else
+            {
+               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+            }
+         }
+
+         if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+            png_ptr->do_filter = PNG_FILTER_NONE;
+      }
+   }
+   else
+      png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline.  While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */
+void PNGAPI
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+   int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs)
+{
+   int i;
+
+   png_debug(1, "in png_set_filter_heuristics");
+
+   if (png_ptr == NULL)
+      return;
+   if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+   {
+      png_warning(png_ptr, "Unknown filter heuristic method");
+      return;
+   }
+
+   if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+   {
+      heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+   }
+
+   if (num_weights < 0 || filter_weights == NULL ||
+      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+   {
+      num_weights = 0;
+   }
+
+   png_ptr->num_prev_filters = (png_byte)num_weights;
+   png_ptr->heuristic_method = (png_byte)heuristic_method;
+
+   if (num_weights > 0)
+   {
+      if (png_ptr->prev_filters == NULL)
+      {
+         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_byte) * num_weights));
+
+         /* To make sure that the weighting starts out fairly */
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->prev_filters[i] = 255;
+         }
+      }
+
+      if (png_ptr->filter_weights == NULL)
+      {
+         png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+
+         png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+            (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+      }
+
+      for (i = 0; i < num_weights; i++)
+      {
+         if (filter_weights[i] < 0.0)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+         else
+         {
+            png_ptr->inv_filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+            png_ptr->filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+         }
+      }
+   }
+
+   /* If, in the future, there are other filter methods, this would
+    * need to be based on png_ptr->filter.
+    */
+   if (png_ptr->filter_costs == NULL)
+   {
+      png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+         (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+   }
+
+   /* Here is where we set the relative costs of the different filters.  We
+    * should take the desired compression level into account when setting
+    * the costs, so that Paeth, for instance, has a high relative cost at low
+    * compression levels, while it has a lower relative cost at higher
+    * compression settings.  The filter types are in order of increasing
+    * relative cost, so it would be possible to do this with an algorithm.
+    */
+   for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+   {
+      if (filter_costs == NULL || filter_costs[i] < 0.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+      else if (filter_costs[i] >= 1.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+         png_ptr->filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+      }
+   }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structp png_ptr, int level)
+{
+   png_debug(1, "in png_set_compression_level");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+   png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+   png_debug(1, "in png_set_compression_mem_level");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+   png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+   png_debug(1, "in png_set_compression_strategy");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+   png_ptr->zlib_strategy = strategy;
+}
+
+void PNGAPI
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+   if (png_ptr == NULL)
+      return;
+   if (window_bits > 15)
+      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+   else if (window_bits < 8)
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+   /* Avoid libpng bug with 256-byte windows */
+   if (window_bits == 8)
+     {
+       png_warning(png_ptr, "Compression window is being reset to 512");
+       window_bits = 9;
+     }
+#endif
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+   png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structp png_ptr, int method)
+{
+   png_debug(1, "in png_set_compression_method");
+
+   if (png_ptr == NULL)
+      return;
+   if (method != 8)
+      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+   png_ptr->zlib_method = method;
+}
+
+void PNGAPI
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+   if (png_ptr == NULL)
+      return;
+   png_ptr->write_row_fn = write_row_fn;
+}
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+void PNGAPI
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   write_user_transform_fn)
+{
+   png_debug(1, "in png_set_write_user_transform_fn");
+
+   if (png_ptr == NULL)
+      return;
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+              int transforms, voidp params)
+{
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   /* Write the file header information. */
+   png_write_info(png_ptr, info_ptr);
+
+   /* ------ these transformations don't touch the info structure ------- */
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+   /* Invert monochrome pixels */
+   if (transforms & PNG_TRANSFORM_INVERT_MONO)
+      png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   if ((transforms & PNG_TRANSFORM_SHIFT)
+               && (info_ptr->valid & PNG_INFO_sBIT))
+      png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+   /* Pack pixels into bytes */
+   if (transforms & PNG_TRANSFORM_PACKING)
+       png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+   /* Swap location of alpha bytes from ARGB to RGBA */
+   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+      png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+   /* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */
+   if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+      png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+   else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+      png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+   /* Flip BGR pixels to RGB */
+   if (transforms & PNG_TRANSFORM_BGR)
+      png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+   /* Swap bytes of 16-bit files to most significant byte first */
+   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+      png_set_swap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+   /* Swap bits of 1, 2, 4 bit packed pixel formats */
+   if (transforms & PNG_TRANSFORM_PACKSWAP)
+      png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+   /* Invert the alpha channel from opacity to transparency */
+   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+      png_set_invert_alpha(png_ptr);
+#endif
+
+   /* ----------------------- end of transformations ------------------- */
+
+   /* Write the bits */
+   if (info_ptr->valid & PNG_INFO_IDAT)
+       png_write_image(png_ptr, info_ptr->row_pointers);
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+
+   transforms = transforms; /* Quiet compiler warnings */
+   params = params;
+}
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwtran.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwtran.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwtran.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,582 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Transform the data according to the user's wishes.  The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_write_transformations");
+
+   if (png_ptr == NULL)
+      return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+      if (png_ptr->write_user_transform_fn != NULL)
+        (*(png_ptr->write_user_transform_fn)) /* User write transform
+                                                 function */
+          (png_ptr,                    /* png_ptr */
+           &(png_ptr->row_info),       /* row_info:     */
+             /*  png_uint_32 width;          width of row */
+             /*  png_uint_32 rowbytes;       number of bytes in row */
+             /*  png_byte color_type;        color type of pixels */
+             /*  png_byte bit_depth;         bit depth of samples */
+             /*  png_byte channels;          number of channels (1-4) */
+             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
+           png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->flags);
+#endif
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_PACK_SUPPORTED
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->bit_depth);
+#endif
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_BGR_SUPPORTED
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
+ * row_info bit depth should be 8 (one pixel per byte).  The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+   png_debug(1, "in png_do_pack");
+
+   if (row_info->bit_depth == 8 &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+      row_info->channels == 1)
+   {
+      switch ((int)bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp, dp;
+            int mask, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            mask = 0x80;
+            v = 0;
+
+            for (i = 0; i < row_width; i++)
+            {
+               if (*sp != 0)
+                  v |= mask;
+               sp++;
+               if (mask > 1)
+                  mask >>= 1;
+               else
+               {
+                  mask = 0x80;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+            }
+            if (mask != 0x80)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 6;
+            v = 0;
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x03);
+               v |= (value << shift);
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 2;
+               sp++;
+            }
+            if (shift != 6)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            sp = row;
+            dp = row;
+            shift = 4;
+            v = 0;
+            for (i = 0; i < row_width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x0f);
+               v |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 4;
+
+               sp++;
+            }
+            if (shift != 4)
+               *dp = (png_byte)v;
+            break;
+         }
+      }
+      row_info->bit_depth = (png_byte)bit_depth;
+      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+         row_info->width);
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+/* Shift pixel values to take advantage of whole range.  Pass the
+ * true number of bits in bit_depth.  The row should be packed
+ * according to row_info->bit_depth.  Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+   png_debug(1, "in png_do_shift");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL &&
+#else
+   if (
+#endif
+      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift_start[4], shift_dec[4];
+      int channels = 0;
+
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->red;
+         shift_dec[channels] = bit_depth->red;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->green;
+         shift_dec[channels] = bit_depth->green;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+         shift_dec[channels] = bit_depth->blue;
+         channels++;
+      }
+      else
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+         shift_dec[channels] = bit_depth->gray;
+         channels++;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+         shift_dec[channels] = bit_depth->alpha;
+         channels++;
+      }
+
+      /* With low row depths, could only be grayscale, so one channel */
+      if (row_info->bit_depth < 8)
+      {
+         png_bytep bp = row;
+         png_uint_32 i;
+         png_byte mask;
+         png_uint_32 row_bytes = row_info->rowbytes;
+
+         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+            mask = 0x55;
+         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+            mask = 0x11;
+         else
+            mask = 0xff;
+
+         for (i = 0; i < row_bytes; i++, bp++)
+         {
+            png_uint_16 v;
+            int j;
+
+            v = *bp;
+            *bp = 0;
+            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+            {
+               if (j > 0)
+                  *bp |= (png_byte)((v << j) & 0xff);
+               else
+                  *bp |= (png_byte)((v >> (-j)) & mask);
+            }
+         }
+      }
+      else if (row_info->bit_depth == 8)
+      {
+         png_bytep bp = row;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (i = 0; i < istop; i++, bp++)
+         {
+
+            png_uint_16 v;
+            int j;
+            int c = (int)(i%channels);
+
+            v = *bp;
+            *bp = 0;
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  *bp |= (png_byte)((v << j) & 0xff);
+               else
+                  *bp |= (png_byte)((v >> (-j)) & 0xff);
+            }
+         }
+      }
+      else
+      {
+         png_bytep bp;
+         png_uint_32 i;
+         png_uint_32 istop = channels * row_info->width;
+
+         for (bp = row, i = 0; i < istop; i++)
+         {
+            int c = (int)(i%channels);
+            png_uint_16 value, v;
+            int j;
+
+            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+            value = 0;
+            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+            {
+               if (j > 0)
+                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+               else
+                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+            }
+            *bp++ = (png_byte)(value >> 8);
+            *bp++ = (png_byte)(value & 0xff);
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_swap_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from ARGB to RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AARRGGBB to RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from AG to GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AAGG to GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               png_byte save[2];
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_invert_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=3; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=6; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            for (i = 0, sp = dp = row; i < row_width; i++)
+            {
+               /* Does nothing
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               */
+               sp+=2; dp = sp;
+               *(dp++) = (png_byte)(255 - *(sp++));
+               *(dp++) = (png_byte)(255 - *(sp++));
+            }
+         }
+      }
+   }
+}
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing  */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_intrapixel");
+
+   if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp)   = (png_byte)((*rp     - *(rp+1))&0xff);
+            *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp  ) << 8) | *(rp+1);
+            png_uint_32 s1   = (*(rp+2) << 8) | *(rp+3);
+            png_uint_32 s2   = (*(rp+4) << 8) | *(rp+5);
+            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+            *(rp  ) = (png_byte)((red >> 8) & 0xff);
+            *(rp+1) = (png_byte)(red & 0xff);
+            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp+5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwutil.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngwutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2832 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Place a 32-bit number into a buffer in PNG byte order.  We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format.  If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+   buf[0] = (png_byte)((i >> 8) & 0xff);
+   buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Simple function to write the signature.  If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void /* PRIVATE */
+png_write_sig(png_structp png_ptr)
+{
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+   /* Write the rest of the 8 byte signature */
+   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+      (png_size_t)(8 - png_ptr->sig_bytes));
+   if (png_ptr->sig_bytes < 3)
+      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Write a PNG chunk all at once.  The type is an array of ASCII characters
+ * representing the chunk name.  The array must be at least 4 bytes in
+ * length, and does not need to be null terminated.  To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined.  The length is the length of the data.
+ * All the data must be present.  If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+   png_bytep data, png_size_t length)
+{
+   if (png_ptr == NULL)
+      return;
+   png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+   png_write_chunk_data(png_ptr, data, (png_size_t)length);
+   png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk.  The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void PNGAPI
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+   png_uint_32 length)
+{
+   png_byte buf[8];
+
+   png_debug2(0, "Writing %s chunk, length = %lu", chunk_name,
+      (unsigned long)length);
+
+   if (png_ptr == NULL)
+      return;
+
+
+   /* Write the length and the chunk name */
+   png_save_uint_32(buf, length);
+   png_memcpy(buf + 4, chunk_name, 4);
+   png_write_data(png_ptr, buf, (png_size_t)8);
+   /* Put the chunk name into png_ptr->chunk_name */
+   png_memcpy(png_ptr->chunk_name, chunk_name, 4);
+   /* Reset the crc and run it over the chunk name */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void PNGAPI
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   /* Write the data, and run the CRC over it */
+   if (png_ptr == NULL)
+      return;
+   if (data != NULL && length > 0)
+   {
+      png_write_data(png_ptr, data, length);
+      /* Update the CRC after writing the data,
+       * in case that the user I/O routine alters it.
+       */
+      png_calculate_crc(png_ptr, data, length);
+   }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void PNGAPI
+png_write_chunk_end(png_structp png_ptr)
+{
+   png_byte buf[4];
+
+   if (png_ptr == NULL) return;
+
+   /* Write the crc in a single operation */
+   png_save_uint_32(buf, png_ptr->crc);
+
+   png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/* This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+   char *input;   /* The uncompressed input data */
+   int input_len;   /* Its length */
+   int num_output_ptr; /* Number of output pointers used */
+   int max_output_ptr; /* Size of output_ptr */
+   png_charpp output_ptr; /* Array of pointers to output */
+} compression_state;
+
+/* Compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+        png_charp text, png_size_t text_len, int compression,
+        compression_state *comp)
+{
+   int ret;
+
+   comp->num_output_ptr = 0;
+   comp->max_output_ptr = 0;
+   comp->output_ptr = NULL;
+   comp->input = NULL;
+   comp->input_len = 0;
+
+   /* We may just want to pass the text right through */
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+       comp->input = text;
+       comp->input_len = text_len;
+       return((int)text_len);
+   }
+
+   if (compression >= PNG_TEXT_COMPRESSION_LAST)
+   {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+      char msg[50];
+      png_snprintf(msg, 50, "Unknown compression type %d", compression);
+      png_warning(png_ptr, msg);
+#else
+      png_warning(png_ptr, "Unknown compression type");
+#endif
+   }
+
+   /* We can't write the chunk until we find out how much data we have,
+    * which means we need to run the compressor first and save the
+    * output.  This shouldn't be a problem, as the vast majority of
+    * comments should be reasonable, but we will set up an array of
+    * malloc'd pointers to be sure.
+    *
+    * If we knew the application was well behaved, we could simplify this
+    * greatly by assuming we can always malloc an output buffer large
+    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+    * and malloc this directly.  The only time this would be a bad idea is
+    * if we can't malloc more than 64K and we have 64K of random input
+    * data, or if the input string is incredibly large (although this
+    * wouldn't cause a failure, just a slowdown due to swapping).
+    */
+
+   /* Set up the compression buffers */
+   png_ptr->zstream.avail_in = (uInt)text_len;
+   png_ptr->zstream.next_in = (Bytef *)text;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+   /* This is the same compression loop as in png_write_row() */
+   do
+   {
+      /* Compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      if (ret != Z_OK)
+      {
+         /* Error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* Check to see if we need more room */
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* Make sure the output array has room */
+         if (comp->num_output_ptr >= comp->max_output_ptr)
+         {
+            int old_max;
+
+            old_max = comp->max_output_ptr;
+            comp->max_output_ptr = comp->num_output_ptr + 4;
+            if (comp->output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = comp->output_ptr;
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)
+                  (comp->max_output_ptr * png_sizeof(png_charpp)));
+               png_memcpy(comp->output_ptr, old_ptr, old_max
+                  * png_sizeof(png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)
+                  (comp->max_output_ptr * png_sizeof(png_charp)));
+         }
+
+         /* Save the data */
+         comp->output_ptr[comp->num_output_ptr] =
+            (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         comp->num_output_ptr++;
+
+         /* and reset the buffer */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   /* Continue until we don't have any more to compress */
+   } while (png_ptr->zstream.avail_in);
+
+   /* Finish the compression */
+   do
+   {
+      /* Tell zlib we are finished */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+      if (ret == Z_OK)
+      {
+         /* Check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            /* Check to make sure our output array has room */
+            if (comp->num_output_ptr >= comp->max_output_ptr)
+            {
+               int old_max;
+
+               old_max = comp->max_output_ptr;
+               comp->max_output_ptr = comp->num_output_ptr + 4;
+               if (comp->output_ptr != NULL)
+               {
+                  png_charpp old_ptr;
+
+                  old_ptr = comp->output_ptr;
+                  /* This could be optimized to realloc() */
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr *
+                     png_sizeof(png_charp)));
+                  png_memcpy(comp->output_ptr, old_ptr,
+                     old_max * png_sizeof(png_charp));
+                  png_free(png_ptr, old_ptr);
+               }
+               else
+                  comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                     (png_uint_32)(comp->max_output_ptr *
+                     png_sizeof(png_charp)));
+            }
+
+            /* Save the data */
+            comp->output_ptr[comp->num_output_ptr] =
+               (png_charp)png_malloc(png_ptr,
+               (png_uint_32)png_ptr->zbuf_size);
+            png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+               png_ptr->zbuf_size);
+            comp->num_output_ptr++;
+
+            /* and reset the buffer pointers */
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+         }
+      }
+      else if (ret != Z_STREAM_END)
+      {
+         /* We got an error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* Text length is number of buffers plus last buffer */
+   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+   return((int)text_len);
+}
+
+/* Ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+   int i;
+
+   /* Handle the no-compression case */
+   if (comp->input)
+   {
+      png_write_chunk_data(png_ptr, (png_bytep)comp->input,
+                            (png_size_t)comp->input_len);
+      return;
+   }
+
+   /* Write saved output buffers, if any */
+   for (i = 0; i < comp->num_output_ptr; i++)
+   {
+      png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i],
+         (png_size_t)png_ptr->zbuf_size);
+      png_free(png_ptr, comp->output_ptr[i]);
+       comp->output_ptr[i]=NULL;
+   }
+   if (comp->max_output_ptr != 0)
+      png_free(png_ptr, comp->output_ptr);
+       comp->output_ptr=NULL;
+   /* Write anything left in zbuf */
+   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+      png_write_chunk_data(png_ptr, png_ptr->zbuf,
+         (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+
+   /* Reset zlib for another zTXt/iTXt or image data */
+   deflateReset(&png_ptr->zstream);
+   png_ptr->zstream.data_type = Z_BINARY;
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.  Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+   int bit_depth, int color_type, int compression_type, int filter_type,
+   int interlace_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IHDR;
+#endif
+   int ret;
+
+   png_byte buf[13]; /* Buffer to store the IHDR info */
+
+   png_debug(1, "in png_write_IHDR");
+
+   /* Check that we have valid input data from the application info */
+   switch (color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8:
+            case 16: png_ptr->channels = 1; break;
+            default: png_error(png_ptr,
+                         "Invalid bit depth for grayscale image");
+         }
+         break;
+      case PNG_COLOR_TYPE_RGB:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGB image");
+         png_ptr->channels = 3;
+         break;
+      case PNG_COLOR_TYPE_PALETTE:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8: png_ptr->channels = 1; break;
+            default: png_error(png_ptr, "Invalid bit depth for paletted image");
+         }
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+         png_ptr->channels = 2;
+         break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGBA image");
+         png_ptr->channels = 4;
+         break;
+      default:
+         png_error(png_ptr, "Invalid image color type specified");
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid compression type specified");
+      compression_type = PNG_COMPRESSION_TYPE_BASE;
+   }
+
+   /* Write filter_method 64 (intrapixel differencing) only if
+    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+    * 2. Libpng did not write a PNG signature (this filter_method is only
+    *    used in PNG datastreams that are embedded in MNG datastreams) and
+    * 3. The application called png_permit_mng_features with a mask that
+    *    included PNG_FLAG_MNG_FILTER_64 and
+    * 4. The filter_method is 64 and
+    * 5. The color_type is RGB or RGBA
+    */
+   if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+      !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+      ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+      (color_type == PNG_COLOR_TYPE_RGB ||
+       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+      (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+      filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid filter type specified");
+      filter_type = PNG_FILTER_TYPE_BASE;
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   if (interlace_type != PNG_INTERLACE_NONE &&
+      interlace_type != PNG_INTERLACE_ADAM7)
+   {
+      png_warning(png_ptr, "Invalid interlace type specified");
+      interlace_type = PNG_INTERLACE_ADAM7;
+   }
+#else
+   interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+   /* Save the relevent information */
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->color_type = (png_byte)color_type;
+   png_ptr->interlaced = (png_byte)interlace_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+   png_ptr->filter_type = (png_byte)filter_type;
+#endif
+   png_ptr->compression_type = (png_byte)compression_type;
+   png_ptr->width = width;
+   png_ptr->height = height;
+
+   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+   /* Set the usr info, so any transformations can modify it */
+   png_ptr->usr_width = png_ptr->width;
+   png_ptr->usr_bit_depth = png_ptr->bit_depth;
+   png_ptr->usr_channels = png_ptr->channels;
+
+   /* Pack the header information into the buffer */
+   png_save_uint_32(buf, width);
+   png_save_uint_32(buf + 4, height);
+   buf[8] = (png_byte)bit_depth;
+   buf[9] = (png_byte)color_type;
+   buf[10] = (png_byte)compression_type;
+   buf[11] = (png_byte)filter_type;
+   buf[12] = (png_byte)interlace_type;
+
+   /* Write the chunk */
+   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
+
+   /* Initialize zlib with PNG info */
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+   if (!(png_ptr->do_filter))
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+         png_ptr->bit_depth < 8)
+         png_ptr->do_filter = PNG_FILTER_NONE;
+      else
+         png_ptr->do_filter = PNG_ALL_FILTERS;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+   {
+      if (png_ptr->do_filter != PNG_FILTER_NONE)
+         png_ptr->zlib_strategy = Z_FILTERED;
+      else
+         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+      png_ptr->zlib_mem_level = 8;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+      png_ptr->zlib_window_bits = 15;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+      png_ptr->zlib_method = 8;
+   ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+         png_ptr->zlib_method, png_ptr->zlib_window_bits,
+         png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+   if (ret != Z_OK)
+   {
+      if (ret == Z_VERSION_ERROR) png_error(png_ptr,
+          "zlib failed to initialize compressor -- version error");
+      if (ret == Z_STREAM_ERROR) png_error(png_ptr,
+           "zlib failed to initialize compressor -- stream error");
+      if (ret == Z_MEM_ERROR) png_error(png_ptr,
+           "zlib failed to initialize compressor -- mem error");
+      png_error(png_ptr, "zlib failed to initialize compressor");
+   }
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   /* libpng is not interested in zstream.data_type */
+   /* Set it to a predefined value, to avoid its evaluation inside zlib */
+   png_ptr->zstream.data_type = Z_BINARY;
+
+   png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* Write the palette.  We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_PLTE;
+#endif
+   png_uint_32 i;
+   png_colorp pal_ptr;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_PLTE");
+
+   if ((
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+        !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+        num_pal == 0) || num_pal > 256)
+   {
+     if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+     {
+        png_error(png_ptr, "Invalid number of colors in palette");
+     }
+     else
+     {
+        png_warning(png_ptr, "Invalid number of colors in palette");
+        return;
+     }
+   }
+
+   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+   {
+      png_warning(png_ptr,
+        "Ignoring request to write a PLTE chunk in grayscale PNG");
+      return;
+   }
+
+   png_ptr->num_palette = (png_uint_16)num_pal;
+   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_PLTE,
+     (png_uint_32)(num_pal * 3));
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+   {
+      buf[0] = pal_ptr->red;
+      buf[1] = pal_ptr->green;
+      buf[2] = pal_ptr->blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+#else
+   /* This is a little slower but some buggy compilers need to do this
+    * instead
+    */
+   pal_ptr=palette;
+   for (i = 0; i < num_pal; i++)
+   {
+      buf[0] = pal_ptr[i].red;
+      buf[1] = pal_ptr[i].green;
+      buf[2] = pal_ptr[i].blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+#endif
+   png_write_chunk_end(png_ptr);
+   png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* Write an IDAT chunk */
+void /* PRIVATE */
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
+
+   png_debug(1, "in png_write_IDAT");
+
+   /* Optimize the CMF field in the zlib stream. */
+   /* This hack of the zlib stream is compliant to the stream specification. */
+   if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+       png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+   {
+      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
+      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+      {
+         /* Avoid memory underflows and multiplication overflows.
+          *
+          * The conditions below are practically always satisfied;
+          * however, they still must be checked.
+          */
+         if (length >= 2 &&
+             png_ptr->height < 16384 && png_ptr->width < 16384)
+         {
+            png_uint_32 uncompressed_idat_size = png_ptr->height *
+               ((png_ptr->width *
+               png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
+            unsigned int z_cinfo = z_cmf >> 4;
+            unsigned int half_z_window_size = 1 << (z_cinfo + 7);
+            while (uncompressed_idat_size <= half_z_window_size &&
+                   half_z_window_size >= 256)
+            {
+               z_cinfo--;
+               half_z_window_size >>= 1;
+            }
+            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+            if (data[0] != (png_byte)z_cmf)
+            {
+               data[0] = (png_byte)z_cmf;
+               data[1] &= 0xe0;
+               data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
+            }
+         }
+      }
+      else
+         png_error(png_ptr,
+            "Invalid zlib compression method or flags in IDAT");
+   }
+
+   png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
+   png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* Write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IEND;
+#endif
+
+   png_debug(1, "in png_write_IEND");
+
+   png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
+     (png_size_t)0);
+   png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+/* Write a gAMA chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
+   png_uint_32 igamma;
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA");
+
+   /* file_gamma is saved in 1/100,000ths */
+   igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+   png_save_uint_32(buf, igamma);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA");
+
+   /* file_gamma is saved in 1/100,000ths */
+   png_save_uint_32(buf, (png_uint_32)file_gamma);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+/* Write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sRGB;
+#endif
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_sRGB");
+
+   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
+         png_warning(png_ptr,
+            "Invalid sRGB rendering intent specified");
+   buf[0]=(png_byte)srgb_intent;
+   png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+/* Write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+   png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iCCP;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   compression_state comp;
+   int embedded_profile_len = 0;
+
+   png_debug(1, "in png_write_iCCP");
+
+   comp.num_output_ptr = 0;
+   comp.max_output_ptr = 0;
+   comp.output_ptr = NULL;
+   comp.input = NULL;
+   comp.input_len = 0;
+
+   if ((name_len = png_check_keyword(png_ptr, name,
+      &new_name)) == 0)
+      return;
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+   if (profile == NULL)
+      profile_len = 0;
+
+   if (profile_len > 3)
+      embedded_profile_len =
+          ((*( (png_bytep)profile    ))<<24) |
+          ((*( (png_bytep)profile + 1))<<16) |
+          ((*( (png_bytep)profile + 2))<< 8) |
+          ((*( (png_bytep)profile + 3))    );
+
+   if (embedded_profile_len < 0)
+   {
+      png_warning(png_ptr,
+        "Embedded profile length in iCCP chunk is negative");
+      png_free(png_ptr, new_name);
+      return;
+   }
+
+   if (profile_len < embedded_profile_len)
+   {
+      png_warning(png_ptr,
+        "Embedded profile length too large in iCCP chunk");
+      png_free(png_ptr, new_name);
+      return;
+   }
+
+   if (profile_len > embedded_profile_len)
+   {
+      png_warning(png_ptr,
+        "Truncating profile to actual length in iCCP chunk");
+      profile_len = embedded_profile_len;
+   }
+
+   if (profile_len)
+      profile_len = png_text_compress(png_ptr, profile,
+        (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
+
+   /* Make sure we include the NULL after the name and the compression type */
+   png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
+          (png_uint_32)(name_len + profile_len + 2));
+   new_name[name_len + 1] = 0x00;
+   png_write_chunk_data(png_ptr, (png_bytep)new_name,
+     (png_size_t)(name_len + 2));
+
+   if (profile_len)
+      png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+/* Write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sPLT;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   png_byte entrybuf[10];
+   int entry_size = (spalette->depth == 8 ? 6 : 10);
+   int palette_size = entry_size * spalette->nentries;
+   png_sPLT_entryp ep;
+#ifndef PNG_POINTER_INDEXING_SUPPORTED
+   int i;
+#endif
+
+   png_debug(1, "in png_write_sPLT");
+
+   if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0)
+      return;
+
+   /* Make sure we include the NULL after the name */
+   png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
+     (png_uint_32)(name_len + 2 + palette_size));
+   png_write_chunk_data(png_ptr, (png_bytep)new_name,
+     (png_size_t)(name_len + 1));
+   png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1);
+
+   /* Loop through each palette entry, writing appropriately */
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
+   {
+      if (spalette->depth == 8)
+      {
+          entrybuf[0] = (png_byte)ep->red;
+          entrybuf[1] = (png_byte)ep->green;
+          entrybuf[2] = (png_byte)ep->blue;
+          entrybuf[3] = (png_byte)ep->alpha;
+          png_save_uint_16(entrybuf + 4, ep->frequency);
+      }
+      else
+      {
+          png_save_uint_16(entrybuf + 0, ep->red);
+          png_save_uint_16(entrybuf + 2, ep->green);
+          png_save_uint_16(entrybuf + 4, ep->blue);
+          png_save_uint_16(entrybuf + 6, ep->alpha);
+          png_save_uint_16(entrybuf + 8, ep->frequency);
+      }
+      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+   }
+#else
+   ep=spalette->entries;
+   for (i=0; i>spalette->nentries; i++)
+   {
+      if (spalette->depth == 8)
+      {
+          entrybuf[0] = (png_byte)ep[i].red;
+          entrybuf[1] = (png_byte)ep[i].green;
+          entrybuf[2] = (png_byte)ep[i].blue;
+          entrybuf[3] = (png_byte)ep[i].alpha;
+          png_save_uint_16(entrybuf + 4, ep[i].frequency);
+      }
+      else
+      {
+          png_save_uint_16(entrybuf + 0, ep[i].red);
+          png_save_uint_16(entrybuf + 2, ep[i].green);
+          png_save_uint_16(entrybuf + 4, ep[i].blue);
+          png_save_uint_16(entrybuf + 6, ep[i].alpha);
+          png_save_uint_16(entrybuf + 8, ep[i].frequency);
+      }
+      png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+   }
+#endif
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+/* Write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sBIT;
+#endif
+   png_byte buf[4];
+   png_size_t size;
+
+   png_debug(1, "in png_write_sBIT");
+
+   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_byte maxbits;
+
+      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+                png_ptr->usr_bit_depth);
+      if (sbit->red == 0 || sbit->red > maxbits ||
+          sbit->green == 0 || sbit->green > maxbits ||
+          sbit->blue == 0 || sbit->blue > maxbits)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->red;
+      buf[1] = sbit->green;
+      buf[2] = sbit->blue;
+      size = 3;
+   }
+   else
+   {
+      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->gray;
+      size = 1;
+   }
+
+   if (color_type & PNG_COLOR_MASK_ALPHA)
+   {
+      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[size++] = sbit->alpha;
+   }
+
+   png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
+}
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+/* Write the cHRM chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
+   png_byte buf[32];
+
+   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y,
+      int_green_x, int_green_y, int_blue_x, int_blue_y;
+
+   png_debug(1, "in png_write_cHRM");
+
+   int_white_x = (png_uint_32)(white_x * 100000.0 + 0.5);
+   int_white_y = (png_uint_32)(white_y * 100000.0 + 0.5);
+   int_red_x   = (png_uint_32)(red_x   * 100000.0 + 0.5);
+   int_red_y   = (png_uint_32)(red_y   * 100000.0 + 0.5);
+   int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5);
+   int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5);
+   int_blue_x  = (png_uint_32)(blue_x  * 100000.0 + 0.5);
+   int_blue_y  = (png_uint_32)(blue_y  * 100000.0 + 0.5);
+
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+   if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y,
+      int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y))
+#endif
+   {
+      /* Each value is saved in 1/100,000ths */
+
+      png_save_uint_32(buf, int_white_x);
+      png_save_uint_32(buf + 4, int_white_y);
+
+      png_save_uint_32(buf + 8, int_red_x);
+      png_save_uint_32(buf + 12, int_red_y);
+
+      png_save_uint_32(buf + 16, int_green_x);
+      png_save_uint_32(buf + 20, int_green_y);
+
+      png_save_uint_32(buf + 24, int_blue_x);
+      png_save_uint_32(buf + 28, int_blue_y);
+
+      png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+   }
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+   png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+   png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+   png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
+   png_byte buf[32];
+
+   png_debug(1, "in png_write_cHRM");
+
+   /* Each value is saved in 1/100,000ths */
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+   if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
+      green_x, green_y, blue_x, blue_y))
+#endif
+   {
+      png_save_uint_32(buf, (png_uint_32)white_x);
+      png_save_uint_32(buf + 4, (png_uint_32)white_y);
+
+      png_save_uint_32(buf + 8, (png_uint_32)red_x);
+      png_save_uint_32(buf + 12, (png_uint_32)red_y);
+
+      png_save_uint_32(buf + 16, (png_uint_32)green_x);
+      png_save_uint_32(buf + 20, (png_uint_32)green_y);
+
+      png_save_uint_32(buf + 24, (png_uint_32)blue_x);
+      png_save_uint_32(buf + 28, (png_uint_32)blue_y);
+
+      png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+   }
+}
+#endif
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+/* Write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+   int num_trans, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tRNS;
+#endif
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_tRNS");
+
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Invalid number of transparent colors specified");
+         return;
+      }
+      /* Write the chunk out as it is */
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans,
+        (png_size_t)num_trans);
+   }
+   else if (color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      /* One 16 bit value */
+      if (tran->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+         return;
+      }
+      png_save_uint_16(buf, tran->gray);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
+   }
+   else if (color_type == PNG_COLOR_TYPE_RGB)
+   {
+      /* Three 16 bit values */
+      png_save_uint_16(buf, tran->red);
+      png_save_uint_16(buf + 2, tran->green);
+      png_save_uint_16(buf + 4, tran->blue);
+      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+         return;
+      }
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
+   }
+   else
+   {
+      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+/* Write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_bKGD;
+#endif
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_bKGD");
+
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+          (png_ptr->num_palette ||
+          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+         back->index >= png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Invalid background palette index");
+         return;
+      }
+      buf[0] = back->index;
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
+   }
+   else if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_save_uint_16(buf, back->red);
+      png_save_uint_16(buf + 2, back->green);
+      png_save_uint_16(buf + 4, back->blue);
+      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+         return;
+      }
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
+   }
+   else
+   {
+      if (back->gray >= (1 << png_ptr->bit_depth))
+      {
+         png_warning(png_ptr,
+           "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+         return;
+      }
+      png_save_uint_16(buf, back->gray);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+/* Write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_hIST;
+#endif
+   int i;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_hIST");
+
+   if (num_hist > (int)png_ptr->num_palette)
+   {
+      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
+         png_ptr->num_palette);
+      png_warning(png_ptr, "Invalid number of histogram entries specified");
+      return;
+   }
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_hIST,
+     (png_uint_32)(num_hist * 2));
+   for (i = 0; i < num_hist; i++)
+   {
+      png_save_uint_16(buf, hist[i]);
+      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+   }
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine.  This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t /* PRIVATE */
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+   png_size_t key_len;
+   png_charp kp, dp;
+   int kflag;
+   int kwarn=0;
+
+   png_debug(1, "in png_check_keyword");
+
+   *new_key = NULL;
+
+   if (key == NULL || (key_len = png_strlen(key)) == 0)
+   {
+      png_warning(png_ptr, "zero length keyword");
+      return ((png_size_t)0);
+   }
+
+   png_debug1(2, "Keyword to be checked is '%s'", key);
+
+   *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
+   if (*new_key == NULL)
+   {
+      png_warning(png_ptr, "Out of memory while procesing keyword");
+      return ((png_size_t)0);
+   }
+
+   /* Replace non-printing characters with a blank and print a warning */
+   for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+   {
+      if ((png_byte)*kp < 0x20 ||
+         ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
+      {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+         char msg[40];
+
+         png_snprintf(msg, 40,
+           "invalid keyword character 0x%02X", (png_byte)*kp);
+         png_warning(png_ptr, msg);
+#else
+         png_warning(png_ptr, "invalid character in keyword");
+#endif
+         *dp = ' ';
+      }
+      else
+      {
+         *dp = *kp;
+      }
+   }
+   *dp = '\0';
+
+   /* Remove any trailing white space. */
+   kp = *new_key + key_len - 1;
+   if (*kp == ' ')
+   {
+      png_warning(png_ptr, "trailing spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+         *(kp--) = '\0';
+         key_len--;
+      }
+   }
+
+   /* Remove any leading white space. */
+   kp = *new_key;
+   if (*kp == ' ')
+   {
+      png_warning(png_ptr, "leading spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+         kp++;
+         key_len--;
+      }
+   }
+
+   png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
+
+   /* Remove multiple internal spaces. */
+   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+   {
+      if (*kp == ' ' && kflag == 0)
+      {
+         *(dp++) = *kp;
+         kflag = 1;
+      }
+      else if (*kp == ' ')
+      {
+         key_len--;
+         kwarn=1;
+      }
+      else
+      {
+         *(dp++) = *kp;
+         kflag = 0;
+      }
+   }
+   *dp = '\0';
+   if (kwarn)
+      png_warning(png_ptr, "extra interior spaces removed from keyword");
+
+   if (key_len == 0)
+   {
+      png_free(png_ptr, *new_key);
+       *new_key=NULL;
+      png_warning(png_ptr, "Zero length keyword");
+   }
+
+   if (key_len > 79)
+   {
+      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
+      (*new_key)[79] = '\0';
+      key_len = 79;
+   }
+
+   return (key_len);
+}
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+/* Write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tEXt;
+#endif
+   png_size_t key_len;
+   png_charp new_key;
+
+   png_debug(1, "in png_write_tEXt");
+
+   if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+      return;
+
+   if (text == NULL || *text == '\0')
+      text_len = 0;
+   else
+      text_len = png_strlen(text);
+
+   /* Make sure we include the 0 after the key */
+   png_write_chunk_start(png_ptr, (png_bytep)png_tEXt,
+      (png_uint_32)(key_len + text_len + 1));
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key,
+     (png_size_t)(key_len + 1));
+   if (text_len)
+      png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+}
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+/* Write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len, int compression)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_zTXt;
+#endif
+   png_size_t key_len;
+   char buf[1];
+   png_charp new_key;
+   compression_state comp;
+
+   png_debug(1, "in png_write_zTXt");
+
+   comp.num_output_ptr = 0;
+   comp.max_output_ptr = 0;
+   comp.output_ptr = NULL;
+   comp.input = NULL;
+   comp.input_len = 0;
+
+   if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_free(png_ptr, new_key);
+      return;
+   }
+
+   if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+   {
+      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+      png_free(png_ptr, new_key);
+      return;
+   }
+
+   text_len = png_strlen(text);
+
+   /* Compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression,
+       &comp);
+
+   /* Write start of chunk */
+   png_write_chunk_start(png_ptr, (png_bytep)png_zTXt,
+     (png_uint_32)(key_len+text_len + 2));
+   /* Write key */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key,
+     (png_size_t)(key_len + 1));
+   png_free(png_ptr, new_key);
+
+   buf[0] = (png_byte)compression;
+   /* Write compression */
+   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+   /* Write the compressed data */
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   /* Close the chunk */
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+/* Write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+    png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iTXt;
+#endif
+   png_size_t lang_len, key_len, lang_key_len, text_len;
+   png_charp new_lang;
+   png_charp new_key = NULL;
+   png_byte cbuf[2];
+   compression_state comp;
+
+   png_debug(1, "in png_write_iTXt");
+
+   comp.num_output_ptr = 0;
+   comp.max_output_ptr = 0;
+   comp.output_ptr = NULL;
+   comp.input = NULL;
+
+   if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+      return;
+
+   if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
+   {
+      png_warning(png_ptr, "Empty language field in iTXt chunk");
+      new_lang = NULL;
+      lang_len = 0;
+   }
+
+   if (lang_key == NULL)
+      lang_key_len = 0;
+   else
+      lang_key_len = png_strlen(lang_key);
+
+   if (text == NULL)
+      text_len = 0;
+   else
+      text_len = png_strlen(text);
+
+   /* Compute the compressed data; do it now for the length */
+   text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+      &comp);
+
+
+   /* Make sure we include the compression flag, the compression byte,
+    * and the NULs after the key, lang, and lang_key parts */
+
+   png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+          (png_uint_32)(
+        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+        + key_len
+        + lang_len
+        + lang_key_len
+        + text_len));
+
+   /* We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_key,
+     (png_size_t)(key_len + 1));
+
+   /* Set the compression flag */
+   if (compression == PNG_ITXT_COMPRESSION_NONE || \
+       compression == PNG_TEXT_COMPRESSION_NONE)
+       cbuf[0] = 0;
+   else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+       cbuf[0] = 1;
+   /* Set the compression method */
+   cbuf[1] = 0;
+   png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
+
+   cbuf[0] = 0;
+   png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf),
+     (png_size_t)(lang_len + 1));
+   png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf),
+     (png_size_t)(lang_key_len + 1));
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+   png_free(png_ptr, new_lang);
+}
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+/* Write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+   int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_oFFs;
+#endif
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_oFFs");
+
+   if (unit_type >= PNG_OFFSET_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+   png_save_int_32(buf, x_offset);
+   png_save_int_32(buf + 4, y_offset);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+/* Write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+   png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pCAL;
+#endif
+   png_size_t purpose_len, units_len, total_len;
+   png_uint_32p params_len;
+   png_byte buf[10];
+   png_charp new_purpose;
+   int i;
+
+   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
+
+   if (type >= PNG_EQUATION_LAST)
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+   purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
+   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+   png_debug1(3, "pCAL units length = %d", (int)units_len);
+   total_len = purpose_len + units_len + 10;
+
+   params_len = (png_uint_32p)png_malloc(png_ptr,
+      (png_uint_32)(nparams * png_sizeof(png_uint_32)));
+
+   /* Find the length of each parameter, making sure we don't count the
+      null terminator for the last parameter. */
+   for (i = 0; i < nparams; i++)
+   {
+      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+      png_debug2(3, "pCAL parameter %d length = %lu", i,
+        (unsigned long) params_len[i]);
+      total_len += (png_size_t)params_len[i];
+   }
+
+   png_debug1(3, "pCAL total length = %d", (int)total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)new_purpose,
+     (png_size_t)purpose_len);
+   png_save_int_32(buf, X0);
+   png_save_int_32(buf + 4, X1);
+   buf[8] = (png_byte)type;
+   buf[9] = (png_byte)nparams;
+   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+   png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+   png_free(png_ptr, new_purpose);
+
+   for (i = 0; i < nparams; i++)
+   {
+      png_write_chunk_data(png_ptr, (png_bytep)params[i],
+         (png_size_t)params_len[i]);
+   }
+
+   png_free(png_ptr, params_len);
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+/* Write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   char buf[64];
+   png_size_t total_len;
+
+   png_debug(1, "in png_write_sCAL");
+
+   buf[0] = (char)unit;
+#ifdef _WIN32_WCE
+/* sprintf() function is not supported on WindowsCE */
+   {
+      wchar_t wc_buf[32];
+      size_t wc_len;
+      swprintf(wc_buf, TEXT("%12.12e"), width);
+      wc_len = wcslen(wc_buf);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL,
+          NULL);
+      total_len = wc_len + 2;
+      swprintf(wc_buf, TEXT("%12.12e"), height);
+      wc_len = wcslen(wc_buf);
+      WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
+         NULL, NULL);
+      total_len += wc_len;
+   }
+#else
+   png_snprintf(buf + 1, 63, "%12.12e", width);
+   total_len = 1 + png_strlen(buf + 1) + 1;
+   png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
+   total_len += png_strlen(buf + total_len);
+#endif
+
+   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+   png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+   png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_byte buf[64];
+   png_size_t wlen, hlen, total_len;
+
+   png_debug(1, "in png_write_sCAL_s");
+
+   wlen = png_strlen(width);
+   hlen = png_strlen(height);
+   total_len = wlen + hlen + 2;
+   if (total_len > 64)
+   {
+      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+      return;
+   }
+
+   buf[0] = (png_byte)unit;
+   png_memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
+   png_memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
+
+   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+   png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len);
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+/* Write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+   png_uint_32 y_pixels_per_unit,
+   int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pHYs;
+#endif
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_pHYs");
+
+   if (unit_type >= PNG_RESOLUTION_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+   png_save_uint_32(buf, x_pixels_per_unit);
+   png_save_uint_32(buf + 4, y_pixels_per_unit);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tIME;
+#endif
+   png_byte buf[7];
+
+   png_debug(1, "in png_write_tIME");
+
+   if (mod_time->month  > 12 || mod_time->month  < 1 ||
+       mod_time->day    > 31 || mod_time->day    < 1 ||
+       mod_time->hour   > 23 || mod_time->second > 60)
+   {
+      png_warning(png_ptr, "Invalid time specified for tIME chunk");
+      return;
+   }
+
+   png_save_uint_16(buf, mod_time->year);
+   buf[2] = mod_time->month;
+   buf[3] = mod_time->day;
+   buf[4] = mod_time->hour;
+   buf[5] = mod_time->minute;
+   buf[6] = mod_time->second;
+
+   png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* Initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   png_size_t buf_size;
+
+   png_debug(1, "in png_write_start_row");
+
+   buf_size = (png_size_t)(PNG_ROWBYTES(
+      png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
+
+   /* Set up row buffer */
+   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)buf_size);
+   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   /* Set up filtering buffer, if using this filter */
+   if (png_ptr->do_filter & PNG_FILTER_SUB)
+   {
+      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)(png_ptr->rowbytes + 1));
+      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+   }
+
+   /* We only need to keep the previous row if we are using one of these. */
+   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+   {
+      /* Set up previous row buffer */
+      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
+         (png_uint_32)buf_size);
+
+      if (png_ptr->do_filter & PNG_FILTER_UP)
+      {
+         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(png_ptr->rowbytes + 1));
+         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_AVG)
+      {
+         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(png_ptr->rowbytes + 1));
+         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_PAETH)
+      {
+         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(png_ptr->rowbytes + 1));
+         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+      }
+   }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced, we need to set up width and height of pass */
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+      {
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+            png_pass_start[0]) / png_pass_inc[0];
+      }
+      else
+      {
+         png_ptr->num_rows = png_ptr->height;
+         png_ptr->usr_width = png_ptr->width;
+      }
+   }
+   else
+#endif
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->usr_width = png_ptr->width;
+   }
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only.  Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   /* Start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+   /* Offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+   int ret;
+
+   png_debug(1, "in png_write_finish_row");
+
+   /* Next row */
+   png_ptr->row_number++;
+
+   /* See if we are done */
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* If interlaced, go to next pass */
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      if (png_ptr->transformations & PNG_INTERLACE)
+      {
+         png_ptr->pass++;
+      }
+      else
+      {
+         /* Loop until we find a non-zero width or height pass */
+         do
+         {
+            png_ptr->pass++;
+            if (png_ptr->pass >= 7)
+               break;
+            png_ptr->usr_width = (png_ptr->width +
+               png_pass_inc[png_ptr->pass] - 1 -
+               png_pass_start[png_ptr->pass]) /
+               png_pass_inc[png_ptr->pass];
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (png_ptr->transformations & PNG_INTERLACE)
+               break;
+         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+      }
+
+      /* Reset the row above the image for the next pass */
+      if (png_ptr->pass < 7)
+      {
+         if (png_ptr->prev_row != NULL)
+            png_memset(png_ptr->prev_row, 0,
+               (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+               png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+         return;
+      }
+   }
+#endif
+
+   /* If we get here, we've just written the last row, so we need
+      to flush the compressor */
+   do
+   {
+      /* Tell the compressor we are done */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+      /* Check for an error */
+      if (ret == Z_OK)
+      {
+         /* Check to see if we need more room */
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+            png_ptr->zstream.next_out = png_ptr->zbuf;
+            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         }
+      }
+      else if (ret != Z_STREAM_END)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* Write any extra space */
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+   {
+      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+         png_ptr->zstream.avail_out);
+   }
+
+   deflateReset(&png_ptr->zstream);
+   png_ptr->zstream.data_type = Z_BINARY;
+}
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass.  As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+   /* Start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+   /* Offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+   png_debug(1, "in png_do_write_interlace");
+
+   /* We don't have to do anything on the last pass (6) */
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+   if (row != NULL && row_info != NULL && pass < 6)
+#else
+   if (pass < 6)
+#endif
+   {
+      /* Each pixel depth is handled separately */
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            d = 0;
+            shift = 7;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 3);
+               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 7;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift--;
+
+            }
+            if (shift != 7)
+               *dp = (png_byte)d;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 6;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 2);
+               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 2;
+            }
+            if (shift != 6)
+                   *dp = (png_byte)d;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+
+            dp = row;
+            shift = 4;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 1);
+               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 4;
+            }
+            if (shift != 4)
+               *dp = (png_byte)d;
+            break;
+         }
+         default:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            png_uint_32 i;
+            png_uint_32 row_width = row_info->width;
+            png_size_t pixel_bytes;
+
+            /* Start at the beginning */
+            dp = row;
+            /* Find out how many bytes each pixel takes up */
+            pixel_bytes = (row_info->pixel_depth >> 3);
+            /* Loop through the row, only looking at the pixels that
+               matter */
+            for (i = png_pass_start[pass]; i < row_width;
+               i += png_pass_inc[pass])
+            {
+               /* Find out where the original pixel is */
+               sp = row + (png_size_t)i * pixel_bytes;
+               /* Move the pixel */
+               if (dp != sp)
+                  png_memcpy(dp, sp, pixel_bytes);
+               /* Next pixel */
+               dp += pixel_bytes;
+            }
+            break;
+         }
+      }
+      /* Set new row width */
+      row_info->width = (row_info->width +
+         png_pass_inc[pass] - 1 -
+         png_pass_start[pass]) /
+         png_pass_inc[pass];
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+            row_info->width);
+   }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
+{
+   png_bytep best_row;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   png_bytep prev_row, row_buf;
+   png_uint_32 mins, bpp;
+   png_byte filter_to_do = png_ptr->do_filter;
+   png_uint_32 row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   int num_p_filters = (int)png_ptr->num_prev_filters;
+#endif 
+
+   png_debug(1, "in png_write_find_filter");
+
+#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
+  {
+      /* These will never be selected so we need not test them. */
+      filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+  }
+#endif 
+
+   /* Find out how many bytes offset each pixel is */
+   bpp = (row_info->pixel_depth + 7) >> 3;
+
+   prev_row = png_ptr->prev_row;
+#endif
+   best_row = png_ptr->row_buf;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   row_buf = best_row;
+   mins = PNG_MAXSUM;
+
+   /* The prediction method we use is to find which method provides the
+    * smallest value when summing the absolute values of the distances
+    * from zero, using anything >= 128 as negative numbers.  This is known
+    * as the "minimum sum of absolute differences" heuristic.  Other
+    * heuristics are the "weighted minimum sum of absolute differences"
+    * (experimental and can in theory improve compression), and the "zlib
+    * predictive" method (not implemented yet), which does test compressions
+    * of lines using different filter methods, and then chooses the
+    * (series of) filter(s) that give minimum compressed data size (VERY
+    * computationally expensive).
+    *
+    * GRR 980525:  consider also
+    *   (1) minimum sum of absolute differences from running average (i.e.,
+    *       keep running sum of non-absolute differences & count of bytes)
+    *       [track dispersion, too?  restart average if dispersion too large?]
+    *  (1b) minimum sum of absolute differences from sliding average, probably
+    *       with window size <= deflate window (usually 32K)
+    *   (2) minimum sum of squared differences from zero or running average
+    *       (i.e., ~ root-mean-square approach)
+    */
+
+
+   /* We don't need to test the 'no filter' case if this is the only filter
+    * that has been chosen, as it doesn't actually do anything to the data.
+    */
+   if ((filter_to_do & PNG_FILTER_NONE) &&
+       filter_to_do != PNG_FILTER_NONE)
+   {
+      png_bytep rp;
+      png_uint_32 sum = 0;
+      png_uint_32 i;
+      int v;
+
+      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+      {
+         v = *rp;
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         int j;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+         /* Reduce the sum if we match any of the previous rows */
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         /* Factor in the cost of this filter (this is here for completeness,
+          * but it makes no sense to have a "cost" for the NONE filter, as
+          * it has the minimum possible computational cost - none).
+          */
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+      mins = sum;
+   }
+
+   /* Sub filter */
+   if (filter_to_do == PNG_FILTER_SUB)
+   /* It's the only filter so no testing is needed */
+   {
+      png_bytep rp, lp, dp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         *dp = *rp;
+      }
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+      }
+      best_row = png_ptr->sub_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_SUB)
+   {
+      png_bytep rp, dp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      /* We temporarily increase the "minimum sum" by the factor we
+       * would reduce the sum of this filter, so that we can do the
+       * early exit comparison without scaling the sum each time.
+       */
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         v = *dp = *rp;
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_bytes;
+         i++, rp++, lp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+            {
+               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->sub_row;
+      }
+   }
+
+   /* Up filter */
+   if (filter_to_do == PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 i;
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+           pp = prev_row + 1; i < row_bytes;
+           i++, rp++, pp++, dp++)
+      {
+         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+      }
+      best_row = png_ptr->up_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+           pp = prev_row + 1; i < row_bytes; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->up_row;
+      }
+   }
+
+   /* Avg filter */
+   if (filter_to_do == PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+      }
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+                 & 0xff);
+      }
+      best_row = png_ptr->avg_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_bytes; i++)
+      {
+         v = *dp++ =
+          (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->avg_row;
+      }
+   }
+
+   /* Paeth filter */
+   if (filter_to_do == PNG_FILTER_PAETH)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 i;
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+         p = b - c;
+         pc = a - c;
+
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+      }
+      best_row = png_ptr->paeth_row;
+   }
+
+   else if (filter_to_do & PNG_FILTER_PAETH)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+           pp = prev_row + 1; i < bpp; i++)
+      {
+         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp++;
+         c = *cp++;
+         a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+         p = b - c;
+         pc = a - c;
+#ifdef PNG_USE_ABS
+         pa = abs(p);
+         pb = abs(pc);
+         pc = abs(p + pc);
+#else
+         pa = p < 0 ? -p : p;
+         pb = pc < 0 ? -pc : pc;
+         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+         p = a + b - c;
+         pa = abs(p - a);
+         pb = abs(p - b);
+         pc = abs(p - c);
+         if (pa <= pb && pa <= pc)
+            p = a;
+         else if (pb <= pc)
+            p = b;
+         else
+            p = c;
+#endif /* PNG_SLOW_PAETH */
+
+         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         int j;
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (j = 0; j < num_p_filters; j++)
+         {
+            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         best_row = png_ptr->paeth_row;
+      }
+   }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+   /* Do the actual writing of the filtered row data from the chosen filter. */
+
+   png_write_filtered_row(png_ptr, best_row);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+   /* Save the type of filter we picked this time for future calculations */
+   if (png_ptr->num_prev_filters > 0)
+   {
+      int j;
+      for (j = 1; j < num_p_filters; j++)
+      {
+         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+      }
+      png_ptr->prev_filters[j] = best_row[0];
+   }
+#endif
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void /* PRIVATE */
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+   png_debug(1, "in png_write_filtered_row");
+
+   png_debug1(2, "filter = %d", filtered_row[0]);
+   /* Set up the zlib input buffer */
+
+   png_ptr->zstream.next_in = filtered_row;
+   png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+   /* Repeat until we have compressed all the data */
+   do
+   {
+      int ret; /* Return of zlib */
+
+      /* Compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      /* Check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      /* See if it is time to write another IDAT */
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* Write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+      }
+   /* Repeat until all data has been compressed */
+   } while (png_ptr->zstream.avail_in);
+
+   /* Swap the current and previous rows */
+   if (png_ptr->prev_row != NULL)
+   {
+      png_bytep tptr;
+
+      tptr = png_ptr->prev_row;
+      png_ptr->prev_row = png_ptr->row_buf;
+      png_ptr->row_buf = tptr;
+   }
+
+   /* Finish row - updates counters and flushes zlib if last row */
+   png_write_finish_row(png_ptr);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+   png_ptr->flush_rows++;
+
+   if (png_ptr->flush_dist > 0 &&
+       png_ptr->flush_rows >= png_ptr->flush_dist)
+   {
+      png_write_flush(png_ptr);
+   }
+#endif
+}
+#endif /* PNG_WRITE_SUPPORTED */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/lmalloc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/lmalloc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/lmalloc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/pmapi.h>
+
+void *lzalloc(size_t size)
+{
+    void *p;
+    p = lmalloc(size);
+    if (!p)
+	errno = ENOMEM;
+    else
+	memset(p, 0, size);
+    return p;
+}
+
+void lfree(void *ptr)
+{
+    free(ptr);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/lrand48.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/lrand48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/lrand48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+/*
+ * lrand48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+unsigned short __rand48_seed[3];
+
+long jrand48(unsigned short xsubi[3])
+{
+    uint64_t x;
+
+    /* The xsubi[] array is littleendian by spec */
+    x = (uint64_t) xsubi[0] +
+	((uint64_t) xsubi[1] << 16) + ((uint64_t) xsubi[2] << 32);
+
+    x = (0x5deece66dULL * x) + 0xb;
+
+    xsubi[0] = (unsigned short)x;
+    xsubi[1] = (unsigned short)(x >> 16);
+    xsubi[2] = (unsigned short)(x >> 32);
+
+    return (long)(int32_t) (x >> 16);
+}
+
+long mrand48(void)
+{
+    return jrand48(__rand48_seed);
+}
+
+long nrand48(unsigned short xsubi[3])
+{
+    return (long)((uint32_t) jrand48(xsubi) >> 1);
+}
+
+long lrand48(void)
+{
+    return (long)((uint32_t) mrand48() >> 1);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/lstrdup.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/lstrdup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/lstrdup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * lstrdup.c
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <com32.h>
+
+char *lstrdup(const char *s)
+{
+    int l = strlen(s) + 1;
+    char *d = lmalloc(l);
+
+    if (d)
+	memcpy(d, s, l);
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/makeerrlist.pl
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/makeerrlist.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/makeerrlist.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+#
+# This creates sys_errlist from <asm/errno.h> through somewhat
+# heuristic matching.  It presumes the relevant entries are of the form
+# #define Exxxx <integer> /* comment */
+#
+
+use FileHandle;
+
+%errors  = ();
+%errmsg  = ();
+$maxerr  = -1;
+@includelist = ();		# Include directories
+
+sub parse_file($) {
+    my($file) = @_;
+    my($fh) = new FileHandle;
+    my($line, $error, $msg);
+    my($kernelonly) = 0;
+    my($root);
+
+    print STDERR "opening $file\n" unless ( $quiet );
+
+    $ok = 0;
+    foreach $root ( @includelist ) {
+	if ( $fh->open($root.'//'.$file, '<') ) {
+	    $ok = 1;
+	    last;
+	}
+    }
+
+    if ( ! $ok ) {
+	die "$0: Cannot find file $file\n";
+    }
+
+    while ( defined($line = <$fh>) ) {
+	if ( $kernelonly ) {
+	    if ( $line =~ /^\#\s*endif/ ) {
+		$kernelonly--;
+	    } elsif ( $line =~ /^\#\sif/ ) {
+		$kernelonly++;
+	    }
+	} else {
+	    if ( $line =~ /^\#\s*define\s+([A-Z0-9_]+)\s+([0-9]+)\s*\/\*\s*(.*\S)\s*\*\// ) {
+		$error = $1;
+		$errno = $2+0;
+		$msg   = $3;
+		print STDERR "$error ($errno) => \"$msg\"\n" unless ( $quiet );
+		$errors{$errno} = $error;
+		$errmsg{$errno} = $msg;
+		$maxerr = $errno if ( $errno > $maxerr );
+	    } elsif ( $line =~ /^\#\s*include\s+[\<\"](.*)[\>\"]/ ) {
+		parse_file($1);
+	    } elsif ( $line =~ /^\#\s*ifdef\s+__KERNEL__/ ) {
+		$kernelonly++;
+	    }
+	}
+    }
+    close($fh);
+    print STDERR "closing $file\n" unless ( $quiet );
+}
+
+$v = $ENV{'KBUILD_VERBOSE'};
+$quiet = defined($v) ? !$v : 0;
+
+foreach $arg ( @ARGV ) {
+    if ( $arg eq '-q' ) {
+	$quiet = 1;
+    } elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) {
+	$type = $arg;
+    } elsif ( $arg =~ '^\-I' ) {
+	push(@includelist, "$'");
+    } else {
+	# Ignore
+    }
+}
+
+parse_file('errno.h');
+
+if ( $type eq '-errlist' ) {
+    print  "#include <errno.h>\n";
+    printf "const int sys_nerr = %d;\n", $maxerr+1;
+    printf "const char * const sys_errlist[%d] = {\n", $maxerr+1;
+    foreach $e ( sort(keys(%errors)) ) {
+	printf "  [%s] = \"%s\",\n", $errors{$e}, $errmsg{$e};
+    }
+    print "};\n";
+} elsif ( $type eq '-errnos' ) {
+    print  "#include <errno.h>\n";
+    printf "const int sys_nerr = %d;\n", $maxerr+1;
+    printf "const char * const sys_errlist[%d] = {\n", $maxerr+1;
+    foreach $e ( sort(keys(%errors)) ) {
+	printf "  [%s] = \"%s\",\n", $errors{$e}, $errors{$e};
+    }
+    print "};\n";
+} elsif ( $type eq '-maxerr' ) {
+    print $maxerr, "\n";
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/malloc.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/malloc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/malloc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/*
+ * malloc.h
+ *
+ * Internals for the memory allocator
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/*
+ * This is the minimum chunk size we will ask the kernel for; this should
+ * be a multiple of the page size on all architectures.
+ */
+#define MALLOC_CHUNK_SIZE	65536
+#define MALLOC_CHUNK_MASK       (MALLOC_CHUNK_SIZE-1)
+
+/*
+ * This structure should be a power of two.  This becomes the
+ * alignment unit.
+ */
+struct free_arena_header;
+
+struct arena_header {
+    size_t type;
+    size_t size;		/* Also gives the location of the next entry */
+    struct free_arena_header *next, *prev;
+};
+
+#ifdef DEBUG_MALLOC
+#define ARENA_TYPE_USED 0x64e69c70
+#define ARENA_TYPE_FREE 0x012d610a
+#define ARENA_TYPE_HEAD 0x971676b5
+#define ARENA_TYPE_DEAD 0xeeeeeeee
+#else
+#define ARENA_TYPE_USED 0
+#define ARENA_TYPE_FREE 1
+#define ARENA_TYPE_HEAD 2
+#endif
+
+#define ARENA_SIZE_MASK (~(uintptr_t)(sizeof(struct arena_header)-1))
+
+#define ARENA_ALIGN_UP(p)	((char *)(((uintptr_t)(p) + ~ARENA_SIZE_MASK) & ARENA_SIZE_MASK))
+#define ARENA_ALIGN_DOWN(p)	((char *)((uintptr_t)(p) & ARENA_SIZE_MASK))
+
+/*
+ * This structure should be no more than twice the size of the
+ * previous structure.
+ */
+struct free_arena_header {
+    struct arena_header a;
+    struct free_arena_header *next_free, *prev_free;
+};
+
+extern struct free_arena_header __malloc_head;
+void __inject_free_block(struct free_arena_header *ah);
Index: bootcd/isolinux/syslinux-6.03/com32/lib/math/pow.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/math/pow.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/math/pow.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+/*
+ * pow.S
+ *
+ * double pow(double base, double exponent)
+ */
+
+	.text
+	.globl	pow
+	.type	pow,@function
+pow:
+	fldl	12(%esp)
+	fldl	4(%esp)
+	fyl2x
+	fld	%st(0)
+	frndint
+	fsubr	%st,%st(1)
+	fxch	%st(1)
+	f2xm1
+	fld1
+	faddp	%st,%st(1)
+	fscale
+	fstp	%st(1)
+	ret
+
+	.size	pow,.-pow
Index: bootcd/isolinux/syslinux-6.03/com32/lib/math/strtod.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/math/strtod.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/math/strtod.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,156 @@
+/*
+ * strtod.c
+ *
+ * Convert string to double
+ *
+ * Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+ * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+
+static inline int is_real(double x)
+{
+    const double Inf = 1.0 / 0.0;
+    return (x < Inf) && (x >= -Inf);
+}
+
+double strtod(const char *str, char **endptr)
+{
+    double number;
+    int exponent;
+    int negative;
+    char *p = (char *)str;
+    double p10;
+    int n;
+    int num_digits;
+    int num_decimals;
+    const double Inf = 1.0 / 0.0;
+
+    // Skip leading whitespace
+    while (isspace(*p))
+	p++;
+
+    // Handle optional sign
+    negative = 0;
+    switch (*p) {
+    case '-':
+	negative = 1;		// Fall through to increment position
+    case '+':
+	p++;
+    }
+
+    number = 0.;
+    exponent = 0;
+    num_digits = 0;
+    num_decimals = 0;
+
+    // Process string of digits
+    while (isdigit(*p)) {
+	number = number * 10. + (*p - '0');
+	p++;
+	num_digits++;
+    }
+
+    // Process decimal part
+    if (*p == '.') {
+	p++;
+
+	while (isdigit(*p)) {
+	    number = number * 10. + (*p - '0');
+	    p++;
+	    num_digits++;
+	    num_decimals++;
+	}
+
+	exponent -= num_decimals;
+    }
+
+    if (num_digits == 0) {
+	errno = ERANGE;
+	return 0.0;
+    }
+    // Correct for sign
+    if (negative)
+	number = -number;
+
+    // Process an exponent string
+    if (*p == 'e' || *p == 'E') {
+	// Handle optional sign
+	negative = 0;
+	switch (*++p) {
+	case '-':
+	    negative = 1;	// Fall through to increment pos
+	case '+':
+	    p++;
+	}
+
+	// Process string of digits
+	n = 0;
+	while (isdigit(*p)) {
+	    n = n * 10 + (*p - '0');
+	    p++;
+	}
+
+	if (negative)
+	    exponent -= n;
+	else
+	    exponent += n;
+    }
+
+    if (exponent < __DBL_MIN_EXP__ || exponent > __DBL_MAX_EXP__) {
+	errno = ERANGE;
+	return Inf;
+    }
+    // Scale the result
+    p10 = 10.;
+    n = exponent;
+    if (n < 0)
+	n = -n;
+    while (n) {
+	if (n & 1) {
+	    if (exponent < 0)
+		number /= p10;
+	    else
+		number *= p10;
+	}
+	n >>= 1;
+	p10 *= p10;
+    }
+
+    if (!is_real(number))
+	errno = ERANGE;
+    if (endptr)
+	*endptr = p;
+
+    return number;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memccpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memccpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memccpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * memccpy.c
+ *
+ * memccpy()
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memccpy(void *dst, const void *src, int c, size_t n)
+{
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    while (n--) {
+	*q++ = ch = *p++;
+	if (ch == (char)c)
+	    return q;
+    }
+
+    return NULL;		/* No instance of "c" found */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memchr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * memchr.c
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memchr(const void *s, int c, size_t n)
+{
+    const unsigned char *sp = s;
+
+    while (n--) {
+	if (*sp == (unsigned char)c)
+	    return (void *)sp;
+    }
+
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memcmp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memcmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memcmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+/*
+ * memcmp.c
+ */
+
+#include <string.h>
+
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+    const unsigned char *c1 = s1, *c2 = s2;
+    int d = 0;
+
+    while (n--) {
+	d = (int)*c1++ - (int)*c2++;
+	if (d)
+	    break;
+    }
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,90 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memcpy.S
+ *
+ * Reasonably efficient memcpy, using aligned transfers at least
+ * for the destination operand.
+ */
+
+	.text
+	.globl	memcpy
+	.type	memcpy, @function
+memcpy:
+	movl	0xc(%esp),%ecx
+	movl	0x8(%esp),%edx
+	movl	0x4(%esp),%eax
+
+	jecxz	1f
+
+	pushl	%esi
+	pushl	%edi
+	pushl	%eax		/* Return value */
+
+	movl	%eax,%edi
+	movl	%edx,%esi
+
+	/* Initial alignment */
+	movl	%edi,%edx
+	shrl	$1,%edx
+	jnc	11f
+	movsb
+	decl	%ecx
+11:
+	movb	%cl,%al
+	cmpl	$2,%ecx
+	jb	13f
+
+	shrl	$1,%edx
+	jnc	12f
+	movsw
+	subl	$2,%ecx
+12:
+	/* Bulk transfer */
+	movb	%cl,%al
+	shrl	$2,%ecx
+	rep; movsl
+
+	/* Final alignment */
+	testb	$2,%al
+	jz	14f
+	movsw
+13:
+14:
+	testb	$1,%al
+	jz	15f
+	movsb
+15:
+
+	popl	%eax		/* Return value */
+	popl	%edi
+	popl	%esi
+1:
+	ret
+
+	.size	memcpy, .-memcpy
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * memcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memcpy(void *dst, const void *src, size_t n)
+{
+	const char *p = src;
+	char *q = dst;
+#if defined(__i386__)
+	size_t nl = n >> 2;
+	asm volatile ("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb":"+c" (nl),
+		      "+S"(p), "+D"(q)
+		      :"r"(n & 3));
+#elif defined(__x86_64__)
+	size_t nq = n >> 3;
+	asm volatile ("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb":"+c"
+		      (nq), "+S"(p), "+D"(q)
+		      :"r"((uint32_t) (n & 7)));
+#else
+	while (n--) {
+		*q++ = *p++;
+	}
+#endif
+
+	return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memmem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/*
+ * memmem.c
+ *
+ * Find a byte string inside a longer byte string
+ *
+ * This uses the "Not So Naive" algorithm, a very simple but
+ * usually effective algorithm, see:
+ *
+ * http://www-igm.univ-mlv.fr/~lecroq/string/
+ */
+
+#include <string.h>
+
+void *memmem(const void *haystack, size_t n, const void *needle, size_t m)
+{
+    const unsigned char *y = (const unsigned char *)haystack;
+    const unsigned char *x = (const unsigned char *)needle;
+
+    size_t j, k, l;
+
+    if (m > n || !m || !n)
+        return NULL;
+
+    if (1 != m) {
+        if (x[0] == x[1]) {
+            k = 2;
+            l = 1;
+        } else {
+            k = 1;
+            l = 2;
+        }
+
+        j = 0;
+        while (j <= n - m) {
+            if (x[1] != y[j + 1]) {
+                j += k;
+            } else {
+                if (!memcmp(x + 2, y + j + 2, m - 2)
+                    && x[0] == y[j])
+                    return (void *)&y[j];
+                j += l;
+            }
+        }
+    } else {
+        do {
+            if (*y == *x)
+                return (void *)y;
+            y++;
+        } while (--n);
+    }
+
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memmove.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memmove.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memmove.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memmove.S
+ *
+ * Reasonably efficient memmove, using aligned transfers at least
+ * for the destination operand.
+ */
+
+	.globl	memmove
+	.type	memmove,@function
+	.text
+memmove:
+	movl	0xc(%esp),%ecx
+	movl	0x8(%esp),%edx
+	movl	0x4(%esp),%eax
+
+	jecxz	4f
+
+	pushl	%esi
+	pushl	%edi
+	pushl	%eax		/* Return value */
+
+	movl	%eax,%edi
+	movl	%edx,%esi
+
+	cmpl	%edi,%esi
+	jb	2f
+
+	/* source >= dest, forwards move */
+
+	/* Initial alignment */
+1:
+	movl	%edi,%edx
+	shrl	$1,%edx
+	jnc	11f
+	movsb
+	decl	%ecx
+11:
+	movb	%cl,%al
+	cmpl	$2,%ecx
+	jb	13f
+
+	shrl	$1,%edx
+	jnc	12f
+	movsw
+	subl	$2,%ecx
+12:
+	/* Bulk transfer */
+	movb	%cl,%al
+	shrl	$2,%ecx
+	rep; movsl
+
+	/* Final alignment */
+	testb	$2,%al
+	jz	14f
+	movsw
+13:
+14:
+	testb	$1,%al
+	jz	15f
+	movsb
+15:
+	/* Common exit stub */
+3:
+	popl	%eax		/* Return value */
+	popl	%edi
+	popl	%esi
+4:
+	ret
+
+
+2:
+	/* source < dest, backwards move if overlap */
+	leal	-1(%ecx,%esi),%eax
+	cmpl	%eax,%edi
+	ja	1b			/* No overlap, after all... */
+
+	std
+	leal	-1(%ecx,%edi),%edi
+	movl	%eax,%esi
+
+	/* Initial alignment */
+	movl	%edi,%edx
+	shrl	$1,%edx
+	jc	21f
+	movsb
+	decl	%ecx
+21:
+	decl	%esi
+	decl	%edi
+	movb	%cl,%al
+	cmpl	$2,%ecx
+	jb	23f
+	shrl	$1,%edx
+	jc	22f
+	movsw
+	subl	$2,%ecx
+22:
+	/* Bulk transfer */
+	subl	$2,%esi
+	subl	$2,%edi
+	movb	%cl,%al
+	shrl	$2,%ecx
+	rep; movsl
+
+	/* Final alignment */
+	addl	$2,%esi
+	addl	$2,%edi
+	testb	$2,%al
+	jz	24f
+	movsw
+23:
+24:
+	incl	%esi
+	incl	%edi
+	testb	$1,%al
+	jz	25f
+	movsb
+25:
+	cld
+	jmp	3b
+
+	.size	memmove, .-memmove
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memmove.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memmove.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memmove.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+/*
+ * memmove.c
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t n)
+{
+	const char *p = src;
+	char *q = dst;
+#if defined(__i386__) || defined(__x86_64__)
+	if (q < p) {
+		asm volatile("cld; rep; movsb"
+			     : "+c" (n), "+S"(p), "+D"(q));
+	} else {
+		p += (n - 1);
+		q += (n - 1);
+		asm volatile("std; rep; movsb; cld"
+			     : "+c" (n), "+S"(p), "+D"(q));
+	}
+#else
+	if (q < p) {
+		while (n--) {
+			*q++ = *p++;
+		}
+	} else {
+		p += n;
+		q += n;
+		while (n--) {
+			*--q = *--p;
+		}
+	}
+#endif
+
+	return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,89 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mempcpy.S
+ *
+ * Reasonably efficient mempcpy, using aligned transfers at least
+ * for the destination operand.
+ */
+
+	.text
+	.globl	mempcpy
+	.type	mempcpy, @function
+mempcpy:
+	movl	0xc(%esp),%ecx
+	movl	0x8(%esp),%edx
+	movl	0x4(%esp),%eax
+
+	jecxz	1f
+
+	pushl	%esi
+	pushl	%edi
+
+	movl	%eax,%edi
+	movl	%edx,%esi
+
+	/* Initial alignment */
+	movl	%edi,%edx
+	shrl	$1,%edx
+	jnc	11f
+	movsb
+	decl	%ecx
+11:
+	movb	%cl,%al
+	cmpl	$2,%ecx
+	jb	13f
+
+	shrl	$1,%edx
+	jnc	12f
+	movsw
+	subl	$2,%ecx
+12:
+	/* Bulk transfer */
+	movb	%cl,%al
+	shrl	$2,%ecx
+	rep; movsl
+
+	/* Final alignment */
+	testb	$2,%al
+	jz	14f
+	movsw
+13:
+14:
+	testb	$1,%al
+	jz	15f
+	movsb
+15:
+
+	movl	%edi,%eax	/* Return value */
+	popl	%edi
+	popl	%esi
+1:
+	ret
+
+	.size	mempcpy, .-mempcpy
Index: bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/mempcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+/*
+ * mempcpy.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+/* simply a wrapper around memcpy implementation */
+
+void *mempcpy(void *dst, const void *src, size_t n)
+{
+
+	return (char *)memcpy(dst, src, n) + n;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memset.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memset.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memset.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,90 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memset.S
+ *
+ * Reasonably efficient memset, using aligned transfers at least
+ * for the destination operand.
+ */
+
+	.globl	memset
+	.type	memset,@function
+	.text
+memset:
+	movl	0xc(%esp),%ecx
+	movl	0x8(%esp),%edx
+	movl	0x4(%esp),%eax
+
+	jecxz	6f
+
+	pushl	%edi
+	pushl	%ebx
+	pushl	%eax		/* Return value */
+
+	movl	%eax,%edi
+	movb	%dl,%dh
+	movzwl	%dx,%eax
+	shll	$16,%edx
+	orl	%edx,%eax
+
+	/* Initial alignment */
+	movl	%edi,%edx
+	shrl	$1,%edx
+	jnc	1f
+	stosb
+	decl	%ecx
+1:
+	movb	%cl,%bl
+	cmpl	$2,%ecx
+	jb	3f
+	shrl	$1,%edx
+	jnc	2f
+	stosw
+	subl	$2,%ecx
+2:
+	/* Bulk transfer */
+	movb	%cl,%bl
+	shrl	$2,%ecx
+	rep; stosl
+
+	testb	$2,%bl
+	jz	4f
+	stosw
+3:
+4:
+	testb	$1,%bl
+	jz	5f
+	stosb
+5:
+	popl	%eax		/* Return value */
+	popl	%ebx
+	popl	%edi
+6:
+	ret
+
+	.size	memset, .-memset
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memset.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memset.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memset.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,30 @@
+/*
+ * memset.c
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dst, int c, size_t n)
+{
+	char *q = dst;
+
+#if defined(__i386__)
+	size_t nl = n >> 2;
+	asm volatile ("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb"
+		      : "+c" (nl), "+D" (q)
+		      : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3));
+#elif defined(__x86_64__)
+	size_t nq = n >> 3;
+	asm volatile ("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb"
+		      :"+c" (nq), "+D" (q)
+		      : "a" ((unsigned char)c * 0x0101010101010101U),
+			"r" ((uint32_t) n & 7));
+#else
+	while (n--) {
+		*q++ = c;
+	}
+#endif
+
+	return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/memswap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/memswap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/memswap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * memswap()
+ *
+ * Swaps the contents of two nonoverlapping memory areas.
+ * This really could be done faster...
+ */
+
+#include <string.h>
+
+void memswap(void *m1, void *m2, size_t n)
+{
+    char *p = m1;
+    char *q = m2;
+    char tmp;
+
+    while (n--) {
+	tmp = *p;
+	*p = *q;
+	*q = tmp;
+
+	p++;
+	q++;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/onexit.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/onexit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/onexit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+/*
+ * onexit.c
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "atexit.h"
+
+static struct atexit *__atexit_list;
+
+static __noreturn on_exit_exit(int rv)
+{
+    struct atexit *ap;
+
+    for (ap = __atexit_list; ap; ap = ap->next) {
+	ap->fctn(rv, ap->arg);	/* This assumes extra args are harmless */
+    }
+
+    _exit(rv);
+}
+
+int on_exit(void (*fctn) (int, void *), void *arg)
+{
+    struct atexit *as = malloc(sizeof(struct atexit));
+
+    if (!as)
+	return -1;
+
+    as->fctn = fctn;
+    as->arg = arg;
+
+    as->next = __atexit_list;
+    __atexit_list = as;
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/bios.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/bios.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/bios.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+#include <com32.h>
+#include <string.h>
+#include "pci/pci.h"
+
+uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a)
+{
+    com32sys_t rs;
+    memset(&rs, 0, sizeof rs);
+    rs.eax.w[0] = call;
+    rs.ebx.w[0] = a >> 8;	/* bus:device:function */
+    rs.edi.b[0] = a;		/* address:reg */
+    rs.ecx.l    = v;
+    rs.eflags.l = EFLAGS_CF;
+    __intcall(0x1a, &rs, &rs);
+
+    return (rs.eflags.l & EFLAGS_CF) ? ~(uint32_t) 0 : rs.ecx.l;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/cfgtype.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/cfgtype.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/cfgtype.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,89 @@
+#include "pci/pci.h"
+#include <com32.h>
+#include <string.h>
+
+enum pci_config_type __pci_cfg_type;
+
+static int type1_ok(void)
+{
+    uint32_t oldcf8, newcf8;
+
+    /* Test for Configuration Method #1 */
+
+    /* Note: XFree86 writes ~0 and expects to read back 0x80fffffc.  Linux
+       does this less severe test; go with Linux. */
+
+    cli();
+    outb(1, 0xcfb);		/* For old Intel chipsets */
+    oldcf8 = inl(0xcf8);
+    outl(0x80000000, 0xcf8);
+    newcf8 = inl(0xcf8);
+    outl(oldcf8, 0xcf8);
+    sti();
+
+    return newcf8 == 0x80000000;
+}
+
+static int type2_ok(void)
+{
+    uint8_t oldcf8, oldcfa;
+    uint8_t cf8, cfa;
+
+    /* Test for Configuration Method #2 */
+
+    /* CM#2 is hard to probe for, but let's do our best... */
+
+    cli();
+    outb(0, 0xcfb);		/* For old Intel chipsets */
+    oldcf8 = inb(0xcf8);
+    outb(0, 0xcf8);
+    oldcfa = inb(0xcfa);
+    outb(0, 0xcfa);
+
+    cf8 = inb(0xcf8);
+    cfa = inb(0xcfa);
+
+    outb(oldcf8, 0xcf8);
+    outb(oldcfa, 0xcfa);
+    sti();
+
+    return cf8 == 0 && cfa == 0;
+}
+
+int pci_set_config_type(enum pci_config_type type)
+{
+    static const com32sys_t ireg = {
+	.eax.l = 0xb101,
+	.edi.l = 0,
+	.eflags.l = EFLAGS_CF,
+    };
+    com32sys_t oreg;
+
+    if (type == PCI_CFG_AUTO) {
+	type = PCI_CFG_NONE;
+
+	/* Try to detect PCI BIOS */
+	__intcall(0x1a, &ireg, &oreg);
+
+	if (!(oreg.eflags.l & EFLAGS_CF) &&
+	    oreg.eax.b[1] == 0 && oreg.edx.l == 0x20494250) {
+	    /* PCI BIOS present.  Use direct access if we know how to do it. */
+
+	    if ((oreg.eax.b[0] & 1) && type1_ok())
+		type = PCI_CFG_TYPE1;
+	    else if ((oreg.eax.b[0] & 2) && type2_ok())
+		type = PCI_CFG_TYPE2;
+	    else
+		type = PCI_CFG_BIOS;	/* Use BIOS calls as fallback */
+
+	} else if (type1_ok()) {
+	    type = PCI_CFG_TYPE1;
+	} else if (type2_ok()) {
+	    type = PCI_CFG_TYPE2;
+	} else {
+	    type = PCI_CFG_NONE;	/* Badness... */
+	}
+    }
+
+    return (__pci_cfg_type = type);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/pci.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/pci.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/pci.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * pci/pci.h
+ *
+ * Common internal header file
+ */
+
+#ifndef PCI_PCI_H
+
+#include <sys/pci.h>
+#include <sys/cpu.h>
+
+extern enum pci_config_type __pci_cfg_type;
+extern uint32_t __pci_read_write_bios(uint32_t call, uint32_t v, pciaddr_t a);
+
+#endif /* PCI_PCI_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/readb.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/readb.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/readb.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint8_t
+#define BWL(x) x ## b
+#define BIOSCALL 0xb108
+#include "pci/readx.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/readl.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/readl.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/readl.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint32_t
+#define BWL(x) x ## l
+#define BIOSCALL 0xb10a
+#include "pci/readx.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/readw.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/readw.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/readw.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint16_t
+#define BWL(x) x ## w
+#define BIOSCALL 0xb109
+#include "pci/readx.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/readx.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/readx.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/readx.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+#include "pci/pci.h"
+
+TYPE BWL(pci_read) (pciaddr_t a)
+{
+    TYPE r;
+
+    for (;;) {
+	switch (__pci_cfg_type) {
+	case PCI_CFG_AUTO:
+	    pci_set_config_type(PCI_CFG_AUTO);
+	    break;		/* Try again */
+
+	case PCI_CFG_TYPE1:
+	    {
+		uint32_t oldcf8;
+		cli();
+		oldcf8 = inl(0xcf8);
+		outl(a, 0xcf8);
+		r = BWL(in) (0xcfc + (a & 3));
+		outl(oldcf8, 0xcf8);
+		sti();
+	    }
+	    return r;
+
+	case PCI_CFG_TYPE2:
+	    {
+		uint8_t oldcf8, oldcfa;
+
+		if (a & (0x10 << 11))
+		    return (TYPE) ~ 0;	/* Device 16-31 not supported */
+
+		cli();
+		oldcf8 = inb(0xcf8);
+		oldcfa = inb(0xcfa);
+		outb(0xf0 + ((a >> (8 - 1)) & 0x0e), 0xcf8);
+		outb(a >> 16, 0xcfa);
+		r = BWL(in) (0xc000 + ((a >> (11 - 8)) & 0xf00) + (a & 0xff));
+		outb(oldcf8, 0xcf8);
+		outb(oldcfa, 0xcfa);
+		sti();
+	    }
+	    return r;
+
+	case PCI_CFG_BIOS:
+	    return (TYPE) __pci_read_write_bios(BIOSCALL, 0, a);
+
+	default:
+	    return (TYPE) ~ 0;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/scan.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/scan.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/scan.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,729 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2007 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pci.c
+ *
+ * A module to extract pci informations
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <sys/pci.h>
+#include <com32.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <syslinux/zio.h>
+#include <dprintf.h>
+
+#define MAX_LINE 512
+
+/* removing any \n found in a string */
+static void remove_eol(char *string)
+{
+    int j = strlen(string);
+    int i = 0;
+    for (i = 0; i < j; i++)
+	if (string[i] == '\n')
+	    string[i] = 0;
+}
+
+/* converting a hexa string into its numerical value */
+static int hex_to_int(char *hexa)
+{
+    return strtoul(hexa, NULL, 16);
+}
+
+/* Try to match any pci device to the appropriate kernel module */
+/* it uses the modules.pcimap from the boot device */
+int get_module_name_from_pcimap(struct pci_domain *domain,
+				char *modules_pcimap_path)
+{
+  char line[MAX_LINE];
+  char module_name[21]; // the module name field is 21 char long
+  char delims[]=" ";    // colums are separated by spaces
+  char vendor_id[16];
+  char product_id[16];
+  char sub_vendor_id[16];
+  char sub_product_id[16];
+  FILE *f;
+  struct pci_device *dev=NULL;
+
+  /* Intializing the linux_kernel_module for each pci device to "unknown" */
+  /* adding a dev_info member if needed */
+  for_each_pci_func(dev, domain) {
+    /* initialize the dev_info structure if it doesn't exist yet. */
+    if (! dev->dev_info) {
+      dev->dev_info = zalloc(sizeof *dev->dev_info);
+      if (!dev->dev_info)
+	return -1;
+    }
+    for (int i=0;i<MAX_KERNEL_MODULES_PER_PCI_DEVICE;i++) {
+     if (strlen(dev->dev_info->linux_kernel_module[i])==0)
+       strlcpy(dev->dev_info->linux_kernel_module[i], "unknown",7);
+    }
+  }
+
+  /* Opening the modules.pcimap (of a linux kernel) from the boot device */
+  f=zfopen(modules_pcimap_path, "r");
+  if (!f)
+    return -ENOMODULESPCIMAP;
+
+  strcpy(vendor_id,"0000");
+  strcpy(product_id,"0000");
+  strcpy(sub_product_id,"0000");
+  strcpy(sub_vendor_id,"0000");
+
+  /* for each line we found in the modules.pcimap */
+  while ( fgets(line, sizeof line, f) ) {
+    /* skipping unecessary lines */
+    if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 10))
+        continue;
+
+    char *result = NULL;
+    int field=0;
+
+    /* looking for the next field */
+    result = strtok(line, delims);
+    while( result != NULL ) {
+       /* if the column is larger than 1 char */
+       /* multiple spaces generates some empty fields */
+       if (strlen(result)>1) {
+	 switch (field) {
+	 /* About case 0, the kernel module name is featuring '_' or '-' 
+	  * in the module name whereas modules.alias is only using '_'.
+	  * To avoid kernel modules duplication, let's rename all '-' in '_' 
+	  * to match what modules.alias provides */
+	 case 0:chrreplace(result,'-','_');strcpy(module_name,result); break;
+	 case 1:strcpy(vendor_id,result); break;
+	 case 2:strcpy(product_id,result); break;
+	 case 3:strcpy(sub_vendor_id,result); break;
+	 case 4:strcpy(sub_product_id,result); break;
+	 }
+	 field++;
+       }
+       /* Searching the next field */
+       result = strtok( NULL, delims );
+   }
+    int int_vendor_id=hex_to_int(vendor_id);
+    int int_sub_vendor_id=hex_to_int(sub_vendor_id);
+    int int_product_id=hex_to_int(product_id);
+    int int_sub_product_id=hex_to_int(sub_product_id);
+    /* if a pci_device matches an entry, fill the linux_kernel_module with
+       the appropriate kernel module */
+    for_each_pci_func(dev, domain) {
+      if (int_vendor_id == dev->vendor &&
+	  int_product_id == dev->product &&
+	  (int_sub_product_id & dev->sub_product)
+	  == dev->sub_product &&
+	  (int_sub_vendor_id & dev->sub_vendor)
+	  == dev->sub_vendor) {
+	      bool found=false;
+
+	      /* Scan all known kernel modules for this pci device */
+	      for (int i=0; i<dev->dev_info->linux_kernel_module_count; i++) {
+
+       	      /* Try to detect if we already knew the same kernel module*/
+	       if (strstr(dev->dev_info->linux_kernel_module[i], module_name)) {
+		      found=true;
+		      break;
+	       }
+	      }
+	      /* If we don't have this kernel module, let's add it */
+	      if (!found) {
+		strcpy(dev->dev_info->linux_kernel_module[dev->dev_info->linux_kernel_module_count], module_name);
+		dev->dev_info->linux_kernel_module_count++;
+	      }
+      }
+    }
+  }
+  fclose(f);
+  return 0;
+}
+
+/* Try to match any pci device to the appropriate class name */
+/* it uses the pci.ids from the boot device */
+int get_class_name_from_pci_ids(struct pci_domain *domain, char *pciids_path)
+{
+    char line[MAX_LINE];
+    char class_name[PCI_CLASS_NAME_SIZE];
+    char sub_class_name[PCI_CLASS_NAME_SIZE];
+    char class_id_str[5];
+    char sub_class_id_str[5];
+    FILE *f;
+    struct pci_device *dev;
+    bool class_mode = false;
+
+    /* Intializing the vendor/product name for each pci device to "unknown" */
+    /* adding a dev_info member if needed */
+    for_each_pci_func(dev, domain) {
+	/* initialize the dev_info structure if it doesn't exist yet. */
+	if (!dev->dev_info) {
+	    dev->dev_info = zalloc(sizeof *dev->dev_info);
+	    if (!dev->dev_info)
+		return -1;
+	}
+	strlcpy(dev->dev_info->class_name, "unknown", 7);
+    }
+
+    /* Opening the pci.ids from the boot device */
+    f = zfopen(pciids_path, "r");
+    if (!f)
+	return -ENOPCIIDS;
+
+    /* for each line we found in the pci.ids */
+    while (fgets(line, sizeof line, f)) {
+	/* Skipping uncessary lines */
+	if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 10))
+	    continue;
+
+	/* Until we found a line starting with a 'C', we are not parsing classes */
+	if (line[0] == 'C')
+	    class_mode = true;
+	if (class_mode == false)
+	    continue;
+	strlcpy(class_name, "unknown", 7);
+	/* If the line doesn't start with a tab, it means that's a class name */
+	if (line[0] != '\t') {
+
+	    /* ignore the two first char and then copy 2 chars (class id) */
+	    strlcpy(class_id_str, &line[2], 2);
+	    class_id_str[2] = 0;
+
+	    /* the class name is the next field */
+	    strlcpy(class_name, skipspace(strstr(line, " ")),
+		    PCI_CLASS_NAME_SIZE - 1);
+	    remove_eol(class_name);
+
+	    int int_class_id_str = hex_to_int(class_id_str);
+	    /* assign the class_name to any matching pci device */
+	    for_each_pci_func(dev, domain) {
+		if (int_class_id_str == dev->class[2]) {
+		    strlcpy(dev->dev_info->class_name, class_name,
+			    PCI_CLASS_NAME_SIZE - 1);
+		    /* This value is usually the main category */
+		    strlcpy(dev->dev_info->category_name, class_name + 4,
+			    PCI_CLASS_NAME_SIZE - 1);
+		}
+	    }
+	    /* if we have a tab + a char, it means this is a sub class name */
+	} else if ((line[0] == '\t') && (line[1] != '\t')) {
+
+	    /* the sub class name the second field */
+	    strlcpy(sub_class_name, skipspace(strstr(line, " ")),
+		    PCI_CLASS_NAME_SIZE - 1);
+	    remove_eol(sub_class_name);
+
+	    /* the sub class id is first field */
+	    strlcpy(sub_class_id_str, &line[1], 2);
+	    sub_class_id_str[2] = 0;
+
+	    int int_class_id_str = hex_to_int(class_id_str);
+	    int int_sub_class_id_str = hex_to_int(sub_class_id_str);
+	    /* assign the product_name to any matching pci device */
+	    for_each_pci_func(dev, domain) {
+		if (int_class_id_str == dev->class[2] &&
+		    int_sub_class_id_str == dev->class[1])
+		    strlcpy(dev->dev_info->class_name, sub_class_name,
+			    PCI_CLASS_NAME_SIZE - 1);
+	    }
+
+	}
+    }
+    fclose(f);
+    return 0;
+}
+
+/* Try to match any pci device to the appropriate vendor and product name */
+/* it uses the pci.ids from the boot device */
+int get_name_from_pci_ids(struct pci_domain *domain, char *pciids_path)
+{
+    char line[MAX_LINE];
+    char vendor[PCI_VENDOR_NAME_SIZE];
+    char vendor_id[5];
+    char product[PCI_PRODUCT_NAME_SIZE];
+    char product_id[5];
+    char sub_product_id[5];
+    char sub_vendor_id[5];
+    FILE *f;
+    struct pci_device *dev;
+    bool skip_to_next_vendor = false;
+    uint16_t int_vendor_id;
+    uint16_t int_product_id;
+    uint16_t int_sub_product_id;
+    uint16_t int_sub_vendor_id;
+
+    /* Intializing the vendor/product name for each pci device to "unknown" */
+    /* adding a dev_info member if needed */
+    for_each_pci_func(dev, domain) {
+	/* initialize the dev_info structure if it doesn't exist yet. */
+	if (!dev->dev_info) {
+	    dev->dev_info = zalloc(sizeof *dev->dev_info);
+	    if (!dev->dev_info)
+		return -1;
+	}
+	strlcpy(dev->dev_info->vendor_name, "unknown", 7);
+	strlcpy(dev->dev_info->product_name, "unknown", 7);
+    }
+
+    /* Opening the pci.ids from the boot device */
+    f = zfopen(pciids_path, "r");
+    if (!f)
+	return -ENOPCIIDS;
+
+    strlcpy(vendor_id, "0000", 4);
+    strlcpy(product_id, "0000", 4);
+    strlcpy(sub_product_id, "0000", 4);
+    strlcpy(sub_vendor_id, "0000", 4);
+
+    /* for each line we found in the pci.ids */
+    while (fgets(line, sizeof line, f)) {
+	/* Skipping uncessary lines */
+	if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') ||
+	    (line[0] == 10))
+	    continue;
+
+	/* If the line doesn't start with a tab, it means that's a vendor id */
+	if (line[0] != '\t') {
+
+	    /* the 4 first chars are the vendor_id */
+	    strlcpy(vendor_id, line, 4);
+
+	    /* the vendor name is the next field */
+	    vendor_id[4] = 0;
+	    strlcpy(vendor, skipspace(strstr(line, " ")),
+		    PCI_VENDOR_NAME_SIZE - 1);
+
+	    remove_eol(vendor);
+	    /* init product_id, sub_product and sub_vendor */
+	    strlcpy(product_id, "0000", 4);
+	    strlcpy(sub_product_id, "0000", 4);
+	    strlcpy(sub_vendor_id, "0000", 4);
+
+	    /* Unless we found a matching device, we have to skip to the next vendor */
+	    skip_to_next_vendor = true;
+
+	    int_vendor_id = hex_to_int(vendor_id);
+	    /* Iterate in all pci devices to find a matching vendor */
+	    for_each_pci_func(dev, domain) {
+		/* if one device that match this vendor */
+		if (int_vendor_id == dev->vendor) {
+		    /* copy the vendor name for this device */
+		    strlcpy(dev->dev_info->vendor_name, vendor,
+			    PCI_VENDOR_NAME_SIZE - 1);
+		    /* Some pci devices match this vendor, so we have to found them */
+		    skip_to_next_vendor = false;
+		    /* Let's loop on the other devices as some may have the same vendor */
+		}
+	    }
+	    /* if we have a tab + a char, it means this is a product id
+	     * but we only look at it if we own some pci devices of the current vendor*/
+	} else if ((line[0] == '\t') && (line[1] != '\t')
+		   && (skip_to_next_vendor == false)) {
+
+	    /* the product name the second field */
+	    strlcpy(product, skipspace(strstr(line, " ")),
+		    PCI_PRODUCT_NAME_SIZE - 1);
+	    remove_eol(product);
+
+	    /* the product id is first field */
+	    strlcpy(product_id, &line[1], 4);
+	    product_id[4] = 0;
+
+	    /* init sub_product and sub_vendor */
+	    strlcpy(sub_product_id, "0000", 4);
+	    strlcpy(sub_vendor_id, "0000", 4);
+
+	    int_vendor_id = hex_to_int(vendor_id);
+	    int_product_id = hex_to_int(product_id);
+	    /* assign the product_name to any matching pci device */
+	    for_each_pci_func(dev, domain) {
+		if (int_vendor_id == dev->vendor &&
+		    int_product_id == dev->product) {
+		    strlcpy(dev->dev_info->vendor_name, vendor,
+			    PCI_VENDOR_NAME_SIZE - 1);
+		    strlcpy(dev->dev_info->product_name, product,
+			    PCI_PRODUCT_NAME_SIZE - 1);
+		}
+	    }
+
+	    /* if we have two tabs, it means this is a sub product
+	     * but we only look at it if we own some pci devices of the current vendor*/
+	} else if ((line[0] == '\t') && (line[1] == '\t')
+		   && (skip_to_next_vendor == false)) {
+
+	    /* the product name is last field */
+	    strlcpy(product, skipspace(strstr(line, " ")),
+		    PCI_PRODUCT_NAME_SIZE - 1);
+	    strlcpy(product, skipspace(strstr(product, " ")),
+		    PCI_PRODUCT_NAME_SIZE - 1);
+	    remove_eol(product);
+
+	    /* the sub_vendor id is first field */
+	    strlcpy(sub_vendor_id, &line[2], 4);
+	    sub_vendor_id[4] = 0;
+
+	    /* the sub_vendor id is second field */
+	    strlcpy(sub_product_id, &line[7], 4);
+	    sub_product_id[4] = 0;
+
+	    int_vendor_id = hex_to_int(vendor_id);
+	    int_sub_vendor_id = hex_to_int(sub_vendor_id);
+	    int_product_id = hex_to_int(product_id);
+	    int_sub_product_id = hex_to_int(sub_product_id);
+	    /* assign the product_name to any matching pci device */
+	    for_each_pci_func(dev, domain) {
+		if (int_vendor_id == dev->vendor &&
+		    int_product_id == dev->product &&
+		    int_sub_product_id == dev->sub_product &&
+		    int_sub_vendor_id == dev->sub_vendor) {
+		    strlcpy(dev->dev_info->vendor_name, vendor,
+			    PCI_VENDOR_NAME_SIZE - 1);
+		    strlcpy(dev->dev_info->product_name, product,
+			    PCI_PRODUCT_NAME_SIZE - 1);
+		}
+	    }
+	}
+    }
+    fclose(f);
+    return 0;
+}
+
+/* searching if any pcidevice match our query */
+struct match *find_pci_device(const struct pci_domain *domain,
+			      struct match *list)
+{
+    uint32_t did, sid;
+    struct match *m;
+    const struct pci_device *dev;
+
+    /* for all matches we have to search */
+    for (m = list; m; m = m->next) {
+	/* for each pci device we know */
+	for_each_pci_func(dev, domain) {
+	    /* sid & did are the easiest way to compare devices */
+	    /* they are made of vendor/product subvendor/subproduct ids */
+	    sid = dev->svid_sdid;
+	    did = dev->vid_did;
+	    /* if the current device match */
+	    if (((did ^ m->did) & m->did_mask) == 0 &&
+		((sid ^ m->sid) & m->sid_mask) == 0 &&
+		dev->revision >= m->rid_min && dev->revision <= m->rid_max) {
+		dprintf
+		    ("PCI Match: Vendor=%04x Product=%04x Sub_vendor=%04x Sub_Product=%04x Release=%02x\n",
+		     dev->vendor, dev->product, dev->sub_vendor,
+		     dev->sub_product, dev->revision);
+		/* returning the matched pci device */
+		return m;
+	    }
+	}
+    }
+    return NULL;
+}
+
+/* scanning the pci bus to find pci devices */
+struct pci_domain *pci_scan(void)
+{
+    struct pci_domain *domain = NULL;
+    struct pci_bus *bus = NULL;
+    struct pci_slot *slot = NULL;
+    struct pci_device *func = NULL;
+    unsigned int nbus, ndev, nfunc, maxfunc;
+    uint32_t did, sid, rcid;
+    uint8_t hdrtype;
+    pciaddr_t a;
+    int cfgtype;
+
+    cfgtype = pci_set_config_type(PCI_CFG_AUTO);
+
+    dprintf("PCI configuration type %d\n", cfgtype);
+
+    if (cfgtype == PCI_CFG_NONE)
+	return NULL;
+
+    dprintf("Scanning PCI Buses\n");
+
+    for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) {
+	dprintf("Probing bus 0x%02x... \n", nbus);
+	bus = NULL;
+
+	for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) {
+	    maxfunc = 1;	/* Assume a single-function device */
+	    slot = NULL;
+
+	    for (nfunc = 0; nfunc < maxfunc; nfunc++) {
+		a = pci_mkaddr(nbus, ndev, nfunc, 0);
+		did = pci_readl(a);
+
+		if (did == 0xffffffff || did == 0xffff0000 ||
+		    did == 0x0000ffff || did == 0x00000000)
+		    continue;
+
+		hdrtype = pci_readb(a + 0x0e);
+
+		if (hdrtype & 0x80)
+		    maxfunc = MAX_PCI_FUNC;	/* Multifunction device */
+
+		rcid = pci_readl(a + 0x08);
+		sid = pci_readl(a + 0x2c);
+
+		if (!domain) {
+		    domain = zalloc(sizeof *domain);
+		    if (!domain)
+			goto bail;
+		}
+		if (!bus) {
+		    bus = zalloc(sizeof *bus);
+		    if (!bus)
+			goto bail;
+		    domain->bus[nbus] = bus;
+		}
+		if (!slot) {
+		    slot = zalloc(sizeof *slot);
+		    if (!slot)
+			goto bail;
+		    bus->slot[ndev] = slot;
+		}
+		func = zalloc(sizeof *func);
+		if (!func)
+		    goto bail;
+
+		slot->func[nfunc] = func;
+
+		func->vid_did = did;
+		func->svid_sdid = sid;
+		func->rid_class = rcid;
+
+		dprintf
+		    ("Scanning: BUS %02x DID %08x (%04x:%04x) SID %08x RID %02x\n",
+		     nbus, did, did >> 16, (did << 16) >> 16, sid, rcid & 0xff);
+	    }
+	}
+    }
+
+    return domain;
+
+bail:
+    free_pci_domain(domain);
+    return NULL;
+}
+
+/* gathering additional configuration*/
+void gather_additional_pci_config(struct pci_domain *domain)
+{
+    struct pci_device *dev;
+    pciaddr_t pci_addr;
+    int cfgtype;
+
+    cfgtype = pci_set_config_type(PCI_CFG_AUTO);
+    if (cfgtype == PCI_CFG_NONE)
+	return;
+
+    for_each_pci_func3(dev, domain, pci_addr) {
+	if (!dev->dev_info) {
+	    dev->dev_info = zalloc(sizeof *dev->dev_info);
+	    if (!dev->dev_info) {
+		return;
+	    }
+	}
+	dev->dev_info->irq = pci_readb(pci_addr + 0x3c);
+	dev->dev_info->latency = pci_readb(pci_addr + 0x0d);
+    }
+}
+
+void free_pci_domain(struct pci_domain *domain)
+{
+    struct pci_bus *bus;
+    struct pci_slot *slot;
+    struct pci_device *func;
+    unsigned int nbus, ndev, nfunc;
+
+    if (domain) {
+	for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) {
+	    bus = domain->bus[nbus];
+	    if (bus) {
+		for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) {
+		    slot = bus->slot[ndev];
+		    if (slot) {
+			for (nfunc = 0; nfunc < MAX_PCI_FUNC; nfunc++) {
+			    func = slot->func[nfunc];
+			    if (func) {
+				if (func->dev_info)
+				    free(func->dev_info);
+				free(func);
+			    }
+			}
+			free(slot);
+		    }
+		}
+		free(bus);
+	    }
+	}
+	free(domain);
+    }
+}
+
+/* Try to match any pci device to the appropriate kernel module */
+/* it uses the modules.alias from the boot device */
+int get_module_name_from_alias(struct pci_domain *domain, char *modules_alias_path)
+{
+  char line[MAX_LINE];
+  char module_name[21]; // the module name field is 21 char long
+  char delims[]="*";    // colums are separated by spaces
+  char vendor_id[16];
+  char product_id[16];
+  char sub_vendor_id[16];
+  char sub_product_id[16];
+  FILE *f;
+  struct pci_device *dev=NULL;
+
+  /* Intializing the linux_kernel_module for each pci device to "unknown" */
+  /* adding a dev_info member if needed */
+  for_each_pci_func(dev, domain) {
+    /* initialize the dev_info structure if it doesn't exist yet. */
+    if (! dev->dev_info) {
+      dev->dev_info = zalloc(sizeof *dev->dev_info);
+      if (!dev->dev_info)
+	return -1;
+    }
+    for (int i=0;i<MAX_KERNEL_MODULES_PER_PCI_DEVICE;i++) {
+     if (strlen(dev->dev_info->linux_kernel_module[i])==0)
+       strlcpy(dev->dev_info->linux_kernel_module[i], "unknown",7);
+    }
+  }
+
+  /* Opening the modules.pcimap (of a linux kernel) from the boot device */
+  f=zfopen(modules_alias_path, "r");
+  if (!f)
+    return -ENOMODULESALIAS;
+
+  /* for each line we found in the modules.pcimap */
+  while ( fgets(line, sizeof line, f) ) {
+    /* skipping unecessary lines */
+    if ((line[0] == '#') || (strstr(line,"alias pci:v")==NULL))
+        continue;
+
+    /* Resetting temp buffer*/
+    memset(module_name,0,sizeof(module_name));
+    memset(vendor_id,0,sizeof(vendor_id));
+    memset(sub_vendor_id,0,sizeof(sub_vendor_id));
+    memset(product_id,0,sizeof(product_id));
+    memset(sub_product_id,0,sizeof(sub_product_id));
+    strcpy(vendor_id,"0000");
+    strcpy(product_id,"0000");
+    /* ffff will be used to match any device as in modules.alias
+     * a missing subvendor/product have to be considered as  0xFFFF*/
+    strcpy(sub_product_id,"ffff");
+    strcpy(sub_vendor_id,"ffff");
+
+    char *result = NULL;
+    int field=0;
+
+    /* looking for the next field */
+    result = strtok(line+strlen("alias pci:v"), delims);
+    while( result != NULL ) {
+	if (field==0) {
+
+		/* Searching for the vendor separator*/
+		char *temp = strstr(result,"d");
+		if (temp != NULL) {
+			strlcpy(vendor_id,result,temp-result);
+			result+=strlen(vendor_id)+1;
+		}
+
+		/* Searching for the product separator*/
+		temp = strstr(result,"sv");
+		if (temp != NULL) {
+			strlcpy(product_id,result,temp-result);
+			result+=strlen(product_id)+1;
+		}
+
+		/* Searching for the sub vendor separator*/
+		temp = strstr(result,"sd");
+		if (temp != NULL) {
+			strlcpy(sub_vendor_id,result,temp-result);
+			result+=strlen(sub_vendor_id)+1;
+		}
+
+		/* Searching for the sub product separator*/
+		temp = strstr(result,"bc");
+		if (temp != NULL) {
+			strlcpy(sub_product_id,result,temp-result);
+			result+=strlen(sub_product_id)+1;
+		}
+	/* That's the module name */
+	} else if ((strlen(result)>2) &&
+			(result[0]==0x20))
+		strcpy(module_name,result+1);
+		/* We have to replace \n by \0*/
+		module_name[strlen(module_name)-1]='\0';
+	field++;
+
+	/* Searching the next field */
+        result = strtok( NULL, delims );
+    }
+
+    /* Now we have extracted informations from the modules.alias
+     * Let's compare it with the devices we know*/
+    int int_vendor_id=hex_to_int(vendor_id);
+    int int_sub_vendor_id=hex_to_int(sub_vendor_id);
+    int int_product_id=hex_to_int(product_id);
+    int int_sub_product_id=hex_to_int(sub_product_id);
+    /* if a pci_device matches an entry, fill the linux_kernel_module with
+       the appropriate kernel module */
+    for_each_pci_func(dev, domain) {
+      if (int_vendor_id == dev->vendor &&
+	  int_product_id == dev->product &&
+	  (int_sub_product_id & dev->sub_product)
+	  == dev->sub_product &&
+	  (int_sub_vendor_id & dev->sub_vendor)
+	  == dev->sub_vendor) {
+	      bool found=false;
+	      
+	      /* Scan all known kernel modules for this pci device */
+	      for (int i=0; i<dev->dev_info->linux_kernel_module_count; i++) {
+
+       	      /* Try to detect if we already knew the same kernel module*/
+	       if (strstr(dev->dev_info->linux_kernel_module[i], module_name)) {
+		      found=true;
+		      break;
+	       }
+	      }
+	      /* If we don't have this kernel module, let's add it */
+	      if (!found) {
+		strcpy(dev->dev_info->linux_kernel_module[dev->dev_info->linux_kernel_module_count], module_name);
+		dev->dev_info->linux_kernel_module_count++;
+	      }
+      }
+    }
+  }
+  fclose(f);
+  return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/writeb.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/writeb.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/writeb.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint8_t
+#define BWL(x) x ## b
+#define BIOSCALL 0xb10b
+#include "pci/writex.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/writel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/writel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/writel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint32_t
+#define BWL(x) x ## l
+#define BIOSCALL 0xb10d
+#include "pci/writex.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/writew.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/writew.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/writew.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#define TYPE uint16_t
+#define BWL(x) x ## w
+#define BIOSCALL 0xb10c
+#include "pci/writex.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/pci/writex.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/pci/writex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/pci/writex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+#include "pci/pci.h"
+
+void BWL(pci_write)(TYPE v, pciaddr_t a)
+{
+    for (;;) {
+	switch (__pci_cfg_type) {
+	case PCI_CFG_AUTO:
+	    pci_set_config_type(PCI_CFG_AUTO);
+	    break;		/* Try again */
+
+	case PCI_CFG_TYPE1:
+	    {
+		uint32_t oldcf8;
+		cli();
+		oldcf8 = inl(0xcf8);
+		outl(a, 0xcf8);
+		BWL(out) (v, 0xcfc + (a & 3));
+		outl(oldcf8, 0xcf8);
+		sti();
+	    }
+	    return;
+
+	case PCI_CFG_TYPE2:
+	    {
+		uint8_t oldcf8, oldcfa;
+
+		if (a & (0x10 << 11))
+		    return;	/* Devices 16-31 not supported */
+
+		cli();
+		oldcf8 = inb(0xcf8);
+		oldcfa = inb(0xcfa);
+		outb(0xf0 + ((a >> (8 - 1)) & 0x0e), 0xcf8);
+		outb(a >> 16, 0xcfa);
+		BWL(out) (v, 0xc000 + ((a >> (11 - 8)) & 0xf00) + (a & 0xff));
+		outb(oldcf8, 0xcf8);
+		outb(oldcfa, 0xcfa);
+		sti();
+	    }
+	    return;
+
+	case PCI_CFG_BIOS:
+	    __pci_read_write_bios(BIOSCALL, v, a);
+	    return;
+
+	default:
+	    return;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/perror.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/perror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/perror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,12 @@
+/*
+ * perror.c
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+void perror(const char *s)
+{
+    fprintf(stderr, "%s: error %d\n", s, errno);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/printf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/printf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/printf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+/*
+ * printf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int printf(const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vfprintf(stdout, format, ap);
+    va_end(ap);
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/putchar.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/putchar.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/putchar.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * putchar.c
+ *
+ * gcc "printf decompilation" expects this to exist...
+ */
+
+#include <stdio.h>
+
+#undef putchar
+
+int putchar(int c)
+{
+    unsigned char ch = c;
+
+    return _fwrite(&ch, 1, stdout) == 1 ? ch : EOF;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/puts.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/puts.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/puts.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * puts.c
+ */
+
+#include <stdio.h>
+
+int puts(const char *s)
+{
+    if (fputs(s, stdout) < 0)
+	return -1;
+
+    return _fwrite("\n", 1, stdout);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/qsort.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/qsort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/qsort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/*
+ * qsort.c
+ *
+ * This is actually combsort.  It's an O(n log n) algorithm with
+ * simplicity/small code size being its main virtue.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+static inline size_t newgap(size_t gap)
+{
+    gap = (gap * 10) / 13;
+    if (gap == 9 || gap == 10)
+	gap = 11;
+
+    if (gap < 1)
+	gap = 1;
+    return gap;
+}
+
+void qsort(void *base, size_t nmemb, size_t size,
+	   int (*compar) (const void *, const void *))
+{
+    size_t gap = nmemb;
+    size_t i, j;
+    char *p1, *p2;
+    int swapped;
+
+    if (!nmemb)
+	return;
+
+    do {
+	gap = newgap(gap);
+	swapped = 0;
+
+	for (i = 0, p1 = base; i < nmemb - gap; i++, p1 += size) {
+	    j = i + gap;
+	    if (compar(p1, p2 = (char *)base + j * size) > 0) {
+		memswap(p1, p2, size);
+		swapped = 1;
+	    }
+	}
+    } while (gap > 1 || swapped);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/seed48.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/seed48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/seed48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * seed48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+extern unsigned short __rand48_seed[3];
+
+unsigned short *seed48(const unsigned short xsubi[3])
+{
+    static unsigned short oldseed[3];
+    memcpy(oldseed, __rand48_seed, sizeof __rand48_seed);
+    memcpy(__rand48_seed, xsubi, sizeof __rand48_seed);
+
+    return oldseed;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/setjmp.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/*
+ * arch/i386/setjmp.S
+ *
+ * setjmp/longjmp for the i386 architecture
+ *
+ *
+ *
+ * The jmp_buf is assumed to contain the following, in order:
+ *	%ebx
+ *	%esp
+ *	%ebp
+ *	%esi
+ *	%edi
+ *	<return address>
+ */
+/*
+	.text
+	.align 4
+
+	.globl _setjmp
+	.type _setjmp, @function
+_setjmp:				# gcc 4.0.1 wants this as an alias?
+
+	.globl setjmp
+	.type setjmp, @function
+setjmp:
+#ifdef REGPARM
+	movl %eax,%edx
+#else
+	movl 4(%esp),%edx
+#endif
+	popl %ecx			# Return address, and adjust the stack
+	xorl %eax,%eax			# Return value
+	movl %ebx,(%edx)
+	movl %esp,4(%edx)		# Post-return %esp!
+	pushl %ecx			# Make the call/return stack happy
+	movl %ebp,8(%edx)
+	movl %esi,12(%edx)
+	movl %edi,16(%edx)
+	movl %ecx,20(%edx)		# Return address
+	ret
+
+	.size setjmp,.-setjmp
+
+	.text
+	.align 4
+	.globl longjmp
+	.type longjmp, @function
+longjmp:
+#ifdef REGPARM
+	xchgl %eax,%edx
+#else
+	movl 4(%esp),%edx		# jmp_ptr address
+	movl 8(%esp),%eax		# Return value
+#endif
+	movl (%edx),%ebx
+	movl 4(%edx),%esp
+	movl 8(%edx),%ebp
+	movl 12(%edx),%esi
+	movl 16(%edx),%edi
+	jmp *20(%edx)
+
+	.size longjmp,.-longjmp
+*/
+#if __SIZEOF_POINTER__ == 4
+#include <i386/setjmp.S>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/setjmp.S>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/skipspace.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/skipspace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/skipspace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,8 @@
+#include <ctype.h>
+
+char *skipspace(const char *p)
+{
+   while (isspace((unsigned char)*p))
+            p++;
+   return (char *)p;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/snprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/snprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/snprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * snprintf.c
+ */
+
+#include <stdio.h>
+
+int snprintf(char *buffer, size_t n, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vsnprintf(buffer, n, format, ap);
+    va_end(ap);
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * sprintf.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int sprintf(char *buffer, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vsnprintf(buffer, ~(size_t) 0, format, ap);
+    va_end(ap);
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/srand48.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/srand48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/srand48.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * srand48.c
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+extern unsigned short __rand48_seed[3];
+
+void srand48(long seedval)
+{
+    __rand48_seed[0] = 0x330e;
+    __rand48_seed[1] = (unsigned short)seedval;
+    __rand48_seed[2] = (unsigned short)((uint32_t) seedval >> 16);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sscanf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sscanf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sscanf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+/*
+ * sscanf()
+ */
+
+#include <stdio.h>
+
+int sscanf(const char *str, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, format);
+    rv = vsscanf(str, format, ap);
+    va_end(ap);
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/stack.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/stack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/stack.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,4 @@
+#include <stdlib.h>
+
+/* Default stack size 8 MB */
+size_t __stack_size = 8 << 20;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/stpcpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/stpcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/stpcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * stpcpy.c
+ *
+ * stpcpy()
+ */
+
+#include <string.h>
+
+char *stpcpy(char *dst, const char *src)
+{
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    for (;;) {
+	*q = ch = *p++;
+	if (!ch)
+	    break;
+	q++;
+    }
+
+    return q;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/stpncpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/stpncpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/stpncpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+/*
+ * stpncpy.c
+ *
+ * stpncpy()
+ */
+
+#include <string.h>
+
+char *stpncpy(char *dst, const char *src, size_t n)
+{
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    while (n--) {
+	*q = ch = *p++;
+	if (!ch)
+	    break;
+	q++;
+    }
+
+    return q;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strcasecmp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strcasecmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strcasecmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * strcasecmp.c
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+int strcasecmp(const char *s1, const char *s2)
+{
+    const unsigned char *c1 = (const unsigned char *)s1;
+    const unsigned char *c2 = (const unsigned char *)s2;
+    unsigned char ch;
+    int d = 0;
+
+    while (1) {
+	/* toupper() expects an unsigned char (implicitly cast to int)
+	   as input, and returns an int, which is exactly what we want. */
+	d = toupper(ch = *c1++) - toupper(*c2++);
+	if (d || !ch)
+	    break;
+    }
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strcat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strcat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strcat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * strcat.c
+ */
+
+#include <string.h>
+
+char *strcat(char *dst, const char *src)
+{
+    strcpy(strchr(dst, '\0'), src);
+    return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strchr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * strchr.c
+ */
+
+#include <string.h>
+
+char *strchr(const char *s, int c)
+{
+    while (*s != (char)c) {
+	if (!*s)
+	    return NULL;
+	s++;
+    }
+
+    return (char *)s;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strcmp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strcmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strcmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * strcmp.c
+ */
+
+#include <string.h>
+
+int strcmp(const char *s1, const char *s2)
+{
+    const unsigned char *c1 = (const unsigned char *)s1;
+    const unsigned char *c2 = (const unsigned char *)s2;
+    unsigned char ch;
+    int d = 0;
+
+    while (1) {
+	d = (int)(ch = *c1++) - (int)*c2++;
+	if (d || !ch)
+	    break;
+    }
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strcpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,20 @@
+/*
+ * strcpy.c
+ *
+ * strcpy()
+ */
+
+#include <string.h>
+
+char *strcpy(char *dst, const char *src)
+{
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    do {
+	*q++ = ch = *p++;
+    } while (ch);
+
+    return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strdup.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strdup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strdup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+/*
+ * strdup.c
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+char *strdup(const char *s)
+{
+    int l = strlen(s) + 1;
+    char *d = malloc(l);
+
+    if (d)
+	memcpy(d, s, l);
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strerror.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strerror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strerror.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+/*
+ * strerror.c
+ */
+
+#include <string.h>
+
+char *strerror(int errnum)
+{
+	static char message[32] = "error ";	/* enough for error 2^63-1 */
+	char numbuf[32];
+	char *p;
+	unsigned int e = (unsigned int)errnum;
+
+	extern const int sys_nerr;
+	extern const char *const sys_errlist[];
+
+	if (e < (unsigned int)sys_nerr && sys_errlist[e])
+		return (char *)sys_errlist[e];
+
+	p = numbuf + sizeof numbuf;
+	*--p = '\0';
+
+	do {
+		*--p = (e % 10) + '0';
+		e /= 10;
+	} while (e);
+
+	memcpy(message + 6, p, (numbuf + sizeof numbuf) - p);
+
+	return message;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strlcat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strlcat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strlcat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ * strlcat.c
+ */
+
+#include <string.h>
+#include <klibc/compiler.h>
+
+size_t strlcat(char *dst, const char *src, size_t size)
+{
+    size_t bytes = 0;
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    while (bytes < size && *q) {
+	q++;
+	bytes++;
+    }
+
+    while ((ch = *p++)) {
+	if (bytes < size)
+	    *q++ = ch;
+
+	bytes++;
+    }
+
+    *q = '\0';
+    return bytes;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strlcpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strlcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strlcpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * strlcpy.c
+ */
+
+#include <string.h>
+#include <klibc/compiler.h>
+
+size_t strlcpy(char *dst, const char *src, size_t size)
+{
+    size_t bytes = 0;
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    while ((ch = *p++)) {
+	if (bytes < size)
+	    *q++ = ch;
+
+	bytes++;
+    }
+
+    *q = '\0';
+    return bytes;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strlen.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strlen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strlen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * strlen()
+ */
+
+#include <string.h>
+
+size_t strlen(const char *s)
+{
+    const char *ss = s;
+    while (*ss)
+	ss++;
+    return ss - s;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strncasecmp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strncasecmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strncasecmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+ * strncasecmp.c
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+int strncasecmp(const char *s1, const char *s2, size_t n)
+{
+    const unsigned char *c1 = (const unsigned char *)s1;
+    const unsigned char *c2 = (const unsigned char *)s2;
+    unsigned char ch;
+    int d = 0;
+
+    while (n--) {
+	/* toupper() expects an unsigned char (implicitly cast to int)
+	   as input, and returns an int, which is exactly what we want. */
+	d = toupper(ch = *c1++) - toupper(*c2++);
+	if (d || !ch)
+	    break;
+    }
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strncat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strncat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strncat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * strncat.c
+ */
+
+#include <string.h>
+
+char *strncat(char *dst, const char *src, size_t n)
+{
+    strncpy(strchr(dst, '\0'), src, n);
+    return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strncmp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strncmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strncmp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * strncmp.c
+ */
+
+#include <string.h>
+
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+    const unsigned char *c1 = (const unsigned char *)s1;
+    const unsigned char *c2 = (const unsigned char *)s2;
+    unsigned char ch;
+    int d = 0;
+
+    while (n--) {
+	d = (int)(ch = *c1++) - (int)*c2++;
+	if (d || !ch)
+	    break;
+    }
+
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strncpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strncpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strncpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,22 @@
+/*
+ * strncpy.c
+ *
+ * strncpy()
+ */
+
+#include <string.h>
+
+char *strncpy(char *dst, const char *src, size_t n)
+{
+    char *q = dst;
+    const char *p = src;
+    char ch;
+
+    while (n--) {
+	*q++ = ch = *p++;
+	if (!ch)
+	    break;
+    }
+
+    return dst;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strndup.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strndup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strndup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,17 @@
+/*
+ * strndup.c
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+char *strndup(const char *s, size_t n)
+{
+    int l = n > strlen(s) ? strlen(s) + 1 : n + 1;
+    char *d = malloc(l);
+
+    if (d)
+	memcpy(d, s, l);
+    d[n] = '\0';
+    return d;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strnlen.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strnlen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strnlen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * strnlen()
+ */
+
+#include <string.h>
+
+size_t strnlen(const char *s, size_t n)
+{
+    const char *ss = s;
+    while (n-- && *ss)
+	ss++;
+    return ss - s;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strntoimax.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strntoimax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strntoimax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * strntoimax.c
+ *
+ * strntoimax()
+ */
+
+#include <stddef.h>
+#include <inttypes.h>
+
+intmax_t strntoimax(const char *nptr, char **endptr, int base, size_t n)
+{
+    return (intmax_t) strntoumax(nptr, endptr, base, n);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strntoumax.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strntoumax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strntoumax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,73 @@
+/*
+ * strntoumax.c
+ *
+ * The strntoumax() function and associated
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <ctype.h>
+
+static inline int digitval(int ch)
+{
+    if (ch >= '0' && ch <= '9') {
+	return ch - '0';
+    } else if (ch >= 'A' && ch <= 'Z') {
+	return ch - 'A' + 10;
+    } else if (ch >= 'a' && ch <= 'z') {
+	return ch - 'a' + 10;
+    } else {
+	return -1;
+    }
+}
+
+uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n)
+{
+    int minus = 0;
+    uintmax_t v = 0;
+    int d;
+
+    while (n && isspace((unsigned char)*nptr)) {
+	nptr++;
+	n--;
+    }
+
+    /* Single optional + or - */
+    if (n && *nptr == '-') {
+	minus = 1;
+	nptr++;
+	n--;
+    } else if (n && *nptr == '+') {
+	nptr++;
+    }
+
+    if (base == 0) {
+	if (n >= 2 && nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) {
+	    n -= 2;
+	    nptr += 2;
+	    base = 16;
+	} else if (n >= 1 && nptr[0] == '0') {
+	    n--;
+	    nptr++;
+	    base = 8;
+	} else {
+	    base = 10;
+	}
+    } else if (base == 16) {
+	if (n >= 2 && nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) {
+	    n -= 2;
+	    nptr += 2;
+	}
+    }
+
+    while (n && (d = digitval(*nptr)) >= 0 && d < base) {
+	v = v * base + d;
+	n--;
+	nptr++;
+    }
+
+    if (endptr)
+	*endptr = (char *)nptr;
+
+    return minus ? -v : v;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strrchr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strrchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strrchr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+/*
+ * strrchr.c
+ */
+
+#include <string.h>
+
+char *strrchr(const char *s, int c)
+{
+    const char *found = NULL;
+
+    while (*s) {
+	if (*s == (char)c)
+	    found = s;
+	s++;
+    }
+
+    return (char *)found;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strreplace.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strreplace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strreplace.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+char *strreplace(const char *string, const char *string_to_replace,
+		 const char *string_to_insert)
+{
+    char *token = NULL;
+    char *out = NULL;
+
+    size_t slen, srlen, silen;
+
+    token = strstr(string, string_to_replace);
+    if (!token)
+	return strdup(string);
+
+    slen  = strlen(string);
+    srlen = strlen(string_to_replace);
+    silen = strlen(string_to_insert);
+    
+    out = malloc(slen - srlen + silen + 1);
+    if (!out)
+	return NULL;
+    
+    memcpy(out, string, token - string);
+    memcpy(out + (token - string), string_to_insert, silen);
+    memcpy(out + (token - string) + silen, token + srlen, 
+	   slen - srlen - (token - string) + 1);
+
+    return out;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strsep.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strsep.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strsep.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,21 @@
+/*
+ * strsep.c
+ */
+
+#include <string.h>
+
+char *strsep(char **stringp, const char *delim)
+{
+    char *s = *stringp;
+    char *e;
+
+    if (!s)
+	return NULL;
+
+    e = strpbrk(s, delim);
+    if (e)
+	*e++ = '\0';
+
+    *stringp = e;
+    return s;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strspn.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strspn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strspn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+/*
+ * strspn, strcspn
+ */
+
+#include <string.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <limits.h>
+
+#ifndef LONG_BIT
+#define LONG_BIT (CHAR_BIT*sizeof(long))
+#endif
+
+static void set_bit(unsigned long *bitmap, unsigned int bit)
+{
+    bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
+}
+
+static int test_bit(unsigned long *bitmap, unsigned int bit)
+{
+    return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1;
+}
+
+static size_t strxspn(const char *s, const char *map, int parity)
+{
+    unsigned long matchmap[((1 << CHAR_BIT) + LONG_BIT - 1) / LONG_BIT];
+    size_t n = 0;
+
+    /* Create bitmap */
+    memset(matchmap, 0, sizeof matchmap);
+    while (*map)
+	set_bit(matchmap, (unsigned char)*map++);
+
+    /* Make sure the null character never matches */
+    if (parity)
+	set_bit(matchmap, 0);
+
+    /* Calculate span length */
+    while (test_bit(matchmap, (unsigned char)*s++) ^ parity)
+	n++;
+
+    return n;
+}
+
+size_t strspn(const char *s, const char *accept)
+{
+    return strxspn(s, accept, 0);
+}
+
+size_t strcspn(const char *s, const char *reject)
+{
+    return strxspn(s, reject, 1);
+}
+
+char *strpbrk(const char *s, const char *accept)
+{
+    const char *ss = s + strxspn(s, accept, 1);
+
+    return *ss ? (char *)ss : NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strstr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+/*
+ * strstr.c
+ */
+
+#include <string.h>
+
+char *strstr(const char *haystack, const char *needle)
+{
+    return (char *)memmem(haystack, strlen(haystack), needle, strlen(needle));
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtoimax.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtoimax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtoimax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE intmax_t
+#define NAME strtoimax
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtok.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtok.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtok.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+/*
+ * strtok.c
+ */
+
+#include <string.h>
+
+char *strtok(char *s, const char *delim)
+{
+    static char *holder;
+
+    if (s)
+	holder = s;
+
+    return strsep(&holder, delim);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtol.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtol.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtol.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE signed long
+#define NAME strtol
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtoll.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtoll.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtoll.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE signed long long
+#define NAME strtoll
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtoul.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtoul.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtoul.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE unsigned long
+#define NAME strtoul
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtoull.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtoull.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtoull.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE unsigned long long
+#define NAME strtoull
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtoumax.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtoumax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtoumax.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#define TYPE uintmax_t
+#define NAME strtoumax
+#include "strtox.c"
Index: bootcd/isolinux/syslinux-6.03/com32/lib/strtox.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/strtox.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/strtox.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,13 @@
+/*
+ * strtox.c
+ *
+ * strto...() functions, by macro definition
+ */
+
+#include <stddef.h>
+#include <inttypes.h>
+
+TYPE NAME(const char *nptr, char **endptr, int base)
+{
+    return (TYPE) strntoumax(nptr, endptr, base, ~(size_t) 0);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/suffix_number.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/suffix_number.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/suffix_number.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * suffix_number.c
+ *
+ * Convert a string of a number with potential SI suffix to int-type
+ */
+
+#include <stdlib.h>
+#include <suffix_number.h>
+
+/* Get a value with a potential suffix (k/m/g/t/p/e) */
+unsigned long long suffix_number(const char *str)
+{
+    char *ep;
+    unsigned long long v;
+    int shift;
+
+    v = strtoull(str, &ep, 0);
+    switch (*ep | 0x20) {
+    case 'k':
+	shift = 10;
+	break;
+    case 'm':
+	shift = 20;
+	break;
+    case 'g':
+	shift = 30;
+	break;
+    case 't':
+	shift = 40;
+	break;
+    case 'p':
+	shift = 50;
+	break;
+    case 'e':
+	shift = 60;
+	break;
+    default:
+	shift = 0;
+	break;
+    }
+    v <<= shift;
+
+    return v;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,444 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ansi.c
+ *
+ * ANSI character code engine
+ */
+
+#include <string.h>
+#include <colortbl.h>
+#include "ansi.h"
+
+static const struct term_state default_state = {
+    .state = st_init,
+    .pvt = false,
+    .nparms = 0,
+    .xy = {0, 0},
+    .cindex = 0,		/* First color table entry */
+    .vtgraphics = false,
+    .intensity = 1,
+    .underline = false,
+    .blink = false,
+    .reverse = false,
+    .fg = 7,
+    .bg = 0,
+    .autocr = true,	  	/* Mimic \n -> \r\n conversion by default */
+    .autowrap = true,		/* Wrap lines by default */
+    .saved_xy = {0, 0},
+    .cursor = true,
+};
+
+/* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */
+static const char decvt_to_cp437[] = {
+    0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361,
+    0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304,
+    0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302,
+    0263, 0363, 0362, 0343, 0330, 0234, 0007, 00
+};
+
+void __ansi_init(const struct term_info *ti)
+{
+    memcpy(ti->ts, &default_state, sizeof default_state);
+}
+
+void __ansi_putchar(const struct term_info *ti, uint8_t ch)
+{
+    const struct ansi_ops *op = ti->op;
+    struct term_state *st = ti->ts;
+    const int rows = ti->rows;
+    const int cols = ti->cols;
+    struct curxy xy = st->xy;
+
+    switch (st->state) {
+    case st_init:
+	switch (ch) {
+	case 1 ... 5:
+	    st->state = st_tbl;
+	    st->parms[0] = ch;
+	    break;
+	case '\a':
+	    op->beep();
+	    break;
+	case '\b':
+	    if (xy.x > 0)
+		xy.x--;
+	    break;
+	case '\t':
+	    {
+		int nsp = 8 - (xy.x & 7);
+		while (nsp--)
+		    __ansi_putchar(ti, ' ');
+	    }
+	    return;		/* Cursor already updated */
+	case '\n':
+	case '\v':
+	case '\f':
+	    xy.y++;
+	    if (st->autocr)
+		xy.x = 0;
+	    break;
+	case '\r':
+	    xy.x = 0;
+	    break;
+	case 127:
+	    /* Ignore delete */
+	    break;
+	case 14:
+	    st->vtgraphics = 1;
+	    break;
+	case 15:
+	    st->vtgraphics = 0;
+	    break;
+	case 27:
+	    st->state = st_esc;
+	    break;
+	default:
+	    /* Print character */
+	    if (ch >= 32) {
+		if (st->vtgraphics && (ch & 0xe0) == 0x60)
+		    ch = decvt_to_cp437[ch - 0x60];
+
+		op->write_char(xy.x, xy.y, ch, st);
+		xy.x++;
+	    }
+	    break;
+	}
+	break;
+
+    case st_esc:
+	switch (ch) {
+	case '%':
+	case '(':
+	case ')':
+	case '#':
+	    /* Ignore this plus the subsequent character, allows
+	       compatibility with Linux sequence to set charset */
+	    break;
+	case '[':
+	    st->state = st_csi;
+	    st->nparms = 0;
+	    st->pvt = false;
+	    memset(st->parms, 0, sizeof st->parms);
+	    break;
+	case 'c':
+	    /* Reset terminal */
+	    memcpy(&st, &default_state, sizeof st);
+	    op->erase(st, 0, 0, cols - 1, rows - 1);
+	    xy.x = xy.y = 0;
+	    st->state = st_init;
+	    break;
+	default:
+	    /* Ignore sequence */
+	    st->state = st_init;
+	    break;
+	}
+	break;
+
+    case st_csi:
+	{
+	    int p0 = st->parms[0] ? st->parms[0] : 1;
+
+	    if (ch >= '0' && ch <= '9') {
+		st->parms[st->nparms] = st->parms[st->nparms] * 10 + (ch - '0');
+	    } else if (ch == ';') {
+		st->nparms++;
+		if (st->nparms >= ANSI_MAX_PARMS)
+		    st->nparms = ANSI_MAX_PARMS - 1;
+		break;
+	    } else if (ch == '?') {
+		st->pvt = true;
+	    } else {
+		switch (ch) {
+		case 'A':
+		    {
+			int y = xy.y - p0;
+			xy.y = (y < 0) ? 0 : y;
+		    }
+		    break;
+		case 'B':
+		    {
+			int y = xy.y + p0;
+			xy.y = (y >= rows) ? rows - 1 : y;
+		    }
+		    break;
+		case 'C':
+		    {
+			int x = xy.x + p0;
+			xy.x = (x >= cols) ? cols - 1 : x;
+		    }
+		    break;
+		case 'D':
+		    {
+			int x = xy.x - p0;
+			xy.x = (x < 0) ? 0 : x;
+		    }
+		    break;
+		case 'E':
+		    {
+			int y = xy.y + p0;
+			xy.y = (y >= rows) ? rows - 1 : y;
+			xy.x = 0;
+		    }
+		    break;
+		case 'F':
+		    {
+			int y = xy.y - p0;
+			xy.y = (y < 0) ? 0 : y;
+			xy.x = 0;
+		    }
+		    break;
+		case 'G':
+		case '\'':
+		    {
+			int x = st->parms[0] - 1;
+			xy.x = (x >= cols) ? cols - 1 : (x < 0) ? 0 : x;
+		    }
+		    break;
+		case 'H':
+		case 'f':
+		    {
+			int y = st->parms[0] - 1;
+			int x = st->parms[1] - 1;
+
+			xy.x = (x >= cols) ? cols - 1 : (x < 0) ? 0 : x;
+			xy.y = (y >= rows) ? rows - 1 : (y < 0) ? 0 : y;
+		    }
+		    break;
+		case 'J':
+		    {
+			switch (st->parms[0]) {
+			case 0:
+			    op->erase(st, xy.x, xy.y, cols - 1, xy.y);
+			    if (xy.y < rows - 1)
+				op->erase(st, 0, xy.y + 1, cols - 1, rows - 1);
+			    break;
+
+			case 1:
+			    if (xy.y > 0)
+				op->erase(st, 0, 0, cols - 1, xy.y - 1);
+			    if (xy.y > 0)
+				op->erase(st, 0, xy.y, xy.x - 1, xy.y);
+			    break;
+
+			case 2:
+			    op->erase(st, 0, 0, cols - 1, rows - 1);
+			    break;
+
+			default:
+			    /* Ignore */
+			    break;
+			}
+		    }
+		    break;
+		case 'K':
+		    {
+			switch (st->parms[0]) {
+			case 0:
+			    op->erase(st, xy.x, xy.y, cols - 1, xy.y);
+			    break;
+
+			case 1:
+			    if (xy.x > 0)
+				op->erase(st, 0, xy.y, xy.x - 1, xy.y);
+			    break;
+
+			case 2:
+			    op->erase(st, 0, xy.y, cols - 1, xy.y);
+			    break;
+
+			default:
+			    /* Ignore */
+			    break;
+			}
+		    }
+		    break;
+		case 'h':
+		case 'l':
+		{
+		    bool set = (ch == 'h');
+		    switch (st->parms[0]) {
+		    case 7:	/* DECAWM */
+			st->autowrap = set;
+			break;
+		    case 20:	/* LNM */
+			st->autocr = set;
+			break;
+		    case 25:	/* DECTECM */
+			st->cursor = set;
+			op->showcursor(st);
+			break;
+		    default:
+			/* Ignore */
+			break;
+		    }
+		    break;
+		}
+		case 'm':
+		    {
+			static const int ansi2pc[8] =
+			    { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+			int i;
+			for (i = 0; i <= st->nparms; i++) {
+			    int a = st->parms[i];
+			    switch (a) {
+			    case 0:
+				st->fg = 7;
+				st->bg = 0;
+				st->intensity = 1;
+				st->underline = 0;
+				st->blink = 0;
+				st->reverse = 0;
+				break;
+			    case 1:
+				st->intensity = 2;
+				break;
+			    case 2:
+				st->intensity = 0;
+				break;
+			    case 4:
+				st->underline = 1;
+				break;
+			    case 5:
+				st->blink = 1;
+				break;
+			    case 7:
+				st->reverse = 1;
+				break;
+			    case 21:
+			    case 22:
+				st->intensity = 1;
+				break;
+			    case 24:
+				st->underline = 0;
+				break;
+			    case 25:
+				st->blink = 0;
+				break;
+			    case 27:
+				st->reverse = 0;
+				break;
+			    case 30 ... 37:
+				st->fg = ansi2pc[a - 30];
+				break;
+			    case 38:
+				st->fg = 7;
+				st->underline = 1;
+				break;
+			    case 39:
+				st->fg = 7;
+				st->underline = 0;
+				break;
+			    case 40 ... 47:
+				st->bg = ansi2pc[a - 40];
+				break;
+			    case 49:
+				st->bg = 7;
+				break;
+			    default:
+				/* Do nothing */
+				break;
+			    }
+			}
+		    }
+		    break;
+		case 's':
+		    st->saved_xy = xy;
+		    break;
+		case 'u':
+		    xy = st->saved_xy;
+		    break;
+		default:	/* Includes CAN and SUB */
+		    break;	/* Drop unknown sequence */
+		}
+		st->state = st_init;
+	    }
+	}
+	break;
+
+    case st_tbl:
+	st->parms[1] = 0;
+	if (ch == '#')
+	    st->state = st_tblc;
+	else
+	    st->state = st_init;
+	break;
+
+    case st_tblc:
+	{
+	    unsigned int n = (unsigned char)ch - '0';
+	    const char *p;
+
+	    if (n < 10) {
+		st->parms[1] = st->parms[1] * 10 + n;
+
+		if (!--st->parms[0]) {
+		    if (st->parms[1] < console_color_table_size) {
+			/* Set the color table index */
+			st->cindex = st->parms[1];
+
+			/* See if there are any other attributes we care about */
+			p = console_color_table[st->parms[1]].ansi;
+			if (p) {
+			    st->state = st_esc;
+			    __ansi_putchar(ti, '[');
+			    __ansi_putchar(ti, '0');
+			    __ansi_putchar(ti, ';');
+			    while (*p)
+				__ansi_putchar(ti, *p++);
+			    __ansi_putchar(ti, 'm');
+			}
+		    }
+		    st->state = st_init;
+		}
+	    } else {
+		st->state = st_init;
+	    }
+	}
+	break;
+    }
+
+    /* If we fell off the end of the screen, adjust */
+    if (xy.x >= cols) {
+	if (st->autowrap) {
+	    xy.x = 0;
+	    xy.y++;
+	} else {
+	    xy.x = cols - 1;
+	}
+    }
+    while (xy.y >= rows) {
+	xy.y--;
+	op->scroll_up(st);
+    }
+
+    /* Update cursor position */
+    op->set_cursor(xy.x, xy.y, st->cursor);
+    st->xy = xy;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+/*
+ * ansi.h
+ */
+
+#ifndef COM32_LIB_SYS_ANSI_H
+#define COM32_LIB_SYS_ANSI_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include "vesa/video.h"
+
+#define ANSI_MAX_PARMS	16
+
+enum ansi_state {
+    st_init,
+    st_esc,
+    st_csi,
+    st_tbl,
+    st_tblc,
+};
+
+struct curxy {
+    uint8_t x, y;
+} __attribute__ ((packed));
+
+struct term_state {
+    enum ansi_state state;
+    int nparms;			/* Number of parameters seen */
+    int parms[ANSI_MAX_PARMS];
+    bool pvt;			/* Private code? */
+    struct curxy xy;
+    struct curxy saved_xy;
+    attr_t cindex;		/* SOH color index */
+    uint8_t fg;
+    uint8_t bg;
+    uint8_t intensity;
+    bool vtgraphics;		/* VT graphics on/off */
+    bool underline;
+    bool blink;
+    bool reverse;
+    bool autocr;
+    bool autowrap;
+    bool cursor;
+};
+
+struct ansi_ops {
+    void (*erase) (const struct term_state * st, int x0, int y0, int x1,
+		   int y1);
+    void (*write_char) (int x, int y, uint8_t ch, const struct term_state * st);
+    void (*showcursor) (const struct term_state * st);
+    void (*scroll_up) (const struct term_state * st);
+    void (*set_cursor) (int x, int y, bool visible);
+    void (*beep) (void);
+};
+
+struct term_info {
+    int rows, cols;		/* Screen size */
+    int disabled;
+    struct term_state *ts;
+    const struct ansi_ops *op;
+};
+
+void __ansi_init(const struct term_info *ti);
+void __ansi_putchar(const struct term_info *ti, uint8_t ch);
+void __ansicon_beep(void);
+
+#endif /* COM32_LIB_SYS_ANSI_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansicon_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansicon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansicon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,212 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ansicon_write.c
+ *
+ * Write to the screen using ANSI control codes (about as capable as
+ * DOS' ANSI.SYS.)
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <minmax.h>
+#include <colortbl.h>
+#include <klibc/compiler.h>
+#include <syslinux/config.h>
+#include "file.h"
+#include "ansi.h"
+#include <syslinux/firmware.h>
+#include "graphics.h"
+
+static void ansicon_erase(const struct term_state *, int, int, int, int);
+static void ansicon_write_char(int, int, uint8_t, const struct term_state *);
+static void ansicon_showcursor(const struct term_state *);
+static void ansicon_scroll_up(const struct term_state *);
+static void ansicon_set_cursor(int, int, bool);
+
+static struct term_state ts;
+struct ansi_ops __ansicon_ops = {
+    .erase = ansicon_erase,
+    .write_char = ansicon_write_char,
+    .showcursor = ansicon_showcursor,
+    .set_cursor = ansicon_set_cursor,
+    .scroll_up = ansicon_scroll_up,
+    .beep = __ansicon_beep,
+};
+
+static struct term_info ti = {
+    .disabled = 0,
+    .ts = &ts,
+    .op = &__ansicon_ops
+};
+
+#define TEXT_MODE 0x0005
+
+/* Reference counter to the screen, to keep track of if we need
+   reinitialization. */
+static int ansicon_counter = 0;
+
+/* Common setup */
+int __ansicon_open(struct file_info *fp)
+{
+    if (!ansicon_counter) {
+	/* Are we disabled? */
+	if (syslinux_serial_console_info()->flowctl & 0x8000) {
+	    ti.disabled = 1;
+	    ti.rows = 25;
+	    ti.cols = 80;
+	} else {
+	    /* Force text mode */
+	    firmware->o_ops->text_mode();
+
+	    /* Initial state */
+	    firmware->o_ops->get_mode(&ti.cols, &ti.rows);
+	    __ansi_init(&ti);
+
+	    /* Get cursor shape and position */
+	    firmware->o_ops->get_cursor(&ti.ts->xy.x, &ti.ts->xy.y);
+	}
+    }
+
+    fp->o.rows = ti.rows;
+    fp->o.cols = ti.cols;
+
+    ansicon_counter++;
+    return 0;
+}
+
+int __ansicon_close(struct file_info *fp)
+{
+    (void)fp;
+
+    ansicon_counter--;
+    return 0;
+}
+
+/* Turn ANSI attributes into VGA attributes */
+static uint8_t ansicon_attribute(const struct term_state *st)
+{
+    int bg = st->bg;
+    int fg;
+
+    if (st->underline)
+	fg = 0x01;
+    else if (st->intensity == 0)
+	fg = 0x08;
+    else
+	fg = st->fg;
+
+    if (st->reverse) {
+	bg = fg & 0x07;
+	fg &= 0x08;
+	fg |= st->bg;
+    }
+
+    if (st->blink)
+	bg ^= 0x08;
+
+    if (st->intensity == 2)
+	fg ^= 0x08;
+
+    return (bg << 4) | fg;
+}
+
+/* Erase a region of the screen */
+static void ansicon_erase(const struct term_state *st,
+			  int x0, int y0, int x1, int y1)
+{
+    uint8_t attribute = ansicon_attribute(st);
+
+    if (firmware->o_ops->erase)
+	firmware->o_ops->erase(x0, y0, x1, y1, attribute);
+}
+
+/* Show or hide the cursor */
+static void ansicon_showcursor(const struct term_state *st)
+{
+    firmware->o_ops->showcursor(st);
+}
+
+static void ansicon_set_cursor(int x, int y, bool visible)
+{
+    firmware->o_ops->set_cursor(x, y, visible);
+}
+
+static void ansicon_write_char(int x, int y, uint8_t ch,
+			       const struct term_state *st)
+{
+    uint8_t attribute = ansicon_attribute(st);
+    ansicon_set_cursor(x, y, false);
+
+    firmware->o_ops->write_char(ch, attribute);
+}
+
+static void ansicon_scroll_up(const struct term_state *st)
+{
+    uint8_t rows, cols, attribute;
+
+    cols = ti.cols - 1;
+    rows = ti.rows - 1;
+    attribute = ansicon_attribute(st);
+
+    firmware->o_ops->scroll_up(cols, rows, attribute);
+}
+
+ssize_t __ansicon_write(struct file_info *fp, const void *buf, size_t count)
+{
+    const unsigned char *bufp = buf;
+    size_t n = 0;
+
+    (void)fp;
+
+    if (ti.disabled)
+	return count;		/* Nothing to do */
+
+    while (count--) {
+	__ansi_putchar(&ti, *bufp++);
+	n++;
+    }
+
+    return n;
+}
+
+void __ansicon_beep(void)
+{
+    if (firmware->o_ops->beep)
+	firmware->o_ops->beep();
+}
+
+const struct output_dev dev_ansicon_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __ansicon_write,
+    .close = __ansicon_close,
+    .open = __ansicon_open,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansiserial_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansiserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/ansiserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ansiserial_write.c
+ *
+ * Write to both to the ANSI console and the serial port
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+extern int __ansicon_open(struct file_info *);
+extern int __ansicon_close(struct file_info *);
+extern ssize_t __ansicon_write(struct file_info *, const void *, size_t);
+extern ssize_t __xserial_write(struct file_info *, const void *, size_t);
+
+static ssize_t __ansiserial_write(struct file_info *fp, const void *buf,
+				  size_t count)
+{
+    __ansicon_write(fp, buf, count);
+    return __xserial_write(fp, buf, count);
+}
+
+const struct output_dev dev_ansiserial_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __ansiserial_write,
+    .close = __ansicon_close,
+    .open = __ansicon_open,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/argv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/argv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/argv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * argv.c
+ *
+ * Parse a single C string into argc and argv (argc is return value.)
+ * memptr points to available memory.
+ */
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <syslinux/align.h>
+#include <com32.h>
+
+extern char _end[];		/* Symbol created by linker */
+void *__mem_end = &_end;	/* Global variable for use by malloc() */
+
+int __parse_argv(char ***argv, const char *str)
+{
+    char dummy_argv0[] = "";
+    char *mem = __mem_end;
+    const char *p = str;
+    char *q = mem;
+    char *r;
+    char **arg;
+    int wasspace = 1;
+    int argc = 1;
+
+    /* First copy the string, turning whitespace runs into nulls */
+    for (p = str;; p++) {
+	if (*p <= ' ') {
+	    if (!wasspace) {
+		wasspace = 1;
+		*q++ = '\0';
+	    }
+	} else {
+	    if (wasspace) {
+		argc++;
+		wasspace = 0;
+	    }
+	    *q++ = *p;
+	}
+
+	/* This test is AFTER we have processed the null byte;
+	   we treat it as a whitespace character so it terminates
+	   the last argument */
+	if (!*p)
+	    break;
+    }
+
+    /* Now create argv */
+    arg = (char **)ALIGN_UP_FOR(q, char *);
+    *argv = arg;
+    *arg++ = __com32.cs_name ? (char *)__com32.cs_name : dummy_argv0; /* argv[0] */
+
+    q--;			/* Point q to final null */
+    if (mem < q)
+	*arg++ = mem;		/* argv[1] */
+
+    for (r = mem; r < q; r++) {
+	if (*r == '\0') {
+	    *arg++ = r + 1;
+	}
+    }
+
+    *arg++ = NULL;		/* Null pointer at the end */
+    __mem_end = arg;		/* End of memory we used */
+
+    return argc;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/cfarcall.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/cfarcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/cfarcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+/*
+ * cfarcall.c
+ */
+
+#include <com32.h>
+
+int __cfarcall(uint16_t cs, uint16_t ip, const void *stack, uint32_t stack_size)
+{
+    return __com32.cs_cfarcall((cs << 16) + ip, stack, stack_size);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/close.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/close.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/close.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * close.c
+ */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include "file.h"
+
+int close(int fd)
+{
+    struct file_info *fp = &__file_info[fd];
+    int rv = 0;
+
+    if (fd >= NFILES || !fp->iop || !fp->oop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    if (fp->iop->close) {
+	rv = fp->iop->close(fp);
+	if (rv)
+	    return rv;
+    }
+    fp->iop = &dev_error_r;
+
+    if (fp->oop->close) {
+	rv = fp->oop->close(fp);
+	if (rv)
+	    return rv;
+    }
+
+    memset(fp, 0, sizeof *fp);	/* File structure unused */
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/colortable.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/colortable.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/colortable.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+#include <colortbl.h>
+
+static struct color_table default_color_table[] = {
+    {"default", "0", 0xffffffff, 0x00000000, SHADOW_NORMAL}
+};
+
+struct color_table *console_color_table = default_color_table;
+int console_color_table_size =
+    (sizeof default_color_table / sizeof(struct color_table));
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/entry.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/entry.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/entry.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * COM32 start up code - must be linked first in the binary
+ */
+
+/* Number of arguments in our version of the entry structure */
+#define COM32_ARGS 9
+
+		.section ".init","ax"
+		.globl _start
+		.type _start, @function
+_start:
+		/* This first instruction acts as COM32R magic number */
+		movl $0x21cd4cfe,%eax
+
+		/* Upwards string operations */
+		cld
+
+		/* Find our own location */
+		call 1f
+1:		popl %ebx
+		addl $_GLOBAL_OFFSET_TABLE_ + (. - 1b), %ebx
+	
+		/* Process relocations (which overlay the .bss segment) */
+		leal _edata@GOTOFF(%ebx),%esi
+		leal _start@GOTOFF(%ebx),%edx
+2:		lodsl
+		andl %eax,%eax
+		jz 3f
+		addl %edx,(%eax,%edx)
+		jmp 2b
+3:
+		/* Relocate the GOT (is this right?) */
+		leal __got_start@GOTOFF(%ebx),%esi
+		leal __got_end@GOTOFF(%ebx),%edi
+4:
+		addl %edx,(%esi)
+		addl $4,%esi
+		cmpl %edi,%esi
+		jb 4b
+	
+		/* Zero the .bss segment */
+		xorl %eax,%eax
+		leal __bss_start@GOTOFF(%ebx),%edi
+		leal _end+3@GOTOFF(%ebx),%ecx
+		subl %edi,%ecx
+		shrl $2,%ecx
+		rep ; stosl
+
+		/* Copy COM32 invocation parameters */
+		leal 4(%esp),%esi		# Argument list
+		leal __com32@GOTOFF(%ebx),%edi
+		movl $(COM32_ARGS),%ecx
+		movl %esp,-4(%edi)		# Save the initial stack ptr
+		cmpl (%esi),%ecx
+		jbe 5f
+		movl (%esi),%ecx
+5:		inc %ecx			# Copy the argument count, too
+		rep ; movsl
+
+		/* Parse the command line (assumes REGPARM) */
+		movl __com32+4@GOTOFF(%ebx),%edx	# Command line
+		pushl %edx				# Make space for argv
+		movl %esp,%eax
+		call __parse_argv
+		pushl %eax				# Save argc
+
+		/* Look for library initialization functions */
+		leal __ctors_start@GOTOFF(%ebx),%esi
+		leal __ctors_end@GOTOFF(%ebx),%edi
+6:
+		cmpl %edi,%esi
+		jae 7f
+		call *(%esi)
+		addl $4,%esi
+		jmp 6b
+/*
+ * Actually run main.  This assumes REGPARM is used!!!!
+ */
+7:
+		popl %eax			# argc
+		popl %edx			# argv
+		call main
+		call *__exit_handler@GOTOFF(%ebx)
+		hlt
+		.size _start, .-_start
+
+		.bss
+		.globl __entry_esp
+__entry_esp:	.space 4
+		.globl __com32
+__com32:	.space 4*(COM32_ARGS+1)
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * err_read.c
+ *
+ * Reading from a device which doesn't support reading
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __err_read(struct file_info *fp, void *buf, size_t count)
+{
+    (void)fp;
+    (void)buf;
+    (void)count;
+    errno = -EINVAL;
+    return -1;
+}
+
+const struct input_dev dev_error_r = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_INPUT | __DEV_ERROR,
+    .fileflags = O_RDONLY,
+    .read = __err_read,
+    .close = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/err_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * err_write.c
+ *
+ * Writing to a device which doesn't support writing
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __err_write(struct file_info *fp, const void *buf, size_t count)
+{
+    (void)fp;
+    (void)buf;
+    (void)count;
+    errno = -EINVAL;
+    return -1;
+}
+
+const struct output_dev dev_error_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_OUTPUT | __DEV_ERROR,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __err_write,
+    .close = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/farcall.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/farcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/farcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+/*
+ * farcall.c
+ */
+
+#include <com32.h>
+
+static inline uint32_t eflags(void)
+{
+    //uint32_t v;
+
+#if __SIZEOF_POINTER__ == 4
+    uint32_t v;
+    asm volatile("pushfl ; popl %0" : "=rm" (v));
+#elif __SIZEOF_POINTER__ == 8
+    uint64_t v;
+    asm volatile("pushfq ; pop %0" : "=rm" (v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+    return v;
+}
+
+void __farcall(uint16_t cs, uint16_t ip,
+	       const com32sys_t * ireg, com32sys_t * oreg)
+{
+    com32sys_t xreg = *ireg;
+
+    /* Enable interrupts if and only if they are enabled in the caller */
+    xreg.eflags.l = (xreg.eflags.l & ~EFLAGS_IF) | (eflags() & EFLAGS_IF);
+
+    __com32.cs_farcall((cs << 16) + ip, &xreg, oreg);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/file.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/file.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/file.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,107 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * file.h
+ *
+ * Internal implementation of file I/O for COM32
+ */
+
+#ifndef _COM32_SYS_FILE_H
+#define _COM32_SYS_FILE_H
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dev.h>
+#include <fcntl.h>
+#include <syslinux/pmapi.h>
+
+/* Device structure; contains the relevant operations */
+
+struct file_info;
+
+#define __DEV_MAGIC	0xf4e7
+#define __DEV_TTY	0x0001	/* TTY - must be bit 0 */
+#define __DEV_FILE	0x0002	/* Ordinary file */
+#define __DEV_OUTPUT	0x0004	/* This is an output device */
+#define __DEV_INPUT	0	/* Dummy */
+#define __DEV_ERROR	0x0008	/* This is the error device */
+#define __DEV_NULL	0x0010	/* This is the null device */
+
+struct input_dev {
+    uint16_t dev_magic;		/* Magic number */
+    uint16_t flags;		/* Flags */
+    int fileflags;		/* Permitted file flags */
+    ssize_t (*read)(struct file_info *, void *, size_t);
+    int (*close)(struct file_info *);
+    int (*open)(struct file_info *);
+};
+
+struct output_dev {
+    uint16_t dev_magic;		/* Magic number */
+    uint16_t flags;		/* Flags */
+    int fileflags;
+    ssize_t (*write)(struct file_info *, const void *, size_t);
+    int (*close)(struct file_info *);
+    int (*open)(struct file_info *);
+    const struct output_dev *fallback;	/* Fallback option for certain consoles */
+};
+
+/* File structure */
+
+#define NFILES 128		/* Number of files to support */
+#define MAXBLOCK 16384		/* Defined by ABI */
+
+struct file_info {
+    const struct input_dev *iop;	/* Input operations */
+    const struct output_dev *oop;	/* Output operations */
+
+    /* Output file data */
+    struct {
+	int rows, cols;		/* Rows and columns */
+    } o;
+
+    /* Structure used for input blocking */
+    struct {
+	struct com32_filedata fd;
+	size_t offset;		/* Current file offset */
+	size_t nbytes;		/* Number of bytes available in buffer */
+	char *datap;		/* Current data pointer */
+	void *pvt;		/* Private pointer for driver */
+	char buf[MAXBLOCK];
+    } i;
+};
+
+extern struct file_info __file_info[NFILES];
+extern const struct input_dev __file_dev;
+
+/* Line input discipline */
+ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize,
+		     ssize_t(*get_char) (struct file_info *, void *, size_t));
+
+#endif /* _COM32_SYS_FILE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileclose.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileclose.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileclose.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fileclose.c
+ *
+ * Close an ordinary file
+ */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include <fs.h>
+#include "file.h"
+
+int __file_close(struct file_info *fp)
+{
+    if (fp->i.fd.handle)
+	close_file(fp->i.fd.handle);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileinfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,3 @@
+#include "file.h"
+
+struct file_info __file_info[NFILES];
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileread.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/fileread.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,99 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * read.c
+ *
+ * Reading from a file
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <pmapi.h>
+#include <syslinux/pmapi.h>
+#include <minmax.h>
+#include "file.h"
+
+int __file_get_block(struct file_info *fp)
+{
+    ssize_t bytes_read;
+
+    bytes_read = pmapi_read_file(&fp->i.fd.handle, fp->i.buf,
+					  MAXBLOCK >> fp->i.fd.blocklg2);
+    if (!bytes_read) {
+	errno = EIO;
+	return -1;
+    }
+    
+    fp->i.nbytes = bytes_read;
+    fp->i.datap  = fp->i.buf;
+    return 0;
+}
+
+ssize_t __file_read(struct file_info * fp, void *buf, size_t count)
+{
+    char *bufp = buf;
+    ssize_t n = 0;
+    size_t ncopy;
+
+    while (count) {
+	if (fp->i.nbytes == 0) {
+	    if (fp->i.offset >= fp->i.fd.size || !fp->i.fd.handle)
+		return n;	/* As good as it gets... */
+
+	    if (count > MAXBLOCK) {
+		/* Large transfer: copy directly, without buffering */
+		ncopy = pmapi_read_file(&fp->i.fd.handle, bufp,
+						 count >> fp->i.fd.blocklg2);
+		if (!ncopy) {
+		    errno = EIO;
+		    return n ? n : -1;
+		}
+
+		goto got_data;
+	    } else {
+		if (__file_get_block(fp))
+		    return n ? n : -1;
+	    }
+	}
+
+	ncopy = min(count, fp->i.nbytes);
+	memcpy(bufp, fp->i.datap, ncopy);
+
+	fp->i.datap += ncopy;
+	fp->i.offset += ncopy;
+	fp->i.nbytes -= ncopy;
+
+    got_data:
+	n += ncopy;
+	bufp += ncopy;
+	count -= ncopy;
+    }
+
+    return n;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/fstat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/fstat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/fstat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fstat.c
+ *
+ * Very trivial fstat emulation
+ */
+
+#include <sys/stat.h>
+#include <errno.h>
+#include "file.h"
+
+int fstat(int fd, struct stat *buf)
+{
+    struct file_info *fp = &__file_info[fd];
+
+    if (fd >= NFILES || !fp->iop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    if (fp->iop->flags & __DEV_FILE) {
+	if (fp->i.fd.size == (uint32_t) - 1) {
+	    /* File of unknown length, report it as a socket
+	       (it probably really is, anyway!) */
+	    buf->st_mode = S_IFSOCK | 0444;
+	    buf->st_size = 0;
+	} else {
+	    buf->st_mode = S_IFREG | 0444;
+	    buf->st_size = fp->i.fd.size;
+	}
+    } else {
+	buf->st_mode = S_IFCHR | 0666;
+	buf->st_size = 0;
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/ftell.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/ftell.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/ftell.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,16 @@
+/*
+ * sys/ftell.c
+ *
+ * We can't seek, but we can at least tell...
+ */
+
+#include <stdio.h>
+#include "sys/file.h"
+
+long ftell(FILE * stream)
+{
+    int fd = fileno(stream);
+    struct file_info *fp = &__file_info[fd];
+
+    return fp->i.offset;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/gpxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/gpxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/gpxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+#include <string.h>
+
+#include <sys/gpxe.h>
+#include <syslinux/config.h>
+#include <syslinux/pxe_api.h>
+
+bool is_gpxe(void)
+{
+    const struct syslinux_version *sv;
+    struct s_PXENV_FILE_CHECK_API *fca;
+    bool gpxe;
+    int err;
+
+    sv = syslinux_version();
+    if (sv->filesystem != SYSLINUX_FS_PXELINUX)
+        return false;           /* Not PXELINUX */
+
+    fca = lzalloc(sizeof *fca);
+    if (!fca)
+	return false;
+
+    fca->Size = sizeof *fca;
+    fca->Magic = 0x91d447b2;
+
+    err = pxe_call(PXENV_FILE_API_CHECK, fca);
+
+    gpxe = true;
+
+    if (err)
+	gpxe = false;           /* Cannot invoke PXE stack */
+
+    if (fca->Status)
+        gpxe = false;           /* PXE failure */
+
+    if (fca->Magic != 0xe9c17b20)
+        gpxe = false;           /* Incorrect magic */
+
+    if (fca->Size < sizeof *fca)
+        gpxe = false;           /* Short return */
+
+    /* XXX: The APIs to test for should be a passed-in option */
+    if (!(fca->APIMask & (1 << 5)))
+	gpxe = false;           /* No FILE EXEC */
+
+    lfree(fca);
+    return gpxe;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/i386/x86_init_fpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/i386/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/i386/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,58 @@
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+    uint32_t v;
+asm("movl %%cr0,%0":"=r"(v));
+    return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+    asm volatile ("movl %0,%%cr0"::"r" (v));
+}
+
+#define CR0_PE	0x00000001
+#define CR0_MP  0x00000002
+#define CR0_EM  0x00000004
+#define CR0_TS  0x00000008
+#define CR0_ET  0x00000010
+#define CR0_NE  0x00000020
+#define CR0_WP  0x00010000
+#define CR0_AM  0x00040000
+#define CR0_NW  0x20000000
+#define CR0_CD  0x40000000
+#define CR0_PG  0x80000000
+
+int x86_init_fpu(void)
+{
+    uint32_t cr0;
+    uint16_t fsw = 0xffff;
+    uint16_t fcw = 0xffff;
+
+    cr0 = get_cr0();
+    cr0 &= ~(CR0_EM | CR0_TS);
+    cr0 |= CR0_MP;
+    set_cr0(cr0);
+
+    asm volatile ("fninit");
+    asm volatile ("fnstsw %0":"+m" (fsw));
+    if (fsw != 0)
+	return -1;
+
+    asm volatile ("fnstcw %0":"+m" (fcw));
+    if ((fcw & 0x103f) != 0x3f)
+	return -1;
+
+    /* Techically, this could be a 386 with a 287.  We could add a check
+       for that here... */
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/intcall.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/intcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/intcall.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+/*
+ * intcall.c
+ */
+
+#include <com32.h>
+
+void __intcall(uint8_t vector, const com32sys_t * ireg, com32sys_t * oreg)
+{
+    __com32.cs_intcall(vector, ireg, oreg);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/isatty.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/isatty.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/isatty.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * isatty.c
+ *
+ * Return if this is a tty or not
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <klibc/compiler.h>
+#include "file.h"
+
+int isatty(int fd)
+{
+    struct file_info *fp = &__file_info[fd];
+
+    if (fd >= NFILES || !fp->iop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    /* __DEV_TTY == 1 */
+    return (fp->iop->flags & __DEV_TTY);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/libansi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/libansi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/libansi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,247 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ *  Ansi Sequences can be found here :
+ *  http://ascii-table.com/ansi-escape-sequences-vt-100.php
+ *  http://en.wikipedia.org/wiki/ANSI_escape_code
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "libansi.h"
+
+void display_cursor(bool status)
+{
+	if (status == true) {
+		fputs(CSI "?25h", stdout);
+	} else {
+		fputs(CSI "?25l", stdout);
+	}
+}
+
+void clear_end_of_line(void)
+{
+	fputs(CSI "0K", stdout);
+}
+
+void move_cursor_left(int count)
+{
+	char buffer[10];
+	memset(buffer,0,sizeof(buffer));
+	sprintf(buffer,CSI "%dD",count);
+	fputs(buffer, stdout);
+}
+
+void move_cursor_right(int count)
+{
+	char buffer[10];
+	memset(buffer,0,sizeof(buffer));
+	sprintf(buffer, CSI "%dC", count);
+	fputs(buffer, stdout);
+}
+
+void set_cursor_blink(bool status) {
+	if (status == true)
+		fputs("\033[05m",stdout);
+	else
+		fputs("\033[0m",stdout);
+}
+
+void clear_line(void)
+{
+	fputs(CSI "2K", stdout);
+}
+
+void clear_beginning_of_line(void)
+{
+	fputs(CSI "1K", stdout);
+}
+
+void move_cursor_to_column(int count)
+{
+	char buffer[10];
+        memset(buffer,0,sizeof(buffer));
+	sprintf(buffer, CSI "%dG", count);
+	fputs(buffer, stdout);
+}
+
+void move_cursor_to_next_line(void)
+{
+	fputs("\033e", stdout);
+}
+
+void disable_utf8(void)
+{
+	fputs("\033%@", stdout);
+}
+
+void set_g1_special_char(void){
+	fputs("\033)0", stdout);
+}
+
+void set_us_g0_charset(void)
+{
+	fputs("\033(B\1#0", stdout);
+}
+
+void clear_entire_screen(void)
+{
+	fputs(CSI "2J", stdout);
+}
+
+/**
+ * cprint_vga2ansi - given a VGA attribute, print a character
+ * @chr:	character to print
+ * @attr:	vga attribute
+ *
+ * Convert the VGA attribute @attr to an ANSI escape sequence and
+ * print it.
+ * For performance, SGR parameters are cached. To reset them,
+ * call cprint_vga2ansi('0', '0').
+ **/
+static void cprint_vga2ansi(const char chr, const char attr)
+{
+	static const char ansi_char[8] = "04261537";
+	static uint16_t last_attr = 0x300;
+	char buf[16], *p;
+
+    if (chr == '0' && attr == '0') {
+        last_attr = 0x300;
+        return;
+    }
+
+	if (attr != last_attr) {
+        bool reset = false;
+		p = buf;
+		*p++ = '\033';
+		*p++ = '[';
+
+		if (last_attr & ~attr & 0x88) {
+			*p++ = '0';
+			*p++ = ';';
+			/* Reset last_attr to unknown to handle
+			 * background/foreground attributes correctly */
+			last_attr = 0x300;
+            reset = true;
+		}
+		if (attr & 0x08) {
+			*p++ = '1';
+			*p++ = ';';
+		}
+		if (attr & 0x80) {
+			*p++ = '4';
+			*p++ = ';';
+		}
+		if (reset || (attr ^ last_attr) & 0x07) {
+			*p++ = '3';
+			*p++ = ansi_char[attr & 7];
+			*p++ = ';';
+		}
+		if (reset || (attr ^ last_attr) & 0x70) {
+			*p++ = '4';
+			*p++ = ansi_char[(attr >> 4) & 7];
+			*p++ = ';';
+		}
+		p[-1] = 'm';	/* We'll have generated at least one semicolon */
+		p[0] = '\0';
+
+		last_attr = attr;
+
+		fputs(buf, stdout);
+	}
+
+	putchar(chr);
+}
+
+/*
+ * cls - clear and initialize the entire screen
+ *
+ * Note: when initializing xterm, one has to specify that
+ * G1 points to the alternate character set (this is not true
+ * by default). Without the initial printf "\033)0", line drawing
+ * characters won't be displayed.
+ */
+void cls(void)
+{
+	fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+
+    /* Reset SGR parameters cache */
+    cprint_vga2ansi('0', '0');
+}
+
+void reset_colors(void)
+{
+    csprint(CSI "1D", 0x07);
+}
+
+/**
+ * cprint - given a VGA attribute, print a single character at cursor
+ * @chr:	character to print
+ * @attr:	VGA attribute
+ * @times:	number of times to print @chr
+ *
+ * Note: @attr is a VGA attribute.
+ **/
+void cprint(const char chr, const char attr, unsigned int times)
+{
+	while (times--)
+		cprint_vga2ansi(chr, attr);
+}
+
+/**
+ * csprint - given a VGA attribute, print a NULL-terminated string
+ * @str:	string to print
+ * @attr:	VGA attribute
+ **/
+void csprint(const char *str, const char attr)
+{
+	while (*str) {
+		cprint(*str, attr, 1);
+		str++;
+	}
+}
+
+/**
+ * clearwindow - fill a given a region on the screen
+ * @top, @left, @bot, @right:	coordinates to fill
+ * @fillchar:			character to use to fill the region
+ * @fillattr:			character attribute (VGA)
+ **/
+void clearwindow(const char top, const char left, const char bot,
+		 const char right, const char fillchar, const char fillattr)
+{
+	char x;
+	for (x = top; x < bot + 1; x++) {
+		gotoxy(x, left);
+		cprint(fillchar, fillattr, right - left + 1);
+	}
+}
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/line_input.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/line_input.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/line_input.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,90 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * line_input.c
+ *
+ * Line-oriented input discupline
+ */
+
+#include "file.h"
+#include <errno.h>
+#include <syslinux/idle.h>
+
+ssize_t __line_input(struct file_info * fp, char *buf, size_t bufsize,
+		     ssize_t(*get_char) (struct file_info *, void *, size_t))
+{
+    size_t n = 0;
+    char ch;
+    int rv;
+    ssize_t(*const Write) (struct file_info *, const void *, size_t) =
+	fp->oop->write;
+
+    for (;;) {
+	rv = get_char(fp, &ch, 1);
+
+	if (rv != 1) {
+	    syslinux_idle();
+	    continue;
+	}
+
+	switch (ch) {
+	case '\n':		/* Ignore incoming linefeed */
+	    break;
+
+	case '\r':
+	    *buf = '\n';
+	    Write(fp, "\n", 1);
+	    return n + 1;
+
+	case '\b':
+	    if (n > 0) {
+		n--;
+		buf--;
+		Write(fp, "\b \b", 3);
+	    }
+	    break;
+
+	case '\x15':		/* Ctrl-U */
+	    while (n) {
+		n--;
+		buf--;
+		Write(fp, "\b \b", 3);
+	    }
+	    break;
+
+	default:
+	    if (n < bufsize - 1) {
+		*buf = ch;
+		Write(fp, buf, 1);
+		n++;
+		buf++;
+	    }
+	    break;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,610 @@
+/*
+ * common.c
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <stdio.h>
+#include <elf.h>
+#include <string.h>
+#include <fs.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+
+#include "elfutils.h"
+#include "common.h"
+
+/**
+ * The one and only list of loaded modules
+ */
+LIST_HEAD(modules_head);
+
+// User-space debugging routines
+#ifdef ELF_DEBUG
+void print_elf_ehdr(Elf_Ehdr *ehdr) {
+	int i;
+
+	fprintf(stderr, "Identification:\t");
+	for (i=0; i < EI_NIDENT; i++) {
+		printf("%d ", ehdr->e_ident[i]);
+	}
+	fprintf(stderr, "\n");
+	fprintf(stderr, "Type:\t\t%u\n", ehdr->e_type);
+	fprintf(stderr, "Machine:\t%u\n", ehdr->e_machine);
+	fprintf(stderr, "Version:\t%u\n", ehdr->e_version);
+	fprintf(stderr, "Entry:\t\t0x%08x\n", ehdr->e_entry);
+	fprintf(stderr, "PHT Offset:\t0x%08x\n", ehdr->e_phoff);
+	fprintf(stderr, "SHT Offset:\t0x%08x\n", ehdr->e_shoff);
+	//fprintf(stderr, "Flags:\t\t%u\n", ehdr->e_flags);
+	//fprintf(stderr, "Header size:\t%u (Structure size: %u)\n", ehdr->e_ehsize,sizeof(Elf_Ehdr));
+	fprintf(stderr, "phnum: %d shnum: %d\n", ehdr->e_phnum,
+		ehdr->e_shnum);
+}
+
+void print_elf_symbols(struct elf_module *module) {
+	unsigned int i;
+	Elf_Sym *crt_sym;
+
+	for (i = 1; i < module->symtable_size/module->syment_size; i++)
+	{
+		crt_sym = (Elf_Sym*)(module->sym_table + i*module->syment_size);
+
+		fprintf(stderr,"%s %d\n", module->str_table + crt_sym->st_name, crt_sym->st_value);
+
+	}
+}
+#endif //ELF_DEBUG
+
+FILE *findpath(char *name)
+{
+	struct path_entry *entry;
+	char path[FILENAME_MAX];
+	FILE *f;
+
+	f = fopen(name, "rb"); /* for full path */
+	if (f)
+		return f;
+
+	list_for_each_entry(entry, &PATH, list) {
+		bool slash = false;
+
+		/* Ensure we have a '/' separator */
+		if (entry->str[strlen(entry->str) - 1] != '/')
+			slash = true;
+
+		snprintf(path, sizeof(path), "%s%s%s",
+			 entry->str, slash ? "/" : "", name);
+
+		dprintf("findpath: trying \"%s\"\n", path);
+		f = fopen(path, "rb");
+		if (f)
+			return f;
+	}
+
+	return NULL;
+}
+
+/*
+ * Image files manipulation routines
+ */
+
+int image_load(struct elf_module *module)
+{
+	module->u.l._file = findpath(module->name);
+
+	if (module->u.l._file == NULL) {
+		dprintf("Could not open object file '%s'\n", module->name);
+		goto error;
+	}
+
+	module->u.l._cr_offset = 0;
+
+	return 0;
+
+error:
+	if (module->u.l._file != NULL) {
+		fclose(module->u.l._file);
+		module->u.l._file = NULL;
+	}
+
+	return -1;
+}
+
+
+int image_unload(struct elf_module *module) {
+	if (module->u.l._file != NULL) {
+		fclose(module->u.l._file);
+		module->u.l._file = NULL;
+
+	}
+	module->u.l._cr_offset = 0;
+
+	return 0;
+}
+
+int image_read(void *buff, size_t size, struct elf_module *module) {
+	size_t result = fread(buff, size, 1, module->u.l._file);
+
+	if (result < 1)
+		return -1;
+
+	module->u.l._cr_offset += size;
+	return 0;
+}
+
+int image_skip(size_t size, struct elf_module *module) {
+	void *skip_buff = NULL;
+	size_t result;
+
+	if (size == 0)
+		return 0;
+
+	skip_buff = malloc(size);
+	result = fread(skip_buff, size, 1, module->u.l._file);
+	free(skip_buff);
+
+	if (result < 1)
+		return -1;
+
+	module->u.l._cr_offset += size;
+	return 0;
+}
+
+int image_seek(Elf_Off offset, struct elf_module *module) {
+	if (offset < module->u.l._cr_offset) // Cannot seek backwards
+		return -1;
+
+	return image_skip(offset - module->u.l._cr_offset, module);
+}
+
+
+// Initialization of the module subsystem
+int modules_init(void) {
+	return 0;
+}
+
+// Termination of the module subsystem
+void modules_term(void) {
+
+}
+
+// Allocates the structure for a new module
+struct elf_module *module_alloc(const char *name) {
+	struct elf_module *result = malloc(sizeof(struct elf_module));
+
+	if (!result) {
+	    dprintf("module: Failed to alloc elf_module\n");
+	    return NULL;
+	}
+
+	memset(result, 0, sizeof(struct elf_module));
+
+	INIT_LIST_HEAD(&result->list);
+	INIT_LIST_HEAD(&result->required);
+	INIT_LIST_HEAD(&result->dependants);
+
+	strncpy(result->name, name, MODULE_NAME_SIZE);
+
+	return result;
+}
+
+struct module_dep *module_dep_alloc(struct elf_module *module) {
+	struct module_dep *result = malloc(sizeof(struct module_dep));
+
+	INIT_LIST_HEAD (&result->list);
+
+	result->module = module;
+
+	return result;
+}
+
+struct elf_module *module_find(const char *name) {
+	struct elf_module *cr_module;
+
+	for_each_module(cr_module) {
+		if (strcmp(cr_module->name, name) == 0)
+			return cr_module;
+	}
+
+	return NULL;
+}
+
+
+// Mouli: This is checking the header for 32bit machine
+// Support 64bit architecture as well.
+// Parts of the ELF header checked are common to both ELF32 and ELF64
+// Adding simple checks for both 32bit and 64bit should work (hopefully)
+//
+// Performs verifications on ELF header to assure that the open file is a
+// valid SYSLINUX ELF module.
+int check_header_common(Elf_Ehdr *elf_hdr) {
+	// Check the header magic
+	if (elf_hdr->e_ident[EI_MAG0] != ELFMAG0 ||
+		elf_hdr->e_ident[EI_MAG1] != ELFMAG1 ||
+		elf_hdr->e_ident[EI_MAG2] != ELFMAG2 ||
+		elf_hdr->e_ident[EI_MAG3] != ELFMAG3) {
+
+		dprintf("The file is not an ELF object\n");
+		return -1;
+	}
+
+	if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32 &&
+	    elf_hdr->e_ident[EI_CLASS] != ELFCLASS64) {
+		dprintf("Invalid ELF class code\n");
+		return -1;
+	}
+
+	if (elf_hdr->e_ident[EI_DATA] != MODULE_ELF_DATA) {
+		dprintf("Invalid ELF data encoding\n");
+		return -1;
+	}
+
+	if (elf_hdr->e_ident[EI_VERSION] != MODULE_ELF_VERSION ||
+			elf_hdr->e_version != MODULE_ELF_VERSION) {
+		dprintf("Invalid ELF file version\n");
+		return -1;
+	}
+
+	if (elf_hdr->e_machine != EM_386 &&
+		elf_hdr->e_machine != EM_X86_64) {
+		dprintf("Invalid ELF architecture\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+int enforce_dependency(struct elf_module *req, struct elf_module *dep) {
+	struct module_dep *crt_dep;
+	struct module_dep *new_dep;
+
+	list_for_each_entry(crt_dep, &req->dependants, list) {
+		if (crt_dep->module == dep) {
+			// The dependency is already enforced
+			return 0;
+		}
+	}
+
+	new_dep = module_dep_alloc(req);
+	list_add(&new_dep->list, &dep->required);
+
+	new_dep = module_dep_alloc(dep);
+	list_add(&new_dep->list, &req->dependants);
+
+	return 0;
+}
+
+int clear_dependency(struct elf_module *req, struct elf_module *dep) {
+	struct module_dep *crt_dep = NULL;
+	int found = 0;
+
+	list_for_each_entry(crt_dep, &req->dependants, list) {
+		if (crt_dep->module == dep) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		list_del(&crt_dep->list);
+		free(crt_dep);
+	}
+
+	found = 0;
+
+	list_for_each_entry(crt_dep, &dep->required, list) {
+		if (crt_dep->module == req) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		list_del(&crt_dep->list);
+		free(crt_dep);
+	}
+
+	return 0;
+}
+
+int check_symbols(struct elf_module *module)
+{
+	unsigned int i;
+	Elf_Sym *crt_sym = NULL, *ref_sym = NULL;
+	char *crt_name;
+	struct elf_module *crt_module;
+
+	int strong_count;
+	int weak_count;
+
+	for (i = 1; i < module->symtable_size/module->syment_size; i++)
+	{
+		crt_sym = symbol_get_entry(module, i);
+		crt_name = module->str_table + crt_sym->st_name;
+
+		strong_count = 0;
+		weak_count = (ELF32_ST_BIND(crt_sym->st_info) == STB_WEAK);
+
+		for_each_module(crt_module)
+		{
+			ref_sym = module_find_symbol(crt_name, crt_module);
+
+			// If we found a definition for our symbol...
+			if (ref_sym != NULL && ref_sym->st_shndx != SHN_UNDEF)
+			{
+				switch (ELF32_ST_BIND(ref_sym->st_info))
+				{
+					case STB_GLOBAL:
+						strong_count++;
+						break;
+					case STB_WEAK:
+						weak_count++;
+						break;
+				}
+			}
+		}
+
+		if (crt_sym->st_shndx == SHN_UNDEF)
+		{
+			// We have an undefined symbol
+			//
+			// We use the weak_count to differentiate
+			// between Syslinux-derivative-specific
+			// functions. For example, unload_pxe() is
+			// only provided by PXELINUX, so we mark it as
+			// __weak and replace it with a reference to
+			// undefined_symbol() on SYSLINUX, EXTLINUX,
+			// and ISOLINUX. See perform_relocations().
+			if (strong_count == 0 && weak_count == 0)
+			{
+				dprintf("Symbol %s is undefined\n", crt_name);
+				printf("Undef symbol FAIL: %s\n",crt_name);
+				return -1;
+			}
+		}
+		else
+		{
+			if (strong_count > 0 && ELF32_ST_BIND(ref_sym->st_info) == STB_GLOBAL)
+			{
+				// It's not an error - at relocation, the most recent symbol
+				// will be considered
+				dprintf("Info: Symbol %s is defined more than once\n", crt_name);
+			}
+		}
+		//printf("symbol %s laoded from %d\n",crt_name,crt_sym->st_value);
+	}
+
+	return 0;
+}
+
+int module_unloadable(struct elf_module *module) {
+	if (!list_empty(&module->dependants))
+		return 0;
+
+	return 1;
+}
+
+
+// Unloads the module from the system and releases all the associated memory
+int _module_unload(struct elf_module *module) {
+	struct module_dep *crt_dep, *tmp;
+	// Make sure nobody needs us
+	if (!module_unloadable(module)) {
+		dprintf("Module is required by other modules.\n");
+		return -1;
+	}
+
+	// Remove any dependency information
+	list_for_each_entry_safe(crt_dep, tmp, &module->required, list) {
+		clear_dependency(crt_dep->module, module);
+	}
+
+	// Remove the module from the module list
+	list_del_init(&module->list);
+
+	// Release the loaded segments or sections
+	if (module->module_addr != NULL) {
+		elf_free(module->module_addr);
+
+		dprintf("%s MODULE %s UNLOADED\n", module->shallow ? "SHALLOW" : "",
+				module->name);
+	}
+
+	dprintf("Unloading module %s\n", module->name);
+	// Release the module structure
+	free(module);
+
+	return 0;
+}
+
+int module_unload(struct elf_module *module) {
+	module_ctor_t *dtor;
+
+	for (dtor = module->dtors; dtor && *dtor; dtor++)
+		(*dtor) ();
+
+	return _module_unload(module);
+}
+
+struct elf_module *unload_modules_since(const char *name) {
+	struct elf_module *m, *mod, *begin = NULL;
+
+	for_each_module(mod) {
+		if (!strcmp(mod->name, name)) {
+			begin = mod;
+			break;
+		}
+	}
+
+	if (!begin)
+		return begin;
+
+	for_each_module_safe(mod, m) {
+		if (mod == begin)
+			break;
+
+		if (mod != begin)
+			module_unload(mod);
+	}
+
+	return begin;
+}
+
+static Elf_Sym *module_find_symbol_sysv(const char *name, struct elf_module *module) {
+	unsigned long h = elf_hash((const unsigned char*)name);
+	Elf_Word *cr_word = module->hash_table;
+
+	Elf_Word nbucket = *cr_word++;
+	cr_word++; // Skip nchain
+
+	Elf_Word *bkt = cr_word;
+	Elf_Word *chn = cr_word + nbucket;
+
+	Elf_Word crt_index = bkt[h % module->hash_table[0]];
+	Elf_Sym *crt_sym;
+
+
+	while (crt_index != STN_UNDEF) {
+		crt_sym = symbol_get_entry(module, crt_index);
+
+		if (strcmp(name, module->str_table + crt_sym->st_name) == 0)
+			return crt_sym;
+
+		crt_index = chn[crt_index];
+	}
+
+	return NULL;
+}
+
+static Elf_Sym *module_find_symbol_gnu(const char *name, struct elf_module *module) {
+	unsigned long h = elf_gnu_hash((const unsigned char*)name);
+
+	// Setup code (TODO: Optimize this by computing only once)
+	Elf_Word *cr_word = module->ghash_table;
+	Elf_Word nbucket = *cr_word++;
+	Elf_Word symbias = *cr_word++;
+	Elf_Word bitmask_nwords = *cr_word++;
+
+	if ((bitmask_nwords & (bitmask_nwords - 1)) != 0) {
+		dprintf("Invalid GNU Hash structure\n");
+		return NULL;
+	}
+
+	Elf_Word gnu_shift = *cr_word++;
+
+	Elf_Addr *gnu_bitmask = (Elf_Addr*)cr_word;
+	cr_word += MODULE_ELF_CLASS_SIZE / 32 * bitmask_nwords;
+
+	Elf_Word *gnu_buckets = cr_word;
+	cr_word += nbucket;
+
+	Elf_Word *gnu_chain_zero = cr_word - symbias;
+
+	// Computations
+	Elf_Bword bitmask_word = gnu_bitmask[(h / MODULE_ELF_CLASS_SIZE) &
+	                                       (bitmask_nwords - 1)];
+
+	unsigned int hashbit1 = h & (MODULE_ELF_CLASS_SIZE - 1);
+	unsigned int hashbit2 = (h >> gnu_shift) & (MODULE_ELF_CLASS_SIZE - 1);
+
+	if ((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1) {
+		unsigned long rem;
+		Elf_Word bucket;
+
+		rem = h % nbucket;
+
+		bucket = gnu_buckets[rem];
+
+		if (bucket != 0) {
+			const Elf_Word* hasharr = &gnu_chain_zero[bucket];
+
+			do {
+				if (((*hasharr ^ h ) >> 1) == 0) {
+					Elf_Sym *crt_sym = symbol_get_entry(module, (hasharr - gnu_chain_zero));
+
+					if (strcmp(name, module->str_table + crt_sym->st_name) == 0) {
+						return crt_sym;
+					}
+				}
+			} while ((*hasharr++ & 1u) == 0);
+		}
+	}
+
+	return NULL;
+}
+
+static Elf_Sym *module_find_symbol_iterate(const char *name,struct elf_module *module)
+{
+
+	unsigned int i;
+	Elf_Sym *crt_sym;
+
+	for (i = 1; i < module->symtable_size/module->syment_size; i++)
+	{
+		crt_sym = symbol_get_entry(module, i);
+		if (strcmp(name, module->str_table + crt_sym->st_name) == 0)
+		{
+			return crt_sym;
+		}
+	}
+
+	return NULL;
+}
+
+Elf_Sym *module_find_symbol(const char *name, struct elf_module *module) {
+	Elf_Sym *result = NULL;
+
+	if (module->ghash_table != NULL)
+		result = module_find_symbol_gnu(name, module);
+
+	if (result == NULL)
+	{
+		if (module->hash_table != NULL)
+		{
+			//printf("Attempting SYSV Symbol search\n");
+			result = module_find_symbol_sysv(name, module);
+		}
+		else
+		{
+			//printf("Attempting Iterative Symbol search\n");
+			result = module_find_symbol_iterate(name, module);
+		}
+	}
+
+	return result;
+}
+
+Elf_Sym *global_find_symbol(const char *name, struct elf_module **module) {
+	struct elf_module *crt_module;
+	Elf_Sym *crt_sym = NULL;
+	Elf_Sym *result = NULL;
+
+	for_each_module(crt_module) {
+		crt_sym = module_find_symbol(name, crt_module);
+
+		if (crt_sym != NULL && crt_sym->st_shndx != SHN_UNDEF) {
+			switch (ELF32_ST_BIND(crt_sym->st_info)) {
+			case STB_GLOBAL:
+				if (module != NULL) {
+					*module = crt_module;
+				}
+				return crt_sym;
+			case STB_WEAK:
+				// Consider only the first weak symbol
+				if (result == NULL) {
+					if (module != NULL) {
+						*module = crt_module;
+					}
+					result = crt_sym;
+				}
+				break;
+			}
+		}
+	}
+
+	return result;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,72 @@
+/*
+ * common.h - Common internal operations performed by the module subsystem
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include <stdio.h>
+
+#include <sys/module.h>
+#include <linux/list.h>
+
+#include "elfutils.h"
+
+// Performs an operation and jumps to a given label if an error occurs
+#define CHECKED(res, expr, error)		\
+	do { 								\
+		(res) = (expr);					\
+		if ((res) < 0)					\
+			goto error;					\
+	} while (0)
+
+#define MIN(x,y)	(((x) < (y)) ? (x) : (y))
+#define MAX(x,y)	(((x) > (y)) ? (x) : (y))
+
+static inline Elf_Sym *symbol_get_entry(struct elf_module *module, int entry)
+{
+	char *sym_table = (char *)module->sym_table;
+	int index = entry * module->syment_size;
+
+	return (Elf_Sym *)(sym_table + index);
+}
+
+//#define ELF_DEBUG
+
+#ifdef ELF_DEBUG
+#define DBG_PRINT(fmt, args...)	fprintf(stderr, "[ELF] " fmt, ##args)
+#else
+#define DBG_PRINT(fmt, args...)	// Expand to nothing
+#endif
+
+// User-space debugging routines
+#ifdef ELF_DEBUG
+extern void print_elf_ehdr(Elf_Ehdr *ehdr);
+extern void print_elf_symbols(struct elf_module *module);
+#endif //ELF_DEBUG
+
+
+/*
+ * Image files manipulation routines
+ */
+
+extern int image_load(struct elf_module *module);
+extern int image_unload(struct elf_module *module);
+extern int image_read(void *buff, size_t size, struct elf_module *module);
+extern int image_skip(size_t size, struct elf_module *module);
+extern int image_seek(Elf_Off offset, struct elf_module *module);
+
+extern struct module_dep *module_dep_alloc(struct elf_module *module);
+
+extern int check_header_common(Elf_Ehdr *elf_hdr);
+
+extern int enforce_dependency(struct elf_module *req, struct elf_module *dep);
+extern int clear_dependency(struct elf_module *req, struct elf_module *dep);
+
+extern int check_symbols(struct elf_module *module);
+
+
+#endif /* COMMON_H_ */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elf_module.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,316 @@
+/*
+ * elf_module.c
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <elf.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#include "elfutils.h"
+#include "common.h"
+
+static int check_header(Elf_Ehdr *elf_hdr) {
+	int res;
+
+	res = check_header_common(elf_hdr);
+
+	if (res != 0)
+		return res;
+
+	if (elf_hdr->e_type != MODULE_ELF_TYPE) {
+		dprintf("The ELF file must be a shared object\n");
+		return -1;
+	}
+
+	if (elf_hdr->e_phoff == 0x00000000) {
+		dprintf("PHT missing\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ *
+ * The implementation assumes that the loadable segments are present
+ * in the PHT sorted by their offsets, so that only forward seeks would
+ * be necessary.
+ */
+extern int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr);
+
+static int prepare_dynlinking(struct elf_module *module) {
+	Elf_Dyn  *dyn_entry = module->dyn_table;
+
+	while (dyn_entry->d_tag != DT_NULL) {
+		switch (dyn_entry->d_tag) {
+		case DT_NEEDED:
+			/*
+			 * It's unlikely there'll be more than
+			 * MAX_NR_DEPS DT_NEEDED entries but if there
+			 * are then inform the user that we ran out of
+			 * space.
+			 */
+			if (module->nr_needed < MAX_NR_DEPS)
+				module->needed[module->nr_needed++] = dyn_entry->d_un.d_ptr;
+			else {
+				printf("Too many dependencies!\n");
+				return -1;
+			}
+			break;
+		case DT_HASH:
+			module->hash_table =
+				(Elf_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_GNU_HASH:
+			module->ghash_table =
+				(Elf_Word*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_STRTAB:
+			module->str_table =
+				(char*)module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_SYMTAB:
+			module->sym_table =
+				module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_STRSZ:
+			module->strtable_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_SYMENT:
+			module->syment_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_PLTGOT: // The first entry in the GOT
+			module->got = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		}
+
+		dyn_entry++;
+	}
+
+	return 0;
+}
+
+void undefined_symbol(void)
+{
+	printf("Error: An undefined symbol was referenced\n");
+	kaboom();
+}
+
+extern int perform_relocation(struct elf_module *module, Elf_Rel *rel);
+extern int resolve_symbols(struct elf_module *module);
+
+static int extract_operations(struct elf_module *module) {
+	Elf_Sym *ctors_start, *ctors_end;
+	Elf_Sym *dtors_start, *dtors_end;
+	module_ctor_t *ctors = NULL;
+	module_ctor_t *dtors = NULL;
+
+	ctors_start = module_find_symbol("__ctors_start", module);
+	ctors_end = module_find_symbol("__ctors_end", module);
+
+	if (ctors_start && ctors_end) {
+		module_ctor_t *start, *end;
+		int nr_ctors = 0;
+		int i, size;
+
+		start = module_get_absolute(ctors_start->st_value, module);
+		end = module_get_absolute(ctors_end->st_value, module);
+
+		nr_ctors = end - start;
+
+		size = nr_ctors * sizeof(module_ctor_t);
+		size += sizeof(module_ctor_t); /* NULL entry */
+
+		ctors = malloc(size);
+		if (!ctors) {
+			printf("Unable to alloc memory for ctors\n");
+			return -1;
+		}
+
+		memset(ctors, 0, size);
+		for (i = 0; i < nr_ctors; i++)
+			ctors[i] = start[i];
+
+		module->ctors = ctors;
+	}
+
+	dtors_start = module_find_symbol("__dtors_start", module);
+	dtors_end = module_find_symbol("__dtors_end", module);
+
+	if (dtors_start && dtors_end) {
+		module_ctor_t *start, *end;
+		int nr_dtors = 0;
+		int i, size;
+
+		start = module_get_absolute(dtors_start->st_value, module);
+		end = module_get_absolute(dtors_end->st_value, module);
+
+		nr_dtors = end - start;
+
+		size = nr_dtors * sizeof(module_ctor_t);
+		size += sizeof(module_ctor_t); /* NULL entry */
+
+		dtors = malloc(size);
+		if (!dtors) {
+			printf("Unable to alloc memory for dtors\n");
+			free(ctors);
+			return -1;
+		}
+
+		memset(dtors, 0, size);
+		for (i = 0; i < nr_dtors; i++)
+			dtors[i] = start[i];
+
+		module->dtors = dtors;
+	}
+
+	return 0;
+}
+
+// Loads the module into the system
+int module_load(struct elf_module *module) {
+	int res;
+	Elf_Sym *main_sym;
+	Elf_Ehdr elf_hdr;
+	module_ctor_t *ctor;
+	struct elf_module *head = NULL;
+
+	// Do not allow duplicate modules
+	if (module_find(module->name) != NULL) {
+		dprintf("Module %s is already loaded.\n", module->name);
+		return EEXIST;
+	}
+
+	// Get a mapping/copy of the ELF file in memory
+	res = image_load(module);
+
+	if (res < 0) {
+		dprintf("Image load failed for %s\n", module->name);
+		return res;
+	}
+
+	// The module is a fully featured dynamic library
+	module->shallow = 0;
+
+	CHECKED(res, image_read(&elf_hdr, sizeof(Elf_Ehdr), module), error);
+	//printf("check... 1\n");
+	
+	//print_elf_ehdr(&elf_hdr);
+
+	// Checking the header signature and members
+	CHECKED(res, check_header(&elf_hdr), error);
+	//printf("check... 2\n");
+
+	// Load the segments in the memory
+	CHECKED(res, load_segments(module, &elf_hdr), error);
+	//printf("bleah... 3\n");
+	// Obtain dynamic linking information
+	CHECKED(res, prepare_dynlinking(module), error);
+	//printf("check... 4\n");
+
+	head = module_current();
+
+	/* Find modules we need to load as dependencies */
+	if (module->str_table) {
+		int i;
+
+		/*
+		 * Note that we have to load the dependencies in
+		 * reverse order.
+		 */
+		for (i = module->nr_needed - 1; i >= 0; i--) {
+			char *dep, *p;
+			char *argv[2] = { NULL, NULL };
+
+			dep = module->str_table + module->needed[i];
+
+			/* strip everything but the last component */
+			if (!strlen(dep))
+				continue;
+
+			if (strchr(dep, '/')) {
+				p = strrchr(dep, '/');
+				p++;
+			} else
+				p = dep;
+
+			argv[0] = p;
+			res = spawn_load(p, 1, argv);
+			if (res < 0) {
+				printf("Failed to load %s\n", p);
+				goto error;
+			}
+		}
+	}
+
+	// Check the symbols for duplicates / missing definitions
+	CHECKED(res, check_symbols(module), error);
+	//printf("check... 5\n");
+
+	main_sym = module_find_symbol("main", module);
+	if (main_sym)
+		module->main_func =
+			module_get_absolute(main_sym->st_value, module);
+
+	//printf("check... 6\n");
+
+	// Add the module at the beginning of the module list
+	list_add(&module->list, &modules_head);
+
+	// Perform the relocations
+	resolve_symbols(module);
+
+	// Obtain constructors and destructors
+	CHECKED(res, extract_operations(module), error);
+
+	//dprintf("module->symtable_size = %d\n", module->symtable_size);
+
+	//print_elf_symbols(module);
+
+	// The file image is no longer needed
+	image_unload(module);
+
+	/*
+	dprintf("MODULE %s LOADED SUCCESSFULLY (main@%p, init@%p, exit@%p)\n",
+			module->name,
+			(module->main_func == NULL) ? NULL : *(module->main_func),
+			(module->init_func == NULL) ? NULL : *(module->init_func),
+			(module->exit_func == NULL) ? NULL : *(module->exit_func));
+	*/
+
+	for (ctor = module->ctors; ctor && *ctor; ctor++)
+		(*ctor) ();
+
+	return 0;
+
+error:
+	if (head)
+		unload_modules_since(head->name);
+
+	// Remove the module from the module list (if applicable)
+	list_del_init(&module->list);
+
+	if (module->module_addr != NULL) {
+		elf_free(module->module_addr);
+		module->module_addr = NULL;
+	}
+
+	image_unload(module);
+
+	// Clear the execution part of the module buffer
+	memset(&module->u, 0, sizeof module->u);
+
+	return res;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,89 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#include "elfutils.h"
+
+unsigned long elf_hash(const unsigned char *name) {
+	unsigned long h = 0;
+	unsigned long g;
+
+	while (*name) {
+		h = (h << 4) + *name++;
+		if ((g = h & 0xF0000000))
+			h ^= g >> 24;
+
+		h &= ~g;
+	}
+
+	return h;
+}
+
+unsigned long elf_gnu_hash(const unsigned char *name) {
+	unsigned long h = 5381;
+	unsigned char c;
+
+	for (c = *name; c != '\0'; c = *++name) {
+		h = h * 33 + c;
+	}
+
+	return h & 0xFFFFFFFF;
+}
+
+#ifndef HAVE_ELF_POSIX_MEMALIGN
+
+struct memalign_info {
+	void 	*start_addr;
+	char	data[0];
+};
+
+int elf_malloc(void **memptr, size_t alignment, size_t size) {
+	char *start_addr = NULL;
+	struct memalign_info *info;
+
+	if ((alignment & (alignment - 1)) != 0)
+		return EINVAL;
+	if (alignment % sizeof(void*) != 0)
+		alignment = sizeof(void*);
+
+	start_addr = malloc(size + (alignment > sizeof(struct memalign_info) ?
+					alignment : sizeof(struct memalign_info)));
+
+	if (start_addr == NULL)
+		return ENOMEM;
+
+
+	info = (struct memalign_info*)(start_addr -
+			((unsigned long)start_addr % alignment) +
+			alignment - sizeof(struct memalign_info));
+
+	info->start_addr = start_addr;
+
+	*memptr = info->data;
+
+	return 0;
+}
+
+void elf_free(char *memptr) {
+	struct memalign_info *info = (struct memalign_info*)(memptr -
+			sizeof(struct memalign_info));
+
+	free(info->start_addr);
+}
+
+#else
+
+int elf_malloc(void **memptr, size_t alignment, size_t size) {
+	if ((alignment & (alignment - 1)) != 0)
+		return EINVAL;
+
+	if (alignment % sizeof(void*) != 0)
+		alignment = sizeof(void*);
+
+	return posix_memalign(memptr, alignment, size);
+}
+
+void elf_free(void *memptr) {
+	free(memptr);
+}
+
+#endif //HAVE_ELF_POSIX_MEMALIGN
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/elfutils.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,65 @@
+#ifndef ELF_UTILS_H_
+#define ELF_UTILS_H_
+
+#include <elf.h>
+#include <stdlib.h>
+#include <sys/module.h>
+
+/**
+ * elf_get_header - Returns a pointer to the ELF header structure.
+ * @elf_image: pointer to the ELF file image in memory
+ */
+static inline Elf_Ehdr *elf_get_header(void *elf_image) {
+	return (Elf_Ehdr*)elf_image;
+}
+
+/**
+ * elf_get_pht - Returns a pointer to the first entry in the PHT.
+ * @elf_image: pointer to the ELF file image in memory
+ */
+static inline Elf_Phdr *elf_get_pht(void *elf_image) {
+	Elf_Ehdr *elf_hdr = elf_get_header(elf_image);
+
+	return (Elf_Phdr*)((Elf_Off)elf_hdr + elf_hdr->e_phoff);
+}
+
+//
+/**
+ * elf_get_ph - Returns the element with the given index in the PTH
+ * @elf_image: pointer to the ELF file image in memory
+ * @index: the index of the PHT entry to look for
+ */
+static inline Elf_Phdr *elf_get_ph(void *elf_image, int index) {
+	Elf_Phdr *elf_pht = elf_get_pht(elf_image);
+	Elf_Ehdr *elf_hdr = elf_get_header(elf_image);
+
+	return (Elf_Phdr*)((Elf_Off)elf_pht + index * elf_hdr->e_phentsize);
+}
+
+/**
+ * elf_hash - Returns the index in a SysV hash table for the symbol name.
+ * @name: the name of the symbol to look for
+ */
+extern unsigned long elf_hash(const unsigned char *name);
+
+/**
+ * elf_gnu_hash - Returns the index in a GNU hash table for the symbol name.
+ * @name: the name of the symbol to look for
+ */
+extern unsigned long elf_gnu_hash(const unsigned char *name);
+
+/**
+ * elf_malloc - Allocates memory to be used by ELF module contents.
+ * @memptr: pointer to a variable to hold the address of the allocated block.
+ * @alignment: alignment constraints of the block
+ * @size: the required size of the block
+ */
+extern int elf_malloc(void **memptr, size_t alignment, size_t size);
+
+/**
+ * elf_free - Releases memory previously allocated by elf_malloc.
+ * @memptr: the address of the allocated block
+ */
+extern void elf_free(char *memptr);
+
+#endif /*ELF_UTILS_H_*/
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/exec.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/exec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/exec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,237 @@
+/*
+ * exec.c
+ *
+ *  Created on: Aug 14, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <sys/module.h>
+#include <sys/exec.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <setjmp.h>
+#include <alloca.h>
+#include <dprintf.h>
+
+#define DBG_PRINT(fmt, args...) dprintf("[EXEC] " fmt, ##args)
+
+struct elf_module *__syslinux_current = NULL;
+
+int get_module_type(struct elf_module *module)
+{
+	if(module->main_func) return EXEC_MODULE;
+	return LIB_MODULE;
+}
+
+jmp_buf __process_exit_jmp;
+
+#if 0
+int spawnv(const char *name, const char **argv)
+{
+	int res, ret_val = 0;
+	const char **arg;
+	int argc;
+	char **argp, **args;
+	struct elf_module *previous;
+	malloc_tag_t prev_mem_tag;
+
+	struct elf_module *module = module_alloc(name);
+
+	if (module == NULL)
+		return -1;
+
+	res = module_load(module);
+	if (res != 0) {
+		module_unload(module);
+		return res;
+	}
+
+	if (module->main_func == NULL) {
+		// We can't execute without a main function
+		module_unload(module);
+		return -1;
+	}
+	/*if (module->main_func != NULL) {
+		const char **last_arg = argv;
+		void *old_tag;
+		while (*last_arg != NULL)
+			last_arg++;
+
+		// Setup the memory allocation context
+		old_tag = __mem_get_tag_global();
+		__mem_set_tag_global(module);
+
+		// Execute the program
+		ret_val = (*(module->main_func))(last_arg - argv, argv);
+
+		// Clean up the allocation context
+		__free_tagged(module);
+		// Restore the allocation context
+		__mem_set_tag_global(old_tag);
+	} else {
+		// We can't execute without a main function
+		module_unload(module);
+		return -1;
+	}*/
+	// Set up the process context
+	previous = __syslinux_current;
+	prev_mem_tag = __mem_get_tag_global();
+
+	// Setup the new process context
+	__syslinux_current = module;
+	__mem_set_tag_global((malloc_tag_t)module);
+
+	// Generate a new process copy of argv (on the stack)
+	argc = 0;
+	for (arg = argv; *arg; arg++)
+		argc++;
+
+	args = alloca((argc+1) * sizeof(char *));
+
+	for (arg = argv, argp = args; *arg; arg++, argp++) {
+		size_t l = strlen(*arg)+1;
+		*argp = alloca(l);
+		memcpy(*argp, *arg, l);
+	}
+
+	*args = NULL;
+
+	// Execute the program
+	ret_val = setjmp(module->u.x.process_exit);
+
+	if (ret_val)
+		ret_val--;		/* Valid range is 0-255 */
+	else if (!module->main_func)
+		ret_val = -1;
+	else
+		exit((module->main_func)(argc, args)); /* Actually run! */
+
+	// Clean up the allocation context
+	__free_tagged(module);
+	// Restore the allocation context
+	__mem_set_tag_global(prev_mem_tag);
+	// Restore the process context
+	__syslinux_current = previous;
+
+	res = module_unload(module);
+
+	if (res != 0) {
+		return res;
+	}
+
+	return ((unsigned int)ret_val & 0xFF);
+}
+
+int spawnl(const char *name, const char *arg, ...)
+{
+	/*
+	 * NOTE: We assume the standard ABI specification for the i386
+	 * architecture. This code may not work if used in other
+	 * circumstances, including non-variadic functions, different
+	 * architectures and calling conventions.
+	 */
+	return spawnv(name, &arg);
+}
+#endif
+
+/*
+ * Load a module and runs its start function.
+ *
+ * For library modules the start function is module->init_func and for
+ * executable modules its module->main_func.
+ *
+ * "name" is the name of the module to load.
+ *
+ * "argv" and "argc" are only passed to module->main_func, for library
+ * modules these arguments can be NULL and 0, respectively.
+ *
+ * "argv" is an array of arguments to pass to module->main_func.
+ * argv[0] must be a pointer to "name" and argv[argc] must be NULL.
+ *
+ * "argc" is the number of arguments in "argv".
+ */
+int spawn_load(const char *name, int argc, char **argv)
+{
+	int res, ret_val = 0;
+	struct elf_module *previous;
+	//malloc_tag_t prev_mem_tag;
+	struct elf_module *module = module_alloc(name);
+	struct elf_module *cur_module;
+	int type;
+
+	dprintf("enter: name = %s", name);
+
+	if (module == NULL)
+		return -1;
+
+	if (get_module_type(module) == EXEC_MODULE) {
+		if (!argc || !argv || strcmp(argv[0], name)) {
+			dprintf("invalid args for %s\n", name);
+			res = -1;
+			goto out;
+		}
+	}
+
+	cur_module = module_current();
+	if (!strcmp(cur_module->name, module->name)) {
+		dprintf("We is running this module %s already!", module->name);
+
+		module_unload(cur_module);
+	}
+
+	res = module_load(module);
+	if (res != 0) {
+		dprintf("failed to load module %s\n", module->name);
+		goto out;
+	}
+
+	type = get_module_type(module);
+
+	dprintf("type = %d, prev = %s, cur = %s",
+		type, cur_module->name, module->name);
+
+	if(type==EXEC_MODULE)
+	{
+		previous = __syslinux_current;
+		//prev_mem_tag = __mem_get_tag_global();
+
+		// Setup the new process context
+		__syslinux_current = module;
+		//__mem_set_tag_global((malloc_tag_t)module);
+
+		// Execute the program
+		ret_val = setjmp(module->u.x.process_exit);
+
+		if (ret_val)
+			ret_val--;		/* Valid range is 0-255 */
+		else if (!module->main_func)
+			ret_val = -1;
+		else
+			exit((module->main_func)(argc, argv)); /* Actually run! */
+
+		// Clean up the allocation context
+		//__free_tagged(module);
+		// Restore the allocation context
+		//__mem_set_tag_global(prev_mem_tag);
+		// Restore the process context
+		__syslinux_current = previous;
+
+		res = module_unload(module);
+
+		if (res != 0)
+			goto out;
+	}
+
+out:
+	if (res)
+		_module_unload(module);
+	return res;
+}
+
+void exec_term(void)
+{
+	modules_term();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/i386/elf_module.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/i386/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/i386/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,349 @@
+/*
+ * elf_module.c
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <elf.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#include "elfutils.h"
+#include "../common.h"
+
+/*
+ *
+ * The implementation assumes that the loadable segments are present
+ * in the PHT sorted by their offsets, so that only forward seeks would
+ * be necessary.
+ */
+int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
+	int i;
+	int res = 0;
+	char *pht = NULL;
+	char *sht = NULL;
+	Elf32_Phdr *cr_pht;
+	Elf32_Shdr *cr_sht;
+
+	Elf32_Addr min_addr  = 0x00000000; // Min. ELF vaddr
+	Elf32_Addr max_addr  = 0x00000000; // Max. ELF vaddr
+	Elf32_Word max_align = sizeof(void*); // Min. align of posix_memalign()
+	Elf32_Addr min_alloc, max_alloc;   // Min. and max. aligned allocables
+
+	Elf32_Addr dyn_addr = 0x00000000;
+
+	// Get to the PHT
+	image_seek(elf_hdr->e_phoff, module);
+
+	// Load the PHT
+	pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+	if (!pht)
+		return -1;
+
+	image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
+
+	// Compute the memory needings of the module
+	for (i=0; i < elf_hdr->e_phnum; i++) {
+		cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+		switch (cr_pht->p_type) {
+		case PT_LOAD:
+			if (i == 0) {
+				min_addr = cr_pht->p_vaddr;
+			} else {
+				min_addr = MIN(min_addr, cr_pht->p_vaddr);
+			}
+
+			max_addr = MAX(max_addr, cr_pht->p_vaddr + cr_pht->p_memsz);
+			max_align = MAX(max_align, cr_pht->p_align);
+			break;
+		case PT_DYNAMIC:
+			dyn_addr = cr_pht->p_vaddr;
+			break;
+		default:
+			// Unsupported - ignore
+			break;
+		}
+	}
+
+	if (max_addr - min_addr == 0) {
+		// No loadable segments
+		DBG_PRINT("No loadable segments found\n");
+		goto out;
+	}
+
+	if (dyn_addr == 0) {
+		DBG_PRINT("No dynamic information segment found\n");
+		goto out;
+	}
+
+	// The minimum address that should be allocated
+	min_alloc = min_addr - (min_addr % max_align);
+
+	// The maximum address that should be allocated
+	max_alloc = max_addr - (max_addr % max_align);
+	if (max_addr % max_align > 0)
+		max_alloc += max_align;
+
+
+	if (elf_malloc(&module->module_addr,
+			max_align,
+			max_alloc-min_alloc) != 0) {
+
+		DBG_PRINT("Could not allocate segments\n");
+		goto out;
+	}
+
+	module->base_addr = (Elf32_Addr)(module->module_addr) - min_alloc;
+	module->module_size = max_alloc - min_alloc;
+
+	// Zero-initialize the memory
+	memset(module->module_addr, 0, module->module_size);
+
+	for (i = 0; i < elf_hdr->e_phnum; i++) {
+		cr_pht = (Elf32_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+		if (cr_pht->p_type == PT_LOAD) {
+			// Copy the segment at its destination
+			if (cr_pht->p_offset < module->u.l._cr_offset) {
+				// The segment contains data before the current offset
+				// It can be discarded without worry - it would contain only
+				// headers
+				Elf32_Off aux_off = module->u.l._cr_offset - cr_pht->p_offset;
+
+				if (image_read((char *)module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
+					       cr_pht->p_filesz - aux_off, module) < 0) {
+					res = -1;
+					goto out;
+				}
+			} else {
+				if (image_seek(cr_pht->p_offset, module) < 0) {
+					res = -1;
+					goto out;
+				}
+
+				if (image_read(module_get_absolute(cr_pht->p_vaddr, module),
+						cr_pht->p_filesz, module) < 0) {
+					res = -1;
+					goto out;
+				}
+			}
+
+			/*
+			DBG_PRINT("Loadable segment of size 0x%08x copied from vaddr 0x%08x at 0x%08x\n",
+					cr_pht->p_filesz,
+					cr_pht->p_vaddr,
+					(Elf32_Addr)module_get_absolute(cr_pht->p_vaddr, module));
+			*/
+		}
+	}
+
+	// Get to the SHT
+	image_seek(elf_hdr->e_shoff, module);
+
+	// Load the SHT
+	sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+	if (!sht) {
+		res = -1;
+		goto out;
+	}
+
+	image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+	// Setup the symtable size
+	for (i = 0; i < elf_hdr->e_shnum; i++) {
+		cr_sht = (Elf32_Shdr*)(sht + i * elf_hdr->e_shentsize);
+
+		if (cr_sht->sh_type == SHT_DYNSYM) {
+			module->symtable_size = cr_sht->sh_size;
+			break;
+		}
+	}
+
+	free(sht);
+
+	// Setup dynamic segment location
+	module->dyn_table = module_get_absolute(dyn_addr, module);
+
+	/*
+	DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr,
+			max_align);
+	DBG_PRINT("Module size: 0x%08x\n", module->module_size);
+	*/
+
+out:
+	// Free up allocated memory
+	if (pht != NULL)
+		free(pht);
+
+	return res;
+}
+
+int perform_relocation(struct elf_module *module, Elf_Rel *rel) {
+	Elf32_Word *dest = module_get_absolute(rel->r_offset, module);
+
+	// The symbol reference index
+	Elf32_Word sym = ELF32_R_SYM(rel->r_info);
+	unsigned char type = ELF32_R_TYPE(rel->r_info);
+
+	// The symbol definition (if applicable)
+	Elf32_Sym *sym_def = NULL;
+	struct elf_module *sym_module = NULL;
+	Elf32_Addr sym_addr = 0x0;
+
+	if (sym > 0) {
+		// Find out details about the symbol
+
+		// The symbol reference
+		Elf32_Sym *sym_ref = symbol_get_entry(module, sym);
+
+		// The symbol definition
+		sym_def =
+			global_find_symbol(module->str_table + sym_ref->st_name,
+					&sym_module);
+
+		if (sym_def == NULL) {
+			DBG_PRINT("Cannot perform relocation for symbol %s\n",
+					module->str_table + sym_ref->st_name);
+
+			if (ELF32_ST_BIND(sym_ref->st_info) != STB_WEAK)
+				return -1;
+
+			// This must be a derivative-specific
+			// function. We're OK as long as we never
+			// execute the function.
+			sym_def = global_find_symbol("undefined_symbol", &sym_module);
+		}
+
+		// Compute the absolute symbol virtual address
+		sym_addr = (Elf32_Addr)module_get_absolute(sym_def->st_value, sym_module);
+
+		if (sym_module != module) {
+			// Create a dependency
+			enforce_dependency(sym_module, module);
+		}
+	}
+
+	switch (type) {
+	case R_386_NONE:
+		// Do nothing
+		break;
+	case R_386_32:
+		*dest += sym_addr;
+		break;
+	case R_386_PC32:
+		*dest += sym_addr - (Elf32_Addr)dest;
+		break;
+	case R_386_COPY:
+		if (sym_addr > 0) {
+			memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
+		}
+		break;
+	case R_386_GLOB_DAT:
+	case R_386_JMP_SLOT:
+		// Maybe TODO: Keep track of the GOT entries allocations
+		*dest = sym_addr;
+		break;
+	case R_386_RELATIVE:
+		*dest += module->base_addr;
+		break;
+	default:
+		DBG_PRINT("Relocation type %d not supported\n", type);
+		return -1;
+	}
+
+	return 0;
+}
+
+int resolve_symbols(struct elf_module *module) {
+	Elf32_Dyn  *dyn_entry = module->dyn_table;
+	unsigned int i;
+	int res;
+
+	Elf32_Word plt_rel_size = 0;
+	char *plt_rel = NULL;
+
+	char *rel = NULL;
+	Elf32_Word rel_size = 0;
+	Elf32_Word rel_entry = 0;
+
+	// The current relocation
+	Elf32_Rel *crt_rel;
+
+	while (dyn_entry->d_tag != DT_NULL) {
+		switch(dyn_entry->d_tag) {
+
+		// PLT relocation information
+		case DT_PLTRELSZ:
+			plt_rel_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_PLTREL:
+			if (dyn_entry->d_un.d_val != DT_REL) {
+				DBG_PRINT("Unsupported PLT relocation\n");
+				return -1;
+			}
+		case DT_JMPREL:
+			plt_rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+
+		// Standard relocation information
+		case DT_REL:
+			rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_RELSZ:
+			rel_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_RELENT:
+			rel_entry = dyn_entry->d_un.d_val;
+			break;
+
+		// Module initialization and termination
+		case DT_INIT:
+			// TODO Implement initialization functions
+			break;
+		case DT_FINI:
+			// TODO Implement finalization functions
+			break;
+		}
+
+		dyn_entry++;
+	}
+
+	if (rel_size > 0) {
+		// Process standard relocations
+		for (i = 0; i < rel_size/rel_entry; i++) {
+			crt_rel = (Elf32_Rel*)(rel + i*rel_entry);
+
+			res = perform_relocation(module, crt_rel);
+
+			if (res < 0)
+				return res;
+		}
+
+	}
+
+	if (plt_rel_size > 0) {
+		// TODO: Permit this lazily
+		// Process PLT relocations
+		for (i = 0; i < plt_rel_size/sizeof(Elf32_Rel); i++) {
+			crt_rel = (Elf32_Rel*)(plt_rel + i*sizeof(Elf32_Rel));
+
+			res = perform_relocation(module, crt_rel);
+
+			if (res < 0)
+				return res;
+		}
+	}
+
+	return 0;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/x86_64/elf_module.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/x86_64/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/module/x86_64/elf_module.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,380 @@
+/*
+ * elf_module.c
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <elf.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include <linux/list.h>
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#include "elfutils.h"
+#include "../common.h"
+
+/*
+ *
+ * The implementation assumes that the loadable segments are present
+ * in the PHT sorted by their offsets, so that only forward seeks would
+ * be necessary.
+ */
+int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
+	int i;
+	int res = 0;
+	char *pht = NULL;
+	char *sht = NULL;
+	Elf64_Phdr *cr_pht;
+	Elf64_Shdr *cr_sht;
+
+	Elf64_Addr min_addr  = 0x0000000000000000; // Min. ELF vaddr
+	Elf64_Addr max_addr  = 0x0000000000000000; // Max. ELF vaddr
+	Elf64_Word max_align = sizeof(void*); // Min. align of posix_memalign()
+	Elf64_Addr min_alloc, max_alloc;   // Min. and max. aligned allocables
+
+	Elf64_Addr dyn_addr = 0x0000000000000000;
+
+	// Get to the PHT
+	image_seek(elf_hdr->e_phoff, module);
+
+	// Load the PHT
+	pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+	if (!pht)
+		return -1;
+
+	image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
+
+	// Compute the memory needings of the module
+	for (i=0; i < elf_hdr->e_phnum; i++) {
+		cr_pht = (Elf64_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+		switch (cr_pht->p_type) {
+		case PT_LOAD:
+			if (i == 0) {
+				min_addr = cr_pht->p_vaddr;
+			} else {
+				min_addr = MIN(min_addr, cr_pht->p_vaddr);
+			}
+
+			max_addr = MAX(max_addr, cr_pht->p_vaddr + cr_pht->p_memsz);
+			max_align = MAX(max_align, cr_pht->p_align);
+			break;
+		case PT_DYNAMIC:
+			dyn_addr = cr_pht->p_vaddr;
+			break;
+		default:
+			// Unsupported - ignore
+			break;
+		}
+	}
+
+	if (max_addr - min_addr == 0) {
+		// No loadable segments
+		DBG_PRINT("No loadable segments found\n");
+		goto out;
+	}
+
+	if (dyn_addr == 0) {
+		DBG_PRINT("No dynamic information segment found\n");
+		goto out;
+	}
+
+	// The minimum address that should be allocated
+	min_alloc = min_addr - (min_addr % max_align);
+
+	// The maximum address that should be allocated
+	max_alloc = max_addr - (max_addr % max_align);
+	if (max_addr % max_align > 0)
+		max_alloc += max_align;
+
+
+	if (elf_malloc(&module->module_addr,
+			max_align,
+			max_alloc-min_alloc) != 0) {
+
+		DBG_PRINT("Could not allocate segments\n");
+		goto out;
+	}
+
+	module->base_addr = (Elf64_Addr)(module->module_addr) - min_alloc;
+	module->module_size = max_alloc - min_alloc;
+
+	// Zero-initialize the memory
+	memset(module->module_addr, 0, module->module_size);
+
+	for (i = 0; i < elf_hdr->e_phnum; i++) {
+		cr_pht = (Elf64_Phdr*)(pht + i * elf_hdr->e_phentsize);
+
+		if (cr_pht->p_type == PT_LOAD) {
+			// Copy the segment at its destination
+			if (cr_pht->p_offset < module->u.l._cr_offset) {
+				// The segment contains data before the current offset
+				// It can be discarded without worry - it would contain only
+				// headers
+				Elf64_Off aux_off = module->u.l._cr_offset - cr_pht->p_offset;
+
+				if (image_read((char *)module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
+					       cr_pht->p_filesz - aux_off, module) < 0) {
+					res = -1;
+					goto out;
+				}
+			} else {
+				if (image_seek(cr_pht->p_offset, module) < 0) {
+					res = -1;
+					goto out;
+				}
+
+				if (image_read(module_get_absolute(cr_pht->p_vaddr, module),
+						cr_pht->p_filesz, module) < 0) {
+					res = -1;
+					goto out;
+				}
+			}
+
+			/*
+			DBG_PRINT("Loadable segment of size 0x%08x copied from vaddr 0x%08x at 0x%08x\n",
+					cr_pht->p_filesz,
+					cr_pht->p_vaddr,
+					(Elf64_Addr)module_get_absolute(cr_pht->p_vaddr, module));
+			*/
+		}
+	}
+
+	// Get to the SHT
+	image_seek(elf_hdr->e_shoff, module);
+
+	// Load the SHT
+	sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+	if (!sht) {
+		res = -1;
+		goto out;
+	}
+
+	image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
+
+	// Setup the symtable size
+	for (i = 0; i < elf_hdr->e_shnum; i++) {
+		cr_sht = (Elf64_Shdr*)(sht + i * elf_hdr->e_shentsize);
+
+		if (cr_sht->sh_type == SHT_DYNSYM) {
+			module->symtable_size = cr_sht->sh_size;
+			break;
+		}
+	}
+
+	free(sht);
+
+	// Setup dynamic segment location
+	module->dyn_table = module_get_absolute(dyn_addr, module);
+
+	/*
+	DBG_PRINT("Base address: 0x%08x, aligned at 0x%08x\n", module->base_addr,
+			max_align);
+	DBG_PRINT("Module size: 0x%08x\n", module->module_size);
+	*/
+
+out:
+	// Free up allocated memory
+	if (pht != NULL)
+		free(pht);
+
+	return res;
+}
+
+int perform_relocation(struct elf_module *module, Elf_Rel *rel) {
+	Elf64_Xword *dest = module_get_absolute(rel->r_offset, module);
+
+	// The symbol reference index
+	Elf64_Word sym = ELF64_R_SYM(rel->r_info);
+	unsigned char type = ELF64_R_TYPE(rel->r_info);
+
+	// The symbol definition (if applicable)
+	Elf64_Sym *sym_def = NULL;
+	struct elf_module *sym_module = NULL;
+	Elf64_Addr sym_addr = 0x0;
+
+	if (sym > 0) {
+		// Find out details about the symbol
+
+		// The symbol reference
+		Elf64_Sym *sym_ref = symbol_get_entry(module, sym);
+
+		// The symbol definition
+		sym_def =
+			global_find_symbol(module->str_table + sym_ref->st_name,
+					&sym_module);
+
+		if (sym_def == NULL) {
+			DBG_PRINT("Cannot perform relocation for symbol %s\n",
+					module->str_table + sym_ref->st_name);
+
+			if (ELF64_ST_BIND(sym_ref->st_info) != STB_WEAK)
+				return -1;
+
+			// This must be a derivative-specific
+			// function. We're OK as long as we never
+			// execute the function.
+			sym_def = global_find_symbol("undefined_symbol", &sym_module);
+		}
+
+		// Compute the absolute symbol virtual address
+		sym_addr = (Elf64_Addr)module_get_absolute(sym_def->st_value, sym_module);
+
+		if (sym_module != module) {
+			// Create a dependency
+			enforce_dependency(sym_module, module);
+		}
+	}
+
+	switch (type) {
+	case R_X86_64_NONE:
+		// Do nothing
+		break;
+	case R_X86_64_64:
+		*dest += sym_addr;
+		break;
+	case R_X86_64_PC32:
+		*dest += sym_addr - (Elf32_Addr)dest;
+		break;
+	case R_X86_64_COPY:
+		if (sym_addr > 0) {
+			memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
+		}
+		break;
+	case R_X86_64_GLOB_DAT:
+	case R_X86_64_JUMP_SLOT:
+		 //Maybe TODO: Keep track of the GOT entries allocations
+		*dest = sym_addr;
+		break;
+	case R_X86_64_RELATIVE:
+		*dest += module->base_addr;
+		break;
+	default:
+		DBG_PRINT("Relocation type %d not supported\n", type);
+		return -1;
+	}
+
+	return 0;
+}
+
+int resolve_symbols(struct elf_module *module) {
+	Elf64_Dyn  *dyn_entry = module->dyn_table;
+	unsigned int i;
+	int res;
+
+	Elf64_Word plt_rel_size = 0;
+	void *plt_rel = NULL;
+
+	void *rel = NULL;
+	Elf64_Word rel_size = 0;
+	Elf64_Word rel_entry = 0;
+	Elf64_Xword rela_size = 0;
+	Elf64_Xword rela_entry = 0;
+	Elf64_Xword sym_ent = 0;
+
+	// The current relocation
+	Elf64_Rel *crt_rel;
+
+	while (dyn_entry->d_tag != DT_NULL) {
+		switch(dyn_entry->d_tag) {
+
+		// PLT relocation information
+		case DT_PLTRELSZ:
+			plt_rel_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_PLTREL:
+			if (dyn_entry->d_un.d_val != DT_REL && dyn_entry->d_un.d_val != DT_RELA) {
+				DBG_PRINT("Unsupported PLT relocation\n");
+				return -1;
+			}
+			//break;
+		case DT_JMPREL:
+			plt_rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+
+		// Standard relocation information
+		case DT_REL:
+			rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_RELA:
+			rel = module_get_absolute(dyn_entry->d_un.d_ptr, module);
+			break;
+		case DT_RELSZ:
+			rel_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_RELASZ:
+			rela_size = dyn_entry->d_un.d_val;
+			break;
+		case DT_RELENT:
+			rel_entry = dyn_entry->d_un.d_val;
+			break;
+		case DT_RELAENT:
+			rela_entry = dyn_entry->d_un.d_val;
+			break;
+		/* FIXME: We may need to rely upon SYMENT if DT_RELAENT is missing in the object file */
+		case DT_SYMENT:
+			sym_ent = dyn_entry->d_un.d_val;
+			break;
+
+		// Module initialization and termination
+		case DT_INIT:
+			// TODO Implement initialization functions
+			break;
+		case DT_FINI:
+			// TODO Implement finalization functions
+			break;
+		}
+
+		dyn_entry++;
+	}
+
+	if (rel_size > 0) {
+		// Process standard relocations
+		for (i = 0; i < rel_size/rel_entry; i++) {
+			crt_rel = (Elf64_Rel*)(rel + i*rel_entry);
+
+			res = perform_relocation(module, crt_rel);
+
+			if (res < 0)
+				return res;
+		}
+
+	}
+
+	if (rela_size > 0) {
+		// Process standard relocations
+		for (i = 0; i < rela_size/rela_entry; i++) {
+			crt_rel = (Elf64_Rel*)(rel + i*rela_entry);
+
+			res = perform_relocation(module, crt_rel);
+
+			if (res < 0)
+				return res;
+		}
+	}
+	if (plt_rel_size > 0) {
+		// TODO: Permit this lazily
+		// Process PLT relocations
+		/* some modules do not have DT_SYMENT, set it sym_ent in such cases */
+		if (!rela_entry) rela_entry = sym_ent; 
+		//for (i = 0; i < plt_rel_size/sizeof(Elf64_Rel); i++) {
+		for (i = 0; i < plt_rel_size/rela_entry; i++) {
+			//crt_rel = (Elf64_Rel*)(plt_rel + i*sizeof(Elf64_Rel));
+			crt_rel = (Elf64_Rel*)(plt_rel + i*rela_entry);
+
+			res = perform_relocation(module, crt_rel);
+
+			if (res < 0)
+				return res;
+		}
+	}
+
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * null_read.c
+ *
+ * Reading null device
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __null_read(struct file_info *fp, void *buf, size_t count)
+{
+    (void)fp;
+    (void)buf;
+    (void)count;
+    return 0;
+}
+
+const struct input_dev dev_null_r = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_INPUT | __DEV_NULL,
+    .fileflags = O_RDONLY,
+    .read = __null_read,
+    .close = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/null_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * null_write.c
+ *
+ * Null writing device
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __null_write(struct file_info *fp, const void *buf, size_t count)
+{
+    (void)fp;
+    (void)buf;
+    (void)count;
+    return count;
+}
+
+const struct output_dev dev_null_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_OUTPUT | __DEV_NULL,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __null_write,
+    .close = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/open.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/open.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/open.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <fs.h>
+#include "file.h"
+
+/*
+ * open.c
+ *
+ * Open an ordinary file
+ */
+
+extern ssize_t __file_read(struct file_info *, void *, size_t);
+extern int __file_close(struct file_info *);
+
+const struct input_dev __file_dev = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_FILE | __DEV_INPUT,
+    .fileflags = O_RDONLY,
+    .read = __file_read,
+    .close = __file_close,
+    .open = NULL,
+};
+
+int open(const char *pathname, int flags, ...)
+{
+    int fd, handle;
+    struct file_info *fp;
+
+    fd = opendev(&__file_dev, NULL, flags);
+
+    //printf("enter, file = %s, fd = %d\n", pathname, fd);
+
+    if (fd < 0)
+	return -1;
+
+    fp = &__file_info[fd];
+
+    handle = open_file(pathname, flags, &fp->i.fd);
+    if (handle < 0) {
+	close(fd);
+	errno = ENOENT;
+	return -1;
+    }
+
+    fp->i.offset = 0;
+    fp->i.nbytes = 0;
+
+    return fd;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/openconsole.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/openconsole.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/openconsole.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * openconsole.c
+ *
+ * Open the chosen console device
+ */
+
+#include <unistd.h>
+#include <console.h>
+#include <fcntl.h>
+
+int openconsole(const struct input_dev *idev, const struct output_dev *odev)
+{
+    close(0);
+    if (opendev(idev, odev, O_RDONLY) != 0)
+	return -1;
+    close(1);
+    if (opendev(idev, odev, O_WRONLY) != 1)
+	return -1;
+    close(2);
+    if (opendev(idev, odev, O_WRONLY) != 2)
+	return -1;
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/opendev.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/opendev.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/opendev.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,99 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include <unistd.h>
+#include "file.h"
+
+/*
+ * opendev.c
+ *
+ * Open a special device
+ */
+
+int opendev(const struct input_dev *idev,
+	    const struct output_dev *odev, int flags)
+{
+    int fd;
+    struct file_info *fp;
+    int okflags;
+    int e;
+
+    okflags = (idev ? idev->fileflags : 0) | (odev ? odev->fileflags : 0);
+
+    if (!(flags & 3) || (flags & ~okflags)) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    for (fd = 0, fp = __file_info; fd < NFILES; fd++, fp++)
+	if (!fp->iop && !fp->oop)
+	    break;
+
+    if (fd >= NFILES) {
+	errno = EMFILE;
+	return -1;
+    }
+
+    /* The file structure is already zeroed */
+    fp->iop = &dev_error_r;
+    fp->oop = &dev_error_w;
+    fp->i.datap = fp->i.buf;
+
+    if (idev) {
+	if (idev->open && (e = idev->open(fp))) {
+	    errno = e;
+	    goto puke;
+	}
+	fp->iop = idev;
+    }
+
+    while (odev) {
+	if (odev->open && (e = odev->open(fp))) {
+	    if (e == EAGAIN) {
+		if (odev->fallback) {
+		    odev = odev->fallback;
+		    continue;
+		} else {
+		    e = EIO;
+		}
+	    }
+	    errno = e;
+	    goto puke;
+	}
+	fp->oop = odev;
+	break;
+    }
+
+    return fd;
+
+puke:
+    close(fd);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/openmem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/openmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/openmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "file.h"
+
+/*
+ * openmem.c
+ *
+ * Open a chunk of memory as if it was a file
+ */
+
+const struct input_dev __file_dev;
+
+int openmem(const void *base, size_t len, int flags)
+{
+    int fd;
+    struct file_info *fp;
+
+    fd = opendev(&__file_dev, NULL, flags);
+
+    if (fd < 0)
+	return -1;
+
+    fp = &__file_info[fd];
+
+    fp->i.fd.size  = fp->i.nbytes = len;
+    fp->i.datap   = (void *)base;
+    fp->i.fd.handle = 0;		/* No actual file */
+    fp->i.offset  = 0;
+
+    return fd;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rawcon_read.c
+ *
+ * Character-oriented reading from the console without echo;
+ * this is a NONBLOCKING device.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include "file.h"
+
+/* Global, since it's used by stdcon_read */
+ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count)
+{
+    char *bufp = buf;
+    size_t n = 0;
+    static char hi = 0;
+    static bool hi_key = false;
+
+    (void)fp;
+
+    while (n < count) {
+	if (hi_key) {
+	    *bufp++ = hi;
+	    n++;
+	    hi_key = false;
+	    continue;
+	}
+
+	/* Poll */
+	if (!pollchar())
+	    break;
+
+	/* We have data, go get it */
+	*bufp = getchar(&hi);
+	if (!*bufp)
+		hi_key = true;
+
+	bufp++;
+	n++;
+    }
+
+    return n;
+}
+
+const struct input_dev dev_rawcon_r = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_INPUT,
+    .fileflags = O_RDONLY,
+    .read = __rawcon_read,
+    .close = NULL,
+    .open = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/rawcon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rawcon_write.c
+ *
+ * Raw writing to the console; no \n -> \r\n translation
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __rawcon_write(struct file_info *fp, const void *buf,
+			      size_t count)
+{
+    const char *bufp = buf;
+    size_t n = 0;
+
+    (void)fp;
+
+    while (count--) {
+	writechr(*bufp++);
+	n++;
+    }
+
+    return n;
+}
+
+const struct output_dev dev_rawcon_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __rawcon_write,
+    .close = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * read.c
+ *
+ * Reading from a file descriptor
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <klibc/compiler.h>
+#include "file.h"
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+    struct file_info *fp = &__file_info[fd];
+
+    if (fd >= NFILES || !fp->iop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    return fp->iop->read(fp, buf, count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/screensize.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/screensize.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/screensize.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <errno.h>
+#include "file.h"
+
+int getscreensize(int fd, int *rows, int *cols)
+{
+    struct file_info *fp = &__file_info[fd];
+
+    if (fd >= NFILES || !fp->iop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    *rows = fp->o.rows;
+    *cols = fp->o.cols;
+
+    if (!*rows || !*cols) {
+	errno = ENOTTY;
+	return -1;
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/serial_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/serial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/serial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * serial_write.c
+ *
+ * Raw writing to the serial port; no \n -> \r\n translation
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include <syslinux/config.h>
+#include "file.h"
+
+ssize_t __serial_write(struct file_info *fp, const void *buf, size_t count)
+{
+    const char *bufp = buf;
+    size_t n = 0;
+
+    (void)fp;
+
+    if (!syslinux_serial_console_info()->iobase)
+	return count;		/* Nothing to do */
+
+    while (count--) {
+	write_serial(*bufp++);
+	n++;
+    }
+
+    return n;
+}
+
+const struct output_dev dev_serial_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __serial_write,
+    .close = NULL,
+    .open = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/sleep.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/sleep.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/sleep.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,22 @@
+/*
+ * sys/sleep.c
+ */
+
+#include <unistd.h>
+#include <sys/times.h>
+#include <syslinux/idle.h>
+
+unsigned int msleep(unsigned int msec)
+{
+    clock_t start = times(NULL);
+
+    while (times(NULL) - start < msec)
+	syslinux_idle();
+
+    return 0;
+}
+
+unsigned int sleep(unsigned int seconds)
+{
+    return msleep(seconds * 1000);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_read.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_read.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * stdcon_read.c
+ *
+ * Line-oriented reading from the standard console
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count);
+
+static ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count)
+{
+    char *bufp = buf;
+    size_t n = 0;
+    char ch;
+
+    (void)fp;
+
+    while (n < count) {
+	if (fp->i.nbytes) {
+	    ch = *bufp++ = *fp->i.datap++;
+	    fp->i.nbytes--;
+	    n++;
+	    if (ch == '\n')
+		return n;
+	} else {
+	    fp->i.nbytes = __line_input(fp, fp->i.buf, MAXBLOCK, __rawcon_read);
+	    fp->i.datap = fp->i.buf;
+
+	    if (fp->i.nbytes == 0)
+		return n;
+	}
+    }
+
+    return n;
+}
+
+const struct input_dev dev_stdcon_r = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_INPUT,
+    .fileflags = O_RDONLY,
+    .read = __stdcon_read,
+    .close = NULL,
+    .open = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/stdcon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,84 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * stdcon_write.c
+ *
+ * Writing to the console; \n -> \r\n conversion.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include "file.h"
+
+#define BIOS_ROWS (*(uint8_t *)0x484)	/* Minus one; if zero use 24 (= 25 lines) */
+#define BIOS_COLS (*(uint16_t *)0x44A)
+
+static int __stdcon_open(struct file_info *fp)
+{
+    fp->o.rows = BIOS_ROWS + 1;
+    fp->o.cols = BIOS_COLS;
+
+    /* Sanity check */
+    if (fp->o.rows < 12)
+	fp->o.rows = 24;
+    if (fp->o.cols < 40)
+	fp->o.cols = 80;
+
+    return 0;
+}
+
+static ssize_t __stdcon_write(struct file_info *fp, const void *buf,
+			      size_t count)
+{
+    const char *bufp = buf;
+    size_t n = 0;
+
+    (void)fp;
+
+    while (count--) {
+	if (*bufp == '\n')
+	    writechr('\r');
+
+	writechr(*bufp++);
+	n++;
+    }
+
+    return n;
+}
+
+const struct output_dev dev_stdcon_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __stdcon_write,
+    .close = NULL,
+    .open  = __stdcon_open,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/alphatbl.pl
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/alphatbl.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/alphatbl.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+#
+# Produce gamma-correction tables for alpha blending, assuming sRGB space.
+#
+
+sub srgb_to_linear($)
+{
+    my($s) = @_;
+
+    if ($s <= 10) {
+	return $s/(255*12.92);
+    } else {
+	return (($s+14.025)/269.025)**2.4;
+    }
+}
+
+sub linear_to_srgb($)
+{
+    my($l) = @_;
+    my $s;
+
+    if ($l <= 0.00304) {
+	$s = 12.92*$l;
+    } else {
+	$s = 1.055*$l**(1.0/2.4) - 0.055;
+    }
+
+    return int($s*255+0.5);
+}
+
+# Header
+print "#include <inttypes.h>\n\n";
+
+#
+# Table 1: convert 8-bit sRGB values to 16-bit linear values
+#
+
+print "const uint16_t __vesacon_srgb_to_linear[256] = {\n";
+for ($i = 0; $i <= 255; $i++) {
+    printf "\t%5d,\n", int(srgb_to_linear($i)*65535+0.5);
+}
+print "};\n\n";
+
+#
+# Table 2: convert linear values in the range [0, 65535*255],
+#          shifted right by 12 bits, to sRGB
+#
+
+print "const uint8_t __vesacon_linear_to_srgb[4080] = {\n";
+for ($i = 0; $i <= 4079; $i++) {
+    printf "\t%3d,\n", linear_to_srgb(($i+0.5)/4079.937744);
+}
+print "};\n\n";
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/background.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/background.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/background.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,455 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <png.h>
+#include <tinyjpeg.h>
+#include <com32.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <minmax.h>
+#include <stdbool.h>
+#include <ilog2.h>
+#include <syslinux/loadfile.h>
+#include "vesa.h"
+#include "video.h"
+
+/*** FIX: This really should be alpha-blended with color index 0 ***/
+
+/* For best performance, "start" should be a multiple of 4, to assure
+   aligned dwords. */
+static void draw_background_line(int line, int start, int npixels)
+{
+    uint32_t *bgptr = &__vesacon_background[line*__vesa_info.mi.h_res+start];
+    unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
+    size_t fbptr = line * __vesa_info.mi.logical_scan + start*bytes_per_pixel;
+
+    __vesacon_copy_to_screen(fbptr, bgptr, npixels);
+}
+
+/* This draws the border, then redraws the text area */
+static void draw_background(void)
+{
+    int i;
+    const int bottom_border = VIDEO_BORDER +
+	(TEXT_PIXEL_ROWS % __vesacon_font_height);
+    const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH);
+
+    for (i = 0; i < VIDEO_BORDER; i++)
+	draw_background_line(i, 0, __vesa_info.mi.h_res);
+
+    for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) {
+	draw_background_line(i, 0, VIDEO_BORDER);
+	draw_background_line(i, __vesa_info.mi.h_res - right_border,
+			     right_border);
+    }
+
+    for (i = __vesa_info.mi.v_res - bottom_border;
+	 i < __vesa_info.mi.v_res; i++)
+	draw_background_line(i, 0, __vesa_info.mi.h_res);
+
+    __vesacon_redraw_text();
+}
+
+/*
+ * Tile an image in the UL corner across the entire screen
+ */
+static void tile_image(int width, int height)
+{
+    int xsize = __vesa_info.mi.h_res;
+    int ysize = __vesa_info.mi.v_res;
+    int x, y, yr;
+    int xl, yl;
+    uint32_t *sp, *dp, *drp, *dtp;
+
+    drp = __vesacon_background;
+    for (y = 0 ; y < ysize ; y += height) {
+	yl = min(height, ysize-y);
+	dtp = drp;
+	for (x = 0 ; x < xsize ; x += width) {
+	    xl = min(width, xsize-x);
+	    if (x || y) {
+		sp = __vesacon_background;
+		dp = dtp;
+		for (yr = 0 ; yr < yl ; yr++) {
+		    memcpy(dp, sp, xl*sizeof(uint32_t));
+		    dp += xsize;
+		    sp += xsize;
+		}
+	    }
+	    dtp += xl;
+	}
+	drp += xsize*height;
+    }
+}
+
+static int read_png_file(FILE * fp)
+{
+    png_structp png_ptr = NULL;
+    png_infop info_ptr = NULL;
+#if 0
+    png_color_16p image_background;
+    static const png_color_16 my_background = { 0, 0, 0, 0, 0 };
+#endif
+    png_bytep row_pointers[__vesa_info.mi.v_res], rp;
+    int i;
+    int rv = -1;
+
+    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    info_ptr = png_create_info_struct(png_ptr);
+
+    if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr)))
+	goto err;
+
+    png_init_io(png_ptr, fp);
+    png_set_sig_bytes(png_ptr, 8);
+
+    png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res);
+
+    png_read_info(png_ptr, info_ptr);
+
+    /* Set the appropriate set of transformations.  We need to end up
+       with 32-bit BGRA format, no more, no less. */
+
+    /* Expand to RGB first... */
+    if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE)
+	png_set_palette_to_rgb(png_ptr);
+    else if (!(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
+	png_set_gray_to_rgb(png_ptr);
+
+    /* Add alpha channel, if need be */
+    if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) {
+	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+	    png_set_tRNS_to_alpha(png_ptr);
+	else
+	    png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER);
+    }
+
+    /* Adjust the byte order, if necessary */
+    png_set_bgr(png_ptr);
+
+    /* Make sure we end up with 8-bit data */
+    if (info_ptr->bit_depth == 16)
+	png_set_strip_16(png_ptr);
+    else if (info_ptr->bit_depth < 8)
+	png_set_packing(png_ptr);
+
+#if 0
+    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+	png_set_background(png_ptr, image_background,
+			   PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+	png_set_background(png_ptr, &my_background,
+			   PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+#endif
+
+    /* Whew!  Now we should get the stuff we want... */
+    rp = (png_bytep)__vesacon_background;
+    for (i = 0; i < (int)info_ptr->height; i++) {
+	row_pointers[i] = rp;
+	rp += __vesa_info.mi.h_res << 2;
+    }
+
+    png_read_image(png_ptr, row_pointers);
+
+    tile_image(info_ptr->width, info_ptr->height);
+
+    rv = 0;
+
+err:
+    if (png_ptr)
+	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
+    return rv;
+}
+
+static int jpeg_sig_cmp(uint8_t * bytes, int len)
+{
+    (void)len;
+
+    return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1;
+}
+
+static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
+{
+    struct jdec_private *jdec = NULL;
+    void *jpeg_file = NULL;
+    size_t length_of_file;
+    unsigned int width, height;
+    int rv = -1;
+    unsigned char *components[1];
+    unsigned int bytes_per_row[1];
+
+    rv = floadfile(fp, &jpeg_file, &length_of_file, header, len);
+    if (rv)
+	goto err;
+
+    jdec = tinyjpeg_init();
+    if (!jdec)
+	goto err;
+
+    if (tinyjpeg_parse_header(jdec, jpeg_file, length_of_file) < 0)
+	goto err;
+
+    tinyjpeg_get_size(jdec, &width, &height);
+    if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res)
+	goto err;
+
+    components[0] = (void *)__vesacon_background;
+    tinyjpeg_set_components(jdec, components, 1);
+    bytes_per_row[0] = __vesa_info.mi.h_res << 2;
+    tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1);
+
+    tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32);
+    tile_image(width, height);
+
+    rv = 0;
+
+err:
+    /* Don't use tinyjpeg_free() here, since we didn't allow tinyjpeg
+       to allocate the frame buffer */
+    if (jdec)
+	free(jdec);
+
+    if (jpeg_file)
+	free(jpeg_file);
+
+    return rv;
+}
+
+/* Simple grey Gaussian hole, enough to look interesting */
+int vesacon_default_background(void)
+{
+    int x, y, dx, dy, dy2;
+    int z;
+    unsigned int shft;
+    uint8_t *bgptr = (uint8_t *)__vesacon_background;
+    uint8_t k;
+
+    if (__vesacon_pixel_format == PXF_NONE)
+	return 0;		/* Not in graphics mode */
+
+    z = max(__vesa_info.mi.v_res, __vesa_info.mi.h_res) >> 1;
+    z = ((z*z) >> 11) - 1;
+    shft = ilog2(z) + 1;
+
+    for (y = 0, dy = -(__vesa_info.mi.v_res >> 1);
+	 y < __vesa_info.mi.v_res; y++, dy++) {
+	dy2 = dy * dy;
+	for (x = 0, dx = -(__vesa_info.mi.h_res >> 1);
+	     x < __vesa_info.mi.h_res; x++, dx++) {
+	    k = __vesacon_linear_to_srgb[500 + ((dx*dx + dy2) >> shft)];
+	    bgptr[0] = k;	/* Blue */
+	    bgptr[1] = k;	/* Green */
+	    bgptr[2] = k;	/* Red */
+	    bgptr += 4;		/* Dummy alpha */
+	}
+    }
+
+    draw_background();
+    return 0;
+}
+
+/* Set the background to a single flat color */
+int vesacon_set_background(unsigned int rgb)
+{
+    void *bgptr = __vesacon_background;
+    unsigned int count = __vesa_info.mi.h_res * __vesa_info.mi.v_res;
+
+    if (__vesacon_pixel_format == PXF_NONE)
+	return 0;		/* Not in graphics mode */
+
+    asm volatile ("rep; stosl":"+D" (bgptr), "+c"(count)
+		  :"a"(rgb)
+		  :"memory");
+
+    draw_background();
+    return 0;
+}
+
+struct lss16_header {
+    uint32_t magic;
+    uint16_t xsize;
+    uint16_t ysize;
+};
+
+#define LSS16_MAGIC 0x1413f33d
+
+static inline int lss16_sig_cmp(const void *header, int len)
+{
+    const struct lss16_header *h = header;
+
+    if (len != 8)
+	return 1;
+
+    return !(h->magic == LSS16_MAGIC &&
+	     h->xsize <= __vesa_info.mi.h_res &&
+	     h->ysize <= __vesa_info.mi.v_res);
+}
+
+static int read_lss16_file(FILE * fp, const void *header, int header_len)
+{
+    const struct lss16_header *h = header;
+    uint32_t colors[16], color;
+    bool has_nybble;
+    uint8_t byte;
+    int count;
+    int nybble, prev;
+    enum state {
+	st_start,
+	st_c0,
+	st_c1,
+	st_c2,
+    } state;
+    int i, x, y;
+    uint32_t *bgptr = __vesacon_background;
+
+    /* Assume the header, 8 bytes, has already been loaded. */
+    if (header_len != 8)
+	return -1;
+
+    for (i = 0; i < 16; i++) {
+	uint8_t rgb[3];
+	if (fread(rgb, 1, 3, fp) != 3)
+	    return -1;
+
+	colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) +
+	    (((rgb[1] & 63) * 255 / 63) << 8) +
+	    ((rgb[2] & 63) * 255 / 63);
+    }
+
+    /* By spec, the state machine is per row */
+    for (y = 0; y < h->ysize; y++) {
+	state = st_start;
+	has_nybble = false;
+	color = colors[prev = 0];	/* By specification */
+	count = 0;
+
+	x = 0;
+	while (x < h->xsize) {
+	    if (!has_nybble) {
+		if (fread(&byte, 1, 1, fp) != 1)
+		    return -1;
+		nybble = byte & 0xf;
+		has_nybble = true;
+	    } else {
+		nybble = byte >> 4;
+		has_nybble = false;
+	    }
+
+	    switch (state) {
+	    case st_start:
+		if (nybble != prev) {
+		    *bgptr++ = color = colors[prev = nybble];
+		    x++;
+		} else {
+		    state = st_c0;
+		}
+		break;
+
+	    case st_c0:
+		if (nybble == 0) {
+		    state = st_c1;
+		} else {
+		    count = nybble;
+		    goto do_run;
+		}
+		break;
+
+	    case st_c1:
+		count = nybble + 16;
+		state = st_c2;
+		break;
+
+	    case st_c2:
+		count += nybble << 4;
+		goto do_run;
+
+do_run:
+		count = min(count, h->xsize - x);
+		x += count;
+		asm volatile ("rep; stosl":"+D" (bgptr),
+			      "+c"(count):"a"(color));
+		state = st_start;
+		break;
+	    }
+	}
+
+	/* Zero-fill rest of row */
+	i = __vesa_info.mi.h_res - x;
+	asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
+    }
+
+    /* Zero-fill rest of screen */
+    i = (__vesa_info.mi.v_res - y) * __vesa_info.mi.h_res;
+    asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
+
+    return 0;
+}
+
+int vesacon_load_background(const char *filename)
+{
+    FILE *fp = NULL;
+    uint8_t header[8];
+    int rv = 1;
+
+    if (__vesacon_pixel_format == PXF_NONE)
+	return 0;		/* Not in graphics mode */
+
+    fp = fopen(filename, "r");
+
+    if (!fp)
+	goto err;
+
+    if (fread(header, 1, 8, fp) != 8)
+	goto err;
+
+    if (!png_sig_cmp(header, 0, 8)) {
+	rv = read_png_file(fp);
+    } else if (!jpeg_sig_cmp(header, 8)) {
+	rv = read_jpeg_file(fp, header, 8);
+    } else if (!lss16_sig_cmp(header, 8)) {
+	rv = read_lss16_file(fp, header, 8);
+    }
+
+    /* This actually displays the stuff */
+    draw_background();
+
+err:
+    if (fp)
+	fclose(fp);
+
+    return rv;
+}
+
+int __vesacon_init_background(void)
+{
+    /* __vesacon_background was cleared by calloc() */
+
+    /* The VESA BIOS has already cleared the screen */
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/debug.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/debug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/debug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+#ifndef LIB_SYS_VESA_DEBUG_H
+#define LIB_SYS_VESA_DEBUG_H
+
+#if 0
+
+#include <stdio.h>
+#include <unistd.h>
+
+ssize_t __serial_write(void *fp, const void *buf, size_t count);
+
+static void debug(const char *str, ...)
+{
+    va_list va;
+    char buf[65536];
+    size_t len;
+
+    va_start(va, str);
+    len = vsnprintf(buf, sizeof buf, str, va);
+    va_end(va);
+
+    if (len >= sizeof buf)
+	len = sizeof buf - 1;
+
+    __serial_write(NULL, buf, len);
+}
+
+#else
+
+static inline void debug(const char *str, ...)
+{
+    (void)str;
+}
+
+#endif
+
+#endif /* LIB_SYS_VESA_DEBUG_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/drawtxt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/drawtxt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/drawtxt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,317 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <inttypes.h>
+#include <colortbl.h>
+#include <string.h>
+#include "vesa.h"
+#include "video.h"
+#include "fill.h"
+
+/*
+ * Visible cursor information
+ */
+static uint8_t cursor_pattern[FONT_MAX_HEIGHT];
+static struct vesa_char *cursor_pointer = NULL;
+static int cursor_x, cursor_y;
+
+static inline void *copy_dword(void *dst, void *src, size_t dword_count)
+{
+    asm volatile ("rep; movsl":"+D" (dst), "+S"(src), "+c"(dword_count));
+    return dst;			/* Updated destination pointer */
+}
+
+static inline __attribute__ ((always_inline))
+uint8_t alpha_val(uint8_t fg, uint8_t bg, uint8_t alpha)
+{
+    unsigned int tmp;
+
+    tmp = __vesacon_srgb_to_linear[fg] * alpha;
+    tmp += __vesacon_srgb_to_linear[bg] * (255 - alpha);
+
+    return __vesacon_linear_to_srgb[tmp >> 12];
+}
+
+static uint32_t alpha_pixel(uint32_t fg, uint32_t bg)
+{
+    uint8_t alpha = fg >> 24;
+    uint8_t fg_r = fg >> 16;
+    uint8_t fg_g = fg >> 8;
+    uint8_t fg_b = fg;
+    uint8_t bg_r = bg >> 16;
+    uint8_t bg_g = bg >> 8;
+    uint8_t bg_b = bg;
+
+    return
+	(alpha_val(fg_r, bg_r, alpha) << 16) |
+	(alpha_val(fg_g, bg_g, alpha) << 8) | (alpha_val(fg_b, bg_b, alpha));
+}
+
+static void vesacon_update_characters(int row, int col, int nrows, int ncols)
+{
+    const int height = __vesacon_font_height;
+    const int width = FONT_WIDTH;
+    uint32_t *bgrowptr, *bgptr, bgval, fgval;
+    uint32_t fgcolor = 0, bgcolor = 0, color;
+    uint8_t chbits = 0, chxbits = 0, chsbits = 0;
+    int i, j, jx, pixrow, pixsrow;
+    struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
+    unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
+    unsigned long pixel_offset;
+    uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr;
+    size_t fbrowptr;
+    uint8_t sha;
+
+    pixel_offset = ((row * height + VIDEO_BORDER) * __vesa_info.mi.h_res) +
+	(col * width + VIDEO_BORDER);
+
+    bgrowptr = &__vesacon_background[pixel_offset];
+    fbrowptr = (row * height + VIDEO_BORDER) * __vesa_info.mi.logical_scan +
+	(col * width + VIDEO_BORDER) * bytes_per_pixel;
+
+    /* Note that we keep a 1-character guard area around the real text area... */
+    rowptr = &__vesacon_text_display[(row+1)*(__vesacon_text_cols+2)+(col+1)];
+    rowsptr = rowptr - ((__vesacon_text_cols+2)+1);
+    pixrow = 0;
+    pixsrow = height - 1;
+
+    for (i = height * nrows; i >= 0; i--) {
+	bgptr = bgrowptr;
+	rowbufptr = row_buffer;
+
+	cptr = rowptr;
+	csptr = rowsptr;
+
+	chsbits = __vesacon_graphics_font[csptr->ch][pixsrow];
+	if (__unlikely(csptr == cursor_pointer))
+	    chsbits |= cursor_pattern[pixsrow];
+	sha = console_color_table[csptr->attr].shadow;
+	chsbits &= (sha & 0x02) ? 0xff : 0x00;
+	chsbits ^= (sha & 0x01) ? 0xff : 0x00;
+	chsbits <<= (width - 2);
+	csptr++;
+
+	/* Draw two pixels beyond the end of the line.  One for the shadow,
+	   and one to make sure we have a whole dword of data for the copy
+	   operation at the end.  Note that this code depends on the fact that
+	   all characters begin on dword boundaries in the frame buffer. */
+
+	for (jx = 1, j = width * ncols + 1; j >= 0; j--) {
+	    chbits <<= 1;
+	    chsbits <<= 1;
+	    chxbits <<= 1;
+
+	    switch (jx) {
+	    case 1:
+		chbits = __vesacon_graphics_font[cptr->ch][pixrow];
+		if (__unlikely(cptr == cursor_pointer))
+		    chbits |= cursor_pattern[pixrow];
+		sha = console_color_table[cptr->attr].shadow;
+		chxbits = chbits;
+		chxbits &= (sha & 0x02) ? 0xff : 0x00;
+		chxbits ^= (sha & 0x01) ? 0xff : 0x00;
+		fgcolor = console_color_table[cptr->attr].argb_fg;
+		bgcolor = console_color_table[cptr->attr].argb_bg;
+		cptr++;
+		jx--;
+		break;
+	    case 0:
+		chsbits = __vesacon_graphics_font[csptr->ch][pixsrow];
+		if (__unlikely(csptr == cursor_pointer))
+		    chsbits |= cursor_pattern[pixsrow];
+		sha = console_color_table[csptr->attr].shadow;
+		chsbits &= (sha & 0x02) ? 0xff : 0x00;
+		chsbits ^= (sha & 0x01) ? 0xff : 0x00;
+		csptr++;
+		jx = width - 1;
+		break;
+	    default:
+		jx--;
+		break;
+	    }
+
+	    /* If this pixel is raised, use the offsetted value */
+	    bgval = (chxbits & 0x80)
+		? bgptr[__vesa_info.mi.h_res + 1] : *bgptr;
+	    bgptr++;
+
+	    /* If this pixel is set, use the fg color, else the bg color */
+	    fgval = (chbits & 0x80) ? fgcolor : bgcolor;
+
+	    /* Produce the combined color pixel value */
+	    color = alpha_pixel(fgval, bgval);
+
+	    /* Apply the shadow (75% shadow) */
+	    if ((chsbits & ~chxbits) & 0x80) {
+		color >>= 2;
+		color &= 0x3f3f3f;
+	    }
+
+	    *rowbufptr++ = color;
+	}
+
+	/* Copy to frame buffer */
+	__vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer);
+
+	bgrowptr += __vesa_info.mi.h_res;
+	fbrowptr += __vesa_info.mi.logical_scan;
+
+	if (++pixrow == height) {
+	    rowptr += __vesacon_text_cols + 2;
+	    pixrow = 0;
+	}
+	if (++pixsrow == height) {
+	    rowsptr += __vesacon_text_cols + 2;
+	    pixsrow = 0;
+	}
+    }
+}
+
+/* Bounding box for changed text.  The (x1, y1) coordinates are +1! */
+static unsigned int upd_x0 = -1U, upd_x1, upd_y0 = -1U, upd_y1;
+
+/* Update the range already touched by various variables */
+void __vesacon_doit(void)
+{
+    if (upd_x1 > upd_x0 && upd_y1 > upd_y0) {
+	vesacon_update_characters(upd_y0, upd_x0, upd_y1 - upd_y0,
+				  upd_x1 - upd_x0);
+	upd_x0 = upd_y0 = -1U;
+	upd_x1 = upd_y1 = 0;
+    }
+}
+
+/* Mark a range for update; note argument sequence is the same as
+   vesacon_update_characters() */
+static inline void vesacon_touch(int row, int col, int rows, int cols)
+{
+    unsigned int y0 = row;
+    unsigned int x0 = col;
+    unsigned int y1 = y0 + rows;
+    unsigned int x1 = x0 + cols;
+
+    if (y0 < upd_y0)
+	upd_y0 = y0;
+    if (y1 > upd_y1)
+	upd_y1 = y1;
+    if (x0 < upd_x0)
+	upd_x0 = x0;
+    if (x1 > upd_x1)
+	upd_x1 = x1;
+}
+
+/* Erase a region of the screen */
+void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
+{
+    int y;
+    struct vesa_char *ptr = &__vesacon_text_display
+	[(y0 + 1) * (__vesacon_text_cols + 2) + (x0 + 1)];
+    struct vesa_char fill = {
+	.ch = ' ',
+	.attr = attr,
+    };
+    int ncols = x1 - x0 + 1;
+
+    for (y = y0; y <= y1; y++) {
+	vesacon_fill(ptr, fill, ncols);
+	ptr += __vesacon_text_cols + 2;
+    }
+
+    vesacon_touch(y0, x0, y1 - y0 + 1, ncols);
+}
+
+/* Scroll the screen up */
+void __vesacon_scroll_up(int nrows, attr_t attr)
+{
+    struct vesa_char *fromptr = &__vesacon_text_display
+	[(nrows + 1) * (__vesacon_text_cols + 2)];
+    struct vesa_char *toptr = &__vesacon_text_display
+	[(__vesacon_text_cols + 2)];
+    int dword_count =
+	(__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2);
+    struct vesa_char fill = {
+	.ch = ' ',
+	.attr = attr,
+    };
+
+    toptr = copy_dword(toptr, fromptr, dword_count);
+
+    dword_count = nrows * (__vesacon_text_cols + 2);
+
+    vesacon_fill(toptr, fill, dword_count);
+
+    vesacon_touch(0, 0, __vesacon_text_rows, __vesacon_text_cols);
+}
+
+/* Draw one character text at a specific area of the screen */
+void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr)
+{
+    struct vesa_char *ptr = &__vesacon_text_display
+	[(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
+
+    ptr->ch = ch;
+    ptr->attr = attr;
+
+    vesacon_touch(y, x, 1, 1);
+}
+
+void __vesacon_set_cursor(int x, int y, bool visible)
+{
+    struct vesa_char *ptr = &__vesacon_text_display
+	[(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
+
+    if (cursor_pointer)
+	vesacon_touch(cursor_y, cursor_x, 1, 1);
+
+    if (!visible) {
+	/* Invisible cursor */
+	cursor_pointer = NULL;
+    } else {
+	cursor_pointer = ptr;
+	vesacon_touch(y, x, 1, 1);
+    }
+
+    cursor_x = x;
+    cursor_y = y;
+}
+
+void __vesacon_init_cursor(int font_height)
+{
+    int r0 = font_height - (font_height < 10 ? 2 : 3);
+
+    if (r0 < 0)
+	r0 = 0;
+
+    memset(cursor_pattern, 0, font_height);
+    cursor_pattern[r0] = 0xff;
+    cursor_pattern[r0 + 1] = 0xff;
+}
+
+void __vesacon_redraw_text(void)
+{
+    vesacon_update_characters(0, 0, __vesacon_text_rows, __vesacon_text_cols);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fill.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fill.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fill.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_FILL_H
+#define LIB_SYS_VESA_FILL_H
+
+#include "video.h"
+
+/* Fill a number of characters. */
+static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr,
+					     struct vesa_char fill,
+					     unsigned int count)
+{
+    switch (sizeof(struct vesa_char)) {
+    case 1:
+	asm volatile ("rep; stosb":"+D" (ptr), "+c"(count)
+		      :"a"(fill)
+		      :"memory");
+	break;
+    case 2:
+	asm volatile ("rep; stosw":"+D" (ptr), "+c"(count)
+		      :"a"(fill)
+		      :"memory");
+	break;
+    case 4:
+	asm volatile ("rep; stosl":"+D" (ptr), "+c"(count)
+		      :"a"(fill)
+		      :"memory");
+	break;
+    default:
+	while (count--)
+	    *ptr++ = fill;
+	break;
+    }
+
+    return ptr;
+}
+
+#endif /* LIB_SYS_VESA_FILL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fmtpixel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fmtpixel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/fmtpixel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fmtpixel.c
+ *
+ * Functions to format a single pixel
+ */
+
+#include <inttypes.h>
+#include "video.h"
+
+/*
+ * Format a sequence of pixels.  The first argument is the line buffer;
+ * we can use it to write up to 4 bytes past the end of the last pixel.
+ * Return the place we should be copying from, this is usually the
+ * buffer address, but doesn't *have* to be.
+ */
+
+static const void *format_pxf_bgra32(void *ptr, const uint32_t * p, size_t n)
+{
+    (void)ptr;
+    (void)n;
+    return p;			/* No conversion needed! */
+}
+
+static const void *format_pxf_bgr24(void *ptr, const uint32_t * p, size_t n)
+{
+    char *q = ptr;
+
+    while (n--) {
+	*(uint32_t *) q = *p++;
+	q += 3;
+    }
+    return ptr;
+}
+
+static const void *format_pxf_le_rgb16_565(void *ptr, const uint32_t * p,
+					   size_t n)
+{
+    uint32_t bgra;
+    uint16_t *q = ptr;
+
+    while (n--) {
+	bgra = *p++;
+	*q++ =
+	    ((bgra >> 3) & 0x1f) +
+	    ((bgra >> (2 + 8 - 5)) & (0x3f << 5)) +
+	    ((bgra >> (3 + 16 - 11)) & (0x1f << 11));
+    }
+    return ptr;
+}
+
+static const void *format_pxf_le_rgb15_555(void *ptr, const uint32_t * p,
+					   size_t n)
+{
+    uint32_t bgra;
+    uint16_t *q = ptr;
+
+    while (n--) {
+	bgra = *p++;
+	*q++ =
+	    ((bgra >> 3) & 0x1f) +
+	    ((bgra >> (2 + 8 - 5)) & (0x1f << 5)) +
+	    ((bgra >> (3 + 16 - 10)) & (0x1f << 10));
+    }
+    return ptr;
+}
+
+__vesacon_format_pixels_t __vesacon_format_pixels;
+
+const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = {
+    [PXF_BGRA32] = format_pxf_bgra32,
+    [PXF_BGR24] = format_pxf_bgr24,
+    [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565,
+    [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/i915resolution.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/i915resolution.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/i915resolution.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,795 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Based on:
+ * 
+ * 915 resolution by steve tomljenovic
+ *
+ * This was tested only on Sony VGN-FS550.  Use at your own risk
+ *
+ * This code is based on the techniques used in :
+ *
+ *   - 855patch.  Many thanks to Christian Zietz (czietz gmx net)
+ *     for demonstrating how to shadow the VBIOS into system RAM
+ *     and then modify it.
+ *
+ *   - 1280patch by Andrew Tipton (andrewtipton null li).
+ *
+ *   - 855resolution by Alain Poirier
+ *
+ * This source code is into the public domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#define __USE_GNU
+#include <string.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <sys/pci.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "video.h"
+#include "debug.h"
+
+#define VBIOS_START         0xc0000
+#define VBIOS_SIZE          0x10000
+
+#define MODE_TABLE_OFFSET_845G 617
+
+#define VERSION "0.5.3"
+
+#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
+#define ATI_SIGNATURE2 "ATI Technologies Inc"
+#define NVIDIA_SIGNATURE "NVIDIA Corp"
+#define INTEL_SIGNATURE "Intel Corp"
+
+typedef unsigned char * address;
+
+typedef enum {
+    CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM,
+    CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME,
+    CHIPSET_TYPES
+} chipset_type;
+
+typedef enum {
+    BT_UNKWN, BT_1, BT_2, BT_3
+} bios_type;
+
+static int freqs[] = { 60, 75, 85 };
+
+typedef struct {
+    uint8_t mode;
+    uint8_t bits_per_pixel;
+    uint16_t resolution;
+    uint8_t unknown;
+} __attribute__((packed)) vbios_mode;
+
+typedef struct {
+    uint16_t clock;		/* Clock frequency in 10 kHz */
+    uint8_t x1;
+    uint8_t x_total;
+    uint8_t x2;
+    uint8_t y1;
+    uint8_t y_total;
+    uint8_t y2;
+} __attribute__((packed)) vbios_resolution_type1;
+
+typedef struct {
+    uint32_t clock;
+
+    uint16_t x1;
+    uint16_t htotal;
+    uint16_t x2;
+    uint16_t hblank;
+    uint16_t hsyncstart;
+    uint16_t hsyncend;
+
+    uint16_t y1;
+    uint16_t vtotal;
+    uint16_t y2;
+    uint16_t vblank;
+    uint16_t vsyncstart;
+    uint16_t vsyncend;
+} __attribute__((packed)) vbios_modeline_type2;
+
+typedef struct {
+    uint8_t xchars;
+    uint8_t ychars;
+    uint8_t unknown[4];
+
+    vbios_modeline_type2 modelines[];
+} __attribute__((packed)) vbios_resolution_type2;
+
+typedef struct {
+    uint32_t clock;
+
+    uint16_t x1;
+    uint16_t htotal;
+    uint16_t x2;
+    uint16_t hblank;
+    uint16_t hsyncstart;
+    uint16_t hsyncend;
+
+    uint16_t y1;
+    uint16_t vtotal;
+    uint16_t y2;
+    uint16_t vblank;
+    uint16_t vsyncstart;
+    uint16_t vsyncend;
+
+    uint16_t timing_h;
+    uint16_t timing_v;
+
+    uint8_t unknown[6];
+} __attribute__((packed)) vbios_modeline_type3;
+
+typedef struct {
+    unsigned char unknown[6];
+
+    vbios_modeline_type3 modelines[];
+} __attribute__((packed)) vbios_resolution_type3;
+
+
+typedef struct {
+    unsigned int chipset_id;
+    chipset_type chipset;
+    bios_type bios;
+    
+    address bios_ptr;
+
+    vbios_mode * mode_table;
+    unsigned int mode_table_size;
+
+    uint8_t b1, b2;
+
+    bool unlocked;
+} vbios_map;
+
+#if 0				/* Debugging hacks */
+static void good_marker(int x)
+{
+    ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void bad_marker(int x)
+{
+    ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f);
+}
+
+static void status(const char *fmt, ...)
+{
+    va_list ap;
+    char msg[81], *p;
+    int i;
+    uint16_t *q;
+
+    memset(msg, 0, sizeof msg);
+    va_start(ap, fmt);
+    vsnprintf(msg, sizeof msg, fmt, ap);
+    va_end(ap);
+    p = msg;
+    q = (uint16_t *)0xb8000 + 80;
+    for (i = 0; i < 80; i++)
+	*q++ = *p++ + 0x1f00;
+}
+#else
+static inline void good_marker(int x) { (void)x; }
+static inline void bad_marker(int x) { (void)x; }
+static inline void status(const char *fmt, ...) { (void)fmt; }
+#endif
+
+static unsigned int get_chipset_id(void) {
+    return pci_readl(0x80000000);
+}
+
+static chipset_type get_chipset(unsigned int id) {
+    chipset_type type;
+
+    switch (id) {
+    case 0x35758086:
+        type = CT_830;
+        break;
+
+    case 0x25608086:
+        type = CT_845G;
+        break;
+        
+    case 0x35808086:
+        type = CT_855GM;
+        break;
+        
+    case 0x25708086:
+        type = CT_865G;
+        break;
+
+    case 0x25808086:
+	type = CT_915G;
+	break;
+
+    case 0x25908086:
+        type = CT_915GM;
+        break;
+
+    case 0x27708086:
+        type = CT_945G;
+        break;
+
+    case 0x27a08086:
+        type = CT_945GM;
+        break;
+
+    case 0x29708086:
+        type = CT_946GZ;
+        break;
+
+    case 0x29a08086:
+	type = CT_G965;
+	break;
+
+    case 0x29908086:
+        type = CT_Q965;
+        break;
+
+    case 0x27ac8086:
+	type = CT_945GME;
+	break;
+
+    default:
+        type = CT_UNKWN;
+        break;
+    }
+
+    return type;
+}
+
+
+static vbios_resolution_type1 * map_type1_resolution(vbios_map * map,
+						     uint16_t res)
+{
+    vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); 
+    return ptr;
+}
+
+static vbios_resolution_type2 * map_type2_resolution(vbios_map * map,
+						     uint16_t res)
+{
+    vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); 
+    return ptr;
+}
+
+static vbios_resolution_type3 * map_type3_resolution(vbios_map * map,
+						     uint16_t res)
+{
+    vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); 
+    return ptr;
+}
+
+
+static bool detect_bios_type(vbios_map * map, int entry_size)
+{
+    unsigned int i;
+    uint16_t r1, r2;
+    
+    r1 = r2 = 32000;
+
+    for (i = 0; i < map->mode_table_size; i++) {
+        if (map->mode_table[i].resolution <= r1) {
+            r1 = map->mode_table[i].resolution;
+    	} else if (map->mode_table[i].resolution <= r2) {
+	    r2 = map->mode_table[i].resolution;
+    	}
+    }
+    
+    return ((r2-r1-6) % entry_size) == 0;
+}
+
+static inline void close_vbios(vbios_map *map)
+{
+    (void)map;
+}
+
+static vbios_map * open_vbios(void)
+{
+    static vbios_map _map;
+    vbios_map * const map = &_map;
+
+    memset(&_map, 0, sizeof _map);
+
+    /*
+     * Determine chipset
+     */
+    map->chipset_id = get_chipset_id();
+    good_marker(0x10);
+    map->chipset = get_chipset(map->chipset_id);
+    good_marker(0x11);
+
+    /*
+     *  Map the video bios to memory
+     */
+    map->bios_ptr = (void *)VBIOS_START;
+
+    /*
+     * check if we have ATI Radeon
+     */
+    
+    if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
+        memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
+        debug("ATI chipset detected.  915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+	return NULL;
+    }
+
+    /*
+     * check if we have NVIDIA
+     */
+    
+    if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
+        debug("NVIDIA chipset detected.  915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+	return NULL;
+    }
+
+    /*
+     * check if we have Intel
+     */
+    
+    if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
+        debug("Intel chipset detected.  However, 915resolution was unable to determine the chipset type.\r\n");
+
+        debug("Chipset Id: %x\r\n", map->chipset_id);
+
+        debug("Please report this problem to stomljen@yahoo.com\r\n");
+        
+        close_vbios(map);
+	return NULL;
+    }
+
+    /*
+     * check for others
+     */
+
+    if (map->chipset == CT_UNKWN) {
+        debug("Unknown chipset type and unrecognized bios.\r\n");
+        debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n");
+
+        debug("Chipset Id: %x\r\n", map->chipset_id);
+        close_vbios(map);
+	return NULL;
+    }
+
+    /*
+     * Figure out where the mode table is 
+     */
+    good_marker(0x12);
+
+    {
+        address p = map->bios_ptr + 16;
+        address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
+        
+        while (p < limit && map->mode_table == 0) {
+            vbios_mode * mode_ptr = (vbios_mode *) p;
+            
+            if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
+                ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
+
+                map->mode_table = mode_ptr;
+            }
+            
+            p++;
+        }
+
+        if (map->mode_table == 0) {
+            debug("Unable to locate the mode table.\r\n");
+            close_vbios(map);
+	    return NULL;
+        }
+    }
+    good_marker(0x13);
+
+    /*
+     * Determine size of mode table
+     */
+    
+    {
+        vbios_mode * mode_ptr = map->mode_table;
+        
+        while (mode_ptr->mode != 0xff) {
+            map->mode_table_size++;
+            mode_ptr++;
+        }
+    }
+    good_marker(0x14);
+    status("mode_table_size = %d", map->mode_table_size);
+
+    /*
+     * Figure out what type of bios we have
+     *  order of detection is important
+     */
+
+    if (detect_bios_type(map, sizeof(vbios_modeline_type3))) {
+        map->bios = BT_3;
+    }
+    else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) {
+        map->bios = BT_2;
+    }
+    else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) {
+        map->bios = BT_1;
+    }
+    else {
+        debug("Unable to determine bios type.\r\n");
+        debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+        debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+	bad_marker(0x15);
+	return NULL;
+    }
+    good_marker(0x15);
+
+    return map;
+}
+
+static void unlock_vbios(vbios_map * map)
+{
+    assert(!map->unlocked);
+
+    map->unlocked = true;
+    
+    switch (map->chipset) {
+    case CT_UNKWN:
+    case CHIPSET_TYPES:		/* Shut up gcc */
+        break;
+    case CT_830:
+    case CT_855GM:
+        map->b1 = pci_readb(0x8000005a);
+        pci_writeb(0x33, 0x8000005a);
+        break;
+    case CT_845G:
+    case CT_865G:
+    case CT_915G:
+    case CT_915GM:
+    case CT_945G:
+    case CT_945GM:
+    case CT_945GME:
+    case CT_946GZ:
+    case CT_G965:
+    case CT_Q965:
+	map->b1 = pci_readb(0x80000091);
+	map->b2 = pci_readb(0x80000092);
+	pci_writeb(0x33, 0x80000091);
+	pci_writeb(0x33, 0x80000092);
+        break;
+    }
+
+#if DEBUG
+    {
+        unsigned int t = inl(0xcfc);
+        debug("unlock PAM: (0x%08x)\r\n", t);
+    }
+#endif
+}
+
+static void relock_vbios(vbios_map * map)
+{
+    assert(map->unlocked);
+    map->unlocked = false;
+    
+    switch (map->chipset) {
+    case CT_UNKWN:
+    case CHIPSET_TYPES:		/* Shut up gcc */
+        break;
+    case CT_830:
+    case CT_855GM:
+	pci_writeb(map->b1, 0x8000005a);
+        break;
+    case CT_845G:
+    case CT_865G:
+    case CT_915G:
+    case CT_915GM:
+    case CT_945G:
+    case CT_945GM:
+    case CT_945GME:
+    case CT_946GZ:
+    case CT_G965:
+    case CT_Q965:
+	pci_writeb(map->b1, 0x80000091);
+	pci_writeb(map->b2, 0x80000092);
+        break;
+    }
+
+#if DEBUG
+    {
+        unsigned int t = inl(0xcfc);
+        debug("relock PAM: (0x%08x)\r\n", t);
+    }
+#endif
+}
+
+#if 0
+static void list_modes(vbios_map *map, unsigned int raw)
+{
+    unsigned int i, x, y;
+
+    for (i=0; i < map->mode_table_size; i++) {
+        switch(map->bios) {
+        case BT_1:
+            {
+                vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+                
+                x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1;
+                y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1;
+                
+                if (x != 0 && y != 0) {
+                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+                }
+
+		if (raw)
+		{
+                    debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
+		}
+
+            }
+            break;
+        case BT_2:
+            {
+                vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+                
+                x = res->modelines[0].x1+1;
+                y = res->modelines[0].y1+1;
+
+                if (x != 0 && y != 0) {
+                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+                }
+            }
+            break;
+        case BT_3:
+            {
+                vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+                
+                x = res->modelines[0].x1+1;
+                y = res->modelines[0].y1+1;
+                
+                if (x != 0 && y != 0) {
+                    debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
+                }
+            }
+            break;
+        case BT_UNKWN:
+            break;
+        }
+    }
+}
+#endif
+
+static void gtf_timings(int x, int y, int freq,	uint32_t *clock,
+        uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank,
+        uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank)
+{
+    int hbl, vbl, vfreq;
+
+    vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
+    vfreq = vbl * freq;
+    hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+            (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
+
+    *vsyncstart = y;
+    *vsyncend = y + 3;
+    *vblank = vbl - 1;
+    *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
+    *hsyncend = x + hbl / 2 - 1;
+    *hblank = x + hbl - 1;
+    *clock = (x + hbl) * vfreq / 1000;
+}
+
+static int set_mode(vbios_map * map, unsigned int mode,
+		     unsigned int x, unsigned int y, unsigned int bp,
+		     unsigned int htotal, unsigned int vtotal)
+{
+    int xprev, yprev;
+    unsigned int i, j;
+    int rv = -1;
+
+    for (i=0; i < map->mode_table_size; i++) {
+        if (map->mode_table[i].mode == mode) {
+            switch(map->bios) {
+            case BT_1:
+                {
+                    vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
+		    uint32_t clock;
+		    uint16_t hsyncstart, hsyncend, hblank;
+		    uint16_t vsyncstart, vsyncend, vblank;
+                    
+                    if (bp) {
+                        map->mode_table[i].bits_per_pixel = bp;
+                    }
+
+		    gtf_timings(x, y, freqs[0], &clock,
+				&hsyncstart, &hsyncend, &hblank,
+				&vsyncstart, &vsyncend, &vblank);
+		    
+		    status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n",
+			  x, y, clock,
+			  hsyncstart, hsyncend, hblank,
+			  vsyncstart, vsyncend, vblank);
+
+		    htotal = htotal ? htotal : (unsigned int)hblank+1;
+		    vtotal = vtotal ? vtotal : (unsigned int)vblank+1;
+
+		    res->clock = clock/10; /* Units appear to be 10 kHz */
+                    res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0);
+                    res->x1 = (x & 0xff);
+                    
+                    res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0);
+                    res->y1 = (y & 0xff);
+		    if (htotal)
+			res->x_total = ((htotal-x) & 0xff);
+
+		    if (vtotal)
+			res->y_total = ((vtotal-y) & 0xff);
+
+		    rv = 0;
+                }
+                break;
+            case BT_2:
+                {
+                    vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
+
+                    res->xchars = x / 8;
+                    res->ychars = y / 16 - 1;
+                    xprev = res->modelines[0].x1;
+                    yprev = res->modelines[0].y1;
+
+                    for(j=0; j < 3; j++) {
+                        vbios_modeline_type2 * modeline = &res->modelines[j];
+                        
+                        if (modeline->x1 == xprev && modeline->y1 == yprev) {
+                            modeline->x1 = modeline->x2 = x-1;
+                            modeline->y1 = modeline->y2 = y-1;
+
+                            gtf_timings(x, y, freqs[j], &modeline->clock,
+                                    &modeline->hsyncstart, &modeline->hsyncend,
+                                    &modeline->hblank, &modeline->vsyncstart,
+                                    &modeline->vsyncend, &modeline->vblank);
+
+                            if (htotal)
+                                modeline->htotal = htotal;
+                            else
+                                modeline->htotal = modeline->hblank;
+
+                            if (vtotal)
+                                modeline->vtotal = vtotal;
+                            else
+                                modeline->vtotal = modeline->vblank;
+                        }
+                    }
+
+		    rv = 0;
+                }
+                break;
+            case BT_3:
+                {
+                    vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
+                    
+                    xprev = res->modelines[0].x1;
+                    yprev = res->modelines[0].y1;
+
+                    for (j=0; j < 3; j++) {
+                        vbios_modeline_type3 * modeline = &res->modelines[j];
+                        
+                        if (modeline->x1 == xprev && modeline->y1 == yprev) {
+                            modeline->x1 = modeline->x2 = x-1;
+                            modeline->y1 = modeline->y2 = y-1;
+                            
+                            gtf_timings(x, y, freqs[j], &modeline->clock,
+                                    &modeline->hsyncstart, &modeline->hsyncend,
+                                    &modeline->hblank, &modeline->vsyncstart,
+                                    &modeline->vsyncend, &modeline->vblank);
+                            if (htotal)
+                                modeline->htotal = htotal;
+                            else
+                                modeline->htotal = modeline->hblank;
+                            if (vtotal)
+                                modeline->vtotal = vtotal;
+                            else
+                                modeline->vtotal = modeline->vblank;
+
+                            modeline->timing_h   = y-1;
+                            modeline->timing_v   = x-1;
+                        }
+                    }
+
+		    rv = 0;
+                }
+                break;
+            case BT_UNKWN:
+                break;
+            }
+        }
+    }
+
+    return rv;
+}   
+
+static inline void display_map_info(vbios_map * map) {
+#ifdef DEBUG
+    static const char * bios_type_names[] =
+	{"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
+    static const char * chipset_type_names[] = {
+	"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G",
+	"945GM", "946GZ", "G965", "Q965", "945GME"
+    };
+
+    debug("Chipset: %s\r\n", chipset_type_names[map->chipset]);
+    debug("BIOS: %s\r\n", bios_type_names[map->bios]);
+
+    debug("Mode Table Offset: $C0000 + $%x\r\n",
+	  ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr));
+    debug("Mode Table Entries: %u\r\n", map->mode_table_size);
+#endif
+    (void)map;
+}
+
+int __vesacon_i915resolution(int x, int y)
+{
+    vbios_map * map;
+    unsigned int mode = 0x52;	/* 800x600x32 mode in known BIOSes */
+    unsigned int bp = 32;	/* 32 bits per pixel */
+    int rv = 0;
+
+    good_marker(0);
+
+    map = open_vbios();
+    if (!map)
+	return -1;
+
+    good_marker(1);
+
+    display_map_info(map);
+
+    debug("\r\n");
+
+    if (mode && x && y) {
+	good_marker(2);
+	cli();
+	good_marker(3);
+	unlock_vbios(map);
+	good_marker(4);
+        rv = set_mode(map, mode, x, y, bp, 0, 0);
+	if (rv)
+	    bad_marker(5);
+	else
+	    good_marker(5);
+	relock_vbios(map);
+	good_marker(6);
+	sti();
+        
+        debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y);
+    }
+    close_vbios(map);
+    
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/initvesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,191 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initvesa.c
+ *
+ * Query the VESA BIOS and select a 640x480x32 mode with local mapping
+ * support, if one exists.
+ */
+
+#include <inttypes.h>
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/fpu.h>
+#include <syslinux/video.h>
+#include "vesa.h"
+#include "video.h"
+#include "fill.h"
+#include "debug.h"
+
+struct vesa_info __vesa_info;
+
+struct vesa_char *__vesacon_text_display;
+
+int __vesacon_font_height;
+int __vesacon_text_rows;
+int __vesacon_text_cols;
+enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE;
+unsigned int __vesacon_bytes_per_pixel;
+uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
+
+uint32_t *__vesacon_background, *__vesacon_shadowfb;
+
+static void unpack_font(uint8_t * dst, uint8_t * src, int height)
+{
+    int i;
+
+    for (i = 0; i < FONT_MAX_CHARS; i++) {
+	memcpy(dst, src, height);
+	memset(dst + height, 0, FONT_MAX_HEIGHT - height);
+
+	dst += FONT_MAX_HEIGHT;
+	src += height;
+    }
+}
+
+static int vesacon_set_mode(int *x, int *y)
+{
+    uint8_t *rom_font;
+    struct vesa_mode_info *mi;
+    enum vesa_pixel_format bestpxf;
+    int rv;
+
+    debug("Hello, World!\r\n");
+
+    /* Free any existing data structures */
+    if (__vesacon_background) {
+	free(__vesacon_background);
+	__vesacon_background = NULL;
+    }
+    if (__vesacon_shadowfb) {
+	free(__vesacon_shadowfb);
+	__vesacon_shadowfb = NULL;
+    }
+
+    rv = firmware->vesa->set_mode(&__vesa_info, x, y, &bestpxf);
+    if (rv)
+	return rv;
+
+    mi = &__vesa_info.mi;
+    __vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3;
+    __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf];
+
+    /* Download the SYSLINUX- or firmware-provided font */
+    __vesacon_font_height = syslinux_font_query(&rom_font);
+    if (!__vesacon_font_height)
+	__vesacon_font_height = firmware->vesa->font_query(&rom_font);
+
+    unpack_font((uint8_t *) __vesacon_graphics_font, rom_font,
+		__vesacon_font_height);
+
+    __vesacon_background = calloc(mi->h_res*mi->v_res, 4);
+    __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4);
+
+    __vesacon_init_copy_to_screen();
+
+    /* Tell syslinux we changed video mode */
+    /* In theory this should be:
+
+       flags = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
+
+       However, that would assume all systems that claim to handle text
+       output in VESA modes actually do that... */
+    syslinux_report_video_mode(0x000f, mi->h_res, mi->v_res);
+
+    __vesacon_pixel_format = bestpxf;
+
+    return 0;
+}
+
+/* FIXME:
+ * Does init_text_display need an EFI counterpart?
+ * e.g. vesa_char may need to setup UNICODE char for EFI
+ * and the number of screen chars may need to be sized up
+ * accordingly. This may also require turning byte strings
+ * into unicode strings in the framebuffer
+ * Possibly, revisit vesacon_fill() for EFI.
+ */
+static int init_text_display(void)
+{
+    size_t nchars;
+    struct vesa_char *ptr;
+    struct vesa_char def_char = {
+	.ch = ' ',
+	.attr = 0,
+    };
+
+    if (__vesacon_text_display)
+	free(__vesacon_text_display);
+
+    __vesacon_text_cols = TEXT_PIXEL_COLS / FONT_WIDTH;
+    __vesacon_text_rows = TEXT_PIXEL_ROWS / __vesacon_font_height;
+    nchars = (__vesacon_text_cols+2) * (__vesacon_text_rows+2);
+
+    __vesacon_text_display = ptr = malloc(nchars * sizeof(struct vesa_char));
+
+    if (!ptr)
+	return -1;
+
+    vesacon_fill(ptr, def_char, nchars);
+    __vesacon_init_cursor(__vesacon_font_height);
+
+    return 0;
+}
+
+/*
+ * On input, VESA initialization is passed a desirable resolution. On
+ * return, either the requested resolution is set or the system
+ * supported default resolution is set and returned to the caller.
+ */
+int __vesacon_init(int *x, int *y)
+{
+    int rv;
+
+    /* We need the FPU for graphics, at least libpng et al will need it... */
+    if (x86_init_fpu())
+	return 10;
+
+    rv = vesacon_set_mode(x, y);
+    if (rv) {
+	/* Try to see if we can just patch the BIOS... */
+	if (__vesacon_i915resolution(*x, *y))
+	    return rv;
+	if (vesacon_set_mode(x, y))
+	    return rv;
+    }
+
+    init_text_display();
+
+    debug("Mode set, now drawing at %#p\r\n", __vesa_info.mi.lfb_ptr);
+
+    __vesacon_init_background();
+
+    debug("Ready!\r\n");
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/screencpy.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/screencpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/screencpy.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <inttypes.h>
+#include <minmax.h>
+#include <klibc/compiler.h>
+#include <string.h>
+#include <com32.h>
+#include <ilog2.h>
+#include "vesa.h"
+#include "video.h"
+
+
+static struct win_info wi;
+
+void __vesacon_init_copy_to_screen(void)
+{
+    struct vesa_mode_info *const mi = &__vesa_info.mi;
+    int winn;
+
+    if (mi->mode_attr & 0x0080) {
+	/* Linear frame buffer */
+
+	wi.win_base = (char *)mi->lfb_ptr;
+	wi.win_size = 1 << 31;	/* 2 GB, i.e. one huge window */
+	wi.win_pos = 0;		/* Already positioned (only one position...) */
+	wi.win_num = -1;	/* Not a window */
+    } else {
+	/* Paged frame buffer */
+
+	/* We have already tested that *one* of these is usable */
+	if ((mi->win_attr[0] & 0x05) == 0x05 && mi->win_seg[0])
+	    winn = 0;
+	else
+	    winn = 1;
+
+	wi.win_num = winn;
+	wi.win_base = (char *)(mi->win_seg[winn] << 4);
+	wi.win_size = mi->win_size << 10;
+	wi.win_gshift = ilog2(mi->win_grain) + 10;
+	wi.win_pos = -1;	/* Undefined position */
+    }
+}
+
+void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels)
+{
+    size_t bytes = npixels * __vesacon_bytes_per_pixel;
+    char rowbuf[bytes + 4] __aligned(4);
+    const uint32_t *s;
+
+    s = (const uint32_t *)__vesacon_format_pixels(rowbuf, src, npixels);
+    firmware->vesa->screencpy(dst, s, bytes, &wi);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/vesa.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,115 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_H
+#define LIB_SYS_VESA_H
+
+#include <syslinux/firmware.h>
+#include <inttypes.h>
+#include <com32.h>
+
+/* VESA General Information table */
+struct vesa_general_info {
+    uint32_t signature;		/* Magic number = "VESA" */
+    uint16_t version;
+    far_ptr_t vendor_string;
+    uint8_t capabilities[4];
+    far_ptr_t video_mode_ptr;
+    uint16_t total_memory;
+
+    uint16_t oem_software_rev;
+    far_ptr_t oem_vendor_name_ptr;
+    far_ptr_t oem_product_name_ptr;
+    far_ptr_t oem_product_rev_ptr;
+
+    uint8_t reserved[222];
+    uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+    uint16_t mode_attr;
+    uint8_t win_attr[2];
+    uint16_t win_grain;
+    uint16_t win_size;
+    uint16_t win_seg[2];
+    far_ptr_t win_scheme;
+    uint16_t logical_scan;
+
+    uint16_t h_res;
+    uint16_t v_res;
+    uint8_t char_width;
+    uint8_t char_height;
+    uint8_t memory_planes;
+    uint8_t bpp;
+    uint8_t banks;
+    uint8_t memory_layout;
+    uint8_t bank_size;
+    uint8_t image_pages;
+    uint8_t page_function;
+
+    uint8_t rmask;
+    uint8_t rpos;
+    uint8_t gmask;
+    uint8_t gpos;
+    uint8_t bmask;
+    uint8_t bpos;
+    uint8_t resv_mask;
+    uint8_t resv_pos;
+    uint8_t dcm_info;
+
+    uint8_t *lfb_ptr;		/* Linear frame buffer address */
+    uint8_t *offscreen_ptr;	/* Offscreen memory address */
+    uint16_t offscreen_size;
+
+    uint8_t reserved[206];
+} __attribute__ ((packed));
+
+struct vesa_info {
+    struct vesa_general_info gi;
+    struct vesa_mode_info mi;
+};
+
+extern struct vesa_info __vesa_info;
+
+#if 0
+static inline void vesa_debug(uint32_t color, int pos)
+{
+    uint32_t *stp = (uint32_t *) __vesa_info.mi.lfb_ptr;
+    stp[pos * 3] = color;
+}
+#else
+static inline void vesa_debug(uint32_t color, int pos)
+{
+    (void)color;
+    (void)pos;
+}
+#endif
+
+#endif /* LIB_SYS_VESA_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/video.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/video.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesa/video.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,105 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_VIDEO_H
+#define LIB_SYS_VESA_VIDEO_H
+
+#include <stdbool.h>
+#include <colortbl.h>
+#include "vesa.h"
+
+#define FONT_MAX_CHARS	256
+#define FONT_MAX_HEIGHT	 32
+#define FONT_WIDTH	  8
+
+#define DEFAULT_VESA_X_SIZE	640
+#define DEFAULT_VESA_Y_SIZE	480
+
+#define VIDEO_BORDER	8
+#define TEXT_PIXEL_ROWS (__vesa_info.mi.v_res - 2*VIDEO_BORDER)
+#define TEXT_PIXEL_COLS (__vesa_info.mi.h_res - 2*VIDEO_BORDER)
+
+typedef uint16_t attr_t;
+
+struct vesa_char {
+    uint8_t ch;			/* Character */
+    uint8_t _filler;		/* Currently unused */
+    attr_t attr;		/* Color table index */
+};
+
+struct win_info {
+    char *win_base;
+    size_t win_pos;
+    size_t win_size;
+    int win_gshift;
+    int win_num;
+};
+
+/* Pixel formats in order of decreasing preference; PXF_NONE should be last */
+/* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */
+enum vesa_pixel_format {
+    PXF_BGR24,			/* 24-bit BGR */
+    PXF_BGRA32,			/* 32-bit BGRA */
+    PXF_LE_RGB16_565,		/* 16-bit littleendian 5:6:5 RGB */
+    PXF_LE_RGB15_555,		/* 15-bit littleendian 5:5:5 RGB */
+    PXF_NONE
+};
+extern enum vesa_pixel_format __vesacon_pixel_format;
+extern unsigned int __vesacon_bytes_per_pixel;
+typedef const void *(*__vesacon_format_pixels_t)
+    (void *, const uint32_t *, size_t);
+extern __vesacon_format_pixels_t __vesacon_format_pixels;
+extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE];
+
+extern struct vesa_char *__vesacon_text_display;
+
+extern int __vesacon_font_height;
+extern int __vesacon_text_rows;
+extern int __vesacon_text_cols;
+extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
+extern uint32_t *__vesacon_background;
+extern uint32_t *__vesacon_shadowfb;
+
+extern const uint16_t __vesacon_srgb_to_linear[256];
+extern const uint8_t __vesacon_linear_to_srgb[4080];
+
+int __vesacon_init_background(void);
+int vesacon_load_background(const char *);
+int __vesacon_init(int *, int *);
+void __vesacon_init_cursor(int);
+void __vesacon_erase(int, int, int, int, attr_t);
+void __vesacon_scroll_up(int, attr_t);
+void __vesacon_write_char(int, int, uint8_t, attr_t);
+void __vesacon_redraw_text(void);
+void __vesacon_doit(void);
+void __vesacon_set_cursor(int, int, bool);
+void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t);
+void __vesacon_init_copy_to_screen(void);
+
+int __vesacon_i915resolution(int x, int y);
+
+#endif /* LIB_SYS_VESA_VIDEO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesacon_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesacon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesacon_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,195 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * vesacon_write.c
+ *
+ * Write to the screen using ANSI control codes (about as capable as
+ * DOS' ANSI.SYS.)
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <colortbl.h>
+#include <console.h>
+#include <klibc/compiler.h>
+#include <syslinux/config.h>
+#include "ansi.h"
+#include "file.h"
+#include "vesa/video.h"
+
+static void vesacon_erase(const struct term_state *, int, int, int, int);
+static void vesacon_write_char(int, int, uint8_t, const struct term_state *);
+static void vesacon_showcursor(const struct term_state *);
+static void vesacon_setcursor(int x, int y, bool visible);
+static void vesacon_scroll_up(const struct term_state *);
+
+static struct term_state ts;
+static struct ansi_ops op = {
+    .erase = vesacon_erase,
+    .write_char = vesacon_write_char,
+    .showcursor = vesacon_showcursor,
+    .set_cursor = vesacon_setcursor,
+    .scroll_up = vesacon_scroll_up,
+    .beep = __ansicon_beep,
+};
+
+static struct term_info ti = {
+    .disabled = 0,
+    .ts = &ts,
+    .op = &op
+};
+
+/* Reference counter to the screen, to keep track of if we need
+   reinitialization. */
+static int vesacon_counter = 0;
+
+static struct {
+    int x, y;
+} vesacon_resolution = {
+    .x = DEFAULT_VESA_X_SIZE,
+    .y = DEFAULT_VESA_Y_SIZE,
+};
+
+/* Set desired resolution - requires a full close/open cycle */
+void vesacon_set_resolution(int x, int y)
+{
+    vesacon_resolution.x = x;
+    vesacon_resolution.y = y;
+}
+
+/* Common setup */
+int __vesacon_open(struct file_info *fp)
+{
+    (void)fp;
+
+    if (!vesacon_counter) {
+	/* Are we disabled? */
+	if (syslinux_serial_console_info()->flowctl & 0x8000) {
+	    ti.disabled = 1;
+	    ti.rows = 25;
+	    ti.cols = 80;
+	} else {
+	    /* Switch mode */
+	    /* Deal with a resolution different from default build */
+	    if (__vesacon_init(&vesacon_resolution.x, &vesacon_resolution.y)) {
+		vesacon_counter = -1;
+		return EAGAIN;
+	    }
+
+	    /* Initial state */
+	    __ansi_init(&ti);
+	    ti.rows = __vesacon_text_rows;
+	    ti.cols = __vesacon_text_cols;
+	}
+    } else if (vesacon_counter == -1) {
+	return EAGAIN;
+    }
+
+    fp->o.rows = ti.rows;
+    fp->o.cols = ti.cols;
+
+    vesacon_counter++;
+    return 0;
+}
+
+int __vesacon_close(struct file_info *fp)
+{
+    (void)fp;
+
+    vesacon_counter--;
+    return 0;
+}
+
+/* Erase a region of the screen */
+static void vesacon_erase(const struct term_state *st,
+			  int x0, int y0, int x1, int y1)
+{
+    __vesacon_erase(x0, y0, x1, y1, st->cindex);
+}
+
+/* Draw text on the screen */
+static void vesacon_write_char(int x, int y, uint8_t ch,
+			       const struct term_state *st)
+{
+    __vesacon_write_char(x, y, ch, st->cindex);
+}
+
+/* Show or hide the cursor */
+static bool cursor_enabled = true;
+void vesacon_cursor_enable(bool enabled)
+{
+    cursor_enabled = enabled;
+}
+static void vesacon_showcursor(const struct term_state *st)
+{
+    vesacon_setcursor(st->xy.x, st->xy.y, st->cursor);
+}
+static void vesacon_setcursor(int x, int y, bool visible)
+{
+    __vesacon_set_cursor(x, y, visible && cursor_enabled);
+}
+
+static void vesacon_scroll_up(const struct term_state *st)
+{
+    __vesacon_scroll_up(1, st->cindex);
+}
+
+ssize_t __vesacon_write(struct file_info *fp, const void *buf, size_t count)
+{
+    const unsigned char *bufp = buf;
+    size_t n = 0;
+
+    (void)fp;
+
+    if (ti.disabled)
+	return count;		/* Nothing to do */
+
+    /* This only updates the shadow text buffer... */
+    while (count--) {
+	__ansi_putchar(&ti, *bufp++);
+	n++;
+    }
+
+    /* This actually draws it */
+    __vesacon_doit();
+
+    return n;
+}
+
+const struct output_dev dev_vesacon_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __vesacon_write,
+    .close = __vesacon_close,
+    .open = __vesacon_open,
+    .fallback = &dev_ansicon_w,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesaserial_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesaserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/vesaserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * vesaserial_write.c
+ *
+ * Write to both to the VESA console and the serial port
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <console.h>
+#include "file.h"
+
+extern int __vesacon_open(struct file_info *);
+extern int __vesacon_close(struct file_info *);
+extern ssize_t __vesacon_write(struct file_info *, const void *, size_t);
+extern ssize_t __xserial_write(struct file_info *, const void *, size_t);
+
+static ssize_t __vesaserial_write(struct file_info *fp, const void *buf,
+				  size_t count)
+{
+    __vesacon_write(fp, buf, count);
+    return __xserial_write(fp, buf, count);
+}
+
+const struct output_dev dev_vesaserial_w = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_TTY | __DEV_OUTPUT,
+    .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+    .write = __vesaserial_write,
+    .close = __vesacon_close,
+    .open = __vesacon_open,
+    .fallback = &dev_ansiserial_w,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * write.c
+ *
+ * Write to a file descriptor
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <klibc/compiler.h>
+#include "file.h"
+
+ssize_t write(int fd, void *buf, size_t count)
+{
+    struct file_info *fp = &__file_info[fd];
+
+    if (fd >= NFILES || !fp->oop) {
+	errno = EBADF;
+	return -1;
+    }
+
+    return fp->oop->write(fp, buf, count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_64/x86_init_fpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_64/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_64/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,58 @@
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+    uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+    return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+    asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+}
+
+#define CR0_PE	0x00000001
+#define CR0_MP  0x00000002
+#define CR0_EM  0x00000004
+#define CR0_TS  0x00000008
+#define CR0_ET  0x00000010
+#define CR0_NE  0x00000020
+#define CR0_WP  0x00010000
+#define CR0_AM  0x00040000
+#define CR0_NW  0x20000000
+#define CR0_CD  0x40000000
+#define CR0_PG  0x80000000
+
+int x86_init_fpu(void)
+{
+    uint32_t cr0;
+    uint16_t fsw = 0xffff;
+    uint16_t fcw = 0xffff;
+
+    cr0 = get_cr0();
+    cr0 &= ~(CR0_EM | CR0_TS);
+    cr0 |= CR0_MP;
+    set_cr0(cr0);
+
+    asm volatile ("fninit");
+    asm volatile ("fnstsw %0":"+m" (fsw));
+    if (fsw != 0)
+	return -1;
+
+    asm volatile ("fnstcw %0":"+m" (fcw));
+    if ((fcw & 0x103f) != 0x3f)
+	return -1;
+
+    /* Techically, this could be a 386 with a 287.  We could add a check
+       for that here... */
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_init_fpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/x86_init_fpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/*
+ * x86_has_fpu.c
+ *
+ * Test for an x86 FPU, and do any necessary setup.
+ */
+
+#if __SIZEOF_POINTER__ == 4
+#include <i386/x86_init_fpu.c>
+#elif __SIZEOF_POINTER__ == 8
+#include <x86_64/x86_init_fpu.c>
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+#if 0
+#include <inttypes.h>
+#include <sys/fpu.h>
+
+static inline uint64_t get_cr0(void)
+{
+#if __SIZEOF_POINTER__ == 4
+    uint32_t v;
+asm("movl %%cr0,%0":"=r"(v));
+#elif __SIZEOF_POINTER__ == 8
+    uint64_t v;
+asm("movq %%cr0,%0":"=r"(v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+    return v;
+}
+
+static inline void set_cr0(uint32_t v)
+{
+#if __SIZEOF_POINTER__ == 4
+    asm volatile ("movl %0,%%cr0"::"r" (v));
+#elif __SIZEOF_POINTER__ == 8
+    asm volatile ("movq %0,%%cr0"::"r" ((uint64_t)v));
+#else
+#error "Unable to build for to-be-defined architecture type"
+#endif
+}
+
+#define CR0_PE	0x00000001
+#define CR0_MP  0x00000002
+#define CR0_EM  0x00000004
+#define CR0_TS  0x00000008
+#define CR0_ET  0x00000010
+#define CR0_NE  0x00000020
+#define CR0_WP  0x00010000
+#define CR0_AM  0x00040000
+#define CR0_NW  0x20000000
+#define CR0_CD  0x40000000
+#define CR0_PG  0x80000000
+
+int x86_init_fpu(void)
+{
+    uint32_t cr0;
+    uint16_t fsw = 0xffff;
+    uint16_t fcw = 0xffff;
+
+    cr0 = get_cr0();
+    cr0 &= ~(CR0_EM | CR0_TS);
+    cr0 |= CR0_MP;
+    set_cr0(cr0);
+
+    asm volatile ("fninit");
+    asm volatile ("fnstsw %0":"+m" (fsw));
+    if (fsw != 0)
+	return -1;
+
+    asm volatile ("fnstcw %0":"+m" (fcw));
+    if ((fcw & 0x103f) != 0x3f)
+	return -1;
+
+    /* Techically, this could be a 386 with a 287.  We could add a check
+       for that here... */
+
+    return 0;
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/xserial_write.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/xserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/xserial_write.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * xserial_write.c
+ *
+ * Raw writing to the serial port; \n -> \r\n translation, and
+ * convert \1# sequences.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include <colortbl.h>
+#include <syslinux/config.h>
+#include "file.h"
+
+static void emit(char ch)
+{
+    write_serial(ch);
+}
+
+ssize_t __xserial_write(struct file_info *fp, const void *buf, size_t count)
+{
+    const char *bufp = buf;
+    size_t n = 0;
+    static enum { st_init, st_tbl, st_tblc } state = st_init;
+    static int ndigits;
+    static int ncolor = 0;
+    int num;
+    const char *p;
+
+    (void)fp;
+
+    if (!syslinux_serial_console_info()->iobase)
+	return count;		/* Nothing to do */
+
+    while (count--) {
+	unsigned char ch = *bufp++;
+
+	switch (state) {
+	case st_init:
+	    if (ch >= 1 && ch <= 5) {
+		state = st_tbl;
+		ndigits = ch;
+	    } else if (ch == '\n') {
+		emit('\r');
+		emit('\n');
+	    } else {
+		emit(ch);
+	    }
+	    break;
+
+	case st_tbl:
+	    if (ch == '#') {
+		state = st_tblc;
+		ncolor = 0;
+	    } else {
+		state = st_init;
+	    }
+	    break;
+
+	case st_tblc:
+	    num = ch - '0';
+	    if (num < 10) {
+		ncolor = (ncolor * 10) + num;
+		if (--ndigits == 0) {
+		    if (ncolor < console_color_table_size) {
+			emit('\033');
+			emit('[');
+			emit('0');
+			emit(';');
+			for (p = console_color_table[ncolor].ansi; *p; p++)
+			    emit(*p);
+			emit('m');
+		    }
+		    state = st_init;
+		}
+	    } else {
+		state = st_init;
+	    }
+	    break;
+	}
+	n++;
+    }
+
+    return n;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/zeroregs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/zeroregs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/zeroregs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,5 @@
+#include <com32.h>
+
+/* When we don't need to pass any registers, it's convenient to just
+   be able to pass a prepared all-zero structure. */
+const com32sys_t __com32_zero_regs;
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfile.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,171 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <syslinux/zio.h>
+
+#include "file.h"
+#include "zlib.h"
+
+/*
+ * zopen.c
+ *
+ * Open an ordinary file, possibly compressed; if so, insert
+ * an appropriate decompressor.
+ */
+
+int __file_get_block(struct file_info *fp);
+int __file_close(struct file_info *fp);
+
+static ssize_t gzip_file_read(struct file_info *, void *, size_t);
+static int gzip_file_close(struct file_info *);
+
+static const struct input_dev gzip_file_dev = {
+    .dev_magic = __DEV_MAGIC,
+    .flags = __DEV_FILE | __DEV_INPUT,
+    .fileflags = O_RDONLY,
+    .read = gzip_file_read,
+    .close = gzip_file_close,
+    .open = NULL,
+};
+
+static int gzip_file_init(struct file_info *fp)
+{
+    z_streamp zs = calloc(1, sizeof(z_stream));
+
+    if (!zs)
+	return -1;
+
+    fp->i.pvt = zs;
+
+    zs->next_in = (void *)fp->i.datap;
+    zs->avail_in = fp->i.nbytes;
+
+    if (inflateInit2(zs, 15 + 32) != Z_OK) {
+	errno = EIO;
+	return -1;
+    }
+
+    fp->iop = &gzip_file_dev;
+    fp->i.fd.size = -1;		/* Unknown */
+
+    return 0;
+}
+
+static ssize_t gzip_file_read(struct file_info *fp, void *ptr, size_t n)
+{
+    z_streamp zs = fp->i.pvt;
+    int rv;
+    ssize_t bytes;
+    ssize_t nout = 0;
+    unsigned char *p = ptr;
+
+    while (n) {
+	zs->next_out = p;
+	zs->avail_out = n;
+
+	if (!zs->avail_in && fp->i.fd.handle) {
+	    if (__file_get_block(fp))
+		return nout ? nout : -1;
+
+	    zs->next_in = (void *)fp->i.datap;
+	    zs->avail_in = fp->i.nbytes;
+	}
+
+	rv = inflate(zs, Z_SYNC_FLUSH);
+
+	bytes = n - zs->avail_out;
+	nout += bytes;
+	p += bytes;
+	n -= bytes;
+
+	switch (rv) {
+	case Z_DATA_ERROR:
+	case Z_NEED_DICT:
+	case Z_BUF_ERROR:
+	case Z_STREAM_ERROR:
+	default:
+	    errno = EIO;
+	    return nout ? nout : -1;
+	case Z_MEM_ERROR:
+	    errno = ENOMEM;
+	    return nout ? nout : -1;
+	case Z_STREAM_END:
+	    return nout;
+	case Z_OK:
+	    break;
+	}
+    }
+
+    return nout;
+}
+
+static int gzip_file_close(struct file_info *fp)
+{
+    z_streamp zs = fp->i.pvt;
+
+    inflateEnd(zs);
+    free(zs);
+    return __file_close(fp);
+}
+
+int zopen(const char *pathname, int flags, ...)
+{
+    int fd, rv;
+    struct file_info *fp;
+
+    /* We don't actually give a hoot about the creation bits... */
+    fd = open(pathname, flags, 0);
+
+    if (fd < 0)
+	return -1;
+
+    fp = &__file_info[fd];
+
+    /* Need to get the first block into the buffer, but not consumed */
+    if (__file_get_block(fp))
+	goto err;
+
+    if (fp->i.nbytes >= 14 &&
+	(uint8_t) fp->i.buf[0] == 037 &&
+	(uint8_t) fp->i.buf[1] == 0213 &&	/* gzip */
+	fp->i.buf[2] == 8)	/* deflate */
+	rv = gzip_file_init(fp);
+    else
+	rv = 0;			/* Plain file */
+
+    if (!rv)
+	return fd;
+
+err:
+    close(fd);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfopen.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfopen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/sys/zfopen.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,44 @@
+/*
+ * zfopen.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <syslinux/zio.h>
+
+FILE *zfopen(const char *file, const char *mode)
+{
+    int flags = O_RDONLY;
+    int plus = 0;
+    int fd;
+
+    while (*mode) {
+	switch (*mode) {
+	case 'r':
+	    flags = O_RDONLY;
+	    break;
+	case 'w':
+	    flags = O_WRONLY | O_CREAT | O_TRUNC;
+	    break;
+	case 'a':
+	    flags = O_WRONLY | O_CREAT | O_APPEND;
+	    break;
+	case '+':
+	    plus = 1;
+	    break;
+	}
+	mode++;
+    }
+
+    if (plus) {
+	flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+    }
+
+    fd = zopen(file, flags, 0666);
+
+    if (fd < 0)
+	return NULL;
+    else
+	return fdopen(fd, mode);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/addlist.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/addlist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/addlist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <syslinux/movebits.h>
+
+int syslinux_add_movelist(struct syslinux_movelist **list,
+			  addr_t dst, addr_t src, addr_t len)
+{
+    struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist));
+    if (!ml)
+	return -1;
+
+    ml->dst = dst;
+    ml->src = src;
+    ml->len = len;
+    ml->next = *list;
+
+    *list = ml;
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/biosboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/biosboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/biosboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2014 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <syslinux/movebits.h>
+
+#ifdef __FIRMWARE_BIOS__
+
+void bios_do_shuffle_and_boot(uint16_t bootflags, uint32_t descaddr,
+			      const void *descbuf, uint32_t dsize)
+{
+    extern void do_raw_shuffle_and_boot(addr_t, const void *, addr_t);
+
+    syslinux_final_cleanup(bootflags);
+    do_raw_shuffle_and_boot(descaddr, descbuf, dsize);
+    /* Should not return */
+}
+
+#endif /* __FIRMWARE_BIOS__ */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/cleanup.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/cleanup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/cleanup.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <syslinux/config.h>
+#include <syslinux/pxe_api.h>
+#include <stddef.h>
+#include <core.h>
+
+void syslinux_final_cleanup(uint16_t flags)
+{
+    if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX)
+	unload_pxe(flags);
+
+    cleanup_hardware();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/debug.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,95 @@
+#include <linux/list.h>
+#include <string.h>
+#include <stdbool.h>
+
+#ifdef DYNAMIC_DEBUG
+
+static LIST_HEAD(debug_funcs);
+
+struct debug_func_entry {
+    const char *name;
+    struct list_head list;
+};
+
+static struct debug_func_entry *lookup_entry(const char *func)
+{
+    struct debug_func_entry *e, *entry = NULL;
+
+    list_for_each_entry(e, &debug_funcs, list) {
+	if (!strcmp(e->name, func)) {
+	    entry = e;
+	    break;
+	}
+    }
+
+    return entry;
+}
+
+bool __syslinux_debug_enabled(const char *func)
+{
+    struct debug_func_entry *entry;
+
+    entry = lookup_entry(func);
+    if (entry)
+	return true;
+
+    return false;
+}
+
+static int __enable(const char *func)
+{
+    struct debug_func_entry *entry;
+
+    entry = lookup_entry(func);
+    if (entry)
+	return 0;	/* already enabled */
+
+    entry = malloc(sizeof(*entry));
+    if (!entry)
+	return -1;
+
+    entry->name = func;
+    list_add(&entry->list, &debug_funcs);
+    return 0;
+}
+
+static int __disable(const char *func)
+{
+    struct debug_func_entry *entry;
+
+    entry = lookup_entry(func);
+    if (!entry)
+	return 0;	/* already disabled */
+
+    list_del(&entry->list);
+    free(entry);
+    return 0;
+}
+
+/*
+ * Enable or disable debug code for function 'func'.
+ */
+int syslinux_debug(const char *func, bool enable)
+{
+    int rv;
+
+    if (enable)
+	rv = __enable(func);
+    else
+	rv = __disable(func);
+
+    return rv;
+}
+
+#else
+
+int syslinux_debug(const char *func, bool enable)
+{
+    (void)func;
+    (void)enable;
+
+    printf("Dynamic debug unavailable\n");
+    return -1;
+}
+
+#endif /* DYNAMIC_DEBUG */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,583 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Copyright (C) 2010 Shao Miller
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/**
+ * @file disk.c
+ *
+ * Deal with disks and partitions
+ */
+
+#include <core.h>
+#include <dprintf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/disk.h>
+
+/**
+ * Call int 13h, but with retry on failure.  Especially floppies need this.
+ *
+ * @v inreg			CPU register settings upon INT call
+ * @v outreg			CPU register settings returned by INT call
+ * @ret (int)			0 upon success, -1 upon failure
+ */
+int disk_int13_retry(const com32sys_t * inreg, com32sys_t * outreg)
+{
+    int retry = 6;		/* Number of retries */
+    com32sys_t tmpregs;
+
+    if (!outreg)
+	outreg = &tmpregs;
+
+    while (retry--) {
+	__intcall(0x13, inreg, outreg);
+	if (!(outreg->eflags.l & EFLAGS_CF))
+	    return 0;		/* CF=0, OK */
+    }
+
+    return -1;			/* Error */
+}
+
+/**
+ * Query disk parameters and EBIOS availability for a particular disk.
+ *
+ * @v disk			The INT 0x13 disk drive number to process
+ * @v diskinfo			The structure to save the queried params to
+ * @ret (int)			0 upon success, -1 upon failure
+ */
+int disk_get_params(int disk, struct disk_info *const diskinfo)
+{
+    static com32sys_t inreg, outreg;
+    struct disk_ebios_eparam *eparam;
+    int rv = 0;
+
+    memset(diskinfo, 0, sizeof *diskinfo);
+    diskinfo->disk = disk;
+    diskinfo->bps = SECTOR;
+
+    /* Get EBIOS support */
+    memset(&inreg, 0, sizeof inreg);
+    inreg.eax.b[1] = 0x41;
+    inreg.ebx.w[0] = 0x55aa;
+    inreg.edx.b[0] = disk;
+    inreg.eflags.b[0] = 0x3;	/* CF set */
+
+    __intcall(0x13, &inreg, &outreg);
+
+    if (!(outreg.eflags.l & EFLAGS_CF) &&
+	outreg.ebx.w[0] == 0xaa55 && (outreg.ecx.b[0] & 1)) {
+	diskinfo->ebios = 1;
+    }
+
+    eparam = lmalloc(sizeof *eparam);
+    if (!eparam)
+	return -1;
+
+    /* Get extended disk parameters if ebios == 1 */
+    if (diskinfo->ebios) {
+	memset(&inreg, 0, sizeof inreg);
+	inreg.eax.b[1] = 0x48;
+	inreg.edx.b[0] = disk;
+	inreg.esi.w[0] = OFFS(eparam);
+	inreg.ds = SEG(eparam);
+
+	memset(eparam, 0, sizeof *eparam);
+	eparam->len = sizeof *eparam;
+
+	__intcall(0x13, &inreg, &outreg);
+
+	if (!(outreg.eflags.l & EFLAGS_CF)) {
+	    diskinfo->lbacnt = eparam->lbacnt;
+	    if (eparam->bps)
+		diskinfo->bps = eparam->bps;
+	    /*
+	     * don't think about using geometry data returned by
+	     * 48h, as it can differ from 08h a lot ...
+	     */
+	}
+    }
+    /*
+     * Get disk parameters the old way - really only useful for hard
+     * disks, but if we have a partitioned floppy it's actually our best
+     * chance...
+     */
+    memset(&inreg, 0, sizeof inreg);
+    inreg.eax.b[1] = 0x08;
+    inreg.edx.b[0] = disk;
+
+    __intcall(0x13, &inreg, &outreg);
+
+    if (outreg.eflags.l & EFLAGS_CF) {
+	rv = diskinfo->ebios ? 0 : -1;
+	goto out;
+    }
+
+    diskinfo->spt = 0x3f & outreg.ecx.b[0];
+    diskinfo->head = 1 + outreg.edx.b[1];
+    diskinfo->cyl = 1 + (outreg.ecx.b[1] | ((outreg.ecx.b[0] & 0xc0u) << 2));
+
+    if (diskinfo->spt)
+	diskinfo->cbios = 1;	/* Valid geometry */
+    else {
+	diskinfo->head = 1;
+	diskinfo->spt = 1;
+	diskinfo->cyl = 1;
+    }
+
+    if (!diskinfo->lbacnt)
+	diskinfo->lbacnt = diskinfo->cyl * diskinfo->head * diskinfo->spt;
+
+out:
+    lfree(eparam);
+    return rv;
+}
+
+/**
+ * Fill inreg based on EBIOS addressing properties.
+ *
+ * @v diskinfo			The disk drive to read from
+ * @v inreg			Register data structure to be filled.
+ * @v lba			The logical block address to begin reading at
+ * @v count			The number of sectors to read
+ * @v op_code			Code to write/read operation
+ * @ret 			lmalloc'd buf upon success, NULL upon failure
+ */
+static void *ebios_setup(const struct disk_info *const diskinfo, com32sys_t *inreg,
+			 uint64_t lba, uint8_t count, uint8_t op_code)
+{
+    static struct disk_ebios_dapa *dapa = NULL;
+    void *buf;
+
+    if (!dapa) {
+	dapa = lmalloc(sizeof *dapa);
+	if (!dapa)
+	    return NULL;
+    }
+
+    buf = lmalloc(count * diskinfo->bps);
+    if (!buf)
+	return NULL;
+
+    dapa->len = sizeof(*dapa);
+    dapa->count = count;
+    dapa->off = OFFS(buf);
+    dapa->seg = SEG(buf);
+    dapa->lba = lba;
+
+    inreg->eax.b[1] = op_code;
+    inreg->esi.w[0] = OFFS(dapa);
+    inreg->ds = SEG(dapa);
+    inreg->edx.b[0] = diskinfo->disk;
+
+    return buf;
+}
+
+/**
+ * Fill inreg based on CHS addressing properties.
+ *
+ * @v diskinfo			The disk drive to read from
+ * @v inreg			Register data structure to be filled.
+ * @v lba			The logical block address to begin reading at
+ * @v count			The number of sectors to read
+ * @v op_code			Code to write/read operation
+ * @ret 			lmalloc'd buf upon success, NULL upon failure
+ */
+static void *chs_setup(const struct disk_info *const diskinfo, com32sys_t *inreg,
+		       uint64_t lba, uint8_t count, uint8_t op_code)
+{
+    unsigned int c, h, s, t;
+    void *buf;
+
+    buf = lmalloc(count * diskinfo->bps);
+    if (!buf)
+	return NULL;
+
+    /*
+     * if we passed lba + count check and we get here, that means that
+     * lbacnt was calculated from chs geometry (or faked from 1/1/1), thus
+     * 32bits are perfectly enough and lbacnt corresponds to cylinder
+     * boundary
+     */
+    s = lba % diskinfo->spt;
+    t = lba / diskinfo->spt;
+    h = t % diskinfo->head;
+    c = t / diskinfo->head;
+
+    memset(inreg, 0, sizeof *inreg);
+    inreg->eax.b[0] = count;
+    inreg->eax.b[1] = op_code;
+    inreg->ecx.b[1] = c;
+    inreg->ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
+    inreg->edx.b[1] = h;
+    inreg->edx.b[0] = diskinfo->disk;
+    inreg->ebx.w[0] = OFFS(buf);
+    inreg->es = SEG(buf);
+
+    return buf;
+}
+
+/**
+ * Get disk block(s) and return a malloc'd buffer.
+ *
+ * @v diskinfo			The disk drive to read from
+ * @v lba			The logical block address to begin reading at
+ * @v count			The number of sectors to read
+ * @ret data			An allocated buffer with the read data
+ *
+ * Uses the disk number and information from diskinfo.  Read count sectors
+ * from drive, starting at lba.  Return a new buffer, or NULL upon failure.
+ */
+void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba,
+			uint8_t count)
+{
+    com32sys_t inreg;
+    void *buf;
+    void *data = NULL;
+    uint32_t maxcnt;
+    uint32_t size = 65536;
+
+    maxcnt = (size - diskinfo->bps) / diskinfo->bps;
+    if (!count || count > maxcnt || lba + count > diskinfo->lbacnt)
+	return NULL;
+
+    memset(&inreg, 0, sizeof inreg);
+
+    if (diskinfo->ebios)
+	buf = ebios_setup(diskinfo, &inreg, lba, count, EBIOS_READ_CODE);
+    else
+	buf = chs_setup(diskinfo, &inreg, lba, count, CHS_READ_CODE);
+
+    if (!buf)
+	return NULL;
+
+    if (disk_int13_retry(&inreg, NULL))
+	goto out;
+
+    data = malloc(count * diskinfo->bps);
+    if (data)
+	memcpy(data, buf, count * diskinfo->bps);
+out:
+    lfree(buf);
+    return data;
+}
+
+/**
+ * Write disk block(s).
+ *
+ * @v diskinfo			The disk drive to write to
+ * @v lba			The logical block address to begin writing at
+ * @v data			The data to write
+ * @v count			The number of sectors to write
+ * @ret (int)			0 upon success, -1 upon failure
+ *
+ * Uses the disk number and information from diskinfo.
+ * Write sector(s) to a disk drive, starting at lba.
+ */
+int disk_write_sectors(const struct disk_info *const diskinfo, uint64_t lba,
+		       const void *data, uint8_t count)
+{
+    com32sys_t inreg;
+    void *buf;
+    uint32_t maxcnt;
+    uint32_t size = 65536;
+    int rv = -1;
+
+    maxcnt = (size - diskinfo->bps) / diskinfo->bps;
+    if (!count || count > maxcnt || lba + count > diskinfo->lbacnt)
+	return -1;
+
+    memset(&inreg, 0, sizeof inreg);
+
+    if (diskinfo->ebios)
+	buf = ebios_setup(diskinfo, &inreg, lba, count, EBIOS_WRITE_CODE);
+    else
+	buf = chs_setup(diskinfo, &inreg, lba, count, CHS_WRITE_CODE);
+
+    if (!buf)
+	return -1;
+
+    memcpy(buf, data, count * diskinfo->bps);
+
+    if (disk_int13_retry(&inreg, NULL))
+	goto out;
+
+    rv = 0;			/* ok */
+out:
+    lfree(buf);
+    return rv;
+}
+
+/**
+ * Write disk blocks and verify they were written.
+ *
+ * @v diskinfo			The disk drive to write to
+ * @v lba			The logical block address to begin writing at
+ * @v buf			The data to write
+ * @v count			The number of sectors to write
+ * @ret rv			0 upon success, -1 upon failure
+ *
+ * Uses the disk number and information from diskinfo.
+ * Writes sectors to a disk drive starting at lba, then reads them back
+ * to verify they were written correctly.
+ */
+int disk_write_verify_sectors(const struct disk_info *const diskinfo,
+			      uint64_t lba, const void *buf, uint8_t count)
+{
+    char *rb;
+    int rv;
+
+    rv = disk_write_sectors(diskinfo, lba, buf, count);
+    if (rv)
+	return rv;		/* Write failure */
+    rb = disk_read_sectors(diskinfo, lba, count);
+    if (!rb)
+	return -1;		/* Readback failure */
+    rv = memcmp(buf, rb, count * diskinfo->bps);
+    free(rb);
+    return rv ? -1 : 0;
+}
+
+/**
+ * Dump info about a DOS partition entry
+ *
+ * @v part			The 16-byte partition entry to examine
+ */
+void disk_dos_part_dump(const struct disk_dos_part_entry *const part)
+{
+    (void)part;
+    dprintf("Partition status _____ : 0x%.2x\n"
+	    "Partition CHS start\n"
+	    "  Cylinder ___________ : 0x%.4x (%u)\n"
+	    "  Head _______________ : 0x%.2x (%u)\n"
+	    "  Sector _____________ : 0x%.2x (%u)\n"
+	    "Partition type _______ : 0x%.2x\n"
+	    "Partition CHS end\n"
+	    "  Cylinder ___________ : 0x%.4x (%u)\n"
+	    "  Head _______________ : 0x%.2x (%u)\n"
+	    "  Sector _____________ : 0x%.2x (%u)\n"
+	    "Partition LBA start __ : 0x%.8x (%u)\n"
+	    "Partition LBA count __ : 0x%.8x (%u)\n"
+	    "-------------------------------\n",
+	    part->active_flag,
+	    chs_cylinder(part->start),
+	    chs_cylinder(part->start),
+	    chs_head(part->start),
+	    chs_head(part->start),
+	    chs_sector(part->start),
+	    chs_sector(part->start),
+	    part->ostype,
+	    chs_cylinder(part->end),
+	    chs_cylinder(part->end),
+	    chs_head(part->end),
+	    chs_head(part->end),
+	    chs_sector(part->end),
+	    chs_sector(part->end),
+	    part->start_lba, part->start_lba, part->length, part->length);
+}
+
+/* Trivial error message output */
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+/**
+ * This walk-map effectively reverses the little-endian
+ * portions of a GPT disk/partition GUID for a string representation.
+ * There might be a better header for this...
+ */
+static const char guid_le_walk_map[] = {
+    3, -1, -1, -1, 0,
+    5, -1, 0,
+    3, -1, 0,
+    2, 1, 0,
+    1, 1, 1, 1, 1, 1
+};
+
+/**
+ * Fill a buffer with a textual GUID representation.
+ *
+ * @v buf			Points to a minimum array of 37 chars
+ * @v id			The GUID to represent as text
+ *
+ * The buffer must be >= char[37] and will be populated
+ * with an ASCII NUL C string terminator.
+ * Example: 11111111-2222-3333-4444-444444444444
+ * Endian:  LLLLLLLL-LLLL-LLLL-BBBB-BBBBBBBBBBBB
+ */
+void guid_to_str(char *buf, const struct guid *const id)
+{
+    unsigned int i = 0;
+    const char *walker = (const char *)id;
+
+    while (i < sizeof(guid_le_walk_map)) {
+	walker += guid_le_walk_map[i];
+	if (!guid_le_walk_map[i])
+	    *buf = '-';
+	else {
+	    *buf = ((*walker & 0xF0) >> 4) + '0';
+	    if (*buf > '9')
+		*buf += 'A' - '9' - 1;
+	    buf++;
+	    *buf = (*walker & 0x0F) + '0';
+	    if (*buf > '9')
+		*buf += 'A' - '9' - 1;
+	}
+	buf++;
+	i++;
+    }
+    *buf = 0;
+}
+
+/**
+ * Create a GUID structure from a textual GUID representation.
+ *
+ * @v buf			Points to a GUID string to parse
+ * @v id			Points to a GUID to be populated
+ * @ret (int)			Returns 0 upon success, -1 upon failure
+ *
+ * The input buffer must be >= 32 hexadecimal chars and be
+ * terminated with an ASCII NUL.  Returns non-zero on failure.
+ * Example: 11111111-2222-3333-4444-444444444444
+ * Endian:  LLLLLLLL-LLLL-LLLL-BBBB-BBBBBBBBBBBB
+ */
+int str_to_guid(const char *buf, struct guid *const id)
+{
+    char guid_seq[sizeof(struct guid) * 2];
+    unsigned int i = 0;
+    char *walker = (char *)id;
+
+    while (*buf && i < sizeof(guid_seq)) {
+	switch (*buf) {
+	    /* Skip these three characters */
+	case '{':
+	case '}':
+	case '-':
+	    break;
+	default:
+	    /* Copy something useful to the temp. sequence */
+	    if ((*buf >= '0') && (*buf <= '9'))
+		guid_seq[i] = *buf - '0';
+	    else if ((*buf >= 'A') && (*buf <= 'F'))
+		guid_seq[i] = *buf - 'A' + 10;
+	    else if ((*buf >= 'a') && (*buf <= 'f'))
+		guid_seq[i] = *buf - 'a' + 10;
+	    else {
+		/* Or not */
+		error("Illegal character in GUID!\n");
+		return -1;
+	    }
+	    i++;
+	}
+	buf++;
+    }
+    /* Check for insufficient valid characters */
+    if (i < sizeof(guid_seq)) {
+	error("Too few GUID characters!\n");
+	return -1;
+    }
+    buf = guid_seq;
+    i = 0;
+    while (i < sizeof(guid_le_walk_map)) {
+	if (!guid_le_walk_map[i])
+	    i++;
+	walker += guid_le_walk_map[i];
+	*walker = *buf << 4;
+	buf++;
+	*walker |= *buf;
+	buf++;
+	i++;
+    }
+    return 0;
+}
+
+/**
+ * Display GPT partition details.
+ *
+ * @v gpt_part			The GPT partition entry to display
+ */
+void disk_gpt_part_dump(const struct disk_gpt_part_entry *const gpt_part)
+{
+    unsigned int i;
+    char guid_text[37];
+
+    dprintf("----------------------------------\n"
+	    "GPT part. LBA first __ : 0x%.16llx\n"
+	    "GPT part. LBA last ___ : 0x%.16llx\n"
+	    "GPT part. attribs ____ : 0x%.16llx\n"
+	    "GPT part. name _______ : '",
+	    gpt_part->lba_first, gpt_part->lba_last, gpt_part->attribs);
+    for (i = 0; i < sizeof(gpt_part->name); i++) {
+	if (gpt_part->name[i])
+	    dprintf("%c", gpt_part->name[i]);
+    }
+    dprintf("'");
+    guid_to_str(guid_text, &gpt_part->type);
+    dprintf("GPT part. type GUID __ : {%s}\n", guid_text);
+    guid_to_str(guid_text, &gpt_part->uid);
+    dprintf("GPT part. unique ID __ : {%s}\n", guid_text);
+}
+
+/**
+ * Display GPT header details.
+ *
+ * @v gpt			The GPT header to display
+ */
+void disk_gpt_header_dump(const struct disk_gpt_header *const gpt)
+{
+    char guid_text[37];
+
+    printf("GPT sig ______________ : '%8.8s'\n"
+	   "GPT major revision ___ : 0x%.4x\n"
+	   "GPT minor revision ___ : 0x%.4x\n"
+	   "GPT header size ______ : 0x%.8x\n"
+	   "GPT header checksum __ : 0x%.8x\n"
+	   "GPT reserved _________ : '%4.4s'\n"
+	   "GPT LBA current ______ : 0x%.16llx\n"
+	   "GPT LBA alternative __ : 0x%.16llx\n"
+	   "GPT LBA first usable _ : 0x%.16llx\n"
+	   "GPT LBA last usable __ : 0x%.16llx\n"
+	   "GPT LBA part. table __ : 0x%.16llx\n"
+	   "GPT partition count __ : 0x%.8x\n"
+	   "GPT partition size ___ : 0x%.8x\n"
+	   "GPT part. table chksum : 0x%.8x\n",
+	   gpt->sig,
+	   gpt->rev.fields.major,
+	   gpt->rev.fields.minor,
+	   gpt->hdr_size,
+	   gpt->chksum,
+	   gpt->reserved1,
+	   gpt->lba_cur,
+	   gpt->lba_alt,
+	   gpt->lba_first_usable,
+	   gpt->lba_last_usable,
+	   gpt->lba_table, gpt->part_count, gpt->part_size, gpt->table_chksum);
+    guid_to_str(guid_text, &gpt->disk_guid);
+    printf("GPT disk GUID ________ : {%s}\n", guid_text);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dsinfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dsinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dsinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <com32.h>
+
+union syslinux_derivative_info __syslinux_derivative_info;
+
+void __constructor __syslinux_get_derivative_info(void)
+{
+    get_derivative_info(&__syslinux_derivative_info);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_mmap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_mmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_mmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dump_mmap.c
+ *
+ * Writes a syslinux_memmap out to a dprintf.
+ */
+
+#include <stdio.h>
+#include <dprintf.h>
+#include <syslinux/movebits.h>
+
+#ifdef DEBUG
+void syslinux_dump_memmap(struct syslinux_memmap *memmap)
+{
+    dprintf("%10s %10s %10s\n"
+	    "--------------------------------\n", "Start", "Length", "Type");
+    while (memmap->next) {
+	dprintf("0x%08x 0x%08x %10d\n", memmap->start,
+		memmap->next->start - memmap->start, memmap->type);
+	memmap = memmap->next;
+    }
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_movelist.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_movelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/dump_movelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dump_movelist.c
+ *
+ * Writes a syslinux_movelist out to a specified file.  This is
+ * intended for debugging.
+ */
+
+#include <stdio.h>
+#include <dprintf.h>
+#include <syslinux/movebits.h>
+
+#ifdef DEBUG
+void syslinux_dump_movelist(struct syslinux_movelist *ml)
+{
+    dprintf("%10s %10s %10s\n"
+	    "--------------------------------\n", "Dest", "Src", "Length");
+    while (ml) {
+	dprintf("0x%08x 0x%08x 0x%08x\n", ml->dst, ml->src, ml->len);
+	ml = ml->next;
+    }
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/floadfile.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/floadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/floadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,108 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * floadfile.c
+ *
+ * Read the contents of a data file into a malloc'd buffer
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int floadfile(FILE * f, void **ptr, size_t * len, const void *prefix,
+	      size_t prefix_len)
+{
+    struct stat st;
+    void *data, *dp;
+    size_t alen, clen, rlen, xlen;
+
+    clen = alen = 0;
+    data = NULL;
+
+    if (fstat(fileno(f), &st))
+	goto err;
+
+    if (!S_ISREG(st.st_mode)) {
+	/* Not a regular file, we can't assume we know the file size */
+	if (prefix_len) {
+	    clen = alen = prefix_len;
+	    data = malloc(prefix_len);
+	    if (!data)
+		goto err;
+
+	    memcpy(data, prefix, prefix_len);
+	}
+
+	do {
+	    alen += INCREMENTAL_CHUNK;
+	    dp = realloc(data, alen);
+	    if (!dp)
+		goto err;
+	    data = dp;
+
+	    rlen = fread((char *)data + clen, 1, alen - clen, f);
+	    clen += rlen;
+	} while (clen == alen);
+
+	*len = clen;
+	xlen = (clen + LOADFILE_ZERO_PAD - 1) & ~(LOADFILE_ZERO_PAD - 1);
+	dp = realloc(data, xlen);
+	if (dp)
+	    data = dp;
+	*ptr = data;
+    } else {
+	*len = clen = st.st_size + prefix_len - ftell(f);
+	xlen = (clen + LOADFILE_ZERO_PAD - 1) & ~(LOADFILE_ZERO_PAD - 1);
+
+	*ptr = data = malloc(xlen);
+	if (!data)
+	    return -1;
+
+	memcpy(data, prefix, prefix_len);
+
+	if ((off_t) fread((char *)data + prefix_len, 1, clen - prefix_len, f)
+	    != clen - prefix_len)
+	    goto err;
+    }
+
+    memset((char *)data + clen, 0, xlen - clen);
+    return 0;
+
+err:
+    if (data)
+	free(data);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/freelist.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/freelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/freelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * freelist.c
+ *
+ * Frees a syslinux_movelist
+ */
+
+#include <stdlib.h>
+#include <syslinux/movebits.h>
+
+void syslinux_free_movelist(struct syslinux_movelist *list)
+{
+    struct syslinux_movelist *m;
+
+    while (list) {
+	m = list;
+	list = list->next;
+	free(m);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/idle.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/idle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/idle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * idle.c
+ *
+ * What to do in a busy loop...
+ */
+
+#include <stddef.h>
+#include <com32.h>
+#include <core.h>
+#include <syslinux/pmapi.h>
+#include <syslinux/idle.h>
+
+void syslinux_reset_idle(void)
+{
+    reset_idle();
+}
+
+void syslinux_idle(void)
+{
+    __idle();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs.c
+ *
+ * Utility functions for initramfs manipulation
+ */
+
+#include <stdlib.h>
+#include <syslinux/linux.h>
+
+struct initramfs *initramfs_init(void)
+{
+    struct initramfs *ir;
+
+    ir = calloc(sizeof(*ir), 1);
+    if (!ir)
+	return NULL;
+
+    ir->prev = ir->next = ir;
+    return ir;
+}
+
+int initramfs_add_data(struct initramfs *ihead, const void *data,
+		       size_t data_len, size_t len, size_t align)
+{
+    struct initramfs *in;
+
+    if (!len)
+	return 0;		/* Nothing to add... */
+
+    /* Alignment must be a power of 2, and <= INITRAMFS_MAX_ALIGN */
+    if (!align || (align & (align - 1)) || align > INITRAMFS_MAX_ALIGN)
+	return -1;
+
+    in = malloc(sizeof(*in));
+    if (!in)
+	return -1;
+
+    in->len = len;
+    in->data = data;
+    in->data_len = data_len;
+    in->align = align;
+
+    in->next = ihead;
+    in->prev = ihead->prev;
+    ihead->prev->next = in;
+    ihead->prev = in;
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_archive.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_archive.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_archive.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_archive.c
+ *
+ * Utility function to load an initramfs archive.
+ */
+
+#include <stdlib.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+
+int initramfs_load_archive(struct initramfs *ihead, const char *filename)
+{
+    void *data;
+    size_t len;
+
+    if (loadfile(filename, &data, &len))
+	return -1;
+
+    return initramfs_add_data(ihead, data, len, len, 4);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_file.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_file.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_file.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_file.c
+ *
+ * Utility functions to add arbitrary files including cpio header
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <syslinux/linux.h>
+
+#define CPIO_MAGIC "070701"
+struct cpio_header {
+    char c_magic[6];		/* 070701 */
+    char c_ino[8];		/* Inode number */
+    char c_mode[8];		/* File mode and permissions */
+    char c_uid[8];		/* uid */
+    char c_gid[8];		/* gid */
+    char c_nlink[8];		/* Number of links */
+    char c_mtime[8];		/* Modification time */
+    char c_filesize[8];		/* Size of data field */
+    char c_maj[8];		/* File device major number */
+    char c_min[8];		/* File device minor number */
+    char c_rmaj[8];		/* Device node reference major number */
+    char c_rmin[8];		/* Device node reference minor number */
+    char c_namesize[8];		/* Length of filename including final \0 */
+    char c_chksum[8];		/* Checksum if c_magic ends in 2 */
+};
+
+static uint32_t next_ino = 1;
+
+/* Create cpio headers for the directory entries leading up to a file.
+   Returns the number of bytes; doesn't touch the buffer if too small. */
+static size_t initramfs_mkdirs(const char *filename, void *buffer,
+			       size_t buflen)
+{
+    const char *p = filename;
+    char *bp = buffer;
+    int len;
+    size_t bytes = 0, hdr_sz;
+    int pad;
+
+    while ((p = strchr(p, '/'))) {
+	if (p != filename && p[-1] != '/') {
+	    len = p - filename;
+	    bytes += ((sizeof(struct cpio_header) + len + 1) + 3) & ~3;
+	}
+	p++;
+    }
+
+    if (buflen >= bytes) {
+	p = filename;
+	while ((p = strchr(p, '/'))) {
+	    if (p != filename && p[-1] != '/') {
+		len = p - filename;
+		hdr_sz = ((sizeof(struct cpio_header) + len + 1) + 3) & ~3;
+		bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x"
+			      "%08x%08x%08x%08x", next_ino++, S_IFDIR | 0755,
+			      0, 0, 1, 0, 0, 0, 1, 0, 1, len + 1, 0);
+		memcpy(bp, filename, len);
+		bp += len;
+		pad = hdr_sz - (sizeof(struct cpio_header) + len);
+		memset(bp, 0, pad);
+		bp += pad;
+	    }
+	    p++;
+	}
+    }
+
+    return bytes;
+}
+
+/*
+ * Create a file header (with optional parent directory entries)
+ * and add it to an initramfs chain
+ */
+int initramfs_mknod(struct initramfs *ihead, const char *filename,
+		    int do_mkdir,
+		    uint16_t mode, size_t len, uint32_t major, uint32_t minor)
+{
+    size_t bytes, hdr_sz;
+    int namelen = strlen(filename);
+    int pad;
+    char *buffer, *bp;
+
+    if (do_mkdir)
+	bytes = initramfs_mkdirs(filename, NULL, 0);
+    else
+	bytes = 0;
+
+    hdr_sz = ((sizeof(struct cpio_header) + namelen + 1) + 3) & ~3;
+    bytes += hdr_sz;
+
+    bp = buffer = malloc(bytes);
+    if (!buffer)
+	return -1;
+
+    if (do_mkdir)
+	bp += initramfs_mkdirs(filename, bp, bytes);
+
+    bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x"
+		  "%08x%08x%08x%08x", next_ino++, mode,
+		  0, 0, 1, 0, len, 0, 1, major, minor, namelen + 1, 0);
+    memcpy(bp, filename, namelen);
+    bp += namelen;
+    pad = hdr_sz - (sizeof(struct cpio_header) + namelen);
+    memset(bp, 0, pad);
+
+    if (initramfs_add_data(ihead, buffer, bytes, bytes, 4)) {
+	free(buffer);
+	return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Add a file given data in memory to an initramfs chain.  This
+ * can be used to create nonfiles like symlinks by specifying an
+ * appropriate mode.
+ */
+int initramfs_add_file(struct initramfs *ihead, const void *data,
+		       size_t data_len, size_t len,
+		       const char *filename, int do_mkdir, uint32_t mode)
+{
+    if (initramfs_mknod(ihead, filename, do_mkdir,
+			(mode & S_IFMT) ? mode : mode | S_IFREG, len, 0, 1))
+	return -1;
+
+    return initramfs_add_data(ihead, data, data_len, len, 4);
+}
+
+int initramfs_add_trailer(struct initramfs *ihead)
+{
+    return initramfs_mknod(ihead, "TRAILER!!!", 0, 0, 0, 0, 0);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_loadfile.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_loadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/initramfs_loadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initramfs_loadfile.c
+ *
+ * Load a single file into an initramfs image.
+ */
+
+#include <syslinux/linux.h>
+#include <syslinux/loadfile.h>
+
+int initramfs_load_file(struct initramfs *ihead, const char *src_filename,
+			const char *dst_filename, int do_mkdir, uint32_t mode)
+{
+    void *data;
+    size_t len;
+
+    if (loadfile(src_filename, &data, &len))
+	return -1;
+
+    return initramfs_add_file(ihead, data, len, len, dst_filename,
+			      do_mkdir, mode);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/ipappend.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/ipappend.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/ipappend.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/ipappend.c
+ *
+ * Get ipappend strings
+ */
+
+#include <syslinux/sysappend.h>
+#include <syslinux/config.h>
+#include <syslinux/pmapi.h>
+#include <klibc/compiler.h>
+#include <core.h>
+
+struct syslinux_ipappend_strings __syslinux_ipappend_strings;
+
+void __constructor __syslinux_get_ipappend_strings(void)
+{
+    __syslinux_ipappend_strings.count = SYSAPPEND_MAX,
+    __syslinux_ipappend_strings.ptr   = sysappend_strings;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/keyboard.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/keyboard.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/keyboard.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/keyboard.h>
+#include <core.h>
+
+struct syslinux_keyboard_map __syslinux_keyboard_map;
+
+void __constructor __syslinux_get_keyboard_map(void)
+{
+    __syslinux_keyboard_map.version = 1;
+    __syslinux_keyboard_map.length = sizeof(KbdMap);
+    __syslinux_keyboard_map.map = (void *)KbdMap;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/load_linux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/load_linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/load_linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,518 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2013 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * load_linux.c
+ *
+ * Load a Linux kernel (Image/zImage/bzImage).
+ */
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <minmax.h>
+#include <errno.h>
+#include <suffix_number.h>
+#include <dprintf.h>
+
+#include <syslinux/align.h>
+#include <syslinux/linux.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+#include <syslinux/firmware.h>
+#include <syslinux/video.h>
+
+#define BOOT_MAGIC 0xAA55
+#define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24))
+#define OLD_CMDLINE_MAGIC 0xA33F
+
+/* loadflags */
+#define LOAD_HIGH	0x01
+#define CAN_USE_HEAP	0x80
+
+/* 
+ * Find the last instance of a particular command line argument
+ * (which should include the final =; do not use for boolean arguments)
+ * Note: the resulting string is typically not null-terminated.
+ */
+static const char *find_argument(const char *cmdline, const char *argument)
+{
+    const char *found = NULL;
+    const char *p = cmdline;
+    bool was_space = true;
+    size_t la = strlen(argument);
+
+    while (*p) {
+	if (isspace(*p)) {
+	    was_space = true;
+	} else if (was_space) {
+	    if (!memcmp(p, argument, la))
+		found = p + la;
+	    was_space = false;
+	}
+	p++;
+    }
+
+    return found;
+}
+
+/* Truncate to 32 bits, with saturate */
+static inline uint32_t saturate32(unsigned long long v)
+{
+    return (v > 0xffffffff) ? 0xffffffff : (uint32_t) v;
+}
+
+/* Create the appropriate mappings for the initramfs */
+static int map_initramfs(struct syslinux_movelist **fraglist,
+			 struct syslinux_memmap **mmap,
+			 struct initramfs *initramfs, addr_t addr)
+{
+    struct initramfs *ip;
+    addr_t next_addr, len, pad;
+
+    for (ip = initramfs->next; ip->len; ip = ip->next) {
+	len = ip->len;
+	next_addr = addr + len;
+
+	/* If this isn't the last entry, extend the zero-pad region
+	   to enforce the alignment of the next chunk. */
+	if (ip->next->len) {
+	    pad = -next_addr & (ip->next->align - 1);
+	    len += pad;
+	    next_addr += pad;
+	}
+
+	if (ip->data_len) {
+	    if (syslinux_add_movelist(fraglist, addr, (addr_t) ip->data, len))
+		return -1;
+	}
+	if (len > ip->data_len) {
+	    if (syslinux_add_memmap(mmap, addr + ip->data_len,
+				    len - ip->data_len, SMT_ZERO))
+		return -1;
+	}
+	addr = next_addr;
+    }
+
+    return 0;
+}
+
+static size_t calc_cmdline_offset(const struct syslinux_memmap *mmap,
+				  const struct linux_header *hdr,
+				  size_t cmdline_size, addr_t base,
+				  addr_t start)
+{
+    size_t max_offset;
+
+    if (hdr->version >= 0x0202 && (hdr->loadflags & LOAD_HIGH))
+	max_offset = 0x10000;
+    else
+	max_offset = 0xfff0 - cmdline_size;
+
+    if (!syslinux_memmap_highest(mmap, SMT_FREE, &start,
+				 cmdline_size, 0xa0000, 16) ||
+	!syslinux_memmap_highest(mmap, SMT_TERMINAL, &start,
+				 cmdline_size, 0xa0000, 16)) {
+	
+
+	return min(start - base, max_offset) & ~15;
+    }
+
+    dprintf("Unable to find lowmem for cmdline\n");
+    return (0x9ff0 - cmdline_size) & ~15; /* Legacy value: pure hope... */
+}
+
+int bios_boot_linux(void *kernel_buf, size_t kernel_size,
+		    struct initramfs *initramfs,
+		    struct setup_data *setup_data,
+		    char *cmdline)
+{
+    struct linux_header hdr, *whdr;
+    size_t real_mode_size, prot_mode_size, base;
+    addr_t real_mode_base, prot_mode_base, prot_mode_max;
+    addr_t irf_size;
+    size_t cmdline_size, cmdline_offset;
+    struct setup_data *sdp;
+    struct syslinux_rm_regs regs;
+    struct syslinux_movelist *fraglist = NULL;
+    struct syslinux_memmap *mmap = NULL;
+    struct syslinux_memmap *amap = NULL;
+    uint32_t memlimit = 0;
+    uint16_t video_mode = 0;
+    const char *arg;
+
+    cmdline_size = strlen(cmdline) + 1;
+
+    errno = EINVAL;
+    if (kernel_size < 2 * 512) {
+	dprintf("Kernel size too small\n");
+	goto bail;
+    }
+
+    /* Look for specific command-line arguments we care about */
+    if ((arg = find_argument(cmdline, "mem=")))
+	memlimit = saturate32(suffix_number(arg));
+
+    if ((arg = find_argument(cmdline, "vga="))) {
+	switch (arg[0] | 0x20) {
+	case 'a':		/* "ask" */
+	    video_mode = 0xfffd;
+	    break;
+	case 'e':		/* "ext" */
+	    video_mode = 0xfffe;
+	    break;
+	case 'n':		/* "normal" */
+	    video_mode = 0xffff;
+	    break;
+	case 'c':		/* "current" */
+	    video_mode = 0x0f04;
+	    break;
+	default:
+	    video_mode = strtoul(arg, NULL, 0);
+	    break;
+	}
+    }
+
+    /* Copy the header into private storage */
+    /* Use whdr to modify the actual kernel header */
+    memcpy(&hdr, kernel_buf, sizeof hdr);
+    whdr = (struct linux_header *)kernel_buf;
+
+    if (hdr.boot_flag != BOOT_MAGIC) {
+	dprintf("Invalid boot magic\n");
+	goto bail;
+    }
+
+    if (hdr.header != LINUX_MAGIC) {
+	hdr.version = 0x0100;	/* Very old kernel */
+	hdr.loadflags = 0;
+    }
+
+    whdr->vid_mode = video_mode;
+
+    if (!hdr.setup_sects)
+	hdr.setup_sects = 4;
+
+    if (hdr.version < 0x0203 || !hdr.initrd_addr_max)
+	hdr.initrd_addr_max = 0x37ffffff;
+
+    if (!memlimit && memlimit - 1 > hdr.initrd_addr_max)
+	memlimit = hdr.initrd_addr_max + 1;	/* Zero for no limit */
+
+    if (hdr.version < 0x0205 || !(hdr.loadflags & LOAD_HIGH))
+	hdr.relocatable_kernel = 0;
+
+    if (hdr.version < 0x0206)
+	hdr.cmdline_max_len = 256;
+
+    if (cmdline_size > hdr.cmdline_max_len) {
+	cmdline_size = hdr.cmdline_max_len;
+	cmdline[cmdline_size - 1] = '\0';
+    }
+
+    real_mode_size = (hdr.setup_sects + 1) << 9;
+    real_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x10000 : 0x90000;
+    prot_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x100000 : 0x10000;
+    prot_mode_max  = (hdr.loadflags & LOAD_HIGH) ? (addr_t)-1 : 0x8ffff;
+    prot_mode_size = kernel_size - real_mode_size;
+
+    /* Get the memory map */
+    mmap = syslinux_memory_map();	/* Memory map for shuffle_boot */
+    amap = syslinux_dup_memmap(mmap);	/* Keep track of available memory */
+    if (!mmap || !amap) {
+	errno = ENOMEM;
+	goto bail;
+    }
+
+    cmdline_offset = calc_cmdline_offset(mmap, &hdr, cmdline_size,
+					 real_mode_base,
+					 real_mode_base + real_mode_size);
+    dprintf("cmdline_offset at 0x%x\n", real_mode_base + cmdline_offset);
+
+    if (hdr.version < 0x020a) {
+	/*
+	 * The 3* here is a total fudge factor... it's supposed to
+	 * account for the fact that the kernel needs to be
+	 * decompressed, and then followed by the BSS and BRK regions.
+	 * This doesn't, however, account for the fact that the kernel
+	 * is decompressed into a whole other place, either.
+	 */
+	hdr.init_size = 3 * prot_mode_size;
+    }
+
+    if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512 * 1024) {
+	dprintf("Kernel cannot be loaded low\n");
+	goto bail;
+    }
+
+    /* Get the size of the initramfs, if there is one */
+    irf_size = initramfs_size(initramfs);
+
+    if (irf_size && hdr.version < 0x0200) {
+	dprintf("Initrd specified but not supported by kernel\n");
+	goto bail;
+    }
+
+    if (hdr.version >= 0x0200) {
+	whdr->type_of_loader = 0x30;	/* SYSLINUX unknown module */
+	if (hdr.version >= 0x0201) {
+	    whdr->heap_end_ptr = cmdline_offset - 0x0200;
+	    whdr->loadflags |= CAN_USE_HEAP;
+	}
+    }
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    /* If the user has specified a memory limit, mark that as unavailable.
+       Question: should we mark this off-limit in the mmap as well (meaning
+       it's unavailable to the boot loader, which probably has already touched
+       some of it), or just in the amap? */
+    if (memlimit)
+	if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED)) {
+	    errno = ENOMEM;
+	    goto bail;
+	}
+
+    /* Place the kernel in memory */
+
+    /*
+     * First, find a suitable place for the protected-mode code.  If
+     * the kernel image is not relocatable, just worry if it fits (it
+     * might not even be a Linux image, after all, and for !LOAD_HIGH
+     * we end up decompressing into a different location anyway), but
+     * if it is, make sure everything fits.
+     */
+    base = prot_mode_base;
+    if (prot_mode_size &&
+	syslinux_memmap_find(amap, &base,
+			     hdr.relocatable_kernel ?
+			     hdr.init_size : prot_mode_size,
+			     hdr.relocatable_kernel, hdr.kernel_alignment,
+			     prot_mode_base, prot_mode_max,
+			     prot_mode_base, prot_mode_max)) {
+	dprintf("Could not find location for protected-mode code\n");
+	goto bail;
+    }
+
+    whdr->code32_start += base - prot_mode_base;
+
+    /* Real mode code */
+    if (syslinux_memmap_find(amap, &real_mode_base,
+			     cmdline_offset + cmdline_size, true, 16,
+			     real_mode_base, 0x90000, 0, 640*1024)) {
+	dprintf("Could not find location for real-mode code\n");
+	goto bail;
+    }
+
+    if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t) kernel_buf,
+			      real_mode_size))
+	goto bail;
+    if (syslinux_add_memmap
+	(&amap, real_mode_base, cmdline_offset + cmdline_size, SMT_ALLOC)) {
+	errno = ENOMEM;
+	goto bail;
+    }
+
+    /* Zero region between real mode code and cmdline */
+    if (syslinux_add_memmap(&mmap, real_mode_base + real_mode_size,
+			    cmdline_offset - real_mode_size, SMT_ZERO)) {
+	errno = ENOMEM;
+	goto bail;
+    }
+
+    /* Command line */
+    if (syslinux_add_movelist(&fraglist, real_mode_base + cmdline_offset,
+			      (addr_t) cmdline, cmdline_size)) {
+	errno = ENOMEM;
+	goto bail;
+    }
+    if (hdr.version >= 0x0202) {
+	whdr->cmd_line_ptr = real_mode_base + cmdline_offset;
+    } else {
+	whdr->old_cmd_line_magic = OLD_CMDLINE_MAGIC;
+	whdr->old_cmd_line_offset = cmdline_offset;
+	if (hdr.version >= 0x0200) {
+	    /* Be paranoid and round up to a multiple of 16 */
+	    whdr->setup_move_size = (cmdline_offset + cmdline_size + 15) & ~15;
+	}
+    }
+
+    /* Protected-mode code */
+    if (prot_mode_size) {
+	if (syslinux_add_movelist(&fraglist, prot_mode_base,
+				  (addr_t) kernel_buf + real_mode_size,
+				  prot_mode_size)) {
+	    errno = ENOMEM;
+	    goto bail;
+	}
+	if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size,
+				SMT_ALLOC)) {
+	    errno = ENOMEM;
+	    goto bail;
+	}
+    }
+
+    /* Figure out the size of the initramfs, and where to put it.
+       We should put it at the highest possible address which is
+       <= hdr.initrd_addr_max, which fits the entire initramfs. */
+
+    if (irf_size) {
+	addr_t best_addr = 0;
+	struct syslinux_memmap *ml;
+	const addr_t align_mask = INITRAMFS_MAX_ALIGN - 1;
+
+	if (irf_size) {
+	    for (ml = amap; ml->type != SMT_END; ml = ml->next) {
+		addr_t adj_start = (ml->start + align_mask) & ~align_mask;
+		addr_t adj_end = ml->next->start & ~align_mask;
+		if (ml->type == SMT_FREE && adj_end - adj_start >= irf_size)
+		    best_addr = (adj_end - irf_size) & ~align_mask;
+	    }
+
+	    if (!best_addr) {
+		dprintf("Insufficient memory for initramfs\n");
+		goto bail;
+	    }
+
+	    whdr->ramdisk_image = best_addr;
+	    whdr->ramdisk_size = irf_size;
+
+	    if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC)) {
+		errno = ENOMEM;
+		goto bail;
+	    }
+
+	    if (map_initramfs(&fraglist, &mmap, initramfs, best_addr)) {
+		errno = ENOMEM;
+		goto bail;
+	    }
+	}
+    }
+
+    if (setup_data) {
+	uint64_t *prev_ptr = &whdr->setup_data;
+
+	for (sdp = setup_data->next; sdp != setup_data; sdp = sdp->next) {
+	    struct syslinux_memmap *ml;
+	    const addr_t align_mask = 15; /* Header is 16 bytes */
+	    addr_t best_addr = 0;
+	    size_t size = sdp->hdr.len + sizeof(sdp->hdr);
+
+	    if (!sdp->data || !sdp->hdr.len)
+		continue;
+
+	    if (hdr.version < 0x0209) {
+		/* Setup data not supported */
+		errno = ENXIO;	/* Kind of arbitrary... */
+		goto bail;
+	    }
+
+	    for (ml = amap; ml->type != SMT_END; ml = ml->next) {
+		addr_t adj_start = (ml->start + align_mask) & ~align_mask;
+		addr_t adj_end = ml->next->start & ~align_mask;
+
+		if (ml->type == SMT_FREE && adj_end - adj_start >= size)
+		    best_addr = (adj_end - size) & ~align_mask;
+	    }
+
+	    if (!best_addr)
+		goto bail;
+
+	    *prev_ptr = best_addr;
+	    prev_ptr = &sdp->hdr.next;
+
+	    if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC)) {
+		errno = ENOMEM;
+		goto bail;
+	    }
+	    if (syslinux_add_movelist(&fraglist, best_addr,
+				      (addr_t)&sdp->hdr, sizeof sdp->hdr)) {
+		errno = ENOMEM;
+		goto bail;
+	    }
+	    if (syslinux_add_movelist(&fraglist, best_addr + sizeof sdp->hdr,
+				      (addr_t)sdp->data, sdp->hdr.len)) {
+		errno = ENOMEM;
+		goto bail;
+	    }
+	}
+    }
+
+    /* Set up the registers on entry */
+    memset(&regs, 0, sizeof regs);
+    regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4;
+    regs.cs = (real_mode_base >> 4) + 0x20;
+    /* regs.ip = 0; */
+    /* Linux is OK with sp = 0 = 64K, but perhaps other things aren't... */
+    regs.esp.w[0] = min(cmdline_offset, (size_t) 0xfff0);
+
+    dprintf("Final memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Final available map:\n");
+    syslinux_dump_memmap(amap);
+
+    dprintf("Initial movelist:\n");
+    syslinux_dump_movelist(fraglist);
+
+    if (video_mode != 0x0f04) {
+	/*
+	 * video_mode is not "current", so if we are in graphics mode we
+	 * need to revert to text mode...
+	 */
+	dprintf("*** Calling syslinux_force_text_mode()...\n");
+	syslinux_force_text_mode();
+    } else {
+	dprintf("*** vga=current, not calling syslinux_force_text_mode()...\n");
+    }
+
+    syslinux_shuffle_boot_rm(fraglist, mmap, 0, &regs);
+    dprintf("shuffle_boot_rm failed\n");
+
+bail:
+    syslinux_free_movelist(fraglist);
+    syslinux_free_memmap(mmap);
+    syslinux_free_memmap(amap);
+    return -1;
+}
+
+int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
+			struct initramfs *initramfs,
+			struct setup_data *setup_data,
+			char *cmdline)
+{
+    if (firmware->boot_linux)
+	return firmware->boot_linux(kernel_buf, kernel_size, initramfs,
+				    setup_data, cmdline);
+
+    return bios_boot_linux(kernel_buf, kernel_size, initramfs,
+			   setup_data, cmdline);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/loadfile.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/loadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/loadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * loadfile.c
+ *
+ * Read the contents of a data file into a malloc'd buffer
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int loadfile(const char *filename, void **ptr, size_t * len)
+{
+    FILE *f;
+    int rv, e;
+
+    f = fopen(filename, "r");
+    if (!f)
+	return -1;
+
+    rv = floadfile(f, ptr, len, NULL, 0);
+    e = errno;
+
+    fclose(f);
+
+    if (rv)
+	errno = e;
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/localboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/localboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/localboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <com32.h>
+#include <localboot.h>
+
+/* This returns only on failure */
+
+void syslinux_local_boot(int16_t flags)
+{
+    local_boot(flags);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memmap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,64 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memmap.c
+ *
+ * Create initial memory map for "shuffle and boot" operation
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <syslinux/memscan.h>
+#include <syslinux/movebits.h>
+
+static int syslinux_memory_map_callback(void *map, addr_t start, addr_t len,
+					enum syslinux_memmap_types type)
+{
+    struct syslinux_memmap **mmap = map;
+    return syslinux_add_memmap(mmap, start, len, type);
+}
+
+struct syslinux_memmap *syslinux_memory_map(void)
+{
+    struct syslinux_memmap *mmap;
+
+    mmap = syslinux_init_memmap();
+    if (!mmap)
+	return NULL;
+
+    if (syslinux_scan_memory(syslinux_memory_map_callback, &mmap)) {
+	syslinux_free_memmap(mmap);
+	return NULL;
+    }
+
+    return mmap;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memscan.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memscan.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/memscan.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memscan.c
+ *
+ * Query the system for free memory
+ */
+
+#include <syslinux/memscan.h>
+
+static LIST_HEAD(syslinux_memscan_head);
+
+/*
+ * Add a memscan entry to the list.
+ */
+void syslinux_memscan_add(struct syslinux_memscan *entry)
+{
+    list_add(&entry->next, &syslinux_memscan_head);
+}
+
+/*
+ * Build a new memscan entry and add it to the list.
+ */
+int syslinux_memscan_new(int func(scan_memory_callback_t, void *data))
+{
+    struct syslinux_memscan *entry;
+
+    entry = malloc(sizeof *entry);
+    if (!entry)
+	return -1;
+
+    entry->func = func;
+    syslinux_memscan_add(entry);
+    return 0;
+}
+
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
+{
+    struct syslinux_memscan *entry;
+    int rv = 0;
+
+    list_for_each_entry(entry, &syslinux_memscan_head, next) {
+	rv = entry->func(callback, data);
+	if (rv)
+	    break;
+    }
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/movebits.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/movebits.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/movebits.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,689 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * movebits.c
+ *
+ * Utility function to take a list of memory areas to shuffle and
+ * convert it to a set of shuffle operations.
+ *
+ * Note: a lot of the functions in this file deal with "parent pointers",
+ * which are pointers to a pointer to a list, or part of the list.
+ * They can be pointers to a variable holding the list root pointer,
+ * or pointers to a next field of a previous entry.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <setjmp.h>
+#include <minmax.h>
+#include <stdbool.h>
+
+#include <syslinux/movebits.h>
+#include <dprintf.h>
+
+static jmp_buf new_movelist_bail;
+
+static struct syslinux_movelist *new_movelist(addr_t dst, addr_t src,
+					      addr_t len)
+{
+    struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist));
+
+    if (!ml)
+	longjmp(new_movelist_bail, 1);
+
+    ml->dst = dst;
+    ml->src = src;
+    ml->len = len;
+    ml->next = NULL;
+
+    return ml;
+}
+
+static struct syslinux_movelist *dup_movelist(struct syslinux_movelist *src)
+{
+    struct syslinux_movelist *dst = NULL, **dstp = &dst, *ml;
+
+    while (src) {
+	ml = new_movelist(src->dst, src->src, src->len);
+	*dstp = ml;
+	dstp = &ml->next;
+	src = src->next;
+    }
+
+    return dst;
+}
+
+static void
+add_freelist(struct syslinux_memmap **mmap, addr_t start,
+	     addr_t len, enum syslinux_memmap_types type)
+{
+    if (syslinux_add_memmap(mmap, start, len, type))
+	longjmp(new_movelist_bail, 1);
+}
+
+/*
+ * Take a chunk, entirely confined in **parentptr, and split it off so that
+ * it has its own structure.
+ */
+static struct syslinux_movelist **split_movelist(addr_t start, addr_t len,
+						 struct syslinux_movelist
+						 **parentptr)
+{
+    struct syslinux_movelist *m, *ml = *parentptr;
+
+    assert(start >= ml->src);
+    assert(start < ml->src + ml->len);
+
+    /* Split off the beginning */
+    if (start > ml->src) {
+	addr_t l = start - ml->src;
+
+	m = new_movelist(ml->dst + l, start, ml->len - l);
+	m->next = ml->next;
+	ml->len = l;
+	ml->next = m;
+
+	parentptr = &ml->next;
+	ml = m;			/* Continue processing the new node */
+    }
+
+    /* Split off the end */
+    if (ml->len > len) {
+	addr_t l = ml->len - len;
+
+	m = new_movelist(ml->dst + len, ml->src + len, l);
+	m->next = ml->next;
+	ml->len = len;
+	ml->next = m;
+    }
+
+    return parentptr;
+}
+
+static void delete_movelist(struct syslinux_movelist **parentptr)
+{
+    struct syslinux_movelist *o = *parentptr;
+    *parentptr = o->next;
+    free(o);
+}
+
+static void free_movelist(struct syslinux_movelist **parentptr)
+{
+    while (*parentptr)
+	delete_movelist(parentptr);
+}
+
+/*
+ * Scan the freelist looking for a particular chunk of memory.  Returns
+ * the memmap chunk containing to the first byte of the region.
+ */
+static const struct syslinux_memmap *is_free_zone(const struct syslinux_memmap
+						  *list, addr_t start,
+						  addr_t len)
+{
+    addr_t last, llast;
+
+    dprintf("f: 0x%08x bytes at 0x%08x\n", len, start);
+
+    last = start + len - 1;
+
+    while (list->type != SMT_END) {
+	if (list->start <= start) {
+	    const struct syslinux_memmap *ilist = list;
+	    while (valid_terminal_type(list->type)) {
+		llast = list->next->start - 1;
+		if (llast >= last)
+		    return ilist;
+		list = list->next;
+	    }
+
+	    if (list->start > start)
+		return NULL;	/* Invalid type in region */
+	}
+	list = list->next;
+    }
+
+    return NULL;		/* Internal error? */
+}
+
+/*
+ * Scan the freelist looking for the smallest chunk of memory which
+ * can fit X bytes; returns the length of the block on success.
+ */
+static addr_t free_area(const struct syslinux_memmap *mmap,
+			addr_t len, addr_t * start)
+{
+    const struct syslinux_memmap *best = NULL;
+    const struct syslinux_memmap *s;
+    addr_t slen, best_len = -1;
+
+    for (s = mmap; s->type != SMT_END; s = s->next) {
+	if (s->type != SMT_FREE)
+	    continue;
+	slen = s->next->start - s->start;
+	if (slen >= len) {
+	    if (!best || best_len > slen) {
+		best = s;
+		best_len = slen;
+	    }
+	}
+    }
+
+    if (best) {
+	*start = best->start;
+	return best_len;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ * Remove a chunk from the freelist
+ */
+static void
+allocate_from(struct syslinux_memmap **mmap, addr_t start, addr_t len)
+{
+    syslinux_add_memmap(mmap, start, len, SMT_ALLOC);
+}
+
+/*
+ * Find chunks of a movelist which are one-to-many (one source, multiple
+ * destinations.)  Those chunks can get turned into post-shuffle copies,
+ * to avoid confusing the shuffler.
+ */
+static void shuffle_dealias(struct syslinux_movelist **fraglist,
+			    struct syslinux_movelist **postcopy)
+{
+    struct syslinux_movelist *mp, **mpp, *mx, *np;
+    addr_t ps, pe, xs, xe, delta;
+    bool advance;
+
+    dprintf("Before alias resolution:\n");
+    syslinux_dump_movelist(*fraglist);
+
+    *postcopy = NULL;
+
+    /*
+     * Note: as written, this is an O(n^2) algorithm; by producing a list
+     * sorted by destination address we could reduce it to O(n log n).
+     */
+    mpp = fraglist;
+    while ((mp = *mpp)) {
+	dprintf("mp -> (%#x,%#x,%#x)\n", mp->dst, mp->src, mp->len);
+	ps = mp->src;
+	pe = mp->src + mp->len - 1;
+	for (mx = *fraglist; mx != mp; mx = mx->next) {
+	    dprintf("mx -> (%#x,%#x,%#x)\n", mx->dst, mx->src, mx->len);
+	    /*
+	     * If there is any overlap between mx and mp, mp should be
+	     * modified and possibly split.
+	     */
+	    xs = mx->src;
+	    xe = mx->src + mx->len - 1;
+
+	    dprintf("?: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe);
+
+	    if (pe <= xs || ps >= xe)
+		continue;	/* No overlap */
+
+	    advance = false;
+	    *mpp = mp->next;	/* Remove from list */
+
+	    if (pe > xe) {
+		delta = pe - xe;
+		np = new_movelist(mp->dst + mp->len - delta,
+				  mp->src + mp->len - delta, delta);
+		mp->len -= delta;
+		pe = xe;
+		np->next = *mpp;
+		*mpp = np;
+		advance = true;
+	    }
+	    if (ps < xs) {
+		delta = xs - ps;
+		np = new_movelist(mp->dst, ps, delta);
+		mp->src += delta;
+		ps = mp->src;
+		mp->dst += delta;
+		mp->len -= delta;
+		np->next = *mpp;
+		*mpp = np;
+		advance = true;
+	    }
+
+	    assert(ps >= xs && pe <= xe);
+
+	    dprintf("Overlap: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe);
+
+	    mp->src = mx->dst + (ps - xs);
+	    mp->next = *postcopy;
+	    *postcopy = mp;
+
+	    mp = *mpp;
+
+	    if (!advance)
+		goto restart;
+	}
+
+	mpp = &mp->next;
+restart:
+	;
+    }
+
+    dprintf("After alias resolution:\n");
+    syslinux_dump_movelist(*fraglist);
+    dprintf("Post-shuffle copies:\n");
+    syslinux_dump_movelist(*postcopy);
+}
+
+/*
+ * The code to actually emit moving of a chunk into its final place.
+ */
+static void
+move_chunk(struct syslinux_movelist ***moves,
+	   struct syslinux_memmap **mmap,
+	   struct syslinux_movelist **fp, addr_t copylen)
+{
+    addr_t copydst, copysrc;
+    addr_t freebase, freelen;
+    addr_t needlen;
+    int reverse;
+    struct syslinux_movelist *f = *fp, *mv;
+
+    if (f->src < f->dst && (f->dst - f->src) < f->len) {
+	/* "Shift up" type overlap */
+	needlen = f->dst - f->src;
+	reverse = 1;
+    } else if (f->src > f->dst && (f->src - f->dst) < f->len) {
+	/* "Shift down" type overlap */
+	needlen = f->src - f->dst;
+	reverse = 0;
+    } else {
+	needlen = f->len;
+	reverse = 0;
+    }
+
+    copydst = f->dst;
+    copysrc = f->src;
+
+    dprintf("Q: copylen = 0x%08x, needlen = 0x%08x\n", copylen, needlen);
+
+    if (copylen < needlen) {
+	if (reverse) {
+	    copydst += (f->len - copylen);
+	    copysrc += (f->len - copylen);
+	}
+
+	dprintf("X: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+		copylen, copysrc, copydst);
+
+	/* Didn't get all we wanted, so we have to split the chunk */
+	fp = split_movelist(copysrc, copylen, fp);	/* Is this right? */
+	f = *fp;
+    }
+
+    mv = new_movelist(f->dst, f->src, f->len);
+    dprintf("A: 0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst);
+    **moves = mv;
+    *moves = &mv->next;
+
+    /* Figure out what memory we just freed up */
+    if (f->dst > f->src) {
+	freebase = f->src;
+	freelen = min(f->len, f->dst - f->src);
+    } else if (f->src >= f->dst + f->len) {
+	freebase = f->src;
+	freelen = f->len;
+    } else {
+	freelen = f->src - f->dst;
+	freebase = f->dst + f->len;
+    }
+
+    dprintf("F: 0x%08x bytes at 0x%08x\n", freelen, freebase);
+
+    add_freelist(mmap, freebase, freelen, SMT_FREE);
+
+    delete_movelist(fp);
+}
+
+/*
+ * moves is computed from "frags" and "freemem".  "space" lists
+ * free memory areas at our disposal, and is (src, cnt) only.
+ */
+int
+syslinux_compute_movelist(struct syslinux_movelist **moves,
+			  struct syslinux_movelist *ifrags,
+			  struct syslinux_memmap *memmap)
+{
+    struct syslinux_memmap *mmap = NULL;
+    const struct syslinux_memmap *mm, *ep;
+    struct syslinux_movelist *frags = NULL;
+    struct syslinux_movelist *postcopy = NULL;
+    struct syslinux_movelist *mv;
+    struct syslinux_movelist *f, **fp;
+    struct syslinux_movelist *o, **op;
+    addr_t needbase, needlen, copysrc, copydst, copylen;
+    addr_t avail;
+    addr_t fstart, flen;
+    addr_t cbyte;
+    addr_t ep_len;
+    int rv = -1;
+    int reverse;
+
+    dprintf("entering syslinux_compute_movelist()...\n");
+
+    if (setjmp(new_movelist_bail)) {
+nomem:
+	dprintf("Out of working memory!\n");
+	goto bail;
+    }
+
+    *moves = NULL;
+
+    /* Create our memory map.  Anything that is SMT_FREE or SMT_ZERO is
+       fair game, but mark anything used by source material as SMT_ALLOC. */
+    mmap = syslinux_init_memmap();
+    if (!mmap)
+	goto nomem;
+
+    frags = dup_movelist(ifrags);
+
+    /* Process one-to-many conditions */
+    shuffle_dealias(&frags, &postcopy);
+
+    for (mm = memmap; mm->type != SMT_END; mm = mm->next)
+	add_freelist(&mmap, mm->start, mm->next->start - mm->start,
+		     mm->type == SMT_ZERO ? SMT_FREE : mm->type);
+
+    for (f = frags; f; f = f->next)
+	add_freelist(&mmap, f->src, f->len, SMT_ALLOC);
+
+    /* As long as there are unprocessed fragments in the chain... */
+    while ((fp = &frags, f = *fp)) {
+
+	dprintf("Current free list:\n");
+	syslinux_dump_memmap(mmap);
+	dprintf("Current frag list:\n");
+	syslinux_dump_movelist(frags);
+
+	/* Scan for fragments which can be discarded without action. */
+	if (f->src == f->dst) {
+	    delete_movelist(fp);
+	    continue;
+	}
+	op = &f->next;
+	while ((o = *op)) {
+	    if (o->src == o->dst)
+		delete_movelist(op);
+	    else
+		op = &o->next;
+	}
+
+	/* Scan for fragments which can be immediately moved
+	   to their final destination, if so handle them now */
+	for (op = fp; (o = *op); op = &o->next) {
+	    if (o->src < o->dst && (o->dst - o->src) < o->len) {
+		/* "Shift up" type overlap */
+		needlen = o->dst - o->src;
+		needbase = o->dst + (o->len - needlen);
+		reverse = 1;
+		cbyte = o->dst + o->len - 1;
+	    } else if (o->src > o->dst && (o->src - o->dst) < o->len) {
+		/* "Shift down" type overlap */
+		needlen = o->src - o->dst;
+		needbase = o->dst;
+		reverse = 0;
+		cbyte = o->dst;	/* "Critical byte" */
+	    } else {
+		needlen = o->len;
+		needbase = o->dst;
+		reverse = 0;
+		cbyte = o->dst;	/* "Critical byte" */
+	    }
+
+	    if (is_free_zone(mmap, needbase, needlen)) {
+		fp = op, f = o;
+		dprintf("!: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+			f->len, f->src, f->dst);
+		copysrc = f->src;
+		copylen = needlen;
+		allocate_from(&mmap, needbase, copylen);
+		goto move_chunk;
+	    }
+	}
+
+	/* Ok, bother.  Need to do real work at least with one chunk. */
+
+	dprintf("@: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+		f->len, f->src, f->dst);
+
+	/* See if we can move this chunk into place by claiming
+	   the destination, or in the case of partial overlap, the
+	   missing portion. */
+
+	if (f->src < f->dst && (f->dst - f->src) < f->len) {
+	    /* "Shift up" type overlap */
+	    needlen = f->dst - f->src;
+	    needbase = f->dst + (f->len - needlen);
+	    reverse = 1;
+	    cbyte = f->dst + f->len - 1;
+	} else if (f->src > f->dst && (f->src - f->dst) < f->len) {
+	    /* "Shift down" type overlap */
+	    needlen = f->src - f->dst;
+	    needbase = f->dst;
+	    reverse = 0;
+	    cbyte = f->dst;	/* "Critical byte" */
+	} else {
+	    needlen = f->len;
+	    needbase = f->dst;
+	    reverse = 0;
+	    cbyte = f->dst;
+	}
+
+	dprintf("need: base = 0x%08x, len = 0x%08x, "
+		"reverse = %d, cbyte = 0x%08x\n",
+		needbase, needlen, reverse, cbyte);
+
+	ep = is_free_zone(mmap, cbyte, 1);
+	if (ep) {
+	    ep_len = ep->next->start - ep->start;
+	    if (reverse)
+		avail = needbase + needlen - ep->start;
+	    else
+		avail = ep_len - (needbase - ep->start);
+	} else {
+	    avail = 0;
+	}
+
+	if (avail) {
+	    /* We can move at least part of this chunk into place without
+	       further ado */
+	    dprintf("space: start 0x%08x, len 0x%08x, free 0x%08x\n",
+		    ep->start, ep_len, avail);
+	    copylen = min(needlen, avail);
+
+	    if (reverse)
+		allocate_from(&mmap, needbase + needlen - copylen, copylen);
+	    else
+		allocate_from(&mmap, needbase, copylen);
+
+	    goto move_chunk;
+	}
+
+	/* At this point, we need to evict something out of our space.
+	   Find the object occupying the critical byte of our target space,
+	   and move it out (the whole object if we can, otherwise a subset.)
+	   Then move a chunk of ourselves into place. */
+	for (op = &f->next, o = *op; o; op = &o->next, o = *op) {
+
+	    dprintf("O: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+		    o->len, o->src, o->dst);
+
+	    if (!(o->src <= cbyte && o->src + o->len > cbyte))
+		continue;	/* Not what we're looking for... */
+
+	    /* Find somewhere to put it... */
+
+	    if (is_free_zone(mmap, o->dst, o->len)) {
+		/* Score!  We can move it into place directly... */
+		copydst = o->dst;
+		copysrc = o->src;
+		copylen = o->len;
+	    } else if (free_area(mmap, o->len, &fstart)) {
+		/* We can move the whole chunk */
+		copydst = fstart;
+		copysrc = o->src;
+		copylen = o->len;
+	    } else {
+		/* Well, copy as much as we can... */
+		if (syslinux_memmap_largest(mmap, SMT_FREE, &fstart, &flen)) {
+		    dprintf("No free memory at all!\n");
+		    goto bail;	/* Stuck! */
+		}
+
+		/* Make sure we include the critical byte */
+		copydst = fstart;
+		if (reverse) {
+		    copysrc = max(o->src, cbyte + 1 - flen);
+		    copylen = cbyte + 1 - copysrc;
+		} else {
+		    copysrc = cbyte;
+		    copylen = min(flen, o->len - (cbyte - o->src));
+		}
+	    }
+	    allocate_from(&mmap, copydst, copylen);
+
+	    if (copylen < o->len) {
+		op = split_movelist(copysrc, copylen, op);
+		o = *op;
+	    }
+
+	    mv = new_movelist(copydst, copysrc, copylen);
+	    dprintf("C: 0x%08x bytes at 0x%08x -> 0x%08x\n",
+		    mv->len, mv->src, mv->dst);
+	    *moves = mv;
+	    moves = &mv->next;
+
+	    o->src = copydst;
+
+	    if (copylen > needlen) {
+		/* We don't need all the memory we freed up.  Mark it free. */
+		if (copysrc < needbase) {
+		    add_freelist(&mmap, copysrc, needbase - copysrc, SMT_FREE);
+		    copylen -= (needbase - copysrc);
+		}
+		if (copylen > needlen) {
+		    add_freelist(&mmap, copysrc + needlen, copylen - needlen,
+				 SMT_FREE);
+		    copylen = needlen;
+		}
+	    }
+	    reverse = 0;
+	    goto move_chunk;
+	}
+	dprintf("Cannot find the chunk containing the critical byte\n");
+	goto bail;		/* Stuck! */
+
+move_chunk:
+	move_chunk(&moves, &mmap, fp, copylen);
+    }
+
+    /* Finally, append the postcopy chain to the end of the moves list */
+    for (op = moves; (o = *op); op = &o->next) ;	/* Locate the end of the list */
+    *op = postcopy;
+    postcopy = NULL;
+
+    rv = 0;
+bail:
+    if (mmap)
+	syslinux_free_memmap(mmap);
+    if (frags)
+	free_movelist(&frags);
+    if (postcopy)
+	free_movelist(&postcopy);
+    return rv;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    FILE *f;
+    unsigned long d, s, l;
+    struct syslinux_movelist *frags;
+    struct syslinux_movelist **fep = &frags;
+    struct syslinux_movelist *mv, *moves;
+    struct syslinux_memmap *memmap;
+    char line[BUFSIZ];
+
+    (void)argc;
+
+    memmap = syslinux_init_memmap();
+
+    f = fopen(argv[1], "r");
+    while (fgets(line, sizeof line, f) != NULL) {
+	if (sscanf(line, "%lx %lx %lx", &s, &d, &l) == 3) {
+	    if (d) {
+		if (s == -1UL) {
+		    syslinux_add_memmap(&memmap, d, l, SMT_ZERO);
+		} else {
+		    mv = new_movelist(d, s, l);
+		    *fep = mv;
+		    fep = &mv->next;
+		}
+	    } else {
+		syslinux_add_memmap(&memmap, s, l, SMT_FREE);
+	    }
+	}
+    }
+    fclose(f);
+
+    *fep = NULL;
+
+    dprintf("Input move list:\n");
+    syslinux_dump_movelist(frags);
+    dprintf("Input free list:\n");
+    syslinux_dump_memmap(memmap);
+
+    if (syslinux_compute_movelist(&moves, frags, memmap)) {
+	printf("Failed to compute a move sequence\n");
+	return 1;
+    } else {
+	dprintf("Final move list:\n");
+	syslinux_dump_movelist(moves);
+	return 0;
+    }
+}
+
+#endif /* TEST */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_dns.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_dns.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_dns.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_dns.c
+ *
+ * Resolve a hostname via DNS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+   or -1 on invocation failure */
+uint32_t pxe_dns(const char *hostname)
+{
+    union {
+	unsigned char b[4];
+	uint32_t ip;
+    } q;
+    char *lm_hostname;
+    uint32_t status;
+
+    /* Is this a dot-quad? */
+    if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu",
+	       &q.b[0], &q.b[1], &q.b[2], &q.b[3]) == 4)
+	return q.ip;
+
+    lm_hostname = lstrdup(hostname);
+    if (!lm_hostname)
+	return 0;
+
+    status = dns_resolv(lm_hostname);
+
+    lfree(lm_hostname);
+
+    return status;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_cached.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_cached.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_cached.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,89 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_get_cached.c
+ *
+ * PXE call "get cached info"
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+   or -1 on invocation failure */
+int pxe_get_cached_info(int level, void **buf, size_t * len)
+{
+    const int max_dhcp_packet = 2048;
+    t_PXENV_GET_CACHED_INFO *gci;
+    void *bbuf, *nbuf;
+    int err;
+
+    gci = lmalloc(sizeof *gci + max_dhcp_packet);
+    if (!gci)
+	return -1;
+
+    bbuf = &gci[1];
+
+    gci->Status = PXENV_STATUS_FAILURE;
+    gci->PacketType = level;
+    gci->BufferSize = gci->BufferLimit = max_dhcp_packet;
+    gci->Buffer.seg = SEG(bbuf);
+    gci->Buffer.offs = OFFS(bbuf);
+
+    err = pxe_call(PXENV_GET_CACHED_INFO, gci);
+
+    if (err) {
+	err = -1;
+	goto exit;
+    }
+
+    if (gci->Status) {
+	err = gci->Status;
+	goto exit;
+    }
+
+    nbuf = malloc(gci->BufferSize);
+    if (!nbuf) {
+	err = -1;
+	goto exit;
+    }
+
+    memcpy(nbuf, bbuf, gci->BufferSize);
+
+    *buf = nbuf;
+    *len = gci->BufferSize;
+    err = 0;
+
+exit:
+    lfree(gci);
+    return err;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_nic.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_nic.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/pxe_get_nic.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxe_get_cached.c
+ *
+ * PXE call "get cached info"
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <com32.h>
+
+#include <syslinux/pxe.h>
+
+/* Returns the status code from PXE (0 on success),
+   or -1 on invocation failure */
+int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt)
+{
+    t_PXENV_UNDI_GET_NIC_TYPE *lgnt;
+    int err;
+
+    lgnt = lzalloc(sizeof *lgnt);
+    if (!lgnt)
+	return -1;
+
+    err = pxe_call(PXENV_UNDI_GET_NIC_TYPE, lgnt);
+
+    memcpy(gnt, lgnt, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
+    lfree(lgnt);
+
+    if (err)
+	return -1;
+
+    return gnt->Status;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/reboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * reboot.c
+ *
+ * Provoke a system reboot
+ */
+
+#include <stddef.h>
+#include <com32.h>
+#include <syslinux/reboot.h>
+
+__noreturn syslinux_reboot(int warm)
+{
+    uint16_t *const reboot_flag = (uint16_t *) 0x472;
+
+    *reboot_flag = warm ? 0x1234 : 0;
+    __farcall(0xf000, 0xfff0, &__com32_zero_regs, NULL);
+
+    while (1)
+	asm volatile ("hlt");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_command.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_command.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_command.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <stddef.h>
+#include <string.h>
+#include <core.h>
+
+int syslinux_run_command(const char *command)
+{
+    char *lm_command = lstrdup(command);
+
+    if (!lm_command)
+	return -1;
+    
+    load_kernel(lm_command);
+
+    /* Should not return even on failure, but in case... */
+    lfree(lm_command);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_default.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_default.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/run_default.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,39 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/boot.h>
+#include <core.h>
+#include <stddef.h>
+
+extern const char *default_cmd;
+
+__noreturn syslinux_run_default(void)
+{
+    load_kernel(default_cmd);
+    /* Should not return even on failure */
+    for (;;) ;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/runimage.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/runimage.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/runimage.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * runimage.c
+ *
+ * Load and run a syslinux image.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/boot.h>
+#include <syslinux/config.h>
+#include <core.h>
+
+void syslinux_run_kernel_image(const char *filename, const char *cmdline,
+			       uint32_t ipappend_flags, uint32_t type)
+{
+    char *bbcmdline  = NULL;
+    size_t len;
+    int rv;
+
+    /* +2 for NULL and space */
+    len = strlen(filename) + strlen(cmdline) + 2;
+    bbcmdline = malloc(len);
+    if (!bbcmdline)
+	return;
+
+    rv = snprintf(bbcmdline, len, "%s %s", filename, cmdline);
+    if (rv == -1 || (size_t)rv >= len)
+	return;
+
+    SysAppends = ipappend_flags;
+    execute(bbcmdline, type, true);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/serial.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/serial.c
+ *
+ * SYSLINUX serial console query
+ */
+
+#include <klibc/compiler.h>
+#include <syslinux/firmware.h>
+#include <syslinux/config.h>
+#include <string.h>
+
+struct syslinux_serial_console_info __syslinux_serial_console_info;
+
+void __syslinux_set_serial_console_info(void)
+{
+    uint16_t iobase, divisor, flowctl;
+
+    firmware->get_serial_console_info(&iobase, &divisor, &flowctl);
+
+    __syslinux_serial_console_info.iobase = iobase;
+    __syslinux_serial_console_info.divisor = divisor;
+    __syslinux_serial_console_info.flowctl = flowctl;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/setup_data.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/setup_data.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/setup_data.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <syslinux/linux.h>
+#include <syslinux/loadfile.h>
+
+struct setup_data *setup_data_init(void)
+{
+    struct setup_data *setup_data;
+
+    setup_data = zalloc(sizeof(*setup_data));
+    if (!setup_data)
+	return NULL;
+
+    setup_data->prev = setup_data->next = setup_data;
+    return setup_data;
+}
+
+int setup_data_add(struct setup_data *head, uint32_t type,
+		   const void *data, size_t data_len)
+{
+	struct setup_data *setup_data;
+
+	setup_data = zalloc(sizeof(*setup_data));
+	if (!setup_data)
+	    return -1;
+
+	setup_data->data     = data;
+	setup_data->hdr.len  = data_len;
+	setup_data->hdr.type = type;
+	setup_data->prev     = head->prev;
+	setup_data->next     = head;
+	head->prev->next     = setup_data;
+	head->prev           = setup_data;
+
+	return 0;
+}
+
+int setup_data_load(struct setup_data *head, uint32_t type,
+		    const char *filename)
+{
+	void *data;
+	size_t len;
+
+	if (loadfile(filename, &data, &len))
+		return -1;
+
+	return setup_data_add(head, type, data, len);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,251 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle.c
+ *
+ * Common code for "shuffle and boot" operation; generates a shuffle list
+ * and puts it in the bounce buffer.  Returns the number of shuffle
+ * descriptors.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <com32.h>
+#include <core.h>
+#include <minmax.h>
+#include <dprintf.h>
+#include <syslinux/movebits.h>
+#include <klibc/compiler.h>
+#include <syslinux/boot.h>
+
+struct shuffle_descriptor {
+    uint32_t dst, src, len;
+};
+
+/*
+ * Allocate descriptor memory in these chunks; if this is large we may
+ * waste memory, if it is small we may get slow convergence.
+ */
+#define DESC_BLOCK_SIZE	256
+
+int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
+			struct syslinux_memmap *memmap,
+			addr_t entry_point, addr_t entry_type,
+			uint16_t bootflags)
+{
+    int rv = -1;
+    struct syslinux_movelist *moves = NULL, *mp;
+    struct syslinux_memmap *rxmap = NULL, *ml;
+    struct shuffle_descriptor *dp, *dbuf;
+    int np;
+    int desc_blocks, need_blocks;
+    int need_ptrs;
+    addr_t desczone, descfree, descaddr;
+    int nmoves, nzero;
+
+#ifndef __FIRMWARE_BIOS__
+    errno = ENOSYS;
+    return -1;			/* Not supported at this time*/
+#endif
+
+    descaddr = 0;
+    dp = dbuf = NULL;
+
+    /* Count the number of zero operations */
+    nzero = 0;
+    for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
+	if (ml->type == SMT_ZERO)
+	    nzero++;
+    }
+
+    /* Find the largest contiguous region unused by input *and* output;
+       this is where we put the move descriptor list and safe area */
+
+    rxmap = syslinux_dup_memmap(memmap);
+    if (!rxmap)
+	goto bail;
+    /* Avoid using the low 1 MB for the shuffle area -- this avoids
+       possible interference with the real mode code or stack */
+    if (syslinux_add_memmap(&rxmap, 0, 1024 * 1024, SMT_RESERVED))
+	goto bail;
+    for (mp = fraglist; mp; mp = mp->next) {
+	if (syslinux_add_memmap(&rxmap, mp->src, mp->len, SMT_ALLOC) ||
+	    syslinux_add_memmap(&rxmap, mp->dst, mp->len, SMT_ALLOC))
+	    goto bail;
+    }
+    if (syslinux_memmap_largest(rxmap, SMT_FREE, &desczone, &descfree))
+	goto bail;
+
+    syslinux_free_memmap(rxmap);
+
+    dprintf("desczone = 0x%08x, descfree = 0x%08x\n", desczone, descfree);
+
+    rxmap = syslinux_dup_memmap(memmap);
+    if (!rxmap)
+	goto bail;
+
+    desc_blocks = (nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE;
+    for (;;) {
+	/* We want (desc_blocks) allocation blocks, plus the terminating
+	   descriptor, plus the shuffler safe area. */
+	addr_t descmem = desc_blocks *
+	    sizeof(struct shuffle_descriptor) * DESC_BLOCK_SIZE
+	    + sizeof(struct shuffle_descriptor)
+	    + syslinux_shuffler_size();
+
+	descaddr = (desczone + descfree - descmem) & ~3;
+
+	if (descaddr < desczone)
+	    goto bail;		/* No memory block large enough */
+
+	/* Mark memory used by shuffle descriptors as reserved */
+	if (syslinux_add_memmap(&rxmap, descaddr, descmem, SMT_RESERVED))
+	    goto bail;
+
+#if DEBUG > 1
+	syslinux_dump_movelist(fraglist);
+#endif
+
+	if (syslinux_compute_movelist(&moves, fraglist, rxmap))
+	    goto bail;
+
+	nmoves = 0;
+	for (mp = moves; mp; mp = mp->next)
+	    nmoves++;
+
+	need_blocks = (nmoves + nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE;
+
+	if (desc_blocks >= need_blocks)
+	    break;		/* Sufficient memory, yay */
+
+	desc_blocks = need_blocks;	/* Try again... */
+    }
+
+#if DEBUG > 1
+    dprintf("Final movelist:\n");
+    syslinux_dump_movelist(moves);
+#endif
+
+    syslinux_free_memmap(rxmap);
+    rxmap = NULL;
+
+    need_ptrs = nmoves + nzero + 1;
+    dbuf = malloc(need_ptrs * sizeof(struct shuffle_descriptor));
+    if (!dbuf)
+	goto bail;
+
+#if DEBUG
+    {
+	addr_t descoffs = descaddr - (addr_t) dbuf;
+
+	dprintf("nmoves = %d, nzero = %d, dbuf = %p, offs = 0x%08x\n",
+		nmoves, nzero, dbuf, descoffs);
+    }
+#endif
+
+    /* Copy the move sequence into the descriptor buffer */
+    np = 0;
+    dp = dbuf;
+    for (mp = moves; mp; mp = mp->next) {
+	dp->dst = mp->dst;
+	dp->src = mp->src;
+	dp->len = mp->len;
+	dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
+	dp++;
+	np++;
+    }
+
+    /* Copy bzero operations into the descriptor buffer */
+    for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
+	if (ml->type == SMT_ZERO) {
+	    dp->dst = ml->start;
+	    dp->src = (addr_t) - 1;	/* bzero region */
+	    dp->len = ml->next->start - ml->start;
+	    dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
+	    dp++;
+	    np++;
+	}
+    }
+
+    /* Finally, record the termination entry */
+    dp->dst = entry_point;
+    dp->src = entry_type;
+    dp->len = 0;
+    dp++;
+    np++;
+
+    if (np != need_ptrs) {
+	dprintf("!!! np = %d : nmoves = %d, nzero = %d, desc_blocks = %d\n",
+		np, nmoves, nzero, desc_blocks);
+    }
+
+    rv = 0;
+
+bail:
+    /* This is safe only because free() doesn't use the bounce buffer!!!! */
+    if (moves)
+	syslinux_free_movelist(moves);
+    if (rxmap)
+	syslinux_free_memmap(rxmap);
+
+    if (rv)
+	return rv;
+
+    /* Actually do it... */
+    bios_do_shuffle_and_boot(bootflags, descaddr, dbuf,
+			     (size_t)dp - (size_t)dbuf);
+
+    return -1;			/* Shouldn't have returned! */
+}
+
+/*
+ * Common helper routine: takes a memory map and blots out the
+ * zones which are used in the destination of a fraglist
+ */
+struct syslinux_memmap *syslinux_target_memmap(struct syslinux_movelist
+					       *fraglist,
+					       struct syslinux_memmap *memmap)
+{
+    struct syslinux_memmap *tmap;
+    struct syslinux_movelist *mp;
+
+    tmap = syslinux_dup_memmap(memmap);
+    if (!tmap)
+	return NULL;
+
+    for (mp = fraglist; mp; mp = mp->next) {
+	if (syslinux_add_memmap(&tmap, mp->dst, mp->len, SMT_ALLOC)) {
+	    syslinux_free_memmap(tmap);
+	    return NULL;
+	}
+    }
+
+    return tmap;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_pm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_pm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_pm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle_pm.c
+ *
+ * Shuffle and boot to protected mode code
+ */
+
+#include <inttypes.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist,
+			     struct syslinux_memmap *memmap,
+			     uint16_t bootflags, struct syslinux_pm_regs *regs)
+{
+    uint8_t handoff_code[9 * 5], *p;
+    const uint32_t *rp;
+    int i, rv;
+    struct syslinux_memmap *tmap;
+    addr_t regstub, stublen;
+
+    tmap = syslinux_target_memmap(fraglist, memmap);
+    if (!tmap)
+	return -1;
+
+    regstub = 0x800;		/* Locate anywhere above this point */
+    stublen = sizeof handoff_code;
+    rv = syslinux_memmap_find_type(tmap, SMT_FREE, &regstub, &stublen, 1);
+    syslinux_free_memmap(tmap);
+    if (rv)
+	return -1;
+
+    /* Build register-setting stub */
+    p = handoff_code;
+    rp = (const uint32_t *)regs;
+    for (i = 0; i < 8; i++) {
+	*p = 0xb8 + i;		/* MOV gpr,imm32 */
+	*(uint32_t *) (p + 1) = *rp++;
+	p += 5;
+    }
+    *p = 0xe9;			/* JMP */
+    *(uint32_t *) (p + 1) = regs->eip - regstub - sizeof handoff_code;
+
+    /* Add register-setting stub to shuffle list */
+    if (syslinux_add_movelist(&fraglist, regstub, (addr_t) handoff_code,
+			      sizeof handoff_code))
+	return -1;
+
+    return syslinux_do_shuffle(fraglist, memmap, regstub, 1, bootflags);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_rm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_rm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/shuffle_rm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,171 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * shuffle_rm.c
+ *
+ * Shuffle and boot to protected mode code
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <com32.h>
+#include <string.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootrm.h>
+
+enum gpr_index { R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI };
+enum seg_index { R_ES, R_CS, R_SS, R_DS, R_FS, R_GS };
+
+#define ST8(P,V)						\
+  do {								\
+    uint8_t *_p = (void *)(P);					\
+    *_p++ = (V);						\
+    (P) = (void *)_p;						\
+  } while (0);
+#define ST16(P,V)						\
+  do {								\
+    uint16_t *_p = (void *)(P);					\
+    *_p++ = (V);						\
+    (P) = (void *)_p;						\
+  } while (0)
+#define ST32(P,V)						\
+  do {								\
+    uint32_t *_p = (void *)(P);					\
+    *_p++ = (V);						\
+    (P) = (void *)_p;						\
+  } while (0)
+
+#define MOV_TO_SEG(P,S,R)					\
+    ST16(P, 0xc08e + ((R) << 8) + ((S) << 11))
+#define MOV_TO_R16(P,R,V)					\
+  do {								\
+    ST8(P, 0xb8 + (R));						\
+    ST16(P, V);							\
+  }  while (0)
+#define MOV_TO_R32(P,R,V)					\
+  do {								\
+    ST16(P, 0xb866 + ((R) << 8));				\
+    ST32(P, V);							\
+  } while (0)
+
+int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist,
+			     struct syslinux_memmap *memmap,
+			     uint16_t bootflags, struct syslinux_rm_regs *regs)
+{
+    const struct syslinux_rm_regs_alt {
+	uint16_t seg[6];
+	uint32_t gpr[8];
+	uint32_t csip;
+	bool sti;
+    } *rp;
+    int i, rv;
+    uint8_t handoff_code[8 + 5 * 5 + 8 * 6 + 1 + 5], *p;
+    uint16_t off;
+    struct syslinux_memmap *tmap;
+    addr_t regstub, stublen;
+    /* Assign GPRs for each sreg, don't use AX and SP */
+    static const uint8_t gpr_for_seg[6] =
+	{ R_CX, R_DX, R_BX, R_BP, R_SI, R_DI };
+
+    tmap = syslinux_target_memmap(fraglist, memmap);
+    if (!tmap)
+	return -1;
+
+    /*
+     * Search for a good place to put the real-mode register stub.
+     * We prefer it as low as possible above 0x800.  KVM barfs horribly
+     * if we're not aligned to a paragraph boundary, so set the alignment
+     * appropriately.
+     */
+    regstub = 0x800;
+    stublen = sizeof handoff_code;
+    rv = syslinux_memmap_find_type(tmap, SMT_FREE, &regstub, &stublen, 16);
+
+    if (rv || (regstub > 0x100000 - sizeof handoff_code)) {
+	/*
+	 * Uh-oh.  This isn't real-mode accessible memory.
+	 * It might be possible to do something insane here like
+	 * putting the stub in the IRQ vectors, or in the 0x5xx segment.
+	 * This code tries the 0x510-0x7ff range and hopes for the best.
+	 */
+	regstub = 0x510;	/* Try the 0x5xx segment... */
+	stublen = sizeof handoff_code;
+	rv = syslinux_memmap_find_type(tmap, SMT_FREE, &regstub, &stublen, 16);
+
+	if (!rv && (regstub > 0x100000 - sizeof handoff_code))
+	    rv = -1;		/* No acceptable memory found */
+    }
+
+    syslinux_free_memmap(tmap);
+    if (rv)
+	return -1;
+
+    /* Build register-setting stub */
+    p = handoff_code;
+    rp = (const struct syslinux_rm_regs_alt *)regs;
+
+    /* Set up GPRs with segment registers - don't use AX */
+    for (i = 0; i < 6; i++) {
+	if (i != R_CS)
+	    MOV_TO_R16(p, gpr_for_seg[i], rp->seg[i]);
+    }
+
+    /* Actual transition to real mode */
+    ST32(p, 0xeac0220f);	/* MOV CR0,EAX; JMP FAR */
+    off = (p - handoff_code) + 4;
+    ST16(p, off);		/* Offset */
+    ST16(p, regstub >> 4);	/* Segment */
+
+    /* Load SS and ESP immediately */
+    MOV_TO_SEG(p, R_SS, R_BX);
+    MOV_TO_R32(p, R_SP, rp->gpr[R_SP]);
+
+    /* Load the other segments */
+    MOV_TO_SEG(p, R_ES, R_CX);
+    MOV_TO_SEG(p, R_DS, R_BP);
+    MOV_TO_SEG(p, R_FS, R_SI);
+    MOV_TO_SEG(p, R_GS, R_DI);
+
+    for (i = 0; i < 8; i++) {
+	if (i != R_SP)
+	    MOV_TO_R32(p, i, rp->gpr[i]);
+    }
+
+    ST8(p, rp->sti ? 0xfb : 0xfa);	/* STI/CLI */
+
+    ST8(p, 0xea);		/* JMP FAR */
+    ST32(p, rp->csip);
+
+    /* Add register-setting stub to shuffle list */
+    if (syslinux_add_movelist(&fraglist, regstub, (addr_t) handoff_code,
+			      sizeof handoff_code))
+	return -1;
+
+    return syslinux_do_shuffle(fraglist, memmap, regstub, 0, bootflags);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/version.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/version.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/version.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/config.h>
+#include <klibc/compiler.h>
+#include <core.h>
+#include <version.h>
+
+struct syslinux_version __syslinux_version;
+
+void __constructor __syslinux_get_version(void)
+{
+    __syslinux_version.version = (VERSION_MAJOR << 8) + VERSION_MINOR;
+
+    /* We no longer support the COMBOOT API  */
+    __syslinux_version.max_api = 0xffff;
+
+    __syslinux_version.filesystem = syslinux_filesystem();
+
+    /* Skip leading CR LF */
+    __syslinux_version.version_string = &syslinux_banner[2];
+
+    /* Skip leading space */
+    __syslinux_version.copyright_string = &copyright_str[1];
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/fontquery.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/fontquery.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/fontquery.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/forcetext.c
+ */
+
+#include <syslinux/video.h>
+#include <graphics.h>
+
+/*
+ * Returns height of font or zero if no custom font loaded
+ */
+int syslinux_font_query(uint8_t **font)
+{
+    if (!UserFont)
+	return 0;
+
+    *font = (uint8_t *)fontbuf;
+
+    return VGAFontSize;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/reportmode.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/reportmode.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/video/reportmode.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/video/reportmode.c
+ */
+
+#include <syslinux/video.h>
+#include <graphics.h>
+
+void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize)
+{
+    if (flags > 0x0f)
+	return;
+
+    using_vga(flags, xsize, ysize);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zloadfile.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zloadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zloadfile.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * zloadfile.c
+ *
+ * Read the contents of a possibly compressed data file into a malloc'd buffer
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <syslinux/zio.h>
+
+#include <syslinux/loadfile.h>
+
+#define INCREMENTAL_CHUNK 1024*1024
+
+int zloadfile(const char *filename, void **ptr, size_t * len)
+{
+    FILE *f;
+    int rv;
+
+    f = zfopen(filename, "r");
+    if (!f)
+	return -1;
+
+    rv = floadfile(f, ptr, len, NULL, 0);
+    fclose(f);
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zonelist.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zonelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/syslinux/zonelist.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,402 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * zonelist.c
+ *
+ * Deal with syslinux_memmap's, which are data structures designed to
+ * hold memory maps.  A zonelist is a sorted linked list of memory
+ * ranges, with the guarantee that no two adjacent blocks have the
+ * same range type.  Additionally, all unspecified memory have a range
+ * type of zero.
+ */
+
+#include <stdlib.h>
+#include <syslinux/align.h>
+#include <syslinux/movebits.h>
+#include <dprintf.h>
+
+/*
+ * Create an empty syslinux_memmap list.
+ */
+struct syslinux_memmap *syslinux_init_memmap(void)
+{
+    struct syslinux_memmap *sp, *ep;
+
+    sp = malloc(sizeof(*sp));
+    if (!sp)
+	return NULL;
+
+    ep = malloc(sizeof(*ep));
+    if (!ep) {
+	free(sp);
+	return NULL;
+    }
+
+    sp->start = 0;
+    sp->type = SMT_UNDEFINED;
+    sp->next = ep;
+
+    ep->start = 0;		/* Wrap around... */
+    ep->type = SMT_END;		/* End of chain */
+    ep->next = NULL;
+
+    return sp;
+}
+
+/*
+ * Add an item to a syslinux_memmap list, potentially overwriting
+ * what is already there.
+ */
+int syslinux_add_memmap(struct syslinux_memmap **list,
+			addr_t start, addr_t len,
+			enum syslinux_memmap_types type)
+{
+    addr_t last;
+    struct syslinux_memmap *mp, **mpp;
+    struct syslinux_memmap *range;
+    enum syslinux_memmap_types oldtype;
+
+    dprintf("Input memmap:\n");
+    syslinux_dump_memmap(*list);
+
+    /* Remove this to make len == 0 mean all of memory */
+    if (len == 0)
+	return 0;
+
+    /* Last byte -- to avoid rollover */
+    last = start + len - 1;
+
+    mpp = list;
+    oldtype = SMT_END;		/* Impossible value */
+    while (mp = *mpp, start > mp->start && mp->type != SMT_END) {
+	oldtype = mp->type;
+	mpp = &mp->next;
+    }
+
+    if (start < mp->start || mp->type == SMT_END) {
+	if (type != oldtype) {
+	    /* Splice in a new start token */
+	    range = malloc(sizeof(*range));
+	    if (!range)
+		return -1;
+
+	    range->start = start;
+	    range->type = type;
+	    *mpp = range;
+	    range->next = mp;
+	    mpp = &range->next;
+	}
+    } else {
+	/* mp is exactly aligned with the start of our region */
+	if (type != oldtype) {
+	    /* Reclaim this entry as our own boundary marker */
+	    oldtype = mp->type;
+	    mp->type = type;
+	    mpp = &mp->next;
+	}
+    }
+
+    while (mp = *mpp, last > mp->start - 1) {
+	oldtype = mp->type;
+	*mpp = mp->next;
+	free(mp);
+    }
+
+    if (last < mp->start - 1) {
+	if (oldtype != type) {
+	    /* Need a new end token */
+	    range = malloc(sizeof(*range));
+	    if (!range)
+		return -1;
+
+	    range->start = last + 1;
+	    range->type = oldtype;
+	    *mpp = range;
+	    range->next = mp;
+	}
+    } else {
+	if (mp->type == type) {
+	    /* Merge this region with the following one */
+	    *mpp = mp->next;
+	    free(mp);
+	}
+    }
+
+    dprintf("After adding (%#x,%#x,%d):\n", start, len, type);
+    syslinux_dump_memmap(*list);
+
+    return 0;
+}
+
+/*
+ * Verify what type a certain memory region is.  This function returns
+ * SMT_ERROR if the memory region has multiple types, except that
+ * SMT_FREE can be demoted to SMT_TERMINAL.
+ */
+enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list,
+						addr_t start, addr_t len)
+{
+    addr_t last, llast;
+
+    last = start + len - 1;
+
+    while (list->type != SMT_END) {
+	llast = list->next->start - 1;
+	if (list->start <= start) {
+	    if (llast >= last) {
+		return list->type;	/* Region has a well-defined type */
+	    } else if (llast >= start) {
+		/* Crosses region boundary */
+		while (valid_terminal_type(list->type)) {
+		    list = list->next;
+		    llast = list->next->start - 1;
+		    if (llast >= last)
+			return SMT_TERMINAL;
+		}
+		return SMT_ERROR;
+	    }
+	}
+	list = list->next;
+    }
+
+    return SMT_ERROR;		/* Internal error? */
+}
+
+/*
+ * Find the largest zone of a specific type.  Returns -1 on failure.
+ */
+int syslinux_memmap_largest(struct syslinux_memmap *list,
+			    enum syslinux_memmap_types type,
+			    addr_t * start, addr_t * len)
+{
+    addr_t size, best_size = 0;
+    struct syslinux_memmap *best = NULL;
+
+    while (list->type != SMT_END) {
+	size = list->next->start - list->start;
+
+	if (list->type == type && size > best_size) {
+	    best = list;
+	    best_size = size;
+	}
+
+	list = list->next;
+    }
+
+    if (!best)
+	return -1;
+
+    *start = best->start;
+    *len = best_size;
+
+    return 0;
+}
+
+/*
+ * Find the highest zone of a specific type that satisfies the
+ * constraints.
+ *
+ * 'start' is updated with the highest address on success. 'start' can
+ * be used to set a minimum address to begin searching from.
+ *
+ * Returns -1 on failure.
+ */
+int syslinux_memmap_highest(const struct syslinux_memmap *list,
+			    enum syslinux_memmap_types type,
+			    addr_t *start, addr_t len,
+			    addr_t ceiling, addr_t align)
+{
+    addr_t size, best;
+
+    for (best = 0; list->type != SMT_END; list = list->next) {
+	size = list->next->start - list->start;
+
+	if (list->type != type)
+	    continue;
+
+	if (list->start + size <= *start)
+	    continue;
+
+	if (list->start + len >= ceiling)
+	    continue;
+
+	if (list->start + size < ceiling)
+	    best = ALIGN_DOWN(list->start + size - len, align);
+	else
+	    best = ALIGN_DOWN(ceiling - len, align);
+
+	if (best < *start)
+	    best = 0;
+    }
+
+    if (!best)
+	return -1;
+
+    *start = best;
+
+    return 0;
+}
+
+/*
+ * Find the first (lowest address) zone of a specific type and of
+ * a certain minimum size, with an optional starting address.
+ * The input values of start and len are used as minima.
+ */
+int syslinux_memmap_find_type(struct syslinux_memmap *list,
+			      enum syslinux_memmap_types type,
+			      addr_t * start, addr_t * len, addr_t align)
+{
+    addr_t min_start = *start;
+    addr_t min_len = *len;
+
+    while (list->type != SMT_END) {
+	if (list->type == type) {
+	    addr_t xstart, xlen;
+	    xstart = min_start > list->start ? min_start : list->start;
+	    xstart = ALIGN_UP(xstart, align);
+
+	    if (xstart < list->next->start) {
+		xlen = list->next->start - xstart;
+		if (xlen >= min_len) {
+		    *start = xstart;
+		    *len = xlen;
+		    return 0;
+		}
+	    }
+	}
+	list = list->next;
+    }
+
+    return -1;			/* Not found */
+}
+
+/*
+ * Free a zonelist.
+ */
+void syslinux_free_memmap(struct syslinux_memmap *list)
+{
+    struct syslinux_memmap *ml;
+
+    while (list) {
+	ml = list;
+	list = list->next;
+	free(ml);
+    }
+}
+
+/*
+ * Duplicate a zonelist.  Returns NULL on failure.
+ */
+struct syslinux_memmap *syslinux_dup_memmap(struct syslinux_memmap *list)
+{
+    struct syslinux_memmap *newlist = NULL, **nlp = &newlist;
+    struct syslinux_memmap *ml;
+
+    while (list) {
+	ml = malloc(sizeof(*ml));
+	if (!ml) {
+	    syslinux_free_memmap(newlist);
+	    return NULL;
+	}
+	ml->start = list->start;
+	ml->type = list->type;
+	ml->next = NULL;
+	*nlp = ml;
+	nlp = &ml->next;
+
+	list = list->next;
+    }
+
+    return newlist;
+}
+
+/*
+ * Find a memory region, given a set of heuristics and update 'base' if
+ * successful.
+ */
+int syslinux_memmap_find(struct syslinux_memmap *mmap,
+			 addr_t *base, size_t size,
+			 bool relocate, size_t align,
+			 addr_t start_min, addr_t start_max,
+			 addr_t end_min, addr_t end_max)
+{
+    const struct syslinux_memmap *mp;
+    enum syslinux_memmap_types type;
+    bool ok;
+
+    if (!size)
+	return 0;
+
+    type = syslinux_memmap_type(mmap, *base, size);
+
+    /* This assumes SMT_TERMINAL is OK if we can get the exact address */
+    if (valid_terminal_type(type))
+	return 0;
+
+    if (!relocate) {
+	dprintf("Cannot relocate\n");
+	return -1;
+    }
+
+    ok = false;
+    for (mp = mmap; mp && mp->type != SMT_END; mp = mp->next) {
+	addr_t start, end;
+	start = mp->start;
+	end = mp->next->start;
+
+	if (mp->type != SMT_FREE)
+	    continue;
+
+	/* min */
+	if (end <= end_min)
+	    continue;	/* Only relocate upwards */
+
+	if (start < start_min)
+	    start = start_min;
+
+	/* max */
+	if (end > end_max)
+	    end = end_max;
+
+	start = ALIGN_UP(start, align);
+	if (start > start_max || start >= end)
+	    continue;
+
+	if (end - start >= size) {
+	    *base = start;
+	    ok = true;
+	    break;
+	}
+    }
+
+    if (!ok)
+	return -1;
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vasprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vasprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vasprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+/*
+ * vasprintf.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+int vasprintf(char **bufp, const char *format, va_list ap)
+{
+    va_list ap1;
+    int bytes;
+    char *p;
+
+    va_copy(ap1, ap);
+
+    bytes = vsnprintf(NULL, 0, format, ap1) + 1;
+    va_end(ap1);
+
+    *bufp = p = malloc(bytes);
+    if (!p)
+	return -1;
+
+    return vsnprintf(p, bytes, format, ap);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vdprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vdprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vdprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,111 @@
+/*
+ * vdprintf.c
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+
+#ifdef DEBUG_PORT
+
+#define BUFFER_SIZE	4096
+
+enum serial_port_regs {
+    THR = 0,
+    RBR = 0,
+    DLL = 0,
+    DLM = 1,
+    IER = 1,
+    IIR = 2,
+    FCR = 2,
+    LCR = 3,
+    MCR = 4,
+    LSR = 5,
+    MSR = 6,
+    SCR = 7,
+};
+
+static const uint16_t debug_base = DEBUG_PORT;
+
+static void debug_putc(char c)
+{
+    if (c == '\n')
+	debug_putc('\r');
+
+    while ((inb(debug_base + LSR) & 0x20) == 0)
+	cpu_relax();
+    outb(c, debug_base + THR);
+}
+
+void vdprintf(const char *format, va_list ap)
+{
+    int rv;
+    char buffer[BUFFER_SIZE];
+    char *p;
+    static bool debug_init = false;
+    static bool debug_ok   = false;
+
+    rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
+    if (rv < 0)
+	return;
+
+    if (rv > BUFFER_SIZE - 1)
+	rv = BUFFER_SIZE - 1;
+
+    /*
+     * This unconditionally outputs to a serial port at 0x3f8 regardless of
+     * if one is enabled or not (this means we don't have to enable the real
+     * serial console and therefore get conflicting output.)
+     */
+    if (__unlikely(!debug_init)) {
+	uint8_t dll, dlm, lcr;
+
+	debug_init = true;
+
+	cli();
+
+	/* Initialize the serial port to 115200 n81 with FIFOs enabled */
+	outb(0x83, debug_base + LCR);
+	outb(0x01, debug_base + DLL);
+	outb(0x00, debug_base + DLM);
+	(void)inb(debug_base + IER);	/* Synchronize */
+	dll = inb(debug_base + DLL);
+	dlm = inb(debug_base + DLM);
+	lcr = inb(debug_base + LCR);
+	
+	outb(0x03, debug_base + LCR);
+	(void)inb(debug_base + IER);	/* Synchronize */
+
+	outb(0x00, debug_base + IER);
+	(void)inb(debug_base + IER);	/* Synchronize */
+
+	sti();
+
+	if (dll != 0x01 || dlm != 0x00 || lcr != 0x83) {
+	    /* No serial port present */
+	    return;
+	}
+
+	outb(0x01, debug_base + FCR);
+	(void)inb(debug_base + IER);	/* Synchronize */
+	if (inb(debug_base + IIR) < 0xc0) {
+	    outb(0x00, debug_base + FCR); /* Disable non-functional FIFOs */
+	    (void)inb(debug_base + IER);	/* Synchronize */
+	}
+
+	debug_ok = true;
+    }
+
+    if (!debug_ok)
+	return;
+
+    p = buffer;
+    while (rv--)
+	debug_putc(*p++);
+}
+
+#endif /* DEBUG_PORT */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vfprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vfprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vfprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/*
+ * vfprintf.c
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#define BUFFER_SIZE	32768
+
+int vfprintf(FILE * file, const char *format, va_list ap)
+{
+    int rv;
+    char buffer[BUFFER_SIZE];
+
+    rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
+
+    if (rv < 0)
+	return rv;
+
+    if (rv > BUFFER_SIZE - 1)
+	rv = BUFFER_SIZE - 1;
+
+    return _fwrite(buffer, rv, file);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * vprintf.c
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int vprintf(const char *format, va_list ap)
+{
+    return vfprintf(stdout, format, ap);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vsnprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vsnprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vsnprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,454 @@
+/*
+ * vsnprintf.c
+ *
+ * vsnprintf(), from which the rest of the printf()
+ * family is built
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+enum flags {
+    FL_ZERO = 0x01,		/* Zero modifier */
+    FL_MINUS = 0x02,		/* Minus modifier */
+    FL_PLUS = 0x04,		/* Plus modifier */
+    FL_TICK = 0x08,		/* ' modifier */
+    FL_SPACE = 0x10,		/* Space modifier */
+    FL_HASH = 0x20,		/* # modifier */
+    FL_SIGNED = 0x40,		/* Number is signed */
+    FL_UPPER = 0x80		/* Upper case digits */
+};
+
+/* These may have to be adjusted on certain implementations */
+enum ranks {
+    rank_char = -2,
+    rank_short = -1,
+    rank_int = 0,
+    rank_long = 1,
+    rank_longlong = 2
+};
+
+#define MIN_RANK	rank_char
+#define MAX_RANK	rank_longlong
+
+#define INTMAX_RANK	rank_longlong
+#define SIZE_T_RANK	rank_long
+#define PTRDIFF_T_RANK	rank_long
+
+#define EMIT(x) ({ if (o<n){*q++ = (x);} o++; })
+
+static size_t
+format_int(char *q, size_t n, uintmax_t val, enum flags flags,
+	   int base, int width, int prec)
+{
+    char *qq;
+    size_t o = 0, oo;
+    static const char lcdigits[] = "0123456789abcdef";
+    static const char ucdigits[] = "0123456789ABCDEF";
+    const char *digits;
+    uintmax_t tmpval;
+    int minus = 0;
+    int ndigits = 0, nchars;
+    int tickskip, b4tick;
+
+    /* Select type of digits */
+    digits = (flags & FL_UPPER) ? ucdigits : lcdigits;
+
+    /* If signed, separate out the minus */
+    if (flags & FL_SIGNED && (intmax_t) val < 0) {
+	minus = 1;
+	val = (uintmax_t) (-(intmax_t) val);
+    }
+
+    /* Count the number of digits needed.  This returns zero for 0. */
+    tmpval = val;
+    while (tmpval) {
+	tmpval /= base;
+	ndigits++;
+    }
+
+    /* Adjust ndigits for size of output */
+
+    if (flags & FL_HASH && base == 8) {
+	if (prec < ndigits + 1)
+	    prec = ndigits + 1;
+    }
+
+    if (ndigits < prec) {
+	ndigits = prec;		/* Mandatory number padding */
+    } else if (val == 0) {
+	ndigits = 1;		/* Zero still requires space */
+    }
+
+    /* For ', figure out what the skip should be */
+    if (flags & FL_TICK) {
+	tickskip = (base == 16) ? 4 : 3;
+    } else {
+	tickskip = ndigits;	/* No tick marks */
+    }
+
+    /* Tick marks aren't digits, but generated by the number converter */
+    ndigits += (ndigits - 1) / tickskip;
+
+    /* Now compute the number of nondigits */
+    nchars = ndigits;
+
+    if (minus || (flags & (FL_PLUS | FL_SPACE)))
+	nchars++;		/* Need space for sign */
+    if ((flags & FL_HASH) && base == 16) {
+	nchars += 2;		/* Add 0x for hex */
+    }
+
+    /* Emit early space padding */
+    if (!(flags & (FL_MINUS | FL_ZERO)) && width > nchars) {
+	while (width > nchars) {
+	    EMIT(' ');
+	    width--;
+	}
+    }
+
+    /* Emit nondigits */
+    if (minus)
+	EMIT('-');
+    else if (flags & FL_PLUS)
+	EMIT('+');
+    else if (flags & FL_SPACE)
+	EMIT(' ');
+
+    if ((flags & FL_HASH) && base == 16) {
+	EMIT('0');
+	EMIT((flags & FL_UPPER) ? 'X' : 'x');
+    }
+
+    /* Emit zero padding */
+    if ((flags & (FL_MINUS | FL_ZERO)) == FL_ZERO && width > ndigits) {
+	while (width > nchars) {
+	    EMIT('0');
+	    width--;
+	}
+    }
+
+    /* Generate the number.  This is done from right to left. */
+    q += ndigits;		/* Advance the pointer to end of number */
+    o += ndigits;
+    qq = q;
+    oo = o;			/* Temporary values */
+
+    b4tick = tickskip;
+    while (ndigits > 0) {
+	if (!b4tick--) {
+	    qq--;
+	    oo--;
+	    ndigits--;
+	    if (oo < n)
+		*qq = '_';
+	    b4tick = tickskip - 1;
+	}
+	qq--;
+	oo--;
+	ndigits--;
+	if (oo < n)
+	    *qq = digits[val % base];
+	val /= base;
+    }
+
+    /* Emit late space padding */
+    while ((flags & FL_MINUS) && width > nchars) {
+	EMIT(' ');
+	width--;
+    }
+
+    return o;
+}
+
+int vsnprintf(char *buffer, size_t n, const char *format, va_list ap)
+{
+    const char *p = format;
+    char ch;
+    char *q = buffer;
+    size_t o = 0;		/* Number of characters output */
+    uintmax_t val = 0;
+    int rank = rank_int;	/* Default rank */
+    int width = 0;
+    int prec = -1;
+    int base;
+    size_t sz;
+    enum flags flags = 0;
+    enum {
+	st_normal,		/* Ground state */
+	st_flags,		/* Special flags */
+	st_width,		/* Field width */
+	st_prec,		/* Field precision */
+	st_modifiers		/* Length or conversion modifiers */
+    } state = st_normal;
+    const char *sarg;		/* %s string argument */
+    char carg;			/* %c char argument */
+    int slen;			/* String length */
+
+    while ((ch = *p++)) {
+	switch (state) {
+	case st_normal:
+	    if (ch == '%') {
+		state = st_flags;
+		flags = 0;
+		rank = rank_int;
+		width = 0;
+		prec = -1;
+	    } else {
+		EMIT(ch);
+	    }
+	    break;
+
+	case st_flags:
+	    switch (ch) {
+	    case '-':
+		flags |= FL_MINUS;
+		break;
+	    case '+':
+		flags |= FL_PLUS;
+		break;
+	    case '\'':
+		flags |= FL_TICK;
+		break;
+	    case ' ':
+		flags |= FL_SPACE;
+		break;
+	    case '#':
+		flags |= FL_HASH;
+		break;
+	    case '0':
+		flags |= FL_ZERO;
+		break;
+	    default:
+		state = st_width;
+		p--;		/* Process this character again */
+		break;
+	    }
+	    break;
+
+	case st_width:
+	    if (ch >= '0' && ch <= '9') {
+		width = width * 10 + (ch - '0');
+	    } else if (ch == '*') {
+		width = va_arg(ap, int);
+		if (width < 0) {
+		    width = -width;
+		    flags |= FL_MINUS;
+		}
+	    } else if (ch == '.') {
+		prec = 0;	/* Precision given */
+		state = st_prec;
+	    } else {
+		state = st_modifiers;
+		p--;		/* Process this character again */
+	    }
+	    break;
+
+	case st_prec:
+	    if (ch >= '0' && ch <= '9') {
+		prec = prec * 10 + (ch - '0');
+	    } else if (ch == '*') {
+		prec = va_arg(ap, int);
+		if (prec < 0)
+		    prec = -1;
+	    } else {
+		state = st_modifiers;
+		p--;		/* Process this character again */
+	    }
+	    break;
+
+	case st_modifiers:
+	    switch (ch) {
+		/* Length modifiers - nonterminal sequences */
+	    case 'h':
+		rank--;		/* Shorter rank */
+		break;
+	    case 'l':
+		rank++;		/* Longer rank */
+		break;
+	    case 'j':
+		rank = INTMAX_RANK;
+		break;
+	    case 'z':
+		rank = SIZE_T_RANK;
+		break;
+	    case 't':
+		rank = PTRDIFF_T_RANK;
+		break;
+	    case 'L':
+	    case 'q':
+		rank += 2;
+		break;
+	    default:
+		/* Output modifiers - terminal sequences */
+		state = st_normal;	/* Next state will be normal */
+		if (rank < MIN_RANK)	/* Canonicalize rank */
+		    rank = MIN_RANK;
+		else if (rank > MAX_RANK)
+		    rank = MAX_RANK;
+
+		switch (ch) {
+		case 'P':	/* Upper case pointer */
+		    flags |= FL_UPPER;
+		    /* fall through */
+		case 'p':	/* Pointer */
+		    base = 16;
+		    prec = (CHAR_BIT * sizeof(void *) + 3) / 4;
+		    flags |= FL_HASH;
+		    val = (uintmax_t) (uintptr_t) va_arg(ap, void *);
+		    goto is_integer;
+
+		case 'd':	/* Signed decimal output */
+		case 'i':
+		    base = 10;
+		    flags |= FL_SIGNED;
+		    switch (rank) {
+		    case rank_char:
+			/* Yes, all these casts are needed... */
+			val =
+			    (uintmax_t) (intmax_t) (signed char)va_arg(ap,
+								       signed
+								       int);
+			break;
+		    case rank_short:
+			val =
+			    (uintmax_t) (intmax_t) (signed short)va_arg(ap,
+									signed
+									int);
+			break;
+		    case rank_int:
+			val = (uintmax_t) (intmax_t) va_arg(ap, signed int);
+			break;
+		    case rank_long:
+			val = (uintmax_t) (intmax_t) va_arg(ap, signed long);
+			break;
+		    case rank_longlong:
+			val =
+			    (uintmax_t) (intmax_t) va_arg(ap, signed long long);
+			break;
+		    }
+		    goto is_integer;
+		case 'o':	/* Octal */
+		    base = 8;
+		    goto is_unsigned;
+		case 'u':	/* Unsigned decimal */
+		    base = 10;
+		    goto is_unsigned;
+		case 'X':	/* Upper case hexadecimal */
+		    flags |= FL_UPPER;
+		    /* fall through */
+		case 'x':	/* Hexadecimal */
+		    base = 16;
+		    goto is_unsigned;
+
+is_unsigned:
+		    switch (rank) {
+		    case rank_char:
+			val =
+			    (uintmax_t) (unsigned char)va_arg(ap, unsigned int);
+			break;
+		    case rank_short:
+			val =
+			    (uintmax_t) (unsigned short)va_arg(ap,
+							       unsigned int);
+			break;
+		    case rank_int:
+			val = (uintmax_t) va_arg(ap, unsigned int);
+			break;
+		    case rank_long:
+			val = (uintmax_t) va_arg(ap, unsigned long);
+			break;
+		    case rank_longlong:
+			val = (uintmax_t) va_arg(ap, unsigned long long);
+			break;
+		    }
+		    /* fall through */
+
+is_integer:
+		    sz = format_int(q, (o < n) ? n - o : 0, val, flags, base,
+				    width, prec);
+		    q += sz;
+		    o += sz;
+		    break;
+
+		case 'c':	/* Character */
+		    carg = (char)va_arg(ap, int);
+		    sarg = &carg;
+		    slen = 1;
+		    goto is_string;
+		case 's':	/* String */
+		    sarg = va_arg(ap, const char *);
+		    sarg = sarg ? sarg : "(null)";
+		    slen = strlen(sarg);
+		    goto is_string;
+
+is_string:
+		    {
+			char sch;
+			int i;
+
+			if (prec != -1 && slen > prec)
+			    slen = prec;
+
+			if (width > slen && !(flags & FL_MINUS)) {
+			    char pad = (flags & FL_ZERO) ? '0' : ' ';
+			    while (width > slen) {
+				EMIT(pad);
+				width--;
+			    }
+			}
+			for (i = slen; i; i--) {
+			    sch = *sarg++;
+			    EMIT(sch);
+			}
+			if (width > slen && (flags & FL_MINUS)) {
+			    while (width > slen) {
+				EMIT(' ');
+				width--;
+			    }
+			}
+		    }
+		    break;
+
+		case 'n':	/* Output the number of characters written */
+		    {
+			switch (rank) {
+			case rank_char:
+			    *va_arg(ap, signed char *) = o;
+			    break;
+			case rank_short:
+			    *va_arg(ap, signed short *) = o;
+			    break;
+			case rank_int:
+			    *va_arg(ap, signed int *) = o;
+			    break;
+			case rank_long:
+			    *va_arg(ap, signed long *) = o;
+			    break;
+			case rank_longlong:
+			    *va_arg(ap, signed long long *) = o;
+			    break;
+			}
+		    }
+		    break;
+
+		default:	/* Anything else, including % */
+		    EMIT(ch);
+		    break;
+		}
+	    }
+	}
+    }
+
+    /* Null-terminate the string */
+    if (o < n)
+	*q = '\0';		/* No overflow */
+    else if (n > 0)
+	buffer[n - 1] = '\0';	/* Overflow - terminate at end of buffer */
+
+    return o;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vsprintf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vsprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vsprintf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/*
+ * vsprintf.c
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+int vsprintf(char *buffer, const char *format, va_list ap)
+{
+    return vsnprintf(buffer, ~(size_t) 0, format, ap);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/vsscanf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/vsscanf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/vsscanf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,349 @@
+/*
+ * vsscanf.c
+ *
+ * vsscanf(), from which the rest of the scanf()
+ * family is built
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+#include <sys/bitops.h>
+
+#ifndef LONG_BIT
+#define LONG_BIT (CHAR_BIT*sizeof(long))
+#endif
+
+enum flags {
+    FL_SPLAT = 0x01,		/* Drop the value, do not assign */
+    FL_WIDTH = 0x02,		/* Field width specified */
+    FL_MINUS = 0x04,		/* Negative number */
+};
+
+enum ranks {
+    rank_char = -2,
+    rank_short = -1,
+    rank_int = 0,
+    rank_long = 1,
+    rank_longlong = 2,
+    rank_ptr = INT_MAX		/* Special value used for pointers */
+};
+
+#define MIN_RANK	rank_char
+#define MAX_RANK	rank_longlong
+
+#define INTMAX_RANK	rank_longlong
+#define SIZE_T_RANK	rank_long
+#define PTRDIFF_T_RANK	rank_long
+
+enum bail {
+    bail_none = 0,		/* No error condition */
+    bail_eof,			/* Hit EOF */
+    bail_err			/* Conversion mismatch */
+};
+
+int vsscanf(const char *buffer, const char *format, va_list ap)
+{
+    const char *p = format;
+    char ch;
+    const char *q = buffer;
+    const char *qq;
+    uintmax_t val = 0;
+    int rank = rank_int;	/* Default rank */
+    unsigned int width = UINT_MAX;
+    int base;
+    enum flags flags = 0;
+    enum {
+	st_normal,		/* Ground state */
+	st_flags,		/* Special flags */
+	st_width,		/* Field width */
+	st_modifiers,		/* Length or conversion modifiers */
+	st_match_init,		/* Initial state of %[ sequence */
+	st_match,		/* Main state of %[ sequence */
+	st_match_range,		/* After - in a %[ sequence */
+    } state = st_normal;
+    char *sarg = NULL;		/* %s %c or %[ string argument */
+    enum bail bail = bail_none;
+    int converted = 0;		/* Successful conversions */
+    unsigned long matchmap[((1 << CHAR_BIT) + (LONG_BIT - 1)) / LONG_BIT];
+    int matchinv = 0;		/* Is match map inverted? */
+    unsigned char range_start = 0;
+
+    while ((ch = *p++) && !bail) {
+	switch (state) {
+	case st_normal:
+	    if (ch == '%') {
+		state = st_flags;
+		flags = 0;
+		rank = rank_int;
+		width = UINT_MAX;
+	    } else if (isspace((unsigned char)ch)) {
+		q = skipspace(q);
+	    } else {
+		if (*q == ch)
+		    q++;
+		else
+		    bail = bail_err;	/* Match failure */
+	    }
+	    break;
+
+	case st_flags:
+	    switch (ch) {
+	    case '*':
+		flags |= FL_SPLAT;
+		break;
+	    case '0' ... '9':
+		width = (ch - '0');
+		state = st_width;
+		flags |= FL_WIDTH;
+		break;
+	    default:
+		state = st_modifiers;
+		p--;		/* Process this character again */
+		break;
+	    }
+	    break;
+
+	case st_width:
+	    if (ch >= '0' && ch <= '9') {
+		width = width * 10 + (ch - '0');
+	    } else {
+		state = st_modifiers;
+		p--;		/* Process this character again */
+	    }
+	    break;
+
+	case st_modifiers:
+	    switch (ch) {
+		/* Length modifiers - nonterminal sequences */
+	    case 'h':
+		rank--;		/* Shorter rank */
+		break;
+	    case 'l':
+		rank++;		/* Longer rank */
+		break;
+	    case 'j':
+		rank = INTMAX_RANK;
+		break;
+	    case 'z':
+		rank = SIZE_T_RANK;
+		break;
+	    case 't':
+		rank = PTRDIFF_T_RANK;
+		break;
+	    case 'L':
+	    case 'q':
+		rank = rank_longlong;	/* long double/long long */
+		break;
+
+	    default:
+		/* Output modifiers - terminal sequences */
+		state = st_normal;	/* Next state will be normal */
+		if (rank < MIN_RANK)	/* Canonicalize rank */
+		    rank = MIN_RANK;
+		else if (rank > MAX_RANK)
+		    rank = MAX_RANK;
+
+		switch (ch) {
+		case 'P':	/* Upper case pointer */
+		case 'p':	/* Pointer */
+#if 0				/* Enable this to allow null pointers by name */
+		    q = skipspace(q);
+		    if (!isdigit((unsigned char)*q)) {
+			static const char *const nullnames[] =
+			    { "null", "nul", "nil", "(null)", "(nul)", "(nil)",
+0 };
+			const char *const *np;
+
+			/* Check to see if it's a null pointer by name */
+			for (np = nullnames; *np; np++) {
+			    if (!strncasecmp(q, *np, strlen(*np))) {
+				val = (uintmax_t) ((void *)NULL);
+				goto set_integer;
+			    }
+			}
+			/* Failure */
+			bail = bail_err;
+			break;
+		    }
+		    /* else */
+#endif
+		    rank = rank_ptr;
+		    base = 0;
+		    goto scan_int;
+
+		case 'i':	/* Base-independent integer */
+		    base = 0;
+		    goto scan_int;
+
+		case 'd':	/* Decimal integer */
+		    base = 10;
+		    goto scan_int;
+
+		case 'o':	/* Octal integer */
+		    base = 8;
+		    goto scan_int;
+
+		case 'u':	/* Unsigned decimal integer */
+		    base = 10;
+		    goto scan_int;
+
+		case 'x':	/* Hexadecimal integer */
+		case 'X':
+		    base = 16;
+		    goto scan_int;
+
+		case 'n':	/* Number of characters consumed */
+		    val = (q - buffer);
+		    goto set_integer;
+
+scan_int:
+		    q = skipspace(q);
+		    if (!*q) {
+			bail = bail_eof;
+			break;
+		    }
+		    val = strntoumax(q, (char **)&qq, base, width);
+		    if (qq == q) {
+			bail = bail_err;
+			break;
+		    }
+		    q = qq;
+		    converted++;
+		    /* fall through */
+
+set_integer:
+		    if (!(flags & FL_SPLAT)) {
+			switch (rank) {
+			case rank_char:
+			    *va_arg(ap, unsigned char *) = (unsigned char)val;
+			    break;
+			case rank_short:
+			    *va_arg(ap, unsigned short *) = (unsigned short)val;
+			    break;
+			case rank_int:
+			    *va_arg(ap, unsigned int *) = (unsigned int)val;
+			    break;
+			case rank_long:
+			    *va_arg(ap, unsigned long *) = (unsigned long)val;
+			    break;
+			case rank_longlong:
+			    *va_arg(ap, unsigned long long *) =
+				(unsigned long long)val;
+			    break;
+			case rank_ptr:
+			    *va_arg(ap, void **) = (void *)(uintptr_t) val;
+			    break;
+			}
+		    }
+		    break;
+
+		case 'c':	/* Character */
+		    width = (flags & FL_WIDTH) ? width : 1;	/* Default width == 1 */
+		    sarg = va_arg(ap, char *);
+		    while (width--) {
+			if (!*q) {
+			    bail = bail_eof;
+			    break;
+			}
+			*sarg++ = *q++;
+		    }
+		    if (!bail)
+			converted++;
+		    break;
+
+		case 's':	/* String */
+		    {
+			char *sp;
+			sp = sarg = va_arg(ap, char *);
+			while (width-- && *q && !isspace((unsigned char)*q)) {
+			    *sp++ = *q++;
+			}
+			if (sarg != sp) {
+			    *sp = '\0';	/* Terminate output */
+			    converted++;
+			} else {
+			    bail = bail_eof;
+			}
+		    }
+		    break;
+
+		case '[':	/* Character range */
+		    sarg = va_arg(ap, char *);
+		    state = st_match_init;
+		    matchinv = 0;
+		    memset(matchmap, 0, sizeof matchmap);
+		    break;
+
+		case '%':	/* %% sequence */
+		    if (*q == '%')
+			q++;
+		    else
+			bail = bail_err;
+		    break;
+
+		default:	/* Anything else */
+		    bail = bail_err;	/* Unknown sequence */
+		    break;
+		}
+	    }
+	    break;
+
+	case st_match_init:	/* Initial state for %[ match */
+	    if (ch == '^' && !matchinv) {
+		matchinv = 1;
+	    } else {
+		range_start = (unsigned char)ch;
+		set_bit((unsigned char)ch, matchmap);
+		state = st_match;
+	    }
+	    break;
+
+	case st_match:		/* Main state for %[ match */
+	    if (ch == ']') {
+		goto match_run;
+	    } else if (ch == '-') {
+		state = st_match_range;
+	    } else {
+		range_start = (unsigned char)ch;
+		set_bit((unsigned char)ch, matchmap);
+	    }
+	    break;
+
+	case st_match_range:	/* %[ match after - */
+	    if (ch == ']') {
+		set_bit((unsigned char)'-', matchmap);	/* - was last character */
+		goto match_run;
+	    } else {
+		int i;
+		for (i = range_start; i <= (unsigned char)ch; i++)
+		    set_bit(i, matchmap);
+		state = st_match;
+	    }
+	    break;
+
+match_run:			/* Match expression finished */
+	    qq = q;
+	    while (width && *q
+		   && test_bit((unsigned char)*q, matchmap) ^ matchinv) {
+		*sarg++ = *q++;
+	    }
+	    if (q != qq) {
+		*sarg = '\0';
+		converted++;
+	    } else {
+		bail = *q ? bail_err : bail_eof;
+	    }
+	    break;
+	}
+    }
+
+    if (bail == bail_eof && !converted)
+	converted = -1;		/* Return EOF (-1) */
+
+    return converted;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/elf.ld
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/elf.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/elf.ld	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,173 @@
+/*
+ * Linker script for ELF dynamic loaded modules.
+ * This simply mirrors the 32bit linker script with minimal x86_64 changes
+ */
+
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0 + SIZEOF_HEADERS;
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash : { *(.hash) }
+  .gnu.hash  : { *(.gnu.hash) }	
+  .dynsym  : { *(.dynsym) }
+  .dynstr  : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+/* mouli: introduce alignment for various segments */
+  .rel.dyn       :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+    }
+  .rela.dyn  :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+    }
+  .rel.plt : { *(.rel.plt); }
+  .rela.plt : { *(.rela.plt) }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0x90909090
+  .plt : { *(.plt) }
+  .text :
+  {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    KEEP (*(.text.*personality*))
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0x90909090
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  . = ALIGN(4);
+  .preinit_array     :
+  {
+    KEEP (*(.preinit_array))
+  }
+  .ctors          :
+  {
+  	__ctors_start = .;
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*(.ctors_modinit))
+    KEEP (*(.ctors_modmain))
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array))
+	__ctors_end = .;
+  }
+  
+  .dtors          :
+  {
+  	__dtors_start = .;
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    KEEP (*(.dtors_modexit))
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+	__dtors_end = .;
+  }
+  
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) }
+  /*. = DATA_SEGMENT_RELRO_END (12, .); -> This gives a "invalid assignment to location counter" error */
+  .got.plt        : { *(.got.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    KEEP (*(.gnu.linkonce.d.*personality*))
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  PROVIDE (edata = .);
+  PROVIDE (_edata = .); 
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   /*. = ALIGN(. != 0 ? 32 / 8 : 1);*/
+   . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  . = ALIGN(32 / 8);
+  . = ALIGN(32 / 8);
+  PROVIDE (_end = .); 
+  PROVIDE (end = .);
+  /*. = DATA_SEGMENT_END (.); -> This gives a "invalid assignment to location counter" error */
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.eh_frame) }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/setjmp.S
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/x86_64/setjmp.S	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+#
+# arch/x86_64/setjmp.S
+#
+# setjmp/longjmp for the x86-64 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+#	%rbx
+#	%rsp (post-return)
+#	%rbp
+#	%r12
+#	%r13
+#	%r14
+#	%r15
+#	<return address>
+#
+
+	.text
+	.align 4
+	.globl setjmp
+	.type setjmp, @function
+setjmp:
+	pop  %rsi			# Return address, and adjust the stack
+	xorl %eax,%eax			# Return value
+	movq %rbx,(%rdi)
+	movq %rsp,8(%rdi)		# Post-return %rsp!
+	push %rsi			# Make the call/return stack happy
+	movq %rbp,16(%rdi)
+	movq %r12,24(%rdi)
+	movq %r13,32(%rdi)
+	movq %r14,40(%rdi)
+	movq %r15,48(%rdi)
+	movq %rsi,56(%rdi)		# Return address
+	ret
+
+	.size setjmp,.-setjmp
+
+	.text
+	.align 4
+	.globl longjmp
+	.type longjmp, @function
+longjmp:
+	movl %esi,%eax			# Return value (int)
+	movq (%rdi),%rbx
+	movq 8(%rdi),%rsp
+	movq 16(%rdi),%rbp
+	movq 24(%rdi),%r12
+	movq 32(%rdi),%r13
+	movq 40(%rdi),%r14
+	movq 48(%rdi),%r15
+	jmp *56(%rdi)
+
+	.size longjmp,.-longjmp
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/FAQ
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/FAQ	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/FAQ	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,366 @@
+
+                Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL.  See the
+    file win32/DLL_FAQ.txt in the zlib distribution.  Pointers to the
+    precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://marknelson.us/1997/01/01/zlib-engine/
+        * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+    Make sure that before the call of compress(), the length of the compressed
+    buffer is equal to the available size of the compressed buffer and not
+    zero.  For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+    Before making the call, make sure that avail_in and avail_out are not zero.
+    When setting the parameter flush equal to Z_FINISH, also make sure that
+    avail_out is big enough to allow processing all pending input.  Note that a
+    Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+    made with more input or output space.  A Z_BUF_ERROR may in fact be
+    unavoidable depending on how the functions are used, since it is not
+    possible to tell whether or not there is more output pending when
+    strm.avail_out returns with zero.  See http://zlib.net/zlib_how.html for a
+    heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h .  Examples of zlib usage are in the files example.c and
+    minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple package.
+    zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of zlib.
+    Please try to reproduce the problem with a small program and send the
+    corresponding source to us at zlib@gzip.org .  Do not send multi-megabyte
+    data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+    Not by itself, no.  See the directory contrib/minizip in the zlib
+    distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry.  You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    make clean
+    ./configure -s
+    make
+
+14. How do I install a shared zlib library on Unix?
+
+    After the above, then:
+
+    make install
+
+    However, many flavors of Unix come with a shared zlib already installed.
+    Before going to the trouble of compiling a shared version of zlib and
+    trying to install it, you may want to check if it's already there!  If you
+    can #include <zlib.h>, it's there.  The -lz option will probably link to
+    it.  You can check the version at the top of zlib.h or with the
+    ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+    Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+    http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+    generates an error such as:
+
+        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+        symbol __register_frame_info: referenced symbol not found
+
+    The symbol __register_frame_info is not part of zlib, it is generated by
+    the C compiler (cc or gcc).  You must recompile applications using zlib
+    which have this problem.  This problem is specific to Solaris.  See
+    http://www.sunfreeware.com for Solaris versions of zlib and applications
+    using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+    The compress and deflate functions produce data in the zlib format, which
+    is different and incompatible with the gzip format.  The gz* functions in
+    zlib on the other hand use the gzip format.  Both the zlib and gzip formats
+    use the same compressed data format internally, but have different headers
+    and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+    The gzip format was designed to retain the directory information about a
+    single file, such as the name and last modification date.  The zlib format
+    on the other hand was designed for in-memory and communication channel
+    applications, and has a much more compact header and trailer and uses a
+    faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+    You can request that deflate write the gzip format instead of the zlib
+    format using deflateInit2().  You can also request that inflate decode the
+    gzip format using inflateInit2().  Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+    Yes.  However any library routines that zlib uses and any application-
+    provided memory allocation routines must also be thread-safe.  zlib's gz*
+    functions use stdio library routines, and most of zlib's functions use the
+    library memory allocation routines by default.  zlib's *Init* functions
+    allow for the application to provide custom memory allocation routines.
+
+    Of course, you should only operate on any given zlib or gzip stream from a
+    single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+    Yes.  Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+    No.  Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+    what exactly do I need to do to meet that requirement?
+
+    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h.  In
+    particular, the final version number needs to be changed to "f", and an
+    identification string should be appended to ZLIB_VERSION.  Version numbers
+    x.x.x.f are reserved for modifications to zlib by others than the zlib
+    maintainers.  For example, if the version of the base zlib you are altering
+    is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+    ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3".  You can also
+    update the version strings in deflate.c and inftrees.c.
+
+    For altered source distributions, you should also note the origin and
+    nature of the changes in zlib.h, as well as in ChangeLog and README, along
+    with the dates of the alterations.  The origin should include at least your
+    name (or your company's name), and an email address to contact for help or
+    issues with the library.
+
+    Note that distributing a compiled zlib library along with zlib.h and
+    zconf.h is also a source distribution, and so you should change
+    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+    in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+    exchange compressed data between them?
+
+    Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+    Yes.  It has been tested on 64-bit machines, and has no dependence on any
+    data types being limited to 32-bits in length.  If you have any
+    difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+    No.  The PKWare DCL uses a completely different compressed data format than
+    does PKZIP and zlib.  However, you can look in zlib's contrib/blast
+    directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+    No, not without some preparation.  If when compressing you periodically use
+    Z_FULL_FLUSH, carefully write all the pending data at those points, and
+    keep an index of those locations, then you can start decompression at those
+    points.  You have to be careful to not use Z_FULL_FLUSH too often, since it
+    can significantly degrade compression.  Alternatively, you can scan a
+    deflate stream once to generate an index, and then use that index for
+    random access.  See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+    It has in the past, but we have not heard of any recent evidence.  There
+    were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+    If you know of recent, successful applications of zlib on these operating
+    systems, please let us know.  Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+    understand the deflate format?
+
+    First off, you should read RFC 1951.  Second, yes.  Look in zlib's
+    contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+    As far as we know, no.  In fact, that was originally the whole point behind
+    zlib.  Look here for some more information:
+
+    http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+    Yes.  inflate() and deflate() will process any amount of data correctly.
+    Each call of inflate() or deflate() is limited to input and output chunks
+    of the maximum value that can be stored in the compiler's "unsigned int"
+    type, but there is no limit to the number of chunks.  Note however that the
+    strm.total_in and strm_total_out counters may be limited to 4 GB.  These
+    counters are provided as a convenience and are not used internally by
+    inflate() or deflate().  The application can easily set up its own counters
+    updated after each call of inflate() or deflate() to count beyond 4 GB.
+    compress() and uncompress() may be limited to 4 GB, since they operate in a
+    single call.  gzseek() and gztell() may be limited to 4 GB depending on how
+    zlib is compiled.  See the zlibCompileFlags() function in zlib.h.
+
+    The word "may" appears several times above since there is a 4 GB limit only
+    if the compiler's "long" type is 32 bits.  If the compiler's "long" type is
+    64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+    The only one that we are aware of is potentially in gzprintf().  If zlib is
+    compiled to use sprintf() or vsprintf(), then there is no protection
+    against a buffer overflow of an 8K string space (or other value as set by
+    gzbuffer()), other than the caller of gzprintf() assuring that the output
+    will not exceed 8K.  On the other hand, if zlib is compiled to use
+    snprintf() or vsnprintf(), which should normally be the case, then there is
+    no vulnerability.  The ./configure script will display warnings if an
+    insecure variation of sprintf() will be used by gzprintf().  Also the
+    zlibCompileFlags() function will return information on what variant of
+    sprintf() is used by gzprintf().
+
+    If you don't have snprintf() or vsnprintf() and would like one, you can
+    find a portable implementation here:
+
+        http://www.ijs.si/software/snprintf/
+
+    Note that you should be using the most recent version of zlib.  Versions
+    1.1.3 and before were subject to a double-free vulnerability, and versions
+    1.2.1 and 1.2.2 were subject to an access exception when decompressing
+    invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+    Probably what you want is to use zlib in Java. zlib is already included
+    as part of the Java SDK in the java.util.zip package. If you really want
+    a version of zlib written in the Java language, look on the zlib home
+    page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+    up to maximally-pedantic. Can't you guys write proper code?
+
+    Many years ago, we gave up attempting to avoid warnings on every compiler
+    in the universe.  It just got to be a waste of time, and some compilers
+    were downright silly as well as contradicted each other.  So now, we simply
+    make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+    performing a conditional jump that depends on an uninitialized value.
+    Isn't that a bug?
+
+    No.  That is intentional for performance reasons, and the output of deflate
+    is not affected.  This only started showing up recently since zlib 1.2.x
+    uses malloc() by default for allocations, whereas earlier versions used
+    calloc(), which zeros out the allocated memory.  Even though the code was
+    correct, versions 1.2.4 and later was changed to not stimulate these
+    checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+    data format?
+
+    Probably not. Look in the comp.compression FAQ for pointers to various
+    formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+    zlib doesn't support encryption.  The original PKZIP encryption is very
+    weak and can be broken with freely available programs.  To get strong
+    encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+    compression.  For PKZIP compatible "encryption", look at
+    http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+    "gzip" is the gzip format, and "deflate" is the zlib format.  They should
+    probably have called the second one "zlib" instead to avoid confusion with
+    the raw deflate compressed data format.  While the HTTP 1.1 RFC 2616
+    correctly points to the zlib specification in RFC 1950 for the "deflate"
+    transfer encoding, there have been reports of servers and browsers that
+    incorrectly produce or expect raw deflate data per the deflate
+    specficiation in RFC 1951, most notably Microsoft.  So even though the
+    "deflate" transfer encoding using the zlib format would be the more
+    efficient approach (and in fact exactly what the zlib format was designed
+    for), using the "gzip" transfer encoding is probably more reliable due to
+    an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+    Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+    No.  PKWare has apparently decided to keep that format proprietary, since
+    they have not documented it as they have previous compression formats.  In
+    any case, the compression improvements are so modest compared to other more
+    modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+    There are no zip functions in zlib.  You are probably using minizip by
+    Giles Vollant, which is found in the contrib directory of zlib.  It is not
+    part of zlib.  In fact none of the stuff in contrib is part of zlib.  The
+    files in there are not supported by the zlib authors.  You need to contact
+    the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+    Since it's part of zlib, doesn't that mean that all of zlib falls under the
+    GNU GPL?
+
+    No.  The files in contrib are not part of zlib.  They were contributed by
+    other authors and are provided as a convenience to the user within the zlib
+    distribution.  Each item in contrib has its own license.
+
+43. Is zlib subject to export controls?  What is its ECCN?
+
+    zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+    so that we can use your software in our product?
+
+    No. Go away. Shoo.
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.5 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly.  Another example is given in the file minigzip.c.  The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in.  In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix.  For Windows, use one
+of the special makefiles in win32/ or contrib/vstudio/ .  For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version.  The zlib home page is
+http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan.  1997
+issue of Dr.  Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.5 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz.  The deflate and
+  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+  people who reported problems and suggested various improvements in zlib; they
+  are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/adler32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/adler32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/adler32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,169 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2007 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
+
+#define BASE 65521UL    /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD4(a) \
+    do { \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD4(sum2);             /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    rem = (unsigned)(len2 % BASE);
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/algorithm.txt
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/algorithm.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/algorithm.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast.  The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and  then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits.  Also the distance trees have 30 possible
+values, and the size of the first table is six bits.  Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like.  You are correct that it's not a Huffman tree.  It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The
+symbol could be as short as one bit or as long as 15 bits.  If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits.  Again, there are duplicated
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data
+compression in the first place.)  For the less frequent long symbols, there
+will be two lookups.  If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient.  For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble.  Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is?  The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols.  At the
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed.  That's compared to 64 entries for a single table.  Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table).  Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the
+meaning of a particular symbol is often more than just a letter.  It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value.  Or it might be the special end-of-block code.  The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/compress.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/compress.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/compress.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,442 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
+#    include <limits.h>
+#    define BYFOUR
+#    if (UINT_MAX == 0xffffffffUL)
+       typedef unsigned int u4;
+#    else
+#      if (ULONG_MAX == 0xffffffffUL)
+         typedef unsigned long u4;
+#      else
+#        if (USHRT_MAX == 0xffffffffUL)
+           typedef unsigned short u4;
+#        else
+#          undef BYFOUR     /* can't find a four-byte integer type! */
+#        endif
+#      endif
+#    endif
+#  endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+#  define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
+                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    unsigned long c;
+    int n, k;
+    unsigned long poly;                 /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0UL;
+        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+            poly |= 1UL << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (unsigned long)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = REV(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = REV(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const unsigned long FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const unsigned long FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        u4 endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = (u4)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register u4 c;
+    register const u4 FAR *buf4;
+
+    c = REV((u4)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/crc32.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1834 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG_ZLIB
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->wrap == 2 ||
+        (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+        return Z_STREAM_ERROR;
+
+    s = strm->state;
+    if (s->wrap)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > s->w_size) {
+        length = s->w_size;
+        dictionary += dictLength - length; /* use the tail of the dictionary */
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+        INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    strm->state->bi_valid = bits;
+    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_BLOCK);
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+    Bytef *str;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == Z_NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != Z_NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                        (*(configuration_table[s->level].func))(s, flush));
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy(dest, source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy(ds, ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, strm->next_in, len);
+    }
+#endif
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG_ZLIB
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG_ZLIB */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest encodable run.
+         */
+        if (s->lookahead < MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (int)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/deflate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,342 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2010 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG_ZLIB
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG_ZLIB
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/infback.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/infback.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/infback.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,632 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->wnext = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            state->length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *in;      /* local strm->next_in */
+    unsigned char FAR *last;    /* while in < last, enough input available */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code here;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        here = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(here.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here.val));
+            PUP(out) = (unsigned char)(here.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            here = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(here.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                PUP(out) = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            PUP(out) = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window - OFF;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode[here.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode[here.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffast.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffixed.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffixed.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inffixed.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications. It
+       is part of the implementation of the compression library and
+       is subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1480 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    strm->adler = 1;        /* to support ill-conceived Java test suite */
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+    int wrap;
+    struct inflate_state FAR *state;
+
+    /* get the state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    int ret;
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->window = Z_NULL;
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+               state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+    struct inflate_state FAR *state;
+    unsigned copy, dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    copy = out - strm->avail_out;
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, strm->next_out - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            else if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = REVERSE(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN_;             /* decode codes */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+        case COPY_:
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN_;
+            if (flush == Z_TREES) goto inf_leave;
+        case LEN_:
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     REVERSE(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+        if (updatewindow(strm, out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long id;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary id */
+    if (state->mode == DICT) {
+        id = adler32(0L, Z_NULL, 0);
+        id = adler32(id, dictionary, dictLength);
+        if (id != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window */
+    if (updatewindow(strm, strm->avail_out)) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    if (dictLength > state->wsize) {
+        zmemcpy(state->window, dictionary + dictLength - state->wsize,
+                state->wsize);
+        state->whave = state->wsize;
+    }
+    else {
+        zmemcpy(state->window + state->wsize - dictLength, dictionary,
+                dictLength);
+        state->whave = dictLength;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy(dest, source, sizeof(z_stream));
+    zmemcpy(copy, state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    return Z_OK;
+#else
+    state->sane = 1;
+    return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+    state = (struct inflate_state FAR *)strm->state;
+    return ((long)(state->back) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inflate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 10K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,330 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used >= ENOUGH_LENS) ||
+        (type == DISTS && used >= ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            here.op = (unsigned char)(extra[work[sym]]);
+            here.val = base[work[sym]];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used >= ENOUGH_LENS) ||
+                (type == DISTS && used >= ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    here.op = (unsigned char)64;                /* invalid code marker */
+    here.bits = (unsigned char)(len - drop);
+    here.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            here.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = here;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/inftrees.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1244 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2010 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG_ZLIB
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG_ZLIB
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG_ZLIB */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG_ZLIB
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG_ZLIB */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG_ZLIB */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG_ZLIB
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG_ZLIB
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+#ifdef DEBUG_ZLIB
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG_ZLIB
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG_ZLIB
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG_ZLIB
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG_ZLIB
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef DEBUG_ZLIB
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG_ZLIB
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG_ZLIB
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG_ZLIB
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/trees.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/uncompr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/uncompr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/uncompr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zconf.in.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zconf.in.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zconf.in.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,322 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_  z_deflateInit_
+#  define deflate       z_deflate
+#  define deflateEnd    z_deflateEnd
+#  define inflateInit_  z_inflateInit_
+#  define inflate       z_inflate
+#  define inflateEnd    z_inflateEnd
+#  define deflateInit2_ z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy   z_deflateCopy
+#  define deflateReset  z_deflateReset
+#  define deflatePrime  z_deflatePrime
+#  define deflateParams z_deflateParams
+#  define deflateBound  z_deflateBound
+#  define inflateInit2_ z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync   z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateCopy   z_inflateCopy
+#  define inflateReset  z_inflateReset
+#  define compress      z_compress
+#  define compress2     z_compress2
+#  define compressBound z_compressBound
+#  define uncompress    z_uncompress
+#  define adler32       z_adler32
+#  define crc32         z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte          z_Byte
+#  define uInt          z_uInt
+#  define uLong         z_uLong
+#  define Bytef         z_Bytef
+#  define charf         z_charf
+#  define intf          z_intf
+#  define uIntf         z_uIntf
+#  define uLongf        z_uLongf
+#  define voidpf        z_voidpf
+#  define voidp         z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+#if defined(__OS400__)
+#define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zlib.3
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zlib.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zlib.3	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,151 @@
+.TH ZLIB 3 "19 Apr 2010"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms may be added later
+with the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in the case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source.
+.LP
+.I zlib
+is available in Java using the java.util.zip package:
+.IP
+http://java.sun.com/developer/technicalArticles/Programming/compression/
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+.I zlib
+is built into
+.IR tcl:
+.IP
+http://wiki.tcl.tk/4610
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/minizip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+source distribution.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at:
+.IP
+http://zlib.net/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (for the zlib header and trailer format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (for the deflate compressed data format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (for the gzip header and trailer format)
+.LP
+Mark Nelson wrote an article about
+.I zlib
+for the Jan. 1997 issue of  Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://marknelson.us/1997/01/01/zlib-engine/
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://zlib.net/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.5
+Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG_ZLIB
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#ifdef STDC
+#  ifdef NO_vsnprintf
+        flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#else
+        flags += 1L << 24;
+#  ifdef NO_snprintf
+        flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+        flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+        flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG_ZLIB
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
Index: bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lib/zlib/zutil.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,274 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#ifdef STDC
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#      include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  ifdef M_I86
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+        but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#endif
+#ifdef VMS
+#  define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG_ZLIB
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((const char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                        unsigned size));
+void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+# Include configuration rules
+VPATH = $(SRC)
+include $(MAKEDIR)/com32.mk
+
+REQFLAGS += -I$(SRC)
+
+LIBOBJS := $(notdir $(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
+
+BINDIR   = /usr/bin
+LIBDIR   = /usr/lib
+DATADIR  = /usr/share
+AUXDIR   = $(DATADIR)/syslinux
+INCDIR   = /usr/include
+COM32DIR = $(AUXDIR)/com32
+
+all: libcom32upload.a
+
+libcom32upload.a : $(LIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $^
+	$(RANLIB) $@
+
+tidy dist clean:
+	find . \( -name \*.o -o -name \*.a -o -name .\*.d -o -name \*.tmp \) -print0 | \
+		xargs -0r rm -f
+
+spotless: clean
+	rm -f *.a
+	rm -f *~ \#* */*~ */\#*
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+	install -m 644 libcom32upload.a $(INSTALLROOT)$(COM32DIR)
+	mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
+	cp -r $(SRC)/*.h $(INSTALLROOT)$(COM32DIR)/include/
+
+-include .*.d */.*.d */*/.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/cpio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+/*
+ * cpio.c
+ *
+ * Write a compressed CPIO file
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "upload_backend.h"
+#include "ctime.h"
+
+int cpio_pad(struct upload_backend *be)
+{
+    static char pad[4];		/* Up to 4 zero bytes */
+    if (be->dbytes & 3)
+	return write_data(be, pad, -be->dbytes & 3);
+    else
+	return 0;
+}
+
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
+	     const char *filename)
+{
+    static uint32_t inode = 2;
+    char hdr[6+13*8+1];
+    int nlen = strlen(filename)+1;
+    int rv = 0;
+
+    cpio_pad(be);
+
+    sprintf(hdr, "%06o%08x%08x%08x%08x%08x%08x%08zx%08x%08x%08x%08x%08x%08x",
+	    070701,		/* c_magic */
+	    inode++,		/* c_ino */
+	    mode,		/* c_mode */
+	    0,			/* c_uid */
+	    0,			/* c_gid */
+	    1,			/* c_nlink */
+	    be->now,		/* c_mtime */
+	    datalen,		/* c_filesize */
+	    0,			/* c_maj */
+	    0,			/* c_min */
+	    0,			/* c_rmaj */
+	    0,			/* c_rmin */
+	    nlen,		/* c_namesize */
+	    0);			/* c_chksum */
+    rv |= write_data(be, hdr, 6+13*8);
+    rv |= write_data(be, filename, nlen);
+    rv |= cpio_pad(be);
+    return rv;
+}
+
+int cpio_mkdir(struct upload_backend *be, const char *filename)
+{
+    return cpio_hdr(be, MODE_DIR, 0, filename);
+}
+
+int cpio_writefile(struct upload_backend *be, const char *filename,
+		   const void *data, size_t len)
+{
+    int rv;
+
+    rv = cpio_hdr(be, MODE_FILE, len, filename);
+    rv |= write_data(be, data, len);
+    rv |= cpio_pad(be);
+
+    return rv;
+}
+
+int cpio_close(struct upload_backend *be)
+{
+    return cpio_hdr(be, 0, 0, "TRAILER!!!");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,79 @@
+#include <com32.h>
+#include <string.h>
+#include "ctime.h"
+
+static uint8_t frombcd(uint8_t v)
+{
+    uint8_t a = v & 0x0f;
+    uint8_t b = v >> 4;
+
+    return a + b*10;
+}
+
+uint32_t posix_time(void)
+{
+    /* Days from March 1 for a specific month, starting in March */
+    static const unsigned int yday[12] =
+	{ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
+    com32sys_t ir, d0, d1, t0;
+    unsigned int c, y, mo, d, h, m, s;
+    uint32_t t;
+
+    memset(&ir, 0, sizeof ir);
+
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d0);
+
+    memset(&ir, 0, sizeof ir);
+    ir.eax.b[1] = 0x02;
+    __intcall(0x1A, &ir, &t0);
+
+    memset(&ir, 0, sizeof ir);
+    ir.eax.b[1] = 0x04;
+    __intcall(0x1A, &ir, &d1);
+
+    if (t0.ecx.b[1] < 0x12)
+	d0 = d1;
+
+    c  = frombcd(d0.ecx.b[1]);
+    y  = frombcd(d0.ecx.b[0]);
+    mo = frombcd(d0.edx.b[1]);
+    d  = frombcd(d0.edx.b[0]);
+
+    h  = frombcd(t0.ecx.b[1]);
+    m  = frombcd(t0.ecx.b[0]);
+    s  = frombcd(t0.edx.b[1]);
+
+    /* We of course have no idea about the timezone, so ignore it */
+
+    /*
+     * Look for impossible dates... this code was written in 2010, so
+     * assume any century less than 20 is just broken.
+     */
+    if (c < 20)
+	c = 20;
+    y += c*100;
+
+    /* Consider Jan and Feb as the last months of the previous year */
+    if (mo < 3) {
+	y--;
+	mo += 12;
+    }
+
+    /*
+     * Just in case: if the month is nonsense, don't read off the end
+     * of the table...
+     */
+    if (mo-3 > 11)
+	return 0;
+
+    t = y*365 + y/4 - y/100 + y/400 + yday[mo-3] + d - 719469;
+    t *= 24;
+    t += h;
+    t *= 60;
+    t += m;
+    t *= 60;
+    t += s;
+
+    return t;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ctime.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,8 @@
+#ifndef CTIME_H
+#define CTIME_H
+
+#include <inttypes.h>
+
+uint32_t posix_time(void);
+
+#endif /* CTIME_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/serial.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,169 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <sys/io.h>
+#include <sys/cpu.h>
+#include <syslinux/config.h>
+
+#include "serial.h"
+
+enum {
+    THR = 0,
+    RBR = 0,
+    DLL = 0,
+    DLM = 1,
+    IER = 1,
+    IIR = 2,
+    FCR = 2,
+    LCR = 3,
+    MCR = 4,
+    LSR = 5,
+    MSR = 6,
+    SCR = 7,
+};
+
+
+int serial_init(struct serial_if *sif, const char *argv[])
+{
+    const struct syslinux_serial_console_info *sci
+	= syslinux_serial_console_info();
+    uint16_t port;
+    unsigned int divisor;
+    uint8_t dll, dlm, lcr;
+
+    if (!argv[0]) {
+	if (sci->iobase) {
+	    port = sci->iobase;
+	} else {
+	    printf("No port number specified and not using serial console!\n");
+	    return -1;
+	}
+    } else {
+	port = strtoul(argv[0], NULL, 0);
+	if (port <= 3) {
+	    uint16_t addr = ((uint16_t *)0x400)[port];
+	    if (!addr) {
+		printf("No serial port address found!\n");
+	    return -1;
+	    }
+	    printf("Serial port %u is at 0x%04x\n", port, addr);
+	    port = addr;
+	}
+    }
+
+    sif->port = port;
+    sif->console = false;
+
+    divisor = 1;		/* Default speed = 115200 bps */
+
+    /* Check to see if this is the same as the serial console */
+    if (port == sci->iobase) {
+	/* Overlaying the console... */
+	sif->console = true;
+
+	/* Default to already configured speed */
+	divisor = sci->divisor;
+
+	/* Shut down I/O to the console for the time being */
+	openconsole(&dev_null_r, &dev_null_w);
+    }
+
+    if (argv[0] && argv[1])
+	divisor = 115200/strtoul(argv[1], NULL, 0);
+
+    cli();			/* Just in case... */
+
+    /* Save old register settings */
+    sif->old.lcr = inb(port + LCR);
+    sif->old.mcr = inb(port + MCR);
+    sif->old.iir = inb(port + IIR);
+
+    /* Set speed */
+    outb(0x83, port + LCR);	/* Enable divisor access */
+    sif->old.dll = inb(port + DLL);
+    sif->old.dlm = inb(port + DLM);
+    outb(divisor, port + DLL);
+    outb(divisor >> 8, port + DLM);
+    (void)inb(port + IER);	/* Synchronize */
+
+    dll = inb(port + DLL);
+    dlm = inb(port + DLM);
+    lcr = inb(port + LCR);
+    outb(0x03, port + LCR);	/* Enable data access, n81 */
+    (void)inb(port + IER);	/* Synchronize */
+    sif->old.ier = inb(port + IER);
+
+    /* Disable interrupts */
+    outb(0, port + IER);
+
+    sti();
+
+    if (dll != (uint8_t)divisor ||
+	dlm != (uint8_t)(divisor >> 8) ||
+	lcr != 0x83) {
+	serial_cleanup(sif);
+	printf("No serial port detected!\n");
+	return -1;		/* This doesn't look like a serial port */
+    }
+
+    /* Enable 16550A FIFOs if available */
+    outb(0x01, port + FCR);	/* Enable FIFO */
+    (void)inb(port + IER);	/* Synchronize */
+    if (inb(port + IIR) < 0xc0)
+	outb(0x00, port + FCR);	/* Disable FIFOs if non-functional */
+    (void)inb(port + IER);	/* Synchronize */
+
+    return 0;
+}
+
+void serial_write(struct serial_if *sif, const void *data, size_t n)
+{
+    uint16_t port = sif->port;
+    const char *p = data;
+    uint8_t lsr;
+
+    while (n--) {
+	do {
+	    lsr = inb(port + LSR);
+	} while (!(lsr & 0x20));
+
+	outb(*p++, port + THR);
+    }
+}
+
+void serial_read(struct serial_if *sif, void *data, size_t n)
+{
+    uint16_t port = sif->port;
+    char *p = data;
+    uint8_t lsr;
+
+    while (n--) {
+	do {
+	    lsr = inb(port + LSR);
+	} while (!(lsr & 0x01));
+
+	*p++ = inb(port + RBR);
+    }
+}
+
+void serial_cleanup(struct serial_if *sif)
+{
+    uint16_t port = sif->port;
+
+    outb(0x83, port + LCR);
+    (void)inb(port + IER);
+    outb(sif->old.dll, port + DLL);
+    outb(sif->old.dlm, port + DLM);
+    (void)inb(port + IER);
+    outb(sif->old.lcr & 0x7f, port + LCR);
+    (void)inb(port + IER);
+    outb(sif->old.mcr, port + MCR);
+    outb(sif->old.ier, port + IER);
+    if (sif->old.iir < 0xc0)
+	outb(0x00, port + FCR);	/* Disable FIFOs */
+
+    /* Re-enable console messages, if we shut them down */
+    if (sif->console)
+	openconsole(&dev_null_r, &dev_stdcon_w);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/serial.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+
+#include <stddef.h>
+
+struct serial_if {
+    uint16_t port;
+    bool console;
+    struct {
+	uint8_t dll, dlm, ier, iir, lcr, mcr;
+    } old;
+};
+
+int serial_init(struct serial_if *sif, const char *argv[]);
+void serial_read(struct serial_if *sif, void *data, size_t n);
+void serial_write(struct serial_if *sif, const void *data, size_t n);
+void serial_cleanup(struct serial_if *sif);
+
+#endif /* SERIAL_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/srecsend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+#ifndef SRECSEND_H
+#define SRECSEND_H
+
+#include "file.h"
+
+void send_srec(struct serial_if *, struct file_info *,
+		 void (*)(void *, size_t, struct file_info *, size_t));
+
+#endif /* SRECSEND_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/tftp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,22 @@
+#include <stdint.h>
+
+#ifndef UPLOAD_TFTP
+#define UPLOAD_TFTP
+/* TFTP Error codes */
+enum tftp_error_codes {
+TFTP_ERR_UNKNOWN_ERROR = 0, // We have to use the message from the server
+TFTP_ERR_FILE_NOT_FOUND	= 1, /**< File not found */
+TFTP_ERR_ACCESS_DENIED = 2, /**< Access violation */
+TFTP_ERR_DISK_FULL = 3, /**< Disk full or allocation exceeded */
+TFTP_ERR_ILLEGAL_OP = 4, /**< Illegal TFTP operation */
+TFTP_ERR_UNKNOWN_TID = 5, /**< Unknown transfer ID */
+TFTP_ERR_FILE_EXISTS = 6, /**< File already exists */
+TFTP_ERR_UNKNOWN_USER = 7, /**< No such user */
+TFTP_ERR_BAD_OPTS = 8, /**< Option negotiation failed */
+TFTP_ERR_UNABLE_TO_RESOLVE = 9, // Not in RFC, internal usage 
+TFTP_ERR_UNABLE_TO_CONNECT = 10, // Not in RFC, internal usage
+TFTP_OK	= 11, /* Not in RFC */
+};
+
+extern const char *tftp_string_error_message[];
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_backend.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,56 @@
+#ifndef BACKEND_H
+#define BACKEND_H
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "serial.h"
+#include "tftp.h"
+
+/* Backend flags */
+#define BE_NEEDLEN	0x01
+
+struct upload_backend {
+    const char *name;
+    const char *helpmsg;
+    int minargs;
+
+    size_t dbytes;
+    size_t zbytes;
+    const char **argv;
+
+    uint32_t now;
+
+    int (*write)(struct upload_backend *);
+
+    z_stream zstream;
+    char *outbuf;
+    size_t alloc;
+};
+
+/* zout.c */
+int init_data(struct upload_backend *be, const char *argv[]);
+int write_data(struct upload_backend *be, const void *buf, size_t len);
+int flush_data(struct upload_backend *be);
+
+/* cpio.c */
+#define cpio_init init_data
+int cpio_hdr(struct upload_backend *be, uint32_t mode, size_t datalen,
+	     const char *filename);
+int cpio_mkdir(struct upload_backend *be, const char *filename);
+int cpio_writefile(struct upload_backend *be, const char *filename,
+		   const void *data, size_t len);
+int cpio_close(struct upload_backend *be);
+#define MODE_FILE	0100644
+#define MODE_DIR	0040755
+
+/* backends.c */
+struct upload_backend *get_upload_backend(const char *name);
+
+/* backends */
+extern struct upload_backend upload_tftp;
+extern struct upload_backend upload_ymodem;
+extern struct upload_backend upload_srec;
+
+#endif /* BACKEND_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_srec.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,85 @@
+/*
+ * S-records dump routine -- dumps S-records on the console
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <minmax.h>
+#include "upload_backend.h"
+
+/* Write a single S-record */
+static int write_srecord(unsigned int len,  unsigned int alen,
+                         uint32_t addr, uint8_t type, const void *data)
+{
+    char buf[2+2+8+255*2+2+2];
+    char *p = buf;
+    uint8_t csum;
+    const uint8_t *dptr = data;
+    unsigned int i;
+
+    switch (alen) {
+    case 2:
+        addr &= 0xffff;
+        break;
+    case 3:
+        addr &= 0xffffff;
+        break;
+    case 4:
+        break;
+    }
+
+    csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
+    for (i = 0; i < len; i++)
+        csum += dptr[i];
+    csum = 0xff-csum;
+
+    p += sprintf(p, "S%c%02X%0*X", type, len+alen+1, alen*2, addr);
+    for (i = 0; i < len; i++)
+        p += sprintf(p, "%02X", dptr[i]);
+    p += sprintf(p, "%02X\n", csum);
+
+    fputs(buf, stdout);
+    return 0;
+}
+
+static int upload_srec_write(struct upload_backend *be)
+{
+    char name[33];
+    const char *buf;
+    size_t len, chunk, offset, hdrlen;
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
+
+    hdrlen = snprintf(name, sizeof name, "%.32s",
+		      be->argv[0] ? be->argv[0] : "");
+
+    /* Write head record */
+    write_srecord(hdrlen, 2, 0, '0', name);
+
+    /* Write data records */
+    offset = 0;
+    while (len) {
+	chunk = min(len, (size_t)32);
+
+	write_srecord(chunk, 4, offset, '3', buf);
+	buf += chunk;
+	len -= chunk;
+	offset += chunk;
+    }
+
+    /* Write termination record */
+    write_srecord(0, 4, 0, '7', NULL);
+
+    return 0;
+}
+
+struct upload_backend upload_srec = {
+    .name       = "srec",
+    .helpmsg    = "[filename]",
+    .minargs    = 0,
+    .write      = upload_srec_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_tftp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,192 @@
+/*
+ * TFTP data output backend
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+#include <netinet/in.h>
+#include <sys/times.h>
+#include "upload_backend.h"
+
+enum tftp_opcode {
+    TFTP_RRQ	= 1,
+    TFTP_WRQ	= 2,
+    TFTP_DATA	= 3,
+    TFTP_ACK	= 4,
+    TFTP_ERROR	= 5,
+};
+
+struct tftp_error {
+	uint16_t opcode;
+	uint16_t errcode;
+	char errmsg[0];
+} __attribute__ (( packed ));
+
+struct tftp_state {
+    uint32_t my_ip;
+    uint32_t srv_ip;
+    uint32_t srv_gw;
+    uint16_t my_port;
+    uint16_t srv_port;
+    uint16_t seq;
+};
+
+const char *tftp_string_error_message[]={
+"",
+"File not found",
+"Access Denied",
+"Disk Full",
+"Illegal Operation",
+"Unknown Transfert ID",
+"File already exists",
+"Unknown User",
+"Negociation failed",
+"Unable to resolve hostname", // not in RFC
+"Unable to connect", // not in RFC
+"No Error",
+};
+
+#define RCV_BUF	2048
+
+static int send_ack_packet(struct tftp_state *tftp,
+			   const void *pkt, size_t len)
+{
+    t_PXENV_UDP_WRITE *uw;
+    t_PXENV_UDP_READ  *ur;
+    clock_t start;
+    static const clock_t timeouts[] = {
+	2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31,
+	37, 44, 53, 64, 77, 92, 110, 132, 159, 191, 229, 0
+    };
+    const clock_t *timeout;
+    int err = -1;
+
+    uw = lmalloc(sizeof *uw + len);
+    ur = lmalloc(sizeof *ur + RCV_BUF);
+
+    for (timeout = timeouts ; *timeout ; timeout++) {
+	memset(uw, 0, sizeof *uw);
+	memcpy(uw+1, pkt, len);
+	uw->ip = tftp->srv_ip;
+	uw->gw = tftp->srv_gw;
+	uw->src_port = tftp->my_port;
+	uw->dst_port = tftp->srv_port ? tftp->srv_port : htons(69);
+	uw->buffer_size = len;
+	uw->buffer = FAR_PTR(uw+1);
+
+	pxe_call(PXENV_UDP_WRITE, uw);
+
+	start = times(NULL);
+
+	do {
+	    memset(ur, 0, sizeof *ur);
+	    ur->src_ip = tftp->srv_ip;
+	    ur->dest_ip = tftp->my_ip;
+	    ur->s_port = tftp->srv_port;
+	    ur->d_port = tftp->my_port;
+	    ur->buffer_size = RCV_BUF;
+	    ur->buffer = FAR_PTR(ur+1);
+
+	    err = pxe_call(PXENV_UDP_READ, ur);
+
+	    if (!err &&	ur->status == PXENV_STATUS_SUCCESS &&
+		tftp->srv_ip == ur->src_ip &&
+		(tftp->srv_port == 0 ||
+		 tftp->srv_port == ur->s_port)) {
+		uint16_t *xb = (uint16_t *)(ur+1);
+		if (ntohs(xb[0]) == TFTP_ACK &&
+		    ntohs(xb[1]) == tftp->seq) {
+		    tftp->srv_port = ur->s_port;
+		    err = TFTP_OK;		/* All good! */
+		    goto done;
+		} else if (ntohs(xb[0]) == TFTP_ERROR) {
+		    struct tftp_error *te = (struct tftp_error *)(ur+1);
+		    if (te->errcode == TFTP_ERR_UNKNOWN_ERROR) {
+		    	tftp_string_error_message[TFTP_ERR_UNKNOWN_ERROR]=strdup(te->errmsg);
+		    }
+ 		    err=-ntohs(te->errcode); // Return the associated error code
+		    goto done;
+		}
+	    }
+	} while ((clock_t)(times(NULL) - start) < *timeout);
+    }
+
+done:
+    lfree(ur);
+    lfree(uw);
+
+    return err;
+}
+
+static int upload_tftp_write(struct upload_backend *be)
+{
+    static uint16_t local_port = 0x4000;
+    struct tftp_state tftp;
+    char buffer[512+4+6];
+    int nlen;
+    int err=TFTP_OK;
+    const union syslinux_derivative_info *sdi =
+	syslinux_derivative_info();
+    const char *data = be->outbuf;
+    size_t len = be->zbytes;
+    size_t chunk;
+
+    tftp.my_ip    = sdi->pxe.myip;
+    tftp.my_port  = htons(local_port++);
+    tftp.srv_gw   = ((tftp.srv_ip ^ tftp.my_ip) & sdi->pxe.ipinfo->netmask)
+	? sdi->pxe.ipinfo->gateway : 0;
+    tftp.srv_port = 0;
+    tftp.seq      = 0;
+
+    if (be->argv[1]) {
+	tftp.srv_ip   = pxe_dns(be->argv[1]);
+	if (!tftp.srv_ip) {
+//	    printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
+	    return -TFTP_ERR_UNABLE_TO_RESOLVE;
+	}
+    } else {
+	tftp.srv_ip   = sdi->pxe.ipinfo->serverip;
+	if (!tftp.srv_ip) {
+//	    printf("\nNo server IP address\n");
+	    return -TFTP_ERR_UNABLE_TO_CONNECT;
+	}
+    }
+
+/*    printf("server %u.%u.%u.%u... ",
+	   ((uint8_t *)&tftp.srv_ip)[0],
+	   ((uint8_t *)&tftp.srv_ip)[1],
+	   ((uint8_t *)&tftp.srv_ip)[2],
+	   ((uint8_t *)&tftp.srv_ip)[3]);*/
+
+    buffer[0] = 0;
+    buffer[1] = TFTP_WRQ;
+    nlen = strlcpy(buffer+2, be->argv[0], 512);
+    memcpy(buffer+3+nlen, "octet", 6);
+
+    if ((err=send_ack_packet(&tftp, buffer, 2+nlen+1+6))!=TFTP_OK)
+	return err;
+
+    do {
+	chunk = len >= 512 ? 512 : len;
+
+	buffer[1] = TFTP_DATA;
+	*((uint16_t *)(buffer+2)) = htons(++tftp.seq);
+	memcpy(buffer+4, data, chunk);
+	data += chunk;
+	len -= chunk;
+
+	if ((err=send_ack_packet(&tftp, buffer, chunk+4))!=TFTP_OK)
+	    return err;
+    } while (chunk == 512);
+
+    return TFTP_OK;
+}
+
+struct upload_backend upload_tftp = {
+    .name       = "tftp",
+    .helpmsg    = "filename [tftp_server]",
+    .minargs    = 1,
+    .write      = upload_tftp_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/upload_ymodem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Ymodem send routine.  Only supports 1K blocks and CRC mode.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "upload_backend.h"
+#include "serial.h"
+
+enum {
+    SOH = 0x01,
+    STX = 0x02,
+    EOT = 0x04,
+    ACK = 0x06,
+    NAK = 0x15,
+    CAN = 0x18,
+};
+
+struct ymodem_state {
+    struct serial_if serial;
+    unsigned int seq, blocks;
+};
+
+/*
+ * Append a CRC16 to a block
+ */
+static void add_crc16(uint8_t * blk, int len)
+{
+    static const uint16_t crctab[256] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+    };
+    uint16_t crc = 0;
+
+    while (len--)
+	crc = crctab[(crc >> 8) ^ *blk++] ^ crc << 8;
+
+    *blk++ = crc >> 8;
+    *blk = crc;
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk,
+		     size_t bytes);
+
+static void send_ack_blk(struct ymodem_state *ym, uint8_t *blk)
+{
+    printf("Sending block %u/%u...\r", ym->seq, ym->blocks);
+
+    blk[0] = STX;
+    blk[1] = ym->seq++;
+    blk[2] = ~blk[1];
+    add_crc16(blk+3, 1024);
+
+    send_ack(ym, blk, 1024+5);
+}
+
+static void send_ack(struct ymodem_state *ym, const uint8_t *blk, size_t bytes)
+{
+    uint8_t ack_buf;
+
+    do {
+	serial_write(&ym->serial, blk, bytes);
+
+	do {
+	    serial_read(&ym->serial, &ack_buf, 1);
+	} while (ack_buf != ACK && ack_buf != NAK);
+    } while (ack_buf == NAK);
+}
+
+static int upload_ymodem_write(struct upload_backend *be)
+{
+    static const uint8_t eot_buf = EOT;
+    uint8_t ack_buf;
+    uint8_t blk_buf[1024 + 5];
+    struct ymodem_state ym;
+    const char *buf;
+    size_t len, chunk;
+    const char ymodem_banner[] = "Now begin Ymodem download...\r\n";
+
+    buf = be->outbuf;
+    len = be->zbytes;
+
+    putchar('\n');
+
+    ym.seq = 0;
+    ym.blocks = (len+1023)/1024;
+
+    /* Initialize serial port */
+    if (serial_init(&ym.serial, &be->argv[1]))
+	return -1;
+
+    /* Write banner */
+    printf("Writing banner...\n");
+    serial_write(&ym.serial, ymodem_banner, sizeof ymodem_banner-1);
+
+    /* Wait for initial handshake */
+    printf("Waiting for handshake...\n");
+    do {
+	serial_read(&ym.serial, &ack_buf, 1);
+    } while (ack_buf != 'C');
+
+    /* Send filename block */
+    memset(blk_buf, 0, sizeof blk_buf);
+    snprintf((char *)blk_buf+3, 1024, "%s%c%zu 0%o 0644",
+	     be->argv[0], 0, be->zbytes, be->now);
+    send_ack_blk(&ym, blk_buf);
+
+    while (len) {
+	chunk = len < 1024 ? len : 1024;
+
+	memcpy(blk_buf+3, buf, chunk);
+	if (chunk < 1024)
+	    memset(blk_buf+3+chunk, 0x1a, 1024-chunk);
+
+	send_ack_blk(&ym, blk_buf);
+	buf += chunk;
+	len -= chunk;
+    }
+
+    printf("\nSending EOT...\n");
+    send_ack(&ym, &eot_buf, 1);
+
+    printf("Waiting for handshake...\n");
+    do {
+	serial_read(&ym.serial, &ack_buf, 1);
+    } while (ack_buf != 'C');
+    ym.seq = 0;
+
+    printf("Sending batch termination block...\n");
+    memset(blk_buf+3, 0, 1024);
+    send_ack_blk(&ym, blk_buf);
+
+    printf("Cleaning up...             \n");
+    serial_cleanup(&ym.serial);
+
+    return 0;
+}
+
+struct upload_backend upload_ymodem = {
+    .name       = "ymodem",
+    .helpmsg    = "filename [port [speed]]",
+    .minargs    = 1,
+    .write      = upload_ymodem_write,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/ymodem.txt	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2108 @@
+
+
+
+                                      - 1 -
+
+
+
+                         XMODEM/YMODEM PROTOCOL REFERENCE
+                     A compendium of documents describing the
+
+                                XMODEM and YMODEM
+
+                             File Transfer Protocols
+
+
+
+
+                      This document was formatted 10-14-88.
+
+
+
+
+
+
+
+                             Edited by Chuck Forsberg
+
+
+
+
+
+
+
+
+
+                This file may be redistributed without restriction
+                        provided the text is not altered.
+
+                     Please distribute as widely as possible.
+
+                           Questions to Chuck Forsberg
+
+
+
+
+
+                               Omen Technology Inc
+                          The High Reliability Software
+                            17505-V Sauvie Island Road
+                              Portland Oregon 97231
+                            VOICE: 503-621-3406 :VOICE
+      TeleGodzilla BBS: 503-621-3746 Speed 19200(Telebit PEP),2400,1200,300
+                              CompuServe: 70007,2304
+                                    GEnie: CAF
+                        UUCP: ...!tektronix!reed!omen!caf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - 2 -
+
+
+
+    1.  TOWER OF BABEL
+
+    A "YMODEM Tower of Babel" has descended on the microcomputing community
+    bringing with it confusion, frustration, bloated phone bills, and wasted
+    man hours.  Sadly, I (Chuck Forsberg) am partly to blame for this mess.
+
+    As author of the early 1980s batch and 1k XMODEM extensions, I assumed
+    readers of earlier versions of this document would implement as much of
+    the YMODEM protocol as their programming skills and computing environments
+    would permit.  This proved a rather naive assumption as programmers
+    motivated by competitive pressure implemented as little of YMODEM as
+    possible.  Some have taken whatever parts of YMODEM that appealed to them,
+    applied them to MODEM7 Batch, Telink, XMODEM or whatever, and called the
+    result YMODEM.
+
+    Jeff Garbers (Crosstalk package development director) said it all: "With
+    protocols in the public domain, anyone who wants to dink around with them
+    can go ahead." [1]
+
+    Documents containing altered examples derived from YMODEM.DOC have added
+    to the confusion.  In one instance, some self styled rewriter of history
+    altered the heading in YMODEM.DOC's Figure 1 from "1024 byte Packets" to
+    "YMODEM/CRC File Transfer Protocol".  None of the XMODEM and YMODEM
+    examples shown in that document were correct.
+
+    To put an end to this confusion, we must make "perfectly clear" what
+    YMODEM stands for, as Ward Christensen defined it in his 1985 coining of
+    the term.
+
+    To the majority of you who read, understood, and respected Ward's
+    definition of YMODEM, I apologize for the inconvenience.
+
+    1.1  Definitions
+
+    ARC     ARC is a program that compresses one or more files into an archive
+            and extracts files from such archives.
+
+    XMODEM  refers to the file transfer etiquette introduced by Ward
+            Christensen's 1977 MODEM.ASM program.  The name XMODEM comes from
+            Keith Petersen's XMODEM.ASM program, an adaptation of MODEM.ASM
+            for Remote CP/M (RCPM) systems.  It's also called the MODEM or
+            MODEM2 protocol.  Some who are unaware of MODEM7's unusual batch
+            file mode call it MODEM7.  Other aliases include "CP/M Users'
+            Group" and "TERM II FTP 3".  The name XMODEM caught on partly
+            because it is distinctive and partly because of media interest in
+
+
+    __________
+
+     1. Page C/12, PC-WEEK July 12, 1987
+
+
+
+
+    Chapter 1
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              3
+
+
+
+            bulletin board and RCPM systems where it was accessed with an
+            "XMODEM" command.  This protocol is supported by every serious
+            communications program because of its universality, simplicity,
+            and reasonable performance.
+
+    XMODEM/CRC replaces XMODEM's 1 byte checksum with a two byte Cyclical
+            Redundancy Check (CRC-16), giving modern error detection
+            protection.
+
+    XMODEM-1k Refers to the XMODEM/CRC protocol with 1024 byte data blocks.
+
+    YMODEM  Refers to the XMODEM/CRC (optional 1k blocks) protocol with batch
+            transmission as described below.  In a nutshell, YMODEM means
+            BATCH.
+
+    YMODEM-g Refers to the streaming YMODEM variation described below.
+
+    True YMODEM(TM) In an attempt to sort out the YMODEM Tower of Babel, Omen
+            Technology has trademarked the term True YMODEM(TM) to represent
+            the complete YMODEM protocol described in this document, including
+            pathname, length, and modification date transmitted in block 0.
+            Please contact Omen Technology about certifying programs for True
+            YMODEM(TM) compliance.
+
+    ZMODEM  uses familiar XMODEM/CRC and YMODEM technology in a new protocol
+            that provides reliability, throughput, file management, and user
+            amenities appropriate to contemporary data communications.
+
+    ZOO     Like ARC, ZOO is a program that compresses one or more files into
+            a "zoo archive".  ZOO supports many different operating systems
+            including Unix and VMS.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 1
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              4
+
+
+
+    2.  YMODEM MINIMUM REQUIREMENTS
+
+    All programs claiming to support YMODEM must meet the following minimum
+    requirements:
+
+       + The sending program shall send the pathname (file name) in block 0.
+
+       + The pathname shall be a null terminated ASCII string as described
+         below.
+
+         For those who are too lazy to read the entire document:
+
+            + Unless specifically requested, only the file name portion is
+              sent.
+
+            + No drive letter is sent.
+
+            + Systems that do not distinguish between upper and lower case
+              letters in filenames shall send the pathname in lower case only.
+
+
+       + The receiving program shall use this pathname for the received file
+         name, unless explicitly overridden.
+
+       + When the receiving program receives this block and successfully
+         opened the output file, it shall acknowledge this block with an ACK
+         character and then proceed with a normal XMODEM file transfer
+         beginning with a "C" or NAK tranmsitted by the receiver.
+
+       + The sending program shall use CRC-16 in response to a "C" pathname
+         nak, otherwise use 8 bit checksum.
+
+       + The receiving program must accept any mixture of 128 and 1024 byte
+         blocks within each file it receives.  Sending programs may
+         arbitrarily switch between 1024 and 128 byte blocks.
+
+       + The sending program must not change the length of an unacknowledged
+         block.
+
+       + At the end of each file, the sending program shall send EOT up to ten
+         times until it receives an ACK character.  (This is part of the
+         XMODEM spec.)
+
+       + The end of a transfer session shall be signified by a null (empty)
+         pathname, this pathname block shall be acknowledged the same as other
+         pathname blocks.
+
+    Programs not meeting all of these requirements are not YMODEM compatible,
+    and shall not be described as supporting YMODEM.
+
+    Meeting these MINIMUM requirements does not guarantee reliable file
+
+
+
+    Chapter 2
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              5
+
+
+
+    transfers under stress.  Particular attention is called to XMODEM's single
+    character supervisory messages that are easily corrupted by transmission
+    errors.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 2
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              6
+
+
+
+    3.  WHY YMODEM?
+
+    Since its development half a decade ago, the Ward Christensen modem
+    protocol has enabled a wide variety of computer systems to interchange
+    data.  There is hardly a communications program that doesn't at least
+    claim to support this protocol.
+
+    Advances in computing, modems and networking have revealed a number of
+    weaknesses in the original protocol:
+
+       + The short block length caused throughput to suffer when used with
+         timesharing systems, packet switched networks, satellite circuits,
+         and buffered (error correcting) modems.
+
+       + The 8 bit arithmetic checksum and other aspects allowed line
+         impairments to interfere with dependable, accurate transfers.
+
+       + Only one file could be sent per command.  The file name had to be
+         given twice, first to the sending program and then again to the
+         receiving program.
+
+       + The transmitted file could accumulate as many as 127 extraneous
+         bytes.
+
+       + The modification date of the file was lost.
+
+    A number of other protocols have been developed over the years, but none
+    have displaced XMODEM to date:
+
+       + Lack of public domain documentation and example programs have kept
+         proprietary protocols such as Blast, Relay, and others tightly bound
+         to the fortunes of their suppliers.
+
+       + Complexity discourages the widespread application of BISYNC, SDLC,
+         HDLC, X.25, and X.PC protocols.
+
+       + Performance compromises and complexity have limited the popularity of
+         the Kermit protocol, which was developed to allow file transfers in
+         environments hostile to XMODEM.
+
+    The XMODEM protocol extensions and YMODEM Batch address some of these
+    weaknesses while maintaining most of XMODEM's simplicity.
+
+    YMODEM is supported by the public domain programs YAM (CP/M),
+    YAM(CP/M-86), YAM(CCPM-86), IMP (CP/M), KMD (CP/M), rz/sz (Unix, Xenix,
+    VMS, Berkeley Unix, Venix, Xenix, Coherent, IDRIS, Regulus).  Commercial
+    implementations include MIRROR, and Professional-YAM.[1] Communications
+
+
+
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              7
+
+
+
+    programs supporting these extensions have been in use since 1981.
+
+    The 1k block length (XMODEM-1k) described below may be used in conjunction
+    with YMODEM Batch Protocol, or with single file transfers identical to the
+    XMODEM/CRC protocol except for minimal changes to support 1k blocks.
+
+    Another extension is the YMODEM-g protocol.  YMODEM-g provides batch
+    transfers with maximum throughput when used with end to end error
+    correcting media, such as X.PC and error correcting modems, including 9600
+    bps units by TeleBit, U.S.Robotics, Hayes, Electronic Vaults, Data Race,
+    and others.
+
+    To complete this tome, edited versions of Ward Christensen's original
+    protocol document and John Byrns's CRC-16 document are included for
+    reference.
+
+    References to the MODEM or MODEM7 protocol have been changed to XMODEM to
+    accommodate the vernacular.  In Australia, it is properly called the
+    Christensen Protocol.
+
+
+    3.1  Some Messages from the Pioneer
+
+    #: 130940 S0/Communications 25-Apr-85  18:38:47
+    Sb: my protocol
+    Fm: Ward Christensen 76703,302 [2]
+    To: all
+
+    Be aware the article[3] DID quote me correctly in terms of the phrases
+    like "not robust", etc.
+
+    It was a quick hack I threw together, very unplanned (like everything I
+    do), to satisfy a personal need to communicate with "some other" people.
+
+    ONLY the fact that it was done in 8/77, and that I put it in the public
+    domain immediately, made it become the standard that it is.
+
+
+
+
+
+
+
+    __________________________________________________________________________
+
+     1. Available for IBM PC,XT,AT, Unix and Xenix
+
+     2. Edited for typesetting appearance
+
+     3. Infoworld April 29 p. 16
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              8
+
+
+
+    I think its time for me to
+
+    (1) document it; (people call me and say "my product is going to include
+    it - what can I 'reference'", or "I'm writing a paper on it, what do I put
+    in the bibliography") and
+
+    (2) propose an "incremental extension" to it, which might take "exactly"
+    the form of Chuck Forsberg's YAM protocol.  He wrote YAM in C for CP/M and
+    put it in the public domain, and wrote a batch protocol for Unix[4] called
+    rb and sb (receive batch, send batch), which was basically XMODEM with
+       (a) a record 0 containing filename date time and size
+       (b) a 1K block size option
+       (c) CRC-16.
+
+    He did some clever programming to detect false ACK or EOT, but basically
+    left them the same.
+
+    People who suggest I make SIGNIFICANT changes to the protocol, such as
+    "full duplex", "multiple outstanding blocks", "multiple destinations", etc
+    etc don't understand that the incredible simplicity of the protocol is one
+    of the reasons it survived to this day in as many machines and programs as
+    it may be found in!
+
+    Consider the PC-NET group back in '77 or so - documenting to beat the band
+    - THEY had a protocol, but it was "extremely complex", because it tried to
+    be "all things to all people" - i.e. send binary files on a 7-bit system,
+    etc.  I was not that "benevolent". I (emphasize > I < ) had an 8-bit UART,
+    so "my protocol was an 8-bit protocol", and I would just say "sorry" to
+    people who were held back by 7-bit limitations.  ...
+
+    Block size: Chuck Forsberg created an extension of my protocol, called
+    YAM, which is also supported via his public domain programs for UNIX
+    called rb and sb - receive batch and send batch.  They cleverly send a
+    "block 0" which contains the filename, date, time, and size.
+    Unfortunately, its UNIX style, and is a bit weird[5] - octal numbers, etc.
+    BUT, it is a nice way to overcome the kludgy "echo the chars of the name"
+    introduced with MODEM7.  Further, chuck uses CRC-16 and optional 1K
+    blocks.  Thus the record 0, 1K, and CRC, make it a "pretty slick new
+    protocol" which is not significantly different from my own.
+
+    Also, there is a catchy name - YMODEM.  That means to some that it is the
+    "next thing after XMODEM", and to others that it is the Y(am)MODEM
+
+
+    __________
+
+     4. VAX/VMS versions of these programs are also available.
+
+     5. The file length, time, and file mode are optional.  The pathname and
+        file length may be sent alone if desired.
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                              9
+
+
+
+    protocol.  I don't want to emphasize that too much - out of fear that
+    other mfgrs might think it is a "competitive" protocol, rather than an
+    "unaffiliated" protocol.  Chuck is currently selling a much-enhanced
+    version of his CP/M-80 C program YAM, calling it Professional Yam, and its
+    for the PC - I'm using it right now.  VERY slick!  32K capture buffer,
+    script, scrolling, previously captured text search, plus built-in commands
+    for just about everything - directory (sorted every which way), XMODEM,
+    YMODEM, KERMIT, and ASCII file upload/download, etc.  You can program it
+    to "behave" with most any system - for example when trying a number for
+    CIS it detects the "busy" string back from the modem and substitutes a
+    diff phone # into the dialing string and branches back to try it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 3
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             10
+
+
+
+    4.  XMODEM PROTOCOL ENHANCEMENTS
+
+    This chapter discusses the protocol extensions to Ward Christensen's 1982
+    XMODEM protocol description document.
+
+    The original document recommends the user be asked whether to continue
+    trying or abort after 10 retries.  Most programs no longer ask the
+    operator whether he wishes to keep retrying.  Virtually all correctable
+    errors are corrected within the first few retransmissions.  If the line is
+    so bad that ten attempts are insufficient, there is a significant danger
+    of undetected errors.  If the connection is that bad, it's better to
+    redial for a better connection, or mail a floppy disk.
+
+
+    4.1  Graceful Abort
+
+    The YAM and Professional-YAM X/YMODEM routines recognize a sequence of two
+    consecutive CAN (Hex 18) characters without modem errors (overrun,
+    framing, etc.) as a transfer abort command.  This sequence is recognized
+    when is waiting for the beginning of a block or for an acknowledgement to
+    a block that has been sent.  The check for two consecutive CAN characters
+    reduces the number of transfers aborted by line hits.  YAM sends eight CAN
+    characters when it aborts an XMODEM, YMODEM, or ZMODEM protocol file
+    transfer.  Pro-YAM then sends eight backspaces to delete the CAN
+    characters from the remote's keyboard input buffer, in case the remote had
+    already aborted the transfer and was awaiting a keyboarded command.
+
+
+    4.2  CRC-16 Option
+
+    The XMODEM protocol uses an optional two character CRC-16 instead of the
+    one character arithmetic checksum used by the original protocol and by
+    most commercial implementations.  CRC-16 guarantees detection of all
+    single and double bit errors,  all errors with an odd number of error
+    bits, all burst errors of length 16 or less, 99.9969% of all 17-bit error
+    bursts, and 99.9984 per cent of all possible longer error bursts.  By
+    contrast, a double bit error, or a burst error of 9 bits or more can sneak
+    past the XMODEM protocol arithmetic checksum.
+
+    The XMODEM/CRC protocol is similar to the XMODEM protocol, except that the
+    receiver specifies CRC-16 by sending C (Hex 43) instead of NAK when
+    requesting the FIRST block.  A two byte CRC is sent in place of the one
+    byte arithmetic checksum.
+
+    YAM's c option to the r command enables CRC-16 in single file reception,
+    corresponding to the original implementation in the MODEM7 series
+    programs.  This remains the default because many commercial communications
+    programs and bulletin board systems still do not support CRC-16,
+    especially those written in Basic or Pascal.
+
+    XMODEM protocol with CRC is accurate provided both sender and receiver
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             11
+
+
+
+    both report a successful transmission.  The protocol is robust in the
+    presence of characters lost by buffer overloading on timesharing systems.
+
+    The single character ACK/NAK responses generated by the receiving program
+    adapt well to split speed modems, where the reverse channel is limited to
+    ten per cent or less of the main channel's speed.
+
+    XMODEM and YMODEM are half duplex protocols which do not attempt to
+    transmit information and control signals in both directions at the same
+    time.  This avoids buffer overrun problems that have been reported by
+    users attempting to exploit full duplex asynchronous file transfer
+    protocols such as Blast.
+
+    Professional-YAM adds several proprietary logic enhancements to XMODEM's
+    error detection and recovery.  These compatible enhancements eliminate
+    most of the bad file transfers other programs make when using the XMODEM
+    protocol under less than ideal conditions.
+
+
+    4.3  XMODEM-1k 1024 Byte Block
+
+    Disappointing throughput downloading from Unix with YMODEM[1] lead to the
+    development of 1024 byte blocks in 1982.  1024 byte blocks reduce the
+    effect of delays from timesharing systems, modems, and packet switched
+    networks on throughput by 87.5 per cent in addition to decreasing XMODEM's
+    3 per cent overhead (block number, CRC, etc.).
+
+    Some environments cannot accept 1024 byte bursts, including some networks
+    and minicomputer ports.  The longer block length should be an option.
+
+    The choice to use 1024 byte blocks is expressed to the sending program on
+    its command line or selection menu.[2] 1024 byte blocks improve throughput
+    in many applications.
+
+    An STX (02) replaces the SOH (01) at the beginning of the transmitted
+    block to notify the receiver of the longer block length.  The transmitted
+    block contains 1024 bytes of data.  The receiver should be able to accept
+    any mixture of 128 and 1024 byte blocks.  The block number (in the second
+    and third bytes of the block) is incremented by one for each block
+    regardless of the block length.
+
+    The sender must not change between 128 and 1024 byte block lengths if it
+    has not received a valid ACK for the current block.  Failure to observe
+
+
+    __________
+
+     1. The name hadn't been coined yet, but the protocol was the same.
+
+     2. See "KMD/IMP Exceptions to YMODEM" below.
+
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             12
+
+
+
+    this restriction allows transmission errors to pass undetected.
+
+    If 1024 byte blocks are being used, it is possible for a file to "grow" up
+    to the next multiple of 1024 bytes.  This does not waste disk space if the
+    allocation granularity is 1k or greater.  With YMODEM batch transmission,
+    the optional file length transmitted in the file name block allows the
+    receiver to discard the padding, preserving the exact file length and
+    contents.
+
+    1024 byte blocks may be used with batch file transmission or with single
+    file transmission.  CRC-16 should be used with the k option to preserve
+    data integrity over phone lines.  If a program wishes to enforce this
+    recommendation, it should cancel the transfer, then issue an informative
+    diagnostic message if the receiver requests checksum instead of CRC-16.
+
+    Under no circumstances may a sending program use CRC-16 unless the
+    receiver commands CRC-16.
+
+             Figure 1.  XMODEM-1k Blocks
+
+             SENDER                                  RECEIVER
+                                                     "sx -k foo.bar"
+             "foo.bar open x.x minutes"
+                                                     C
+             STX 01 FE Data[1024] CRC CRC
+                                                     ACK
+             STX 02 FD Data[1024] CRC CRC
+                                                     ACK
+             STX 03 FC Data[1000] CPMEOF[24] CRC CRC
+                                                     ACK
+             EOT
+                                                     ACK
+
+             Figure 2.  Mixed 1024 and 128 byte Blocks
+
+             SENDER                                  RECEIVER
+                                                     "sx -k foo.bar"
+             "foo.bar open x.x minutes"
+                                                     C
+             STX 01 FE Data[1024] CRC CRC
+                                                     ACK
+             STX 02 FD Data[1024] CRC CRC
+                                                     ACK
+             SOH 03 FC Data[128] CRC CRC
+                                                     ACK
+             SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+                                                     ACK
+             EOT
+                                                     ACK
+
+
+
+
+
+    Chapter 4                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             13
+
+
+
+    5.  YMODEM Batch File Transmission
+
+    The YMODEM Batch protocol is an extension to the XMODEM/CRC protocol that
+    allows 0 or more files to be transmitted with a single command.  (Zero
+    files may be sent if none of the requested files is accessible.) The
+    design approach of the YMODEM Batch protocol is to use the normal routines
+    for sending and receiving XMODEM blocks in a layered fashion similar to
+    packet switching methods.
+
+    Why was it necessary to design a new batch protocol when one already
+    existed in MODEM7?[1] The batch file mode used by MODEM7 is unsuitable
+    because it does not permit full pathnames, file length, file date, or
+    other attribute information to be transmitted.  Such a restrictive design,
+    hastily implemented with only CP/M in mind, would not have permitted
+    extensions to current areas of personal computing such as Unix, DOS, and
+    object oriented systems.  In addition, the MODEM7 batch file mode is
+    somewhat susceptible to transmission impairments.
+
+    As in the case of single a file transfer, the receiver initiates batch
+    file transmission by sending a "C" character (for CRC-16).
+
+    The sender opens the first file and sends block number 0 with the
+    following information.[2]
+
+    Only the pathname (file name) part is required for batch transfers.
+
+    To maintain upwards compatibility, all unused bytes in block 0 must be set
+    to null.
+
+    Pathname The pathname (conventionally, the file name) is sent as a null
+         terminated ASCII string.  This is the filename format used by the
+         handle oriented MSDOS(TM) functions and C library fopen functions.
+         An assembly language example follows:
+                                  DB      'foo.bar',0
+         No spaces are included in the pathname.  Normally only the file name
+         stem (no directory prefix) is transmitted unless the sender has
+         selected YAM's f option to send the full pathname.  The source drive
+         (A:, B:, etc.) is not sent.
+
+         Filename Considerations:
+
+
+
+    __________
+
+     1. The MODEM7 batch protocol transmitted CP/M FCB bytes f1...f8 and
+        t1...t3 one character at a time.  The receiver echoed these bytes as
+        received, one at a time.
+
+     2. Only the data part of the block is described here.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             14
+
+
+
+            + File names are forced to lower case unless the sending system
+              supports upper/lower case file names.  This is a convenience for
+              users of systems (such as Unix) which store filenames in upper
+              and lower case.
+
+            + The receiver should accommodate file names in lower and upper
+              case.
+
+            + When transmitting files between different operating systems,
+              file names must be acceptable to both the sender and receiving
+              operating systems.
+
+         If directories are included, they are delimited by /; i.e.,
+         "subdir/foo" is acceptable, "subdir\foo" is not.
+
+    Length The file length and each of the succeeding fields are optional.[3]
+         The length field is stored in the block as a decimal string counting
+         the number of data bytes in the file.  The file length does not
+         include any CPMEOF (^Z) or other garbage characters used to pad the
+         last block.
+
+         If the file being transmitted is growing during transmission, the
+         length field should be set to at least the final expected file
+         length, or not sent.
+
+         The receiver stores the specified number of characters, discarding
+         any padding added by the sender to fill up the last block.
+
+    Modification Date The mod date is optional, and the filename and length
+         may be sent without requiring the mod date to be sent.
+
+         Iff the modification date is sent, a single space separates the
+         modification date from the file length.
+
+         The mod date is sent as an octal number giving the time the contents
+         of the file were last changed, measured in seconds from Jan 1 1970
+         Universal Coordinated Time (GMT).  A date of 0 implies the
+         modification date is unknown and should be left as the date the file
+         is received.
+
+         This standard format was chosen to eliminate ambiguities arising from
+         transfers between different time zones.
+
+
+
+
+
+    __________
+
+     3. Fields may not be skipped.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             15
+
+
+
+    Mode Iff the file mode is sent, a single space separates the file mode
+         from the modification date.  The file mode is stored as an octal
+         string.  Unless the file originated from a Unix system, the file mode
+         is set to 0.  rb(1) checks the file mode for the 0x8000 bit which
+         indicates a Unix type regular file.  Files with the 0x8000 bit set
+         are assumed to have been sent from another Unix (or similar) system
+         which uses the same file conventions.  Such files are not translated
+         in any way.
+
+
+    Serial Number Iff the serial number is sent, a single space separates the
+         serial number from the file mode.  The serial number of the
+         transmitting program is stored as an octal string.  Programs which do
+         not have a serial number should omit this field, or set it to 0.  The
+         receiver's use of this field is optional.
+
+
+    Other Fields YMODEM was designed to allow additional header fields to be
+         added as above without creating compatibility problems with older
+         YMODEM programs.  Please contact Omen Technology if other fields are
+         needed for special application requirements.
+
+    The rest of the block is set to nulls.  This is essential to preserve
+    upward compatibility.[4]
+
+    If the filename block is received with a CRC or other error, a
+    retransmission is requested.  After the filename block has been received,
+    it is ACK'ed if the write open is successful.  If the file cannot be
+    opened for writing, the receiver cancels the transfer with CAN characters
+    as described above.
+
+    The receiver then initiates transfer of the file contents with a "C"
+    character, according to the standard XMODEM/CRC protocol.
+
+    After the file contents and XMODEM EOT have been transmitted and
+    acknowledged, the receiver again asks for the next pathname.
+
+    Transmission of a null pathname terminates batch file transmission.
+
+    Note that transmission of no files is not necessarily an error.  This is
+    possible if none of the files requested of the sender could be opened for
+    reading.
+
+
+
+    __________
+
+     4. If, perchance, this information extends beyond 128 bytes (possible
+        with Unix 4.2 BSD extended file names), the block should be sent as a
+        1k block as described above.
+
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             16
+
+
+
+    Most YMODEM receivers request CRC-16 by default.
+
+    The Unix programs sz(1) and rz(1) included in the source code file
+    RZSZ.ZOO should answer other questions about YMODEM batch protocol.
+
+              Figure 3.  YMODEM Batch Transmission Session (1 file)
+
+              SENDER                                  RECEIVER
+                                                      "sb foo.*<CR>"
+              "sending in batch mode etc."
+                                                      C (command:rb)
+              SOH 00 FF foo.c NUL[123] CRC CRC
+                                                      ACK
+                                                      C
+              SOH 01 FE Data[128] CRC CRC
+                                                      ACK
+              SOH 02 FC Data[128] CRC CRC
+                                                      ACK
+              SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                      ACK
+              EOT
+                                                      NAK
+              EOT
+                                                      ACK
+                                                      C
+              SOH 00 FF NUL[128] CRC CRC
+                                                      ACK
+
+                Figure 7.  YMODEM Header Information and Features
+
+    _____________________________________________________________
+    | Program   | Length | Date | Mode | S/N | 1k-Blk | YMODEM-g |
+    |___________|________|______|______|_____|________|__________|
+    |Unix rz/sz | yes    | yes  | yes  | no  | yes    | sb only  |
+    |___________|________|______|______|_____|________|__________|
+    |VMS rb/sb  | yes    | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+    |Pro-YAM    | yes    | yes  | no   | yes | yes    | yes      |
+    |___________|________|______|______|_____|________|__________|
+    |CP/M YAM   | no     | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+    |KMD/IMP    | ?      | no   | no   | no  | yes    | no       |
+    |___________|________|______|______|_____|________|__________|
+
+    5.1  KMD/IMP Exceptions to YMODEM
+
+    KMD and IMP use a "CK" character sequence emitted by the receiver to
+    trigger the use of 1024 byte blocks as an alternative to specifying this
+    option to the sending program.  This two character sequence generally
+    works well on single process micros in direct communication, provided the
+    programs rigorously adhere to all the XMODEM recommendations included
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             17
+
+
+
+           Figure 4.  YMODEM Batch Transmission Session (2 files)
+
+           SENDER                                  RECEIVER
+                                                   "sb foo.c baz.c<CR>"
+           "sending in batch mode etc."
+                                                   C (command:rb)
+           SOH 00 FF foo.c NUL[123] CRC CRC
+                                                   ACK
+                                                   C
+           SOH 01 FE Data[128] CRC CRC
+                                                   ACK
+           SOH 02 FC Data[128] CRC CRC
+                                                   ACK
+           SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                   ACK
+           EOT
+                                                   NAK
+           EOT
+                                                   ACK
+                                                   C
+           SOH 00 FF baz.c NUL[123] CRC CRC
+                                                   ACK
+                                                   C
+           SOH 01 FB Data[100] CPMEOF[28] CRC CRC
+                                                   ACK
+           EOT
+                                                   NAK
+           EOT
+                                                   ACK
+                                                   C
+           SOH 00 FF NUL[128] CRC CRC
+                                                   ACK
+
+            Figure 5.  YMODEM Batch Transmission Session-1k Blocks
+
+            SENDER                                  RECEIVER
+                                                    "sb -k foo.*<CR>"
+            "sending in batch mode etc."
+                                                    C (command:rb)
+            SOH 00 FF foo.c NUL[123] CRC CRC
+                                                    ACK
+                                                    C
+            STX 01 FD Data[1024] CRC CRC
+                                                    ACK
+            SOH 02 FC Data[128] CRC CRC
+                                                    ACK
+            SOH 03 FB Data[100] CPMEOF[28] CRC CRC
+                                                    ACK
+            EOT
+                                                    NAK
+            EOT
+
+
+
+    Chapter 5                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             18
+
+
+
+                                                    ACK
+                                                    C
+            SOH 00 FF NUL[128] CRC CRC
+                                                    ACK
+
+           Figure 6.  YMODEM Filename block transmitted by sz
+
+           -rw-r--r--  6347 Jun 17 1984 20:34 bbcsched.txt
+
+           00 0100FF62 62637363 6865642E 74787400   |...bbcsched.txt.|
+           10 36333437 20333331 34373432 35313320   |6347 3314742513 |
+           20 31303036 34340000 00000000 00000000   |100644..........|
+           30 00000000 00000000 00000000 00000000
+           40 00000000 00000000 00000000 00000000
+           50 00000000 00000000 00000000 00000000
+           60 00000000 00000000 00000000 00000000
+           70 00000000 00000000 00000000 00000000
+           80 000000CA 56
+
+    herein.  Programs with marginal XMODEM implementations do not fare so
+    well.  Timesharing systems and packet switched networks can separate the
+    successive characters, rendering this method unreliable.
+
+    Sending programs may detect the CK sequence if the operating enviornment
+    does not preclude reliable implementation.
+
+    Instead of the standard YMODEM file length in decimal, KMD and IMP
+    transmit the CP/M record count in the last two bytes of the header block.
+
+
+    6.  YMODEM-g File Transmission
+
+    Developing technology is providing phone line data transmission at ever
+    higher speeds using very specialized techniques.  These high speed modems,
+    as well as session protocols such as X.PC, provide high speed, nearly
+    error free communications at the expense of considerably increased delay
+    time.
+
+    This delay time is moderate compared to human interactions, but it
+    cripples the throughput of most error correcting protocols.
+
+    The g option to YMODEM has proven effective under these circumstances.
+    The g option is driven by the receiver, which initiates the batch transfer
+    by transmitting a G instead of C.  When the sender recognizes the G, it
+    bypasses the usual wait for an ACK to each transmitted block, sending
+    succeeding blocks at full speed, subject to XOFF/XON or other flow control
+    exerted by the medium.
+
+    The sender expects an inital G to initiate the transmission of a
+    particular file, and also expects an ACK on the EOT sent at the end of
+    each file.  This synchronization allows the receiver time to open and
+
+
+
+    Chapter 6                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             19
+
+
+
+    close files as necessary.
+
+    If an error is detected in a YMODEM-g transfer, the receiver aborts the
+    transfer with the multiple CAN abort sequence.  The ZMODEM protocol should
+    be used in applications that require both streaming throughput and error
+    recovery.
+
+            Figure 8.  YMODEM-g Transmission Session
+
+            SENDER                                  RECEIVER
+                                                    "sb foo.*<CR>"
+            "sending in batch mode etc..."
+                                                    G (command:rb -g)
+            SOH 00 FF foo.c NUL[123] CRC CRC
+                                                    G
+            SOH 01 FE Data[128] CRC CRC
+            STX 02 FD Data[1024] CRC CRC
+            SOH 03 FC Data[128] CRC CRC
+            SOH 04 FB Data[100] CPMEOF[28] CRC CRC
+            EOT
+                                                    ACK
+                                                    G
+            SOH 00 FF NUL[128] CRC CRC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 6                                     XMODEM Protocol Enhancements
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             20
+
+
+
+    7.  XMODEM PROTOCOL OVERVIEW
+
+    8/9/82 by Ward Christensen.
+
+    I will maintain a master copy of this.  Please pass on changes or
+    suggestions via CBBS/Chicago at (312) 545-8086, CBBS/CPMUG (312) 849-1132
+    or by voice at (312) 849-6279.
+
+    7.1  Definitions
+
+      <soh> 01H
+      <eot> 04H
+      <ack> 06H
+      <nak> 15H
+      <can> 18H
+      <C>   43H
+
+
+    7.2  Transmission Medium Level Protocol
+
+    Asynchronous, 8 data bits, no parity, one stop bit.
+
+    The protocol imposes no restrictions on the contents of the data being
+    transmitted.  No control characters are looked for in the 128-byte data
+    messages.  Absolutely any kind of data may be sent - binary, ASCII, etc.
+    The protocol has not formally been adopted to a 7-bit environment for the
+    transmission of ASCII-only (or unpacked-hex) data , although it could be
+    simply by having both ends agree to AND the protocol-dependent data with
+    7F hex before validating it.  I specifically am referring to the checksum,
+    and the block numbers and their ones- complement.
+
+    Those wishing to maintain compatibility of the CP/M file structure, i.e.
+    to allow modemming ASCII files to or from CP/M systems should follow this
+    data format:
+
+       + ASCII tabs used (09H); tabs set every 8.
+
+       + Lines terminated by CR/LF (0DH 0AH)
+
+       + End-of-file indicated by ^Z, 1AH.  (one or more)
+
+       + Data is variable length, i.e. should be considered a continuous
+         stream of data bytes, broken into 128-byte chunks purely for the
+         purpose of transmission.
+
+       + A CP/M "peculiarity": If the data ends exactly on a 128-byte
+         boundary, i.e. CR in 127, and LF in 128, a subsequent sector
+         containing the ^Z EOF character(s) is optional, but is preferred.
+         Some utilities or user programs still do not handle EOF without ^Zs.
+
+
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             21
+
+
+
+       + The last block sent is no different from others, i.e.  there is no
+         "short block".
+                  Figure 9.  XMODEM Message Block Level Protocol
+
+    Each block of the transfer looks like:
+          <SOH><blk #><255-blk #><--128 data bytes--><cksum>
+    in which:
+    <SOH>         = 01 hex
+    <blk #>       = binary number, starts at 01 increments by 1, and
+                    wraps 0FFH to 00H (not to 01)
+    <255-blk #>   = blk # after going thru 8080 "CMA" instr, i.e.
+                    each bit complemented in the 8-bit block number.
+                    Formally, this is the "ones complement".
+    <cksum>       = the sum of the data bytes only.  Toss any carry.
+
+    7.3  File Level Protocol
+
+    7.3.1  Common_to_Both_Sender_and_Receiver
+    All errors are retried 10 times.  For versions running with an operator
+    (i.e. NOT with XMODEM), a message is typed after 10 errors asking the
+    operator whether to "retry or quit".
+
+    Some versions of the protocol use <can>, ASCII ^X, to cancel transmission.
+    This was never adopted as a standard, as having a single "abort" character
+    makes the transmission susceptible to false termination due to an <ack>
+    <nak> or <soh> being corrupted into a <can> and aborting transmission.
+
+    The protocol may be considered "receiver driven", that is, the sender need
+    not automatically re-transmit, although it does in the current
+    implementations.
+
+
+    7.3.2  Receive_Program_Considerations
+    The receiver has a 10-second timeout.  It sends a <nak> every time it
+    times out.  The receiver's first timeout, which sends a <nak>, signals the
+    transmitter to start.  Optionally, the receiver could send a <nak>
+    immediately, in case the sender was ready.  This would save the initial 10
+    second timeout.  However, the receiver MUST continue to timeout every 10
+    seconds in case the sender wasn't ready.
+
+    Once into a receiving a block, the receiver goes into a one-second timeout
+    for each character and the checksum.  If the receiver wishes to <nak> a
+    block for any reason (invalid header, timeout receiving data), it must
+    wait for the line to clear.  See "programming tips" for ideas
+
+    Synchronizing:  If a valid block number is received, it will be: 1) the
+    expected one, in which case everything is fine; or 2) a repeat of the
+    previously received block.  This should be considered OK, and only
+    indicates that the receivers <ack> got glitched, and the sender re-
+    transmitted; 3) any other block number indicates a fatal loss of
+    synchronization, such as the rare case of the sender getting a line-glitch
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             22
+
+
+
+    that looked like an <ack>.  Abort the transmission, sending a <can>
+
+
+    7.3.3  Sending_program_considerations
+    While waiting for transmission to begin, the sender has only a single very
+    long timeout, say one minute.  In the current protocol, the sender has a
+    10 second timeout before retrying.  I suggest NOT doing this, and letting
+    the protocol be completely receiver-driven.  This will be compatible with
+    existing programs.
+
+    When the sender has no more data, it sends an <eot>, and awaits an <ack>,
+    resending the <eot> if it doesn't get one.  Again, the protocol could be
+    receiver-driven, with the sender only having the high-level 1-minute
+    timeout to abort.
+
+
+    Here is a sample of the data flow, sending a 3-block message.  It includes
+    the two most common line hits - a garbaged block, and an <ack> reply
+    getting garbaged.  <xx> represents the checksum byte.
+
+                  Figure 10.  Data flow including Error Recovery
+
+    SENDER                                  RECEIVER
+                                  times out after 10 seconds,
+                                  <---              <nak>
+    <soh> 01 FE -data- <xx>       --->
+                                  <---              <ack>
+    <soh> 02 FD -data- xx         --->       (data gets line hit)
+                                  <---              <nak>
+    <soh> 02 FD -data- xx         --->
+                                  <---              <ack>
+    <soh> 03 FC -data- xx         --->
+    (ack gets garbaged)           <---              <ack>
+    <soh> 03 FC -data- xx         --->              <ack>
+    <eot>                         --->
+                                  <---       <anything except ack>
+    <eot>                         --->
+                                  <---              <ack>
+    (finished)
+
+    7.4  Programming Tips
+
+       + The character-receive subroutine should be called with a parameter
+         specifying the number of seconds to wait.  The receiver should first
+         call it with a time of 10, then <nak> and try again, 10 times.
+
+         After receiving the <soh>, the receiver should call the character
+         receive subroutine with a 1-second timeout, for the remainder of the
+         message and the <cksum>.  Since they are sent as a continuous stream,
+         timing out of this implies a serious like glitch that caused, say,
+         127 characters to be seen instead of 128.
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             23
+
+
+
+       + When the receiver wishes to <nak>, it should call a "PURGE"
+         subroutine, to wait for the line to clear.  Recall the sender tosses
+         any characters in its UART buffer immediately upon completing sending
+         a block, to ensure no glitches were mis- interpreted.
+
+         The most common technique is for "PURGE" to call the character
+         receive subroutine, specifying a 1-second timeout,[1] and looping
+         back to PURGE until a timeout occurs.  The <nak> is then sent,
+         ensuring the other end will see it.
+
+       + You may wish to add code recommended by John Mahr to your character
+         receive routine - to set an error flag if the UART shows framing
+         error, or overrun.  This will help catch a few more glitches - the
+         most common of which is a hit in the high bits of the byte in two
+         consecutive bytes.  The <cksum> comes out OK since counting in 1-byte
+         produces the same result of adding 80H + 80H as with adding 00H +
+         00H.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    __________
+
+     1. These times should be adjusted for use with timesharing systems.
+
+
+
+
+    Chapter 7                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             24
+
+
+
+    8.  XMODEM/CRC Overview
+
+    Original 1/13/85 by John Byrns -- CRC option.
+
+    Please pass on any reports of errors in this document or suggestions for
+    improvement to me via Ward's/CBBS at (312) 849-1132, or by voice at (312)
+    885-1105.
+
+    The CRC used in the Modem Protocol is an alternate form of block check
+    which provides more robust error detection than the original checksum.
+    Andrew S. Tanenbaum says in his book, Computer Networks, that the CRC-
+    CCITT used by the Modem Protocol will detect all single and double bit
+    errors, all errors with an odd number of bits, all burst errors of length
+    16 or less, 99.997% of 17-bit error bursts, and 99.998% of 18-bit and
+    longer bursts.[1]
+
+    The changes to the Modem Protocol to replace the checksum with the CRC are
+    straight forward. If that were all that we did we would not be able to
+    communicate between a program using the old checksum protocol and one
+    using the new CRC protocol. An initial handshake was added to solve this
+    problem. The handshake allows a receiving program with CRC capability to
+    determine whether the sending program supports the CRC option, and to
+    switch it to CRC mode if it does. This handshake is designed so that it
+    will work properly with programs which implement only the original
+    protocol. A description of this handshake is presented in section 10.
+
+                Figure 11.  Message Block Level Protocol, CRC mode
+
+    Each block of the transfer in CRC mode looks like:
+         <SOH><blk #><255-blk #><--128 data bytes--><CRC hi><CRC lo>
+    in which:
+    <SOH>        = 01 hex
+    <blk #>      = binary number, starts at 01 increments by 1, and
+                   wraps 0FFH to 00H (not to 01)
+    <255-blk #>  = ones complement of blk #.
+    <CRC hi>     = byte containing the 8 hi order coefficients of the CRC.
+    <CRC lo>     = byte containing the 8 lo order coefficients of the CRC.
+
+    8.1  CRC Calculation
+
+    8.1.1  Formal_Definition
+    To calculate the 16 bit CRC the message bits are considered to be the
+    coefficients of a polynomial. This message polynomial is first multiplied
+    by X^16 and then divided by the generator polynomial (X^16 + X^12 + X^5 +
+
+
+    __________
+
+     1. This reliability figure is misleading because XMODEM's critical
+        supervisory functions are not protected by this CRC.
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             25
+
+
+
+    1) using modulo two arithmetic. The remainder left after the division is
+    the desired CRC. Since a message block in the Modem Protocol is 128 bytes
+    or 1024 bits, the message polynomial will be of order X^1023. The hi order
+    bit of the first byte of the message block is the coefficient of X^1023 in
+    the message polynomial.  The lo order bit of the last byte of the message
+    block is the coefficient of X^0 in the message polynomial.
+
+               Figure 12.  Example of CRC Calculation written in C
+
+    The following XMODEM crc routine is taken from "rbsb.c".  Please refer to
+    the source code for these programs (contained in RZSZ.ZOO) for usage.  A
+    fast table driven version is also included in this file.
+
+    /* update CRC */
+    unsigned short
+    updcrc(c, crc)
+    register c;
+    register unsigned crc;
+    {
+            register count;
+
+            for (count=8; --count>=0;) {
+                    if (crc & 0x8000) {
+                            crc <<= 1;
+                            crc += (((c<<=1) & 0400)  !=  0);
+                            crc ^= 0x1021;
+                    }
+                    else {
+                            crc <<= 1;
+                            crc += (((c<<=1) & 0400)  !=  0);
+                    }
+            }
+            return crc;
+    }
+
+    8.2  CRC File Level Protocol Changes
+
+    8.2.1  Common_to_Both_Sender_and_Receiver
+    The only change to the File Level Protocol for the CRC option is the
+    initial handshake which is used to determine if both the sending and the
+    receiving programs support the CRC mode. All Modem Programs should support
+    the checksum mode for compatibility with older versions.  A receiving
+    program that wishes to receive in CRC mode implements the mode setting
+    handshake by sending a <C> in place of the initial <nak>.  If the sending
+    program supports CRC mode it will recognize the <C> and will set itself
+    into CRC mode, and respond by sending the first block as if a <nak> had
+    been received. If the sending program does not support CRC mode it will
+    not respond to the <C> at all. After the receiver has sent the <C> it will
+    wait up to 3 seconds for the <soh> that starts the first block. If it
+    receives a <soh> within 3 seconds it will assume the sender supports CRC
+    mode and will proceed with the file exchange in CRC mode. If no <soh> is
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             26
+
+
+
+    received within 3 seconds the receiver will switch to checksum mode, send
+    a <nak>, and proceed in checksum mode. If the receiver wishes to use
+    checksum mode it should send an initial <nak> and the sending program
+    should respond to the <nak> as defined in the original Modem Protocol.
+    After the mode has been set by the initial <C> or <nak> the protocol
+    follows the original Modem Protocol and is identical whether the checksum
+    or CRC is being used.
+
+
+    8.2.2  Receive_Program_Considerations
+    There are at least 4 things that can go wrong with the mode setting
+    handshake.
+
+      1.  the initial <C> can be garbled or lost.
+
+      2.  the initial <soh> can be garbled.
+
+      3.  the initial <C> can be changed to a <nak>.
+
+      4.  the initial <nak> from a receiver which wants to receive in checksum
+          can be changed to a <C>.
+
+    The first problem can be solved if the receiver sends a second <C> after
+    it times out the first time. This process can be repeated several times.
+    It must not be repeated too many times before sending a <nak> and
+    switching to checksum mode or a sending program without CRC support may
+    time out and abort. Repeating the <C> will also fix the second problem if
+    the sending program cooperates by responding as if a <nak> were received
+    instead of ignoring the extra <C>.
+
+    It is possible to fix problems 3 and 4 but probably not worth the trouble
+    since they will occur very infrequently. They could be fixed by switching
+    modes in either the sending or the receiving program after a large number
+    of successive <nak>s. This solution would risk other problems however.
+
+
+    8.2.3  Sending_Program_Considerations
+    The sending program should start in the checksum mode. This will insure
+    compatibility with checksum only receiving programs. Anytime a <C> is
+    received before the first <nak> or <ack> the sending program should set
+    itself into CRC mode and respond as if a <nak> were received. The sender
+    should respond to additional <C>s as if they were <nak>s until the first
+    <ack> is received. This will assist the receiving program in determining
+    the correct mode when the <soh> is lost or garbled. After the first <ack>
+    is received the sending program should ignore <C>s.
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             27
+
+
+
+    8.3  Data Flow Examples with CRC Option
+
+    Here is a data flow example for the case where the receiver requests
+    transmission in the CRC mode but the sender does not support the CRC
+    option. This example also includes various transmission errors.  <xx>
+    represents the checksum byte.
+
+          Figure 13.  Data Flow: Receiver has CRC Option, Sender Doesn't
+
+    SENDER                                        RECEIVER
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <C>
+                                    times out after 3 seconds,
+                            <---                <nak>
+    <soh> 01 FE -data- <xx> --->
+                            <---                <ack>
+    <soh> 02 FD -data- <xx> --->        (data gets line hit)
+                            <---                <nak>
+    <soh> 02 FD -data- <xx> --->
+                            <---                <ack>
+    <soh> 03 FC -data- <xx> --->
+       (ack gets garbaged)  <---                <ack>
+                                    times out after 10 seconds,
+                            <---                <nak>
+    <soh> 03 FC -data- <xx> --->
+                            <---                <ack>
+    <eot>                   --->
+                            <---                <ack>
+
+    Here is a data flow example for the case where the receiver requests
+    transmission in the CRC mode and the sender supports the CRC option.  This
+    example also includes various transmission errors.  <xxxx> represents the
+    2 CRC bytes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             28
+
+
+
+               Figure 14.  Receiver and Sender Both have CRC Option
+
+    SENDER                                       RECEIVER
+                              <---                 <C>
+    <soh> 01 FE -data- <xxxx> --->
+                              <---                 <ack>
+    <soh> 02 FD -data- <xxxx> --->         (data gets line hit)
+                              <---                 <nak>
+    <soh> 02 FD -data- <xxxx> --->
+                              <---                 <ack>
+    <soh> 03 FC -data- <xxxx> --->
+    (ack gets garbaged)       <---                 <ack>
+                                         times out after 10 seconds,
+                              <---                 <nak>
+    <soh> 03 FC -data- <xxxx> --->
+                              <---                 <ack>
+    <eot>                     --->
+                              <---                 <ack>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    Chapter 8                                         Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             29
+
+
+
+    9.  MORE INFORMATION
+
+    Please contact Omen Technology for troff source files and typeset copies
+    of this document.
+
+
+    9.1  TeleGodzilla Bulletin Board
+
+    More information may be obtained by calling TeleGodzilla at 503-621-3746.
+    Speed detection is automatic for 1200, 2400 and 19200(Telebit PEP) bps.
+    TrailBlazer modem users may issue the TeleGodzilla trailblazer command to
+    swith to 19200 bps once they have logged in.
+
+    Interesting files include RZSZ.ZOO (C source code), YZMODEM.ZOO (Official
+    XMODEM, YMODEM, and ZMODEM protocol descriptions), ZCOMMEXE.ARC,
+    ZCOMMDOC.ARC, and ZCOMMHLP.ARC (PC-DOS shareware comm program with XMODEM,
+    True YMODEM(TM), ZMODEM, Kermit Sliding Windows, Telink, MODEM7 Batch,
+    script language, etc.).
+
+
+    9.2  Unix UUCP Access
+
+    UUCP sites can obtain the current version of this file with
+                     uucp omen!/u/caf/public/ymodem.doc /tmp
+    A continually updated list of available files is stored in
+    /usr/spool/uucppublic/FILES.  When retrieving these files with uucp,
+    remember that the destination directory on your system must be writeable
+    by anyone, or the UUCP transfer will fail.
+
+    The following L.sys line calls TeleGodzilla (Pro-YAM in host operation).
+    TeleGodzilla determines the incoming speed automatically.
+
+    In response to "Name Please:" uucico gives the Pro-YAM "link" command as a
+    user name.  The password (Giznoid) controls access to the Xenix system
+    connected to the IBM PC's other serial port.  Communications between
+    Pro-YAM and Xenix use 9600 bps; YAM converts this to the caller's speed.
+
+    Finally, the calling uucico logs in as uucp.
+
+    omen Any ACU 2400 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp
+
+
+
+    10.  REVISIONS
+
+    6-18-88 Further revised for clarity.  Corrected block numbering in two
+    examples.
+    10-27-87 Optional fields added for number of files remaining to be sent
+    and total number of bytes remaining to be sent.
+    10-18-87 Flow control discussion added to 1024 byte block descritpion,
+    minor revisions for clarity per user comments.
+
+
+
+    Chapter 10                                        Xmodem Protocol Overview
+
+
+
+
+
+
+
+    X/YMODEM Protocol Reference    June 18 1988                             30
+
+
+
+    8-03-87 Revised for clarity.
+    5-31-1987 emphasizes minimum requirements for YMODEM, and updates
+    information on accessing files.
+    9-11-1986 clarifies nomenclature and some minor points.
+    The April 15 1986 edition clarifies some points concerning CRC
+    calculations and spaces in the header.
+
+
+    11.  YMODEM Programs
+
+    ZCOMM, A shareware little brother to Professional-YAM, is available as
+    ZCOMMEXE.ARC on TeleGodzilla and other bulletin board systems.  ZCOMM may
+    be used to test YMODEM amd ZMODEM implementations.
+
+    Unix programs supporting YMODEM are available on TeleGodzilla in RZSZ.ZOO.
+    This ZOO archive includes a ZCOMM/Pro-YAM/PowerCom script ZUPL.T to upload
+    a bootstrap program MINIRB.C, compile it, and then upload the rest of the
+    files using the compiled MINIRB.  Most Unix like systems are supported,
+    including V7, Xenix, Sys III, 4.2 BSD, SYS V, Idris, Coherent, and
+    Regulus.
+
+    A version for VAX-VMS is available in VRBSB.SHQ.
+
+    Irv Hoff has added 1k blocks and basic YMODEM batch transfers to the KMD
+    and IMP series programs, which replace the XMODEM and MODEM7/MDM7xx series
+    respectively.  Overlays are available for a wide variety of CP/M systems.
+
+    Questions about Professional-YAM communications software may be directed
+    to:
+         Chuck Forsberg
+         Omen Technology Inc
+         17505-V Sauvie Island Road
+         Portland Oregon 97231
+         VOICE: 503-621-3406 :VOICE
+         Modem: 503-621-3746 Speed: 19200(Telebit PEP),2400,1200,300
+         Usenet: ...!tektronix!reed!omen!caf
+         CompuServe: 70007,2304
+         GEnie: CAF
+
+    Unlike ZMODEM and Kermit, XMODEM and YMODEM place obstacles in the path of
+    a reliable high performance implementation, evidenced by poor reliability
+    under stress of the industry leaders' XMODEM and YMODEM programs.  Omen
+    Technology provides consulting and other services to those wishing to
+    implement XMODEM, YMODEM, and ZMODEM with state of the art features and
+    reliability.
+
+
+
+
+
+
+
+
+
+    Chapter 11                                        Xmodem Protocol Overview
+
+
+
+
+
+
+
+
+
+
+
+                                     CONTENTS
+
+
+     1.  TOWER OF BABEL...................................................   2
+         1.1  Definitions.................................................   2
+
+     2.  YMODEM MINIMUM REQUIREMENTS......................................   4
+
+     3.  WHY YMODEM?......................................................   6
+         3.1  Some Messages from the Pioneer..............................   7
+
+     4.  XMODEM PROTOCOL ENHANCEMENTS.....................................  10
+         4.1  Graceful Abort..............................................  10
+         4.2  CRC-16 Option...............................................  10
+         4.3  XMODEM-1k 1024 Byte Block...................................  11
+
+     5.  YMODEM Batch File Transmission...................................  13
+         5.1  KMD/IMP Exceptions to YMODEM................................  16
+
+     6.  YMODEM-g File Transmission.......................................  18
+
+     7.  XMODEM PROTOCOL OVERVIEW.........................................  20
+         7.1  Definitions.................................................  20
+         7.2  Transmission Medium Level Protocol..........................  20
+         7.3  File Level Protocol.........................................  21
+         7.4  Programming Tips............................................  22
+
+     8.  XMODEM/CRC Overview..............................................  24
+         8.1  CRC Calculation.............................................  24
+         8.2  CRC File Level Protocol Changes.............................  25
+         8.3  Data Flow Examples with CRC Option..........................  27
+
+     9.  MORE INFORMATION.................................................  29
+         9.1  TeleGodzilla Bulletin Board.................................  29
+         9.2  Unix UUCP Access............................................  29
+
+    10.  REVISIONS........................................................  29
+
+    11.  YMODEM Programs..................................................  30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - i -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                 LIST OF FIGURES
+
+
+     Figure 1.  XMODEM-1k Blocks..........................................  12
+
+     Figure 2.  Mixed 1024 and 128 byte Blocks............................  12
+
+     Figure 3.  YMODEM Batch Transmission Session (1 file)................  16
+
+     Figure 4.  YMODEM Batch Transmission Session (2 files)...............  16
+
+     Figure 5.  YMODEM Batch Transmission Session-1k Blocks...............  16
+
+     Figure 6.  YMODEM Filename block transmitted by sz...................  16
+
+     Figure 7.  YMODEM Header Information and Features....................  16
+
+     Figure 8.  YMODEM-g Transmission Session.............................  19
+
+     Figure 9.  XMODEM Message Block Level Protocol.......................  21
+
+    Figure 10.  Data flow including Error Recovery........................  22
+
+    Figure 11.  Message Block Level Protocol, CRC mode....................  24
+
+    Figure 12.  Example of CRC Calculation written in C...................  25
+
+    Figure 13.  Data Flow: Receiver has CRC Option, Sender Doesn't........  27
+
+    Figure 14.  Receiver and Sender Both have CRC Option..................  28
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                      - ii -
Index: bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libupload/zout.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,100 @@
+/*
+ * Compress input and feed it to a block-oriented back end.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "upload_backend.h"
+#include "ctime.h"
+
+#define ALLOC_CHUNK	65536
+
+int init_data(struct upload_backend *be, const char *argv[])
+{
+    be->now = posix_time();
+    be->argv = argv;
+
+    memset(&be->zstream, 0, sizeof be->zstream);
+
+    be->zstream.next_out  = NULL;
+    be->outbuf = NULL;
+    be->zstream.avail_out = be->alloc  = 0;
+    be->dbytes = be->zbytes = 0;
+
+    /* Initialize a gzip data stream */
+    if (deflateInit2(&be->zstream, 9, Z_DEFLATED,
+		     16+15, 9, Z_DEFAULT_STRATEGY) < 0)
+	return -1;
+
+    return 0;
+}
+
+static int do_deflate(struct upload_backend *be, int flush)
+{
+    int rv;
+    char *buf;
+
+    while (1) {
+	rv = deflate(&be->zstream, flush);
+	be->zbytes = be->alloc - be->zstream.avail_out;
+	if (be->zstream.avail_out)
+	    return rv;		   /* Not an issue of output space... */
+
+	buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK);
+	if (!buf)
+	    return Z_MEM_ERROR;
+	be->outbuf = buf;
+	be->alloc += ALLOC_CHUNK;
+	be->zstream.next_out = (void *)(buf + be->zbytes);
+	be->zstream.avail_out = be->alloc - be->zbytes;
+    }
+}
+
+
+int write_data(struct upload_backend *be, const void *buf, size_t len)
+{
+    int rv = Z_OK;
+
+    be->zstream.next_in = (void *)buf;
+    be->zstream.avail_in = len;
+
+    be->dbytes += len;
+
+    while (be->zstream.avail_in) {
+	rv = do_deflate(be, Z_NO_FLUSH);
+	if (rv < 0) {
+	    printf("do_deflate returned %d\n", rv);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+/* Output the data and shut down the stream */
+int flush_data(struct upload_backend *be)
+{
+    int rv = Z_OK;
+    int err=-1;
+
+    while (rv != Z_STREAM_END) {
+	rv = do_deflate(be, Z_FINISH);
+	if (rv < 0)
+	    return -1;
+    }
+
+//    printf("Uploading data, %u bytes... ", be->zbytes);
+
+    if ((err=be->write(be)) != 0)
+	return err;
+
+    free(be->outbuf);
+    be->outbuf = NULL;
+    be->dbytes = be->zbytes = be->alloc = 0;
+
+//    printf("done.\n");
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,65 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+##
+##   Permission is hereby granted, free of charge, to any person
+##   obtaining a copy of this software and associated documentation
+##   files (the "Software"), to deal in the Software without
+##   restriction, including without limitation the rights to use,
+##   copy, modify, merge, publish, distribute, sublicense, and/or
+##   sell copies of the Software, and to permit persons to whom
+##   the Software is furnished to do so, subject to the following
+##   conditions:
+##
+##   The above copyright notice and this permission notice shall
+##   be included in all copies or substantial portions of the Software.
+##
+##   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+##   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+##   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+##   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+##   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+##   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+##   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+##   OTHER DEALINGS IN THE SOFTWARE.
+##
+## -----------------------------------------------------------------------
+
+##
+## Utility companion library for the COM32 library
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LIBOBJS	   = ansiline.o ansiraw.o keyname.o \
+	     sha1hash.o unbase64.o \
+	     md5.o crypt-md5.o sha256crypt.o sha512crypt.o base64.o \
+	     quicksort.o
+LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS))
+
+all: libutil.c32 libutil_lnx.a
+
+libutil.elf: $(LIBOBJS)
+	$(LD) $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
+
+libutil_lnx.a: $(LNXLIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $(LNXLIBOBJS)
+	$(RANLIB) $@
+
+tidy dist:
+	rm -f *.o *.lo *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx libutil_lnx.a
+
+spotless: clean
+	rm -f *.lss *.a *.c32 *.com
+	rm -f *~ \#*
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
+	install -m 644 libutil_lnx.a $(INSTALLROOT)$(COM32DIR)
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/ansiline.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/ansiline.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/ansiline.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ansiline.c
+ *
+ * Configures the console for ANSI output in line mode; versions
+ * for COM32 and Linux support.
+ */
+
+#ifdef __COM32__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <console.h>
+
+void console_ansi_std(void)
+{
+    openconsole(&dev_stdcon_r, &dev_ansiserial_w);
+}
+
+#else
+
+#include <stdio.h>
+#include <termios.h>
+
+static struct termios original_termios_settings;
+
+static void __attribute__ ((constructor)) console_init(void)
+{
+    tcgetattr(0, &original_termios_settings);
+}
+
+static void __attribute__ ((destructor)) console_cleanup(void)
+{
+    tcsetattr(0, TCSANOW, &original_termios_settings);
+}
+
+void console_ansi_std(void)
+{
+    struct termios tio;
+
+    /* Disable stdio buffering */
+    setbuf(stdin, NULL);
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+
+    /* Set the termios flag so we behave the same as libcom32 */
+    tcgetattr(0, &tio);
+    tio.c_iflag &= ~ICRNL;
+    tio.c_iflag |= IGNCR;
+    tio.c_lflag |= ICANON | ECHO;
+    if (!tio.c_oflag & OPOST)
+	tio.c_oflag = 0;
+    tio.c_oflag |= OPOST | ONLCR;
+    tcsetattr(0, TCSANOW, &tio);
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/ansiraw.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/ansiraw.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/ansiraw.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,104 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ansiraw.c
+ *
+ * Configures the console for ANSI output in raw mode; versions
+ * for COM32 and Linux support.
+ */
+
+#ifdef __COM32__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <console.h>
+
+void console_ansi_raw(void)
+{
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+}
+
+#else
+
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+
+static struct termios original_termios_settings;
+
+static void __attribute__ ((constructor)) console_init(void)
+{
+    tcgetattr(0, &original_termios_settings);
+}
+
+static void __attribute__ ((destructor)) console_cleanup(void)
+{
+    tcsetattr(0, TCSANOW, &original_termios_settings);
+}
+
+void console_ansi_raw(void)
+{
+    struct termios tio;
+
+    /* Disable stdio buffering */
+    setbuf(stdin, NULL);
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+
+    /* Set the termios flag so we behave the same as libcom32 */
+    tcgetattr(0, &tio);
+    tio.c_iflag &= ~ICRNL;
+    tio.c_iflag |= IGNCR;
+    tio.c_lflag &= ~(ISIG | ICANON | ECHO);
+    if (!tio.c_oflag & OPOST)
+	tio.c_oflag = 0;
+    tio.c_oflag |= OPOST | ONLCR;
+    tio.c_cc[VMIN] = 0;
+    tio.c_cc[VTIME] = 1;	/* Don't 100% busy-wait in Linux */
+    tcsetattr(0, TCSAFLUSH, &tio);
+}
+
+int raw_read(int fd, void *buf, size_t count)
+{
+	struct termios tio, rtio;
+	int rv;
+
+	tcgetattr(fd, &tio);
+
+	cfmakeraw(&rtio);
+	tcsetattr(fd, 0, &rtio);
+
+	rv = read(fd, buf, count);
+
+	/* Restore settings */
+	tcsetattr(fd, 0, &tio);
+
+	return rv;
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/base64.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/base64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/base64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,95 @@
+/*
+ * Output a base64 string.
+ *
+ * Options include:
+ * - Character 62 and 63;
+ * - To pad or not to pad.
+ */
+
+#include <inttypes.h>
+#include <base64.h>
+
+size_t genbase64(char *output, const void *input, size_t size, int flags)
+{
+    static char charz[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
+    uint8_t buf[3];
+    int j;
+    const uint8_t *p;
+    char *q;
+    uint32_t bv;
+    int left = size;
+
+    charz[62] = (char)flags;
+    charz[63] = (char)(flags >> 8);
+
+    p = input;
+    q = output;
+
+    while (left > 0) {
+	if (left < 3) {
+	    buf[0] = p[0];
+	    buf[1] = (left > 1) ? p[1] : 0;
+	    buf[2] = 0;
+	    p = buf;
+	}
+
+	bv = (p[0] << 16) | (p[1] << 8) | p[2];
+	p += 3;
+	left -= 3;
+
+	for (j = 0; j < 4; j++) {
+	    *q++ = charz[(bv >> 18) & 0x3f];
+	    bv <<= 6;
+	}
+    }
+
+    switch (left) {
+    case -1:
+	if (flags & BASE64_PAD)
+	    q[-1] = '=';
+	else
+	    q--;
+	break;
+
+    case -2:
+	if (flags & BASE64_PAD)
+	    q[-2] = q[-1] = '=';
+	else
+	    q -= 2;
+	break;
+
+    default:
+	break;
+    }
+
+    *q = '\0';
+
+    return q - output;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+    int i;
+    char buf[4096];
+    int len, bytes;
+
+    for (i = 1; i < argc; i++) {
+	printf("Original: \"%s\"\n", argv[i]);
+
+	len = strlen(argv[i]);
+	bytes = genbase64(buf, argv[i], len, BASE64_MIME | BASE64_PAD);
+	printf("    MIME: \"%s\" (%d)\n", buf, bytes);
+	bytes = genbase64(buf, argv[i], len, BASE64_SAFE);
+	printf("    Safe: \"%s\" (%d)\n", buf, bytes);
+    }
+
+    return 0;
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/crypt-md5.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/crypt-md5.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/crypt-md5.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <inttypes.h>
+#include <md5.h>
+#include <string.h>
+
+/*
+ * UNIX password
+ */
+
+static char *_crypt_to64(char *s, uint32_t v, int n)
+{
+    static const char itoa64[64] = "./0123456789"
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+    while (--n >= 0) {
+	*s++ = itoa64[v & 0x3f];
+	v >>= 6;
+    }
+    return s;
+}
+
+char *crypt_md5(const char *pw, const char *salt)
+{
+    MD5_CTX ctx, ctx1;
+    unsigned long l;
+    int sl, pl;
+    uint32_t i;
+    uint8_t final[MD5_SIZE];
+    const char *sp;
+    static char passwd[120];	/* Output buffer */
+    static const char magic[] = "$1$";
+    char *p;
+    const int magic_len = sizeof magic - 1;
+    int pwlen = strlen(pw);
+
+    /* Refine the Salt first */
+    sp = salt;
+
+    /* If it starts with the magic string, then skip that */
+    if (!strncmp(sp, magic, magic_len))
+	sp += magic_len;
+
+    /* Compute the salt length:
+       it stops at the first '$', max 8 chars */
+    for (sl = 0; sl < 8 && sp[sl] && sp[sl] != '$'; sl++) ;
+
+    MD5Init(&ctx);
+
+    /* The password first, since that is what is most unknown */
+    MD5Update(&ctx, pw, pwlen);
+
+    /* Then our magic string */
+    MD5Update(&ctx, magic, magic_len);
+
+    /* Then the raw salt */
+    MD5Update(&ctx, sp, sl);
+
+    /* Then just as many characters of the MD5(pw,salt,pw) */
+    MD5Init(&ctx1);
+    MD5Update(&ctx1, pw, pwlen);
+    MD5Update(&ctx1, sp, sl);
+    MD5Update(&ctx1, pw, pwlen);
+    MD5Final(final, &ctx1);
+    for (pl = pwlen; pl > 0; pl -= MD5_SIZE)
+	MD5Update(&ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl);
+
+    /* Don't leave anything around in vm they could use. */
+    memset(final, 0, sizeof final);
+
+    /* Then something really weird... */
+    for (i = pwlen; i; i >>= 1)
+	if (i & 1)
+	    MD5Update(&ctx, final, 1);
+	else
+	    MD5Update(&ctx, pw, 1);
+
+    /* Now make the output string */
+    p = passwd;
+
+    memcpy(p, magic, magic_len);
+    p += magic_len;
+
+    memcpy(p, sp, sl);
+    p += sl;
+
+    *p++ = '$';
+
+    MD5Final(final, &ctx);
+
+    /*
+     * and now, just to make sure things don't run too fast
+     * On a 60 Mhz Pentium this takes 34 msec, so you would
+     * need 30 seconds to build a 1000 entry dictionary...
+     */
+    for (i = 0; i < 1000; i++) {
+	MD5Init(&ctx1);
+	if (i & 1)
+	    MD5Update(&ctx1, pw, pwlen);
+	else
+	    MD5Update(&ctx1, final, MD5_SIZE);
+
+	if (i % 3)
+	    MD5Update(&ctx1, sp, sl);
+
+	if (i % 7)
+	    MD5Update(&ctx1, pw, pwlen);
+
+	if (i & 1)
+	    MD5Update(&ctx1, final, MD5_SIZE);
+	else
+	    MD5Update(&ctx1, pw, pwlen);
+	MD5Final(final, &ctx1);
+    }
+
+    l = (final[0] << 16) | (final[6] << 8) | final[12];
+    p = _crypt_to64(p, l, 4);
+    l = (final[1] << 16) | (final[7] << 8) | final[13];
+    p = _crypt_to64(p, l, 4);
+    l = (final[2] << 16) | (final[8] << 8) | final[14];
+    p = _crypt_to64(p, l, 4);
+    l = (final[3] << 16) | (final[9] << 8) | final[15];
+    p = _crypt_to64(p, l, 4);
+    l = (final[4] << 16) | (final[10] << 8) | final[5];
+    p = _crypt_to64(p, l, 4);
+    l = final[11];
+    p = _crypt_to64(p, l, 2);
+    *p = '\0';
+
+    /* Don't leave anything around in vm they could use. */
+    memset(final, 0, sizeof final);
+
+    return passwd;
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int i;
+
+    for (i = 2; i < argc; i += 2) {
+	puts(crypt_md5(argv[i], argv[i - 1]));
+    }
+    return 0;
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/base64.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/base64.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/base64.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * base64.h
+ *
+ * Simple routines for handing base64 text
+ */
+
+#ifndef LIBUTIL_BASE64_H
+#define LIBUTIL_BASE64_H
+
+#include <stddef.h>
+
+#define BASE64_PAD	0x10000
+
+/* There is plenty of disagreement w.r.t. the last few characters... */
+#define BASE64_MIME	('+' + ('/' << 8))
+#define BASE64_SAFE	('-' + ('_' << 8))
+#define BASE64_CRYPT	('.' + ('/' << 8))
+#define BASE64_URL	('*' + ('-' << 8))	/* Haven't seen myself */
+#define BASE64_REGEX	('|' + ('-' << 8))	/* Ditto... */
+
+size_t genbase64(char *output, const void *digest, size_t size, int flags);
+size_t unbase64(unsigned char *, size_t, const char *);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/consoles.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/consoles.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/consoles.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * consoles.h
+ *
+ * Utility functions for common console configurations
+ */
+
+#ifndef LIBUTIL_CONSOLES_H
+#define LIBUTIL_CONSOLES_H
+
+void console_ansi_std(void);
+void console_ansi_raw(void);
+
+#endif /* LIBUTIL_CONSOLES_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/getkey.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/getkey.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/getkey.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,87 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * getkey.h
+ *
+ * Function to get a key symbol and parse it
+ */
+
+#ifndef LIBUTIL_GETKEY_H
+#define LIBUTIL_GETKEY_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/times.h>
+
+#ifndef CLK_TCK
+# define CLK_TCK sysconf(_SC_CLK_TCK)
+#endif
+
+#define KEY_NONE	(-1)
+
+#define KEY_CTRL(x)	((x) & 0x001f)
+#define KEY_BACKSPACE	0x0008
+#define KEY_TAB		0x0009
+#define KEY_ENTER	0x000d
+#define KEY_ESC		0x001b
+#define KEY_DEL		0x007f
+
+#define KEY_F1		0x0100
+#define KEY_F2		0x0101
+#define KEY_F3		0x0102
+#define KEY_F4		0x0103
+#define KEY_F5		0x0104
+#define KEY_F6		0x0105
+#define KEY_F7		0x0106
+#define KEY_F8		0x0107
+#define KEY_F9		0x0108
+#define KEY_F10		0x0109
+#define KEY_F11		0x010A
+#define KEY_F12		0x010B
+
+#define KEY_UP		0x0120
+#define KEY_DOWN	0x0121
+#define KEY_LEFT	0x0122
+#define KEY_RIGHT	0x0123
+#define KEY_PGUP	0x0124
+#define KEY_PGDN	0x0125
+#define KEY_HOME	0x0126
+#define KEY_END		0x0127
+#define KEY_INSERT	0x0128
+#define KEY_DELETE	0x0129
+
+#define KEY_MAX		0x012a
+
+#define KEY_MAXLEN	8
+
+int get_key(FILE *, clock_t);
+int key_name_to_code(const char *);
+const char *key_code_to_name(int);
+int get_key_decode(char *, int, int *);
+
+#endif /* LIBUTIL_GETKEY_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/libutil.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/libutil.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/libutil.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * libutil.h
+ *
+ * Misc libutil functions
+ */
+
+#ifndef LIBUTIL_LIBUTIL_H
+#define LIBUTIL_LIBUTIL_H
+
+#ifdef __COM32__
+
+# include <syslinux/idle.h>
+
+# define do_idle syslinux_idle
+
+#else /* not __COM32__ */
+
+# include <sched.h>
+
+# define do_idle sched_yield
+
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/md5.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/md5.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/md5.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifndef _LIBUTIL_MD5_H
+#define _LIBUTIL_MD5_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MD5_SIZE 16		/* 128 bits */
+
+/* MD5 context. */
+typedef struct {
+    uint32_t state[4];		/* state (ABCD) */
+    uint32_t count[2];		/* number of bits, modulo 2^64 (lsb first) */
+    unsigned char buffer[64];	/* input buffer */
+} MD5_CTX;
+
+void MD5Init(MD5_CTX *);
+void MD5Update(MD5_CTX *, const void *, size_t);
+void MD5Final(unsigned char[MD5_SIZE], MD5_CTX *);
+
+char *crypt_md5(const char *, const char *);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/minmax.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/minmax.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/minmax.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _MINMAX_H
+#define _MINMAX_H
+
+/*
+ * minmax.h: Type-independent safe min/max macros
+ */
+
+#define min(x,y) ({ __typeof(x) xx = (x); \
+                    __typeof(y) yy = (y); \
+                    xx < yy ? xx : yy; })
+#define max(x,y) ({ __typeof(x) xx = (x); \
+                    __typeof(y) yy = (y); \
+                    xx > yy ? xx : yy; })
+
+#endif /* _MINMAX_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/sha1.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/sha1.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/sha1.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,18 @@
+#ifndef LIBUTIL_SHA1_H
+#define LIBUTIL_SHA1_H
+
+#include <stdint.h>
+
+typedef struct {
+    uint32_t state[5];
+    uint32_t count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX * context);
+void SHA1Update(SHA1_CTX * context, const unsigned char *data, uint32_t len);	/*
+										   JHB */
+void SHA1Final(unsigned char digest[20], SHA1_CTX * context);
+
+#endif /* LIBUTIL_SHA1_H */
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/include/xcrypt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/include/xcrypt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/include/xcrypt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10 @@
+#ifndef _LIBUTIL_XCRYPT_H
+#define _LIBUTIL_XCRYPT_H
+
+/* Extended crypt() implementations */
+
+char *crypt_md5(const char *, const char *);
+char *sha256_crypt(const char *, const char *);
+char *sha512_crypt(const char *, const char *);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/keyname.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/keyname.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/keyname.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,138 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * keyname.c
+ *
+ * Conversion between strings and get_key() key numbers.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/times.h>
+#include <getkey.h>
+#include <libutil.h>
+
+struct keyname {
+    const char *string;
+    int key;
+};
+
+static const struct keyname key_names[] = {
+    { "Backspace", KEY_BACKSPACE },
+    { "Tab", KEY_TAB },
+    { "Enter", KEY_ENTER },
+    { "Esc", KEY_ESC },
+    { "Escape", KEY_ESC },
+    { "Space", ' ' },
+    { "^?", KEY_DEL },
+    { "F1", KEY_F1 },
+    { "F2", KEY_F2},
+    { "F3", KEY_F3 },
+    { "F4", KEY_F4 },
+    { "F5", KEY_F5 },
+    { "F6", KEY_F6 },
+    { "F7", KEY_F7 },
+    { "F8", KEY_F8 },
+    { "F9", KEY_F9 },
+    { "F10", KEY_F10 },
+    { "F11", KEY_F11 },
+    { "F12", KEY_F12 },
+    { "Up", KEY_UP },
+    { "Down", KEY_DOWN },
+    { "Left", KEY_LEFT },
+    { "Right", KEY_RIGHT },
+    { "PgUp", KEY_PGUP },
+    { "PgDn", KEY_PGDN },
+    { "Home", KEY_HOME },
+    { "End", KEY_END },
+    { "Insert", KEY_INSERT },
+    { "Delete", KEY_DELETE },
+    { NULL, KEY_NONE }
+};
+
+int key_name_to_code(const char *code)
+{
+    const struct keyname *name;
+
+    if (code[0] && !code[1]) {
+	/* Single character */
+	return (unsigned char)code[0];
+    } else if (code[0] == '^' && code[1] && !code[2]) {
+	/* Control character */
+	if (code[1] == '?')
+	    return 0x7f;
+	else
+	    return (unsigned char)code[1] & 0x9f;
+    }
+
+
+    for (name = key_names; name->string; name++) {
+	if (!strcasecmp(name->string, code))
+	    break;
+    }
+    return name->key;	/* KEY_NONE at end of array */
+}
+
+const char *key_code_to_name(int key)
+{
+    static char buf[4];
+    const struct keyname *name;
+
+    if (key < 0)
+	return NULL;
+
+    if (key > ' ' && key < 0x100) {
+	if (key & 0x60) {
+	    buf[0] = key;
+	    buf[1] = '\0';
+	} else {
+	    buf[0] = '^';
+	    buf[1] = key | 0x40;
+	    buf[2] = '\0';
+	}
+	return buf;
+    }
+
+    for (name = key_names; name->string; name++) {
+	if (key == name->key)
+	    return name->string;
+    }
+
+    if (key < ' ') {
+	buf[0] = '^';
+	buf[1] = key | 0x40;
+	buf[2] = '\0';
+	return buf;
+    }
+
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/md5.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/md5.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/md5.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,273 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * This code is the same as the code published by RSA Inc.  It has been
+ * edited for clarity and style only.
+ */
+
+#include <string.h>
+#include <endian.h>
+#include <md5.h>
+
+static void MD5Transform(uint32_t[4], const unsigned char[64]);
+
+#define Encode memcpy
+#define Decode memcpy
+
+static unsigned char PADDING[64] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+	(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+	(a) = ROTATE_LEFT ((a), (s)); \
+	(a) += (b); \
+	}
+#define GG(a, b, c, d, x, s, ac) { \
+	(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+	(a) = ROTATE_LEFT ((a), (s)); \
+	(a) += (b); \
+	}
+#define HH(a, b, c, d, x, s, ac) { \
+	(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+	(a) = ROTATE_LEFT ((a), (s)); \
+	(a) += (b); \
+	}
+#define II(a, b, c, d, x, s, ac) { \
+	(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+	(a) = ROTATE_LEFT ((a), (s)); \
+	(a) += (b); \
+	}
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+
+void MD5Init(MD5_CTX * context)
+{
+    context->count[0] = context->count[1] = 0;
+
+    /* Load magic initialization constants.  */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xefcdab89;
+    context->state[2] = 0x98badcfe;
+    context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+
+void MD5Update(MD5_CTX * context, const void *in, size_t inputLen)
+{
+    unsigned int i, idx, partLen;
+    const unsigned char *input = in;
+
+    /* Compute number of bytes mod 64 */
+    idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+    /* Update number of bits */
+    if ((context->count[0] += ((uint32_t) inputLen << 3))
+	< ((uint32_t) inputLen << 3))
+	context->count[1]++;
+    context->count[1] += ((uint32_t) inputLen >> 29);
+
+    partLen = 64 - idx;
+
+    /* Transform as many times as possible. */
+    if (inputLen >= partLen) {
+	memcpy((void *)&context->buffer[idx], (const void *)input, partLen);
+	MD5Transform(context->state, context->buffer);
+
+	for (i = partLen; i + 63 < inputLen; i += 64)
+	    MD5Transform(context->state, &input[i]);
+
+	idx = 0;
+    } else
+	i = 0;
+
+    /* Buffer remaining input */
+    memcpy((void *)&context->buffer[idx], (const void *)&input[i],
+	   inputLen - i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+
+static void MD5Pad(MD5_CTX * context)
+{
+    unsigned char bits[8];
+    unsigned int idx, padLen;
+
+    /* Save number of bits */
+    Encode(bits, context->count, 8);
+
+    /* Pad out to 56 mod 64. */
+    idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
+    padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+    MD5Update(context, PADDING, padLen);
+
+    /* Append length (before padding) */
+    MD5Update(context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+
+void MD5Final(unsigned char digest[16], MD5_CTX * context)
+{
+    /* Do padding. */
+    MD5Pad(context);
+
+    /* Store state in digest */
+    Encode(digest, context->state, 16);
+
+    /* Zeroize sensitive information. */
+    memset((void *)context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static void MD5Transform(state, block)
+uint32_t state[4];
+const unsigned char block[64];
+{
+    uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+    Decode(x, block, 64);
+
+    /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+    FF(a, b, c, d, x[0], S11, 0xd76aa478);	/* 1 */
+    FF(d, a, b, c, x[1], S12, 0xe8c7b756);	/* 2 */
+    FF(c, d, a, b, x[2], S13, 0x242070db);	/* 3 */
+    FF(b, c, d, a, x[3], S14, 0xc1bdceee);	/* 4 */
+    FF(a, b, c, d, x[4], S11, 0xf57c0faf);	/* 5 */
+    FF(d, a, b, c, x[5], S12, 0x4787c62a);	/* 6 */
+    FF(c, d, a, b, x[6], S13, 0xa8304613);	/* 7 */
+    FF(b, c, d, a, x[7], S14, 0xfd469501);	/* 8 */
+    FF(a, b, c, d, x[8], S11, 0x698098d8);	/* 9 */
+    FF(d, a, b, c, x[9], S12, 0x8b44f7af);	/* 10 */
+    FF(c, d, a, b, x[10], S13, 0xffff5bb1);	/* 11 */
+    FF(b, c, d, a, x[11], S14, 0x895cd7be);	/* 12 */
+    FF(a, b, c, d, x[12], S11, 0x6b901122);	/* 13 */
+    FF(d, a, b, c, x[13], S12, 0xfd987193);	/* 14 */
+    FF(c, d, a, b, x[14], S13, 0xa679438e);	/* 15 */
+    FF(b, c, d, a, x[15], S14, 0x49b40821);	/* 16 */
+
+    /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+    GG(a, b, c, d, x[1], S21, 0xf61e2562);	/* 17 */
+    GG(d, a, b, c, x[6], S22, 0xc040b340);	/* 18 */
+    GG(c, d, a, b, x[11], S23, 0x265e5a51);	/* 19 */
+    GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);	/* 20 */
+    GG(a, b, c, d, x[5], S21, 0xd62f105d);	/* 21 */
+    GG(d, a, b, c, x[10], S22, 0x2441453);	/* 22 */
+    GG(c, d, a, b, x[15], S23, 0xd8a1e681);	/* 23 */
+    GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);	/* 24 */
+    GG(a, b, c, d, x[9], S21, 0x21e1cde6);	/* 25 */
+    GG(d, a, b, c, x[14], S22, 0xc33707d6);	/* 26 */
+    GG(c, d, a, b, x[3], S23, 0xf4d50d87);	/* 27 */
+    GG(b, c, d, a, x[8], S24, 0x455a14ed);	/* 28 */
+    GG(a, b, c, d, x[13], S21, 0xa9e3e905);	/* 29 */
+    GG(d, a, b, c, x[2], S22, 0xfcefa3f8);	/* 30 */
+    GG(c, d, a, b, x[7], S23, 0x676f02d9);	/* 31 */
+    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);	/* 32 */
+
+    /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+    HH(a, b, c, d, x[5], S31, 0xfffa3942);	/* 33 */
+    HH(d, a, b, c, x[8], S32, 0x8771f681);	/* 34 */
+    HH(c, d, a, b, x[11], S33, 0x6d9d6122);	/* 35 */
+    HH(b, c, d, a, x[14], S34, 0xfde5380c);	/* 36 */
+    HH(a, b, c, d, x[1], S31, 0xa4beea44);	/* 37 */
+    HH(d, a, b, c, x[4], S32, 0x4bdecfa9);	/* 38 */
+    HH(c, d, a, b, x[7], S33, 0xf6bb4b60);	/* 39 */
+    HH(b, c, d, a, x[10], S34, 0xbebfbc70);	/* 40 */
+    HH(a, b, c, d, x[13], S31, 0x289b7ec6);	/* 41 */
+    HH(d, a, b, c, x[0], S32, 0xeaa127fa);	/* 42 */
+    HH(c, d, a, b, x[3], S33, 0xd4ef3085);	/* 43 */
+    HH(b, c, d, a, x[6], S34, 0x4881d05);	/* 44 */
+    HH(a, b, c, d, x[9], S31, 0xd9d4d039);	/* 45 */
+    HH(d, a, b, c, x[12], S32, 0xe6db99e5);	/* 46 */
+    HH(c, d, a, b, x[15], S33, 0x1fa27cf8);	/* 47 */
+    HH(b, c, d, a, x[2], S34, 0xc4ac5665);	/* 48 */
+
+    /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+    II(a, b, c, d, x[0], S41, 0xf4292244);	/* 49 */
+    II(d, a, b, c, x[7], S42, 0x432aff97);	/* 50 */
+    II(c, d, a, b, x[14], S43, 0xab9423a7);	/* 51 */
+    II(b, c, d, a, x[5], S44, 0xfc93a039);	/* 52 */
+    II(a, b, c, d, x[12], S41, 0x655b59c3);	/* 53 */
+    II(d, a, b, c, x[3], S42, 0x8f0ccc92);	/* 54 */
+    II(c, d, a, b, x[10], S43, 0xffeff47d);	/* 55 */
+    II(b, c, d, a, x[1], S44, 0x85845dd1);	/* 56 */
+    II(a, b, c, d, x[8], S41, 0x6fa87e4f);	/* 57 */
+    II(d, a, b, c, x[15], S42, 0xfe2ce6e0);	/* 58 */
+    II(c, d, a, b, x[6], S43, 0xa3014314);	/* 59 */
+    II(b, c, d, a, x[13], S44, 0x4e0811a1);	/* 60 */
+    II(a, b, c, d, x[4], S41, 0xf7537e82);	/* 61 */
+    II(d, a, b, c, x[11], S42, 0xbd3af235);	/* 62 */
+    II(c, d, a, b, x[2], S43, 0x2ad7d2bb);	/* 63 */
+    II(b, c, d, a, x[9], S44, 0xeb86d391);	/* 64 */
+
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+
+    /* Zeroize sensitive information. */
+    memset((void *)x, 0, sizeof(x));
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/quicksort.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/quicksort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/quicksort.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/*
+ * sort.c - Sample ELF module providing a quick sort function
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <stdlib.h>
+
+static inline void swap(int *x, int *y)
+{
+    int tmp;
+    tmp = *x;
+    *x = *y;
+    *y = tmp;
+}
+
+static inline int randint(int l, int u)
+{
+    return l + (rand() % (u - l + 1));
+}
+
+/**
+ * quick_sort_range - A small and efficient version of quicksort.
+ * @nums: The numbers to sort
+ * @l: The lower index in the vector (inclusive)
+ * @u: The upper index in the vector (inclusive)
+ *
+ * The implementation is taken from "Beautiful Code", by O'Reilly, the
+ * book students received from Google as a gift for their acceptance
+ * in the GSoC 2008 program. The code belongs to Jon Bentley, who
+ * wrote the third chapter of the book. Since ELF modules were written
+ * as part of this program, the author of the module considered
+ * the book had to be put to some use. :)
+ */
+static void quick_sort_range(int *nums, int l, int u)
+{
+    int i, m;
+    if (l >= u)
+	return;
+
+    swap(&nums[l], &nums[randint(l, u)]);
+
+    m = l;
+    for (i = l + 1; i <= u; i++) {
+	if (nums[i] < nums[l])
+	    swap(&nums[++m], &nums[i]);
+    }
+
+    swap(&nums[l], &nums[m]);
+
+    quick_sort_range(nums, l, m - 1);
+    quick_sort_range(nums, m + 1, u);
+}
+
+void quick_sort(int *nums, int count)
+{
+    quick_sort_range(nums, 0, count - 1);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/sha1hash.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/sha1hash.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/sha1hash.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,364 @@
+/*
+SHA-1 in C
+By Steve Reid <sreid@sea-to-sky.net>
+100% Public Domain
+
+-----------------
+Modified 7/98
+By James H. Brown <jbrown@burgoyne.com>
+Still 100% Public Domain
+
+Corrected a problem which generated improper hash values on 16 bit machines
+Routine SHA1Update changed from
+	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
+len)
+to
+	void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
+long len)
+
+The 'len' parameter was declared an int which works fine on 32 bit machines.
+However, on 16 bit machines an int is too small for the shifts being done
+against
+it.  This caused the hash function to generate incorrect values if len was
+greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
+
+Since the file IO in main() reads 16K at a time, any file 8K or larger would
+be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
+"a"s).
+
+I also changed the declaration of variables i & j in SHA1Update to
+unsigned long from unsigned int for the same reason.
+
+These changes should make no difference to any 32 bit implementations since
+an
+int and a long are the same size in those environments.
+
+--
+I also corrected a few compiler warnings generated by Borland C.
+1. Added #include <process.h> for exit() prototype
+2. Removed unused variable 'j' in SHA1Final
+3. Changed exit(0) to return(0) at end of main.
+
+ALL changes I made can be located by searching for comments containing 'JHB'
+-----------------
+Modified 8/98
+By Steve Reid <sreid@sea-to-sky.net>
+Still 100% public domain
+
+1- Removed #include <process.h> and used return() instead of exit()
+2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
+3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
+
+-----------------
+Modified 4/01
+By Saul Kravitz <Saul.Kravitz@celera.com>
+Still 100% PD
+Modified to run on Compaq Alpha hardware.
+
+-----------------
+Modified 2/03
+By H. Peter Anvin <hpa@zytor.com>
+Still 100% PD
+Modified to run on any hardware with <inttypes.h> and <netinet/in.h>
+Changed the driver program
+
+*/
+
+/*
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define SHA1HANDSOFF  */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <netinet/in.h>		/* For htonl/ntohl/htons/ntohs */
+
+#include "sha1.h"
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#define blk0(i) (block->l[i] = ntohl(block->l[i]))
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+#ifdef VERBOSE			/* SAK */
+void SHAPrintContext(SHA1_CTX * context, char *msg)
+{
+    printf("%s (%d,%d) %x %x %x %x %x\n",
+	   msg,
+	   context->count[0], context->count[1],
+	   context->state[0],
+	   context->state[1],
+	   context->state[2], context->state[3], context->state[4]);
+}
+#endif
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64])
+{
+    uint32_t a, b, c, d, e;
+    typedef union {
+	unsigned char c[64];
+	uint32_t l[16];
+    } CHAR64LONG16;
+    CHAR64LONG16 *block;
+#ifdef SHA1HANDSOFF
+    static unsigned char workspace[64];
+    block = (CHAR64LONG16 *) workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16 *) buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a, b, c, d, e, 0);
+    R0(e, a, b, c, d, 1);
+    R0(d, e, a, b, c, 2);
+    R0(c, d, e, a, b, 3);
+    R0(b, c, d, e, a, 4);
+    R0(a, b, c, d, e, 5);
+    R0(e, a, b, c, d, 6);
+    R0(d, e, a, b, c, 7);
+    R0(c, d, e, a, b, 8);
+    R0(b, c, d, e, a, 9);
+    R0(a, b, c, d, e, 10);
+    R0(e, a, b, c, d, 11);
+    R0(d, e, a, b, c, 12);
+    R0(c, d, e, a, b, 13);
+    R0(b, c, d, e, a, 14);
+    R0(a, b, c, d, e, 15);
+    R1(e, a, b, c, d, 16);
+    R1(d, e, a, b, c, 17);
+    R1(c, d, e, a, b, 18);
+    R1(b, c, d, e, a, 19);
+    R2(a, b, c, d, e, 20);
+    R2(e, a, b, c, d, 21);
+    R2(d, e, a, b, c, 22);
+    R2(c, d, e, a, b, 23);
+    R2(b, c, d, e, a, 24);
+    R2(a, b, c, d, e, 25);
+    R2(e, a, b, c, d, 26);
+    R2(d, e, a, b, c, 27);
+    R2(c, d, e, a, b, 28);
+    R2(b, c, d, e, a, 29);
+    R2(a, b, c, d, e, 30);
+    R2(e, a, b, c, d, 31);
+    R2(d, e, a, b, c, 32);
+    R2(c, d, e, a, b, 33);
+    R2(b, c, d, e, a, 34);
+    R2(a, b, c, d, e, 35);
+    R2(e, a, b, c, d, 36);
+    R2(d, e, a, b, c, 37);
+    R2(c, d, e, a, b, 38);
+    R2(b, c, d, e, a, 39);
+    R3(a, b, c, d, e, 40);
+    R3(e, a, b, c, d, 41);
+    R3(d, e, a, b, c, 42);
+    R3(c, d, e, a, b, 43);
+    R3(b, c, d, e, a, 44);
+    R3(a, b, c, d, e, 45);
+    R3(e, a, b, c, d, 46);
+    R3(d, e, a, b, c, 47);
+    R3(c, d, e, a, b, 48);
+    R3(b, c, d, e, a, 49);
+    R3(a, b, c, d, e, 50);
+    R3(e, a, b, c, d, 51);
+    R3(d, e, a, b, c, 52);
+    R3(c, d, e, a, b, 53);
+    R3(b, c, d, e, a, 54);
+    R3(a, b, c, d, e, 55);
+    R3(e, a, b, c, d, 56);
+    R3(d, e, a, b, c, 57);
+    R3(c, d, e, a, b, 58);
+    R3(b, c, d, e, a, 59);
+    R4(a, b, c, d, e, 60);
+    R4(e, a, b, c, d, 61);
+    R4(d, e, a, b, c, 62);
+    R4(c, d, e, a, b, 63);
+    R4(b, c, d, e, a, 64);
+    R4(a, b, c, d, e, 65);
+    R4(e, a, b, c, d, 66);
+    R4(d, e, a, b, c, 67);
+    R4(c, d, e, a, b, 68);
+    R4(b, c, d, e, a, 69);
+    R4(a, b, c, d, e, 70);
+    R4(e, a, b, c, d, 71);
+    R4(d, e, a, b, c, 72);
+    R4(c, d, e, a, b, 73);
+    R4(b, c, d, e, a, 74);
+    R4(a, b, c, d, e, 75);
+    R4(e, a, b, c, d, 76);
+    R4(d, e, a, b, c, 77);
+    R4(c, d, e, a, b, 78);
+    R4(b, c, d, e, a, 79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX * context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX * context, const unsigned char *data, uint32_t len)
+{				/*
+				   JHB */
+    uint32_t i, j;		/* JHB */
+
+#ifdef VERBOSE
+    SHAPrintContext(context, "before");
+#endif
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3))
+	context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+	memcpy(&context->buffer[j], data, (i = 64 - j));
+	SHA1Transform(context->state, context->buffer);
+	for (; i + 63 < len; i += 64) {
+	    SHA1Transform(context->state, &data[i]);
+	}
+	j = 0;
+    } else
+	i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+#ifdef VERBOSE
+    SHAPrintContext(context, "after ");
+#endif
+}
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX * context)
+{
+    uint32_t i;			/* JHB */
+    unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+	finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+					 >> ((3 - (i & 3)) * 8)) & 255);	/* Endian independent */
+    }
+    SHA1Update(context, (unsigned char *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+	SHA1Update(context, (unsigned char *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);	/* Should cause a SHA1Transform()
+					 */
+    for (i = 0; i < 20; i++) {
+	digest[i] = (unsigned char)
+	    ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+    }
+    /* Wipe variables */
+    i = 0;			/* JHB */
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(finalcount, 0, 8);	/* SWR */
+#ifdef SHA1HANDSOFF		/* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+/*************************************************************/
+
+/* This is not quite the MIME base64 algorithm: it uses _ instead of /,
+   and instead of padding the output with = characters we just make the
+   output shorter. */
+char *mybase64(uint8_t digest[20])
+{
+    static const char charz[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
+    uint8_t input[21];
+    static char output[28];
+    int i, j;
+    uint8_t *p;
+    char *q;
+    uint32_t bv;
+
+    memcpy(input, digest, 20);
+    input[20] = 0;		/* Pad to multiple of 3 bytes */
+
+    p = input;
+    q = output;
+    for (i = 0; i < 7; i++) {
+	bv = (p[0] << 16) | (p[1] << 8) | p[2];
+	p += 3;
+	for (j = 0; j < 4; j++) {
+	    *q++ = charz[(bv >> 18) & 0x3f];
+	    bv <<= 6;
+	}
+    }
+    *--q = '\0';		/* The last character is not significant */
+    return output;
+}
+
+#ifdef FOR_TESTING_ONLY
+
+int main(int argc, char **argv)
+{
+    int i;
+    SHA1_CTX context;
+    uint8_t digest[20], buffer[16384];
+    FILE *file;
+
+    if (argc < 2) {
+	file = stdin;
+    } else {
+	if (!(file = fopen(argv[1], "rb"))) {
+	    fputs("Unable to open file.", stderr);
+	    return (-1);
+	}
+    }
+    SHA1Init(&context);
+    while (!feof(file)) {	/* note: what if ferror(file) */
+	i = fread(buffer, 1, 16384, file);
+	SHA1Update(&context, buffer, i);
+    }
+    SHA1Final(digest, &context);
+    fclose(file);
+
+    puts(mybase64(digest));
+
+    return 0;
+}
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/sha256crypt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/sha256crypt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/sha256crypt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,680 @@
+/* SHA256-based Unix crypt implementation.
+   Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.  */
+
+#include <alloca.h>
+#include <endian.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <minmax.h>
+#include <sys/types.h>
+
+#include "xcrypt.h"
+
+#define MIN(x,y) min(x,y)
+#define MAX(x,y) max(x,y)
+
+/* Structure to save state of computation between the single steps.  */
+struct sha256_ctx {
+    uint32_t H[8];
+
+    uint32_t total[2];
+    uint32_t buflen;
+    char buffer[128];		/* NB: always correctly aligned for uint32_t.  */
+};
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define SWAP(n) \
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (FIPS 180-2:5.1.1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */  };
+
+/* Constants for SHA256 from FIPS 180-2:4.2.2.  */
+static const uint32_t K[64] = {
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+static void
+sha256_process_block(const void *buffer, size_t len, struct sha256_ctx *ctx)
+{
+    unsigned int t;
+    const uint32_t *words = buffer;
+    size_t nwords = len / sizeof(uint32_t);
+    uint32_t a = ctx->H[0];
+    uint32_t b = ctx->H[1];
+    uint32_t c = ctx->H[2];
+    uint32_t d = ctx->H[3];
+    uint32_t e = ctx->H[4];
+    uint32_t f = ctx->H[5];
+    uint32_t g = ctx->H[6];
+    uint32_t h = ctx->H[7];
+
+    /* First increment the byte count.  FIPS 180-2 specifies the possible
+       length of the file up to 2^64 bits.  Here we only compute the
+       number of bytes.  Do a double word increment.  */
+    ctx->total[0] += len;
+    if (ctx->total[0] < len)
+	++ctx->total[1];
+
+    /* Process all bytes in the buffer with 64 bytes in each round of
+       the loop.  */
+    while (nwords > 0) {
+	uint32_t W[64];
+	uint32_t a_save = a;
+	uint32_t b_save = b;
+	uint32_t c_save = c;
+	uint32_t d_save = d;
+	uint32_t e_save = e;
+	uint32_t f_save = f;
+	uint32_t g_save = g;
+	uint32_t h_save = h;
+
+	/* Operators defined in FIPS 180-2:4.1.2.  */
+#define Ch(x, y, z) ((x & y) ^ (~x & z))
+#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+#define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22))
+#define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25))
+#define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3))
+#define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10))
+
+	/* It is unfortunate that C does not provide an operator for
+	   cyclic rotation.  Hope the C compiler is smart enough.  */
+#define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
+
+	/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2.  */
+	for (t = 0; t < 16; ++t) {
+	    W[t] = SWAP(*words);
+	    ++words;
+	}
+	for (t = 16; t < 64; ++t)
+	    W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
+
+	/* The actual computation according to FIPS 180-2:6.2.2 step 3.  */
+	for (t = 0; t < 64; ++t) {
+	    uint32_t T1 = h + S1(e) + Ch(e, f, g) + K[t] + W[t];
+	    uint32_t T2 = S0(a) + Maj(a, b, c);
+	    h = g;
+	    g = f;
+	    f = e;
+	    e = d + T1;
+	    d = c;
+	    c = b;
+	    b = a;
+	    a = T1 + T2;
+	}
+
+	/* Add the starting values of the context according to FIPS 180-2:6.2.2
+	   step 4.  */
+	a += a_save;
+	b += b_save;
+	c += c_save;
+	d += d_save;
+	e += e_save;
+	f += f_save;
+	g += g_save;
+	h += h_save;
+
+	/* Prepare for the next round.  */
+	nwords -= 16;
+    }
+
+    /* Put checksum in context given as argument.  */
+    ctx->H[0] = a;
+    ctx->H[1] = b;
+    ctx->H[2] = c;
+    ctx->H[3] = d;
+    ctx->H[4] = e;
+    ctx->H[5] = f;
+    ctx->H[6] = g;
+    ctx->H[7] = h;
+}
+
+/* Initialize structure containing state of computation.
+   (FIPS 180-2:5.3.2)  */
+static void sha256_init_ctx(struct sha256_ctx *ctx)
+{
+    ctx->H[0] = 0x6a09e667;
+    ctx->H[1] = 0xbb67ae85;
+    ctx->H[2] = 0x3c6ef372;
+    ctx->H[3] = 0xa54ff53a;
+    ctx->H[4] = 0x510e527f;
+    ctx->H[5] = 0x9b05688c;
+    ctx->H[6] = 0x1f83d9ab;
+    ctx->H[7] = 0x5be0cd19;
+
+    ctx->total[0] = ctx->total[1] = 0;
+    ctx->buflen = 0;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf)
+{
+    unsigned int i;
+    /* Take yet unprocessed bytes into account.  */
+    uint32_t bytes = ctx->buflen;
+    size_t pad;
+
+    /* Now count remaining bytes.  */
+    ctx->total[0] += bytes;
+    if (ctx->total[0] < bytes)
+	++ctx->total[1];
+
+    pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+    memcpy(&ctx->buffer[bytes], fillbuf, pad);
+
+    /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+    *(uint32_t *) & ctx->buffer[bytes + pad + 4] = SWAP(ctx->total[0] << 3);
+    *(uint32_t *) & ctx->buffer[bytes + pad] = SWAP((ctx->total[1] << 3) |
+						    (ctx->total[0] >> 29));
+
+    /* Process last bytes.  */
+    sha256_process_block(ctx->buffer, bytes + pad + 8, ctx);
+
+    /* Put result from CTX in first 32 bytes following RESBUF.  */
+    for (i = 0; i < 8; ++i)
+	((uint32_t *) resbuf)[i] = SWAP(ctx->H[i]);
+
+    return resbuf;
+}
+
+static void
+sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx)
+{
+    /* When we already have some bits in our internal buffer concatenate
+       both inputs first.  */
+    if (ctx->buflen != 0) {
+	size_t left_over = ctx->buflen;
+	size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+	memcpy(&ctx->buffer[left_over], buffer, add);
+	ctx->buflen += add;
+
+	if (ctx->buflen > 64) {
+	    sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
+
+	    ctx->buflen &= 63;
+	    /* The regions in the following copy operation cannot overlap.  */
+	    memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+		   ctx->buflen);
+	}
+
+	buffer = (const char *)buffer + add;
+	len -= add;
+    }
+
+    /* Process available complete blocks.  */
+    if (len >= 64) {
+/* To check alignment gcc has an appropriate operator.  Other
+   compilers don't.  */
+#if __GNUC__ >= 2
+# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0)
+#else
+# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0)
+#endif
+	if (UNALIGNED_P(buffer))
+	    while (len > 64) {
+		sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx);
+		buffer = (const char *)buffer + 64;
+		len -= 64;
+	} else {
+	    sha256_process_block(buffer, len & ~63, ctx);
+	    buffer = (const char *)buffer + (len & ~63);
+	    len &= 63;
+	}
+    }
+
+    /* Move remaining bytes into internal buffer.  */
+    if (len > 0) {
+	size_t left_over = ctx->buflen;
+
+	memcpy(&ctx->buffer[left_over], buffer, len);
+	left_over += len;
+	if (left_over >= 64) {
+	    sha256_process_block(ctx->buffer, 64, ctx);
+	    left_over -= 64;
+	    memcpy(ctx->buffer, &ctx->buffer[64], left_over);
+	}
+	ctx->buflen = left_over;
+    }
+}
+
+/* Define our magic string to mark salt for SHA256 "encryption"
+   replacement.  */
+static const char sha256_salt_prefix[] = "$5$";
+
+/* Prefix for optional rounds specification.  */
+static const char sha256_rounds_prefix[] = "rounds=";
+
+/* Maximum salt string length.  */
+#define SALT_LEN_MAX 16U
+/* Default number of rounds if not explicitly specified.  */
+#define ROUNDS_DEFAULT 5000UL
+/* Minimum number of rounds.  */
+#define ROUNDS_MIN 1000UL
+/* Maximum number of rounds.  */
+#define ROUNDS_MAX 999999999UL
+
+/* Table with characters for base64 transformation.  */
+static const char b64t[64] =
+    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *sha256_crypt_r(const char *key, const char *salt, char *buffer,
+			    int buflen)
+{
+    unsigned char alt_result[32]
+	__attribute__ ((__aligned__(__alignof__(uint32_t))));
+    unsigned char temp_result[32]
+	__attribute__ ((__aligned__(__alignof__(uint32_t))));
+    struct sha256_ctx ctx;
+    struct sha256_ctx alt_ctx;
+    size_t salt_len;
+    size_t key_len;
+    size_t cnt;
+    char *cp;
+    char *copied_key = NULL;
+    char *copied_salt = NULL;
+    char *p_bytes;
+    char *s_bytes;
+    /* Default number of rounds.  */
+    size_t rounds = ROUNDS_DEFAULT;
+    bool rounds_custom = false;
+
+    /* Find beginning of salt string.  The prefix should normally always
+       be present.  Just in case it is not.  */
+    if (strncmp(sha256_salt_prefix, salt, sizeof(sha256_salt_prefix) - 1) == 0)
+	/* Skip salt prefix.  */
+	salt += sizeof(sha256_salt_prefix) - 1;
+
+    if (strncmp(salt, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1)
+	== 0) {
+	const char *num = salt + sizeof(sha256_rounds_prefix) - 1;
+	char *endp;
+	unsigned long int srounds = strtoul(num, &endp, 10);
+	if (*endp == '$') {
+	    salt = endp + 1;
+	    rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
+	    rounds_custom = true;
+	}
+    }
+
+    salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
+    key_len = strlen(key);
+
+    if ((key - (char *)0) % __alignof__(uint32_t) != 0) {
+	char *tmp = (char *)alloca(key_len + __alignof__(uint32_t));
+	key = copied_key = memcpy(tmp + __alignof__(uint32_t)
+				  - (tmp - (char *)0) % __alignof__(uint32_t),
+				  key, key_len);
+    }
+
+    if ((salt - (char *)0) % __alignof__(uint32_t) != 0) {
+	char *tmp = (char *)alloca(salt_len + __alignof__(uint32_t));
+	salt = copied_salt = memcpy(tmp + __alignof__(uint32_t)
+				    - (tmp - (char *)0) % __alignof__(uint32_t),
+				    salt, salt_len);
+    }
+
+    /* Prepare for the real work.  */
+    sha256_init_ctx(&ctx);
+
+    /* Add the key string.  */
+    sha256_process_bytes(key, key_len, &ctx);
+
+    /* The last part is the salt string.  This must be at most 8
+       characters and it ends at the first `$' character (for
+       compatibility with existing implementations).  */
+    sha256_process_bytes(salt, salt_len, &ctx);
+
+    /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
+       final result will be added to the first context.  */
+    sha256_init_ctx(&alt_ctx);
+
+    /* Add key.  */
+    sha256_process_bytes(key, key_len, &alt_ctx);
+
+    /* Add salt.  */
+    sha256_process_bytes(salt, salt_len, &alt_ctx);
+
+    /* Add key again.  */
+    sha256_process_bytes(key, key_len, &alt_ctx);
+
+    /* Now get result of this (32 bytes) and add it to the other
+       context.  */
+    sha256_finish_ctx(&alt_ctx, alt_result);
+
+    /* Add for any character in the key one byte of the alternate sum.  */
+    for (cnt = key_len; cnt > 32; cnt -= 32)
+	sha256_process_bytes(alt_result, 32, &ctx);
+    sha256_process_bytes(alt_result, cnt, &ctx);
+
+    /* Take the binary representation of the length of the key and for every
+       1 add the alternate sum, for every 0 the key.  */
+    for (cnt = key_len; cnt; cnt >>= 1)
+	if ((cnt & 1) != 0)
+	    sha256_process_bytes(alt_result, 32, &ctx);
+	else
+	    sha256_process_bytes(key, key_len, &ctx);
+
+    /* Create intermediate result.  */
+    sha256_finish_ctx(&ctx, alt_result);
+
+    /* Start computation of P byte sequence.  */
+    sha256_init_ctx(&alt_ctx);
+
+    /* For every character in the password add the entire password.  */
+    for (cnt = 0; cnt < key_len; ++cnt)
+	sha256_process_bytes(key, key_len, &alt_ctx);
+
+    /* Finish the digest.  */
+    sha256_finish_ctx(&alt_ctx, temp_result);
+
+    /* Create byte sequence P.  */
+    cp = p_bytes = alloca(key_len);
+    for (cnt = key_len; cnt >= 32; cnt -= 32)
+	cp = mempcpy(cp, temp_result, 32);
+    memcpy(cp, temp_result, cnt);
+
+    /* Start computation of S byte sequence.  */
+    sha256_init_ctx(&alt_ctx);
+
+    /* For every character in the password add the entire password.  */
+    for (cnt = 0; cnt < (size_t)16 + alt_result[0]; ++cnt)
+	sha256_process_bytes(salt, salt_len, &alt_ctx);
+
+    /* Finish the digest.  */
+    sha256_finish_ctx(&alt_ctx, temp_result);
+
+    /* Create byte sequence S.  */
+    cp = s_bytes = alloca(salt_len);
+    for (cnt = salt_len; cnt >= 32; cnt -= 32)
+	cp = mempcpy(cp, temp_result, 32);
+    memcpy(cp, temp_result, cnt);
+
+    /* Repeatedly run the collected hash value through SHA256 to burn
+       CPU cycles.  */
+    for (cnt = 0; cnt < rounds; ++cnt) {
+	/* New context.  */
+	sha256_init_ctx(&ctx);
+
+	/* Add key or last result.  */
+	if ((cnt & 1) != 0)
+	    sha256_process_bytes(p_bytes, key_len, &ctx);
+	else
+	    sha256_process_bytes(alt_result, 32, &ctx);
+
+	/* Add salt for numbers not divisible by 3.  */
+	if (cnt % 3 != 0)
+	    sha256_process_bytes(s_bytes, salt_len, &ctx);
+
+	/* Add key for numbers not divisible by 7.  */
+	if (cnt % 7 != 0)
+	    sha256_process_bytes(p_bytes, key_len, &ctx);
+
+	/* Add key or last result.  */
+	if ((cnt & 1) != 0)
+	    sha256_process_bytes(alt_result, 32, &ctx);
+	else
+	    sha256_process_bytes(p_bytes, key_len, &ctx);
+
+	/* Create intermediate result.  */
+	sha256_finish_ctx(&ctx, alt_result);
+    }
+
+    /* Now we can construct the result string.  It consists of three
+       parts.  */
+    cp = stpncpy(buffer, sha256_salt_prefix, MAX(0, buflen));
+    buflen -= sizeof(sha256_salt_prefix) - 1;
+
+    if (rounds_custom) {
+	int n = snprintf(cp, MAX(0, buflen), "%s%zu$",
+			 sha256_rounds_prefix, rounds);
+	cp += n;
+	buflen -= n;
+    }
+
+    cp = stpncpy(cp, salt, MIN((size_t) MAX(0, buflen), salt_len));
+    buflen -= MIN((size_t) MAX(0, buflen), salt_len);
+
+    if (buflen > 0) {
+	*cp++ = '$';
+	--buflen;
+    }
+#define b64_from_24bit(B2, B1, B0, N)					      \
+  do {									      \
+    unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);			      \
+    int n = (N);							      \
+    while (n-- > 0 && buflen > 0)					      \
+      {									      \
+	*cp++ = b64t[w & 0x3f];						      \
+	--buflen;							      \
+	w >>= 6;							      \
+      }									      \
+  } while (0)
+
+    b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4);
+    b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4);
+    b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4);
+    b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4);
+    b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4);
+    b64_from_24bit(alt_result[15], alt_result[25], alt_result[5], 4);
+    b64_from_24bit(alt_result[6], alt_result[16], alt_result[26], 4);
+    b64_from_24bit(alt_result[27], alt_result[7], alt_result[17], 4);
+    b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4);
+    b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4);
+    b64_from_24bit(0, alt_result[31], alt_result[30], 3);
+    if (buflen <= 0) {
+	errno = ERANGE;
+	buffer = NULL;
+    } else
+	*cp = '\0';		/* Terminate the string.  */
+
+    /* Clear the buffer for the intermediate result so that people
+       attaching to processes or reading core dumps cannot get any
+       information.  We do it in this way to clear correct_words[]
+       inside the SHA256 implementation as well.  */
+    sha256_init_ctx(&ctx);
+    sha256_finish_ctx(&ctx, alt_result);
+    memset(temp_result, '\0', sizeof(temp_result));
+    memset(p_bytes, '\0', key_len);
+    memset(s_bytes, '\0', salt_len);
+    memset(&ctx, '\0', sizeof(ctx));
+    memset(&alt_ctx, '\0', sizeof(alt_ctx));
+    if (copied_key != NULL)
+	memset(copied_key, '\0', key_len);
+    if (copied_salt != NULL)
+	memset(copied_salt, '\0', salt_len);
+
+    return buffer;
+}
+
+/* This entry point is equivalent to the `crypt' function in Unix
+   libcs.  */
+char *sha256_crypt(const char *key, const char *salt)
+{
+    /* We don't want to have an arbitrary limit in the size of the
+       password.  We can compute an upper bound for the size of the
+       result in advance and so we can prepare the buffer we pass to
+       `sha256_crypt_r'.  */
+    static char *buffer;
+    static int buflen;
+    int needed = (sizeof(sha256_salt_prefix) - 1
+		  + sizeof(sha256_rounds_prefix) + 9 + 1
+		  + strlen(salt) + 1 + 43 + 1);
+
+    if (buflen < needed) {
+	char *new_buffer = (char *)realloc(buffer, needed);
+	if (new_buffer == NULL)
+	    return NULL;
+
+	buffer = new_buffer;
+	buflen = needed;
+    }
+
+    return sha256_crypt_r(key, salt, buffer, buflen);
+}
+
+#ifdef TEST
+static const struct {
+    const char *input;
+    const char result[32];
+} tests[] = {
+    /* Test vectors from FIPS 180-2: appendix B.1.  */
+    {
+    "abc",
+	    "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
+	    "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad"},
+	/* Test vectors from FIPS 180-2: appendix B.2.  */
+    {
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	    "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+	    "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"},
+	/* Test vectors from the NESSIE project.  */
+    {
+    "", "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
+	    "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"},
+    {
+    "a", "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d"
+	    "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb"},
+    {
+    "message digest",
+	    "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad"
+	    "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50"},
+    {
+    "abcdefghijklmnopqrstuvwxyz",
+	    "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52"
+	    "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73"},
+    {
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	    "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+	    "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"},
+    {
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	    "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80"
+	    "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0"},
+    {
+    "123456789012345678901234567890123456789012345678901234567890"
+	    "12345678901234567890",
+	    "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e"
+	    "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e"}
+};
+
+#define ntests (sizeof (tests) / sizeof (tests[0]))
+
+static const struct {
+    const char *salt;
+    const char *input;
+    const char *expected;
+} tests2[] = {
+    {
+    "$5$saltstring", "Hello world!",
+	    "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5"}, {
+    "$5$rounds=10000$saltstringsaltstring", "Hello world!",
+	    "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
+	    "opqey6IcA"}, {
+    "$5$rounds=5000$toolongsaltstring", "This is just a test",
+	    "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
+	    "mGRcvxa5"}, {
+    "$5$rounds=1400$anotherlongsaltstring",
+	    "a very much longer text to encrypt.  This one even stretches over more"
+	    "than one line.",
+	    "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
+	    "oP84Bnq1"}, {
+    "$5$rounds=77777$short",
+	    "we have a short salt string but not a short password",
+	    "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/"},
+    {
+    "$5$rounds=123456$asaltof16chars..", "a short string",
+	    "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
+	    "cZKmF/wJvD"}, {
+"$5$rounds=10$roundstoolow", "the minimum number is still observed",
+	    "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
+	    "2bIC"},};
+#define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
+
+int main(void)
+{
+    struct sha256_ctx ctx;
+    char sum[32];
+    int result = 0;
+    int cnt;
+
+    for (cnt = 0; cnt < (int)ntests; ++cnt) {
+	sha256_init_ctx(&ctx);
+	sha256_process_bytes(tests[cnt].input, strlen(tests[cnt].input), &ctx);
+	sha256_finish_ctx(&ctx, sum);
+	if (memcmp(tests[cnt].result, sum, 32) != 0) {
+	    printf("test %d run %d failed\n", cnt, 1);
+	    result = 1;
+	}
+
+	sha256_init_ctx(&ctx);
+	for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
+	    sha256_process_bytes(&tests[cnt].input[i], 1, &ctx);
+	sha256_finish_ctx(&ctx, sum);
+	if (memcmp(tests[cnt].result, sum, 32) != 0) {
+	    printf("test %d run %d failed\n", cnt, 2);
+	    result = 1;
+	}
+    }
+
+    /* Test vector from FIPS 180-2: appendix B.3.  */
+    char buf[1000];
+    memset(buf, 'a', sizeof(buf));
+    sha256_init_ctx(&ctx);
+    for (int i = 0; i < 1000; ++i)
+	sha256_process_bytes(buf, sizeof(buf), &ctx);
+    sha256_finish_ctx(&ctx, sum);
+    static const char expected[32] =
+	"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
+	"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
+    if (memcmp(expected, sum, 32) != 0) {
+	printf("test %d failed\n", cnt);
+	result = 1;
+    }
+
+    for (cnt = 0; cnt < ntests2; ++cnt) {
+	char *cp = sha256_crypt(tests2[cnt].input, tests2[cnt].salt);
+
+	if (strcmp(cp, tests2[cnt].expected) != 0) {
+	    printf("test %d: expected \"%s\", got \"%s\"\n",
+		   cnt, tests2[cnt].expected, cp);
+	    result = 1;
+	}
+    }
+
+    if (result == 0)
+	puts("all tests OK");
+
+    return result;
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/sha512crypt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/sha512crypt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/sha512crypt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,749 @@
+/* SHA512-based Unix crypt implementation.
+   Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.  */
+
+#include <alloca.h>
+#include <endian.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <minmax.h>
+#include <sys/types.h>
+
+#include "xcrypt.h"
+
+#define MIN(x,y) min(x,y)
+#define MAX(x,y) max(x,y)
+
+/* Structure to save state of computation between the single steps.  */
+struct sha512_ctx {
+    uint64_t H[8];
+
+    uint64_t total[2];
+    uint64_t buflen;
+    char buffer[256];		/* NB: always correctly aligned for uint64_t.  */
+};
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define SWAP(n) \
+  (((n) << 56)					\
+   | (((n) & 0xff00) << 40)			\
+   | (((n) & 0xff0000) << 24)			\
+   | (((n) & 0xff000000) << 8)			\
+   | (((n) >> 8) & 0xff000000)			\
+   | (((n) >> 24) & 0xff0000)			\
+   | (((n) >> 40) & 0xff00)			\
+   | ((n) >> 56))
+#else
+# define SWAP(n) (n)
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (FIPS 180-2:5.1.2)  */
+static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ...  */  };
+
+/* Constants for SHA512 from FIPS 180-2:4.2.3.  */
+static const uint64_t K[80] = {
+    UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
+    UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
+    UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
+    UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
+    UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
+    UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
+    UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
+    UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
+    UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
+    UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
+    UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
+    UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
+    UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
+    UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
+    UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
+    UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
+    UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
+    UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
+    UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
+    UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
+    UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
+    UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
+    UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
+    UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
+    UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
+    UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
+    UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
+    UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
+    UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
+    UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
+    UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
+    UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
+    UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
+    UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
+    UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
+    UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
+    UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
+    UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
+    UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
+    UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
+};
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 128 == 0.  */
+static void
+sha512_process_block(const void *buffer, size_t len, struct sha512_ctx *ctx)
+{
+    unsigned int t;
+    const uint64_t *words = buffer;
+    size_t nwords = len / sizeof(uint64_t);
+    uint64_t a = ctx->H[0];
+    uint64_t b = ctx->H[1];
+    uint64_t c = ctx->H[2];
+    uint64_t d = ctx->H[3];
+    uint64_t e = ctx->H[4];
+    uint64_t f = ctx->H[5];
+    uint64_t g = ctx->H[6];
+    uint64_t h = ctx->H[7];
+
+    /* First increment the byte count.  FIPS 180-2 specifies the possible
+       length of the file up to 2^128 bits.  Here we only compute the
+       number of bytes.  Do a double word increment.  */
+    ctx->total[0] += len;
+    if (ctx->total[0] < len)
+	++ctx->total[1];
+
+    /* Process all bytes in the buffer with 128 bytes in each round of
+       the loop.  */
+    while (nwords > 0) {
+	uint64_t W[80];
+	uint64_t a_save = a;
+	uint64_t b_save = b;
+	uint64_t c_save = c;
+	uint64_t d_save = d;
+	uint64_t e_save = e;
+	uint64_t f_save = f;
+	uint64_t g_save = g;
+	uint64_t h_save = h;
+
+	/* Operators defined in FIPS 180-2:4.1.2.  */
+#define Ch(x, y, z) ((x & y) ^ (~x & z))
+#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
+#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
+#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
+#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
+
+	/* It is unfortunate that C does not provide an operator for
+	   cyclic rotation.  Hope the C compiler is smart enough.  */
+#define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))
+
+	/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2.  */
+	for (t = 0; t < 16; ++t) {
+	    W[t] = SWAP(*words);
+	    ++words;
+	}
+	for (t = 16; t < 80; ++t)
+	    W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
+
+	/* The actual computation according to FIPS 180-2:6.3.2 step 3.  */
+	for (t = 0; t < 80; ++t) {
+	    uint64_t T1 = h + S1(e) + Ch(e, f, g) + K[t] + W[t];
+	    uint64_t T2 = S0(a) + Maj(a, b, c);
+	    h = g;
+	    g = f;
+	    f = e;
+	    e = d + T1;
+	    d = c;
+	    c = b;
+	    b = a;
+	    a = T1 + T2;
+	}
+
+	/* Add the starting values of the context according to FIPS 180-2:6.3.2
+	   step 4.  */
+	a += a_save;
+	b += b_save;
+	c += c_save;
+	d += d_save;
+	e += e_save;
+	f += f_save;
+	g += g_save;
+	h += h_save;
+
+	/* Prepare for the next round.  */
+	nwords -= 16;
+    }
+
+    /* Put checksum in context given as argument.  */
+    ctx->H[0] = a;
+    ctx->H[1] = b;
+    ctx->H[2] = c;
+    ctx->H[3] = d;
+    ctx->H[4] = e;
+    ctx->H[5] = f;
+    ctx->H[6] = g;
+    ctx->H[7] = h;
+}
+
+/* Initialize structure containing state of computation.
+   (FIPS 180-2:5.3.3)  */
+static void sha512_init_ctx(struct sha512_ctx *ctx)
+{
+    ctx->H[0] = UINT64_C(0x6a09e667f3bcc908);
+    ctx->H[1] = UINT64_C(0xbb67ae8584caa73b);
+    ctx->H[2] = UINT64_C(0x3c6ef372fe94f82b);
+    ctx->H[3] = UINT64_C(0xa54ff53a5f1d36f1);
+    ctx->H[4] = UINT64_C(0x510e527fade682d1);
+    ctx->H[5] = UINT64_C(0x9b05688c2b3e6c1f);
+    ctx->H[6] = UINT64_C(0x1f83d9abfb41bd6b);
+    ctx->H[7] = UINT64_C(0x5be0cd19137e2179);
+
+    ctx->total[0] = ctx->total[1] = 0;
+    ctx->buflen = 0;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *sha512_finish_ctx(struct sha512_ctx *ctx, void *resbuf)
+{
+    unsigned int i;
+    /* Take yet unprocessed bytes into account.  */
+    uint64_t bytes = ctx->buflen;
+    size_t pad;
+
+    /* Now count remaining bytes.  */
+    ctx->total[0] += bytes;
+    if (ctx->total[0] < bytes)
+	++ctx->total[1];
+
+    pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes;
+    memcpy(&ctx->buffer[bytes], fillbuf, pad);
+
+    /* Put the 128-bit file length in *bits* at the end of the buffer.  */
+    *(uint64_t *) & ctx->buffer[bytes + pad + 8] = SWAP(ctx->total[0] << 3);
+    *(uint64_t *) & ctx->buffer[bytes + pad] = SWAP((ctx->total[1] << 3) |
+						    (ctx->total[0] >> 61));
+
+    /* Process last bytes.  */
+    sha512_process_block(ctx->buffer, bytes + pad + 16, ctx);
+
+    /* Put result from CTX in first 64 bytes following RESBUF.  */
+    for (i = 0; i < 8; ++i)
+	((uint64_t *) resbuf)[i] = SWAP(ctx->H[i]);
+
+    return resbuf;
+}
+
+static void
+sha512_process_bytes(const void *buffer, size_t len, struct sha512_ctx *ctx)
+{
+    /* When we already have some bits in our internal buffer concatenate
+       both inputs first.  */
+    if (ctx->buflen != 0) {
+	size_t left_over = ctx->buflen;
+	size_t add = 256 - left_over > len ? len : 256 - left_over;
+
+	memcpy(&ctx->buffer[left_over], buffer, add);
+	ctx->buflen += add;
+
+	if (ctx->buflen > 128) {
+	    sha512_process_block(ctx->buffer, ctx->buflen & ~127, ctx);
+
+	    ctx->buflen &= 127;
+	    /* The regions in the following copy operation cannot overlap.  */
+	    memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
+		   ctx->buflen);
+	}
+
+	buffer = (const char *)buffer + add;
+	len -= add;
+    }
+
+    /* Process available complete blocks.  */
+    if (len >= 128) {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator.  Other
+   compilers don't.  */
+# if __GNUC__ >= 2
+#  define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0)
+# else
+#  define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0)
+# endif
+	if (UNALIGNED_P(buffer))
+	    while (len > 128) {
+		sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128,
+				     ctx);
+		buffer = (const char *)buffer + 128;
+		len -= 128;
+	} else
+#endif
+	{
+	    sha512_process_block(buffer, len & ~127, ctx);
+	    buffer = (const char *)buffer + (len & ~127);
+	    len &= 127;
+	}
+    }
+
+    /* Move remaining bytes into internal buffer.  */
+    if (len > 0) {
+	size_t left_over = ctx->buflen;
+
+	memcpy(&ctx->buffer[left_over], buffer, len);
+	left_over += len;
+	if (left_over >= 128) {
+	    sha512_process_block(ctx->buffer, 128, ctx);
+	    left_over -= 128;
+	    memcpy(ctx->buffer, &ctx->buffer[128], left_over);
+	}
+	ctx->buflen = left_over;
+    }
+}
+
+/* Define our magic string to mark salt for SHA512 "encryption"
+   replacement.  */
+static const char sha512_salt_prefix[] = "$6$";
+
+/* Prefix for optional rounds specification.  */
+static const char sha512_rounds_prefix[] = "rounds=";
+
+/* Maximum salt string length.  */
+#define SALT_LEN_MAX 16U
+/* Default number of rounds if not explicitly specified.  */
+#define ROUNDS_DEFAULT 5000UL
+/* Minimum number of rounds.  */
+#define ROUNDS_MIN 1000UL
+/* Maximum number of rounds.  */
+#define ROUNDS_MAX 999999999UL
+
+/* Table with characters for base64 transformation.  */
+static const char b64t[64] =
+    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *sha512_crypt_r(const char *key, const char *salt, char *buffer,
+			    int buflen)
+{
+    unsigned char alt_result[64]
+	__attribute__ ((__aligned__(__alignof__(uint64_t))));
+    unsigned char temp_result[64]
+	__attribute__ ((__aligned__(__alignof__(uint64_t))));
+    struct sha512_ctx ctx;
+    struct sha512_ctx alt_ctx;
+    size_t salt_len;
+    size_t key_len;
+    size_t cnt;
+    char *cp;
+    char *copied_key = NULL;
+    char *copied_salt = NULL;
+    char *p_bytes;
+    char *s_bytes;
+    /* Default number of rounds.  */
+    size_t rounds = ROUNDS_DEFAULT;
+    bool rounds_custom = false;
+
+    /* Find beginning of salt string.  The prefix should normally always
+       be present.  Just in case it is not.  */
+    if (strncmp(sha512_salt_prefix, salt, sizeof(sha512_salt_prefix) - 1) == 0)
+	/* Skip salt prefix.  */
+	salt += sizeof(sha512_salt_prefix) - 1;
+
+    if (strncmp(salt, sha512_rounds_prefix, sizeof(sha512_rounds_prefix) - 1)
+	== 0) {
+	const char *num = salt + sizeof(sha512_rounds_prefix) - 1;
+	char *endp;
+	unsigned long int srounds = strtoul(num, &endp, 10);
+	if (*endp == '$') {
+	    salt = endp + 1;
+	    rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
+	    rounds_custom = true;
+	}
+    }
+
+    salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
+    key_len = strlen(key);
+
+    if ((key - (char *)0) % __alignof__(uint64_t) != 0) {
+	char *tmp = (char *)alloca(key_len + __alignof__(uint64_t));
+	key = copied_key = memcpy(tmp + __alignof__(uint64_t)
+				  - (tmp - (char *)0) % __alignof__(uint64_t),
+				  key, key_len);
+    }
+
+    if ((salt - (char *)0) % __alignof__(uint64_t) != 0) {
+	char *tmp = (char *)alloca(salt_len + __alignof__(uint64_t));
+	salt = copied_salt = memcpy(tmp + __alignof__(uint64_t)
+				    - (tmp - (char *)0) % __alignof__(uint64_t),
+				    salt, salt_len);
+    }
+
+    /* Prepare for the real work.  */
+    sha512_init_ctx(&ctx);
+
+    /* Add the key string.  */
+    sha512_process_bytes(key, key_len, &ctx);
+
+    /* The last part is the salt string.  This must be at most 8
+       characters and it ends at the first `$' character (for
+       compatibility with existing implementations).  */
+    sha512_process_bytes(salt, salt_len, &ctx);
+
+    /* Compute alternate SHA512 sum with input KEY, SALT, and KEY.  The
+       final result will be added to the first context.  */
+    sha512_init_ctx(&alt_ctx);
+
+    /* Add key.  */
+    sha512_process_bytes(key, key_len, &alt_ctx);
+
+    /* Add salt.  */
+    sha512_process_bytes(salt, salt_len, &alt_ctx);
+
+    /* Add key again.  */
+    sha512_process_bytes(key, key_len, &alt_ctx);
+
+    /* Now get result of this (64 bytes) and add it to the other
+       context.  */
+    sha512_finish_ctx(&alt_ctx, alt_result);
+
+    /* Add for any character in the key one byte of the alternate sum.  */
+    for (cnt = key_len; cnt > 64; cnt -= 64)
+	sha512_process_bytes(alt_result, 64, &ctx);
+    sha512_process_bytes(alt_result, cnt, &ctx);
+
+    /* Take the binary representation of the length of the key and for every
+       1 add the alternate sum, for every 0 the key.  */
+    for (cnt = key_len; cnt > 0; cnt >>= 1)
+	if ((cnt & 1) != 0)
+	    sha512_process_bytes(alt_result, 64, &ctx);
+	else
+	    sha512_process_bytes(key, key_len, &ctx);
+
+    /* Create intermediate result.  */
+    sha512_finish_ctx(&ctx, alt_result);
+
+    /* Start computation of P byte sequence.  */
+    sha512_init_ctx(&alt_ctx);
+
+    /* For every character in the password add the entire password.  */
+    for (cnt = 0; cnt < key_len; ++cnt)
+	sha512_process_bytes(key, key_len, &alt_ctx);
+
+    /* Finish the digest.  */
+    sha512_finish_ctx(&alt_ctx, temp_result);
+
+    /* Create byte sequence P.  */
+    cp = p_bytes = alloca(key_len);
+    for (cnt = key_len; cnt >= 64; cnt -= 64)
+	cp = mempcpy(cp, temp_result, 64);
+    memcpy(cp, temp_result, cnt);
+
+    /* Start computation of S byte sequence.  */
+    sha512_init_ctx(&alt_ctx);
+
+    /* For every character in the password add the entire password.  */
+    for (cnt = 0; cnt < (size_t)16 + alt_result[0]; ++cnt)
+	sha512_process_bytes(salt, salt_len, &alt_ctx);
+
+    /* Finish the digest.  */
+    sha512_finish_ctx(&alt_ctx, temp_result);
+
+    /* Create byte sequence S.  */
+    cp = s_bytes = alloca(salt_len);
+    for (cnt = salt_len; cnt >= 64; cnt -= 64)
+	cp = mempcpy(cp, temp_result, 64);
+    memcpy(cp, temp_result, cnt);
+
+    /* Repeatedly run the collected hash value through SHA512 to burn
+       CPU cycles.  */
+    for (cnt = 0; cnt < rounds; ++cnt) {
+	/* New context.  */
+	sha512_init_ctx(&ctx);
+
+	/* Add key or last result.  */
+	if ((cnt & 1) != 0)
+	    sha512_process_bytes(p_bytes, key_len, &ctx);
+	else
+	    sha512_process_bytes(alt_result, 64, &ctx);
+
+	/* Add salt for numbers not divisible by 3.  */
+	if (cnt % 3 != 0)
+	    sha512_process_bytes(s_bytes, salt_len, &ctx);
+
+	/* Add key for numbers not divisible by 7.  */
+	if (cnt % 7 != 0)
+	    sha512_process_bytes(p_bytes, key_len, &ctx);
+
+	/* Add key or last result.  */
+	if ((cnt & 1) != 0)
+	    sha512_process_bytes(alt_result, 64, &ctx);
+	else
+	    sha512_process_bytes(p_bytes, key_len, &ctx);
+
+	/* Create intermediate result.  */
+	sha512_finish_ctx(&ctx, alt_result);
+    }
+
+    /* Now we can construct the result string.  It consists of three
+       parts.  */
+    cp = stpncpy(buffer, sha512_salt_prefix, MAX(0, buflen));
+    buflen -= sizeof(sha512_salt_prefix) - 1;
+
+    if (rounds_custom) {
+	int n = snprintf(cp, MAX(0, buflen), "%s%zu$",
+			 sha512_rounds_prefix, rounds);
+	cp += n;
+	buflen -= n;
+    }
+
+    cp = stpncpy(cp, salt, MIN((size_t) MAX(0, buflen), salt_len));
+    buflen -= MIN((size_t) MAX(0, buflen), salt_len);
+
+    if (buflen > 0) {
+	*cp++ = '$';
+	--buflen;
+    }
+#define b64_from_24bit(B2, B1, B0, N)					      \
+  do {									      \
+    unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);			      \
+    int n = (N);							      \
+    while (n-- > 0 && buflen > 0)					      \
+      {									      \
+	*cp++ = b64t[w & 0x3f];						      \
+	--buflen;							      \
+	w >>= 6;							      \
+      }									      \
+  } while (0)
+
+    b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4);
+    b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4);
+    b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4);
+    b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4);
+    b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4);
+    b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4);
+    b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4);
+    b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4);
+    b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4);
+    b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4);
+    b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4);
+    b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4);
+    b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4);
+    b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4);
+    b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4);
+    b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4);
+    b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4);
+    b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4);
+    b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4);
+    b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4);
+    b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4);
+    b64_from_24bit(0, 0, alt_result[63], 2);
+
+    if (buflen <= 0) {
+	errno = ERANGE;
+	buffer = NULL;
+    } else
+	*cp = '\0';		/* Terminate the string.  */
+
+    /* Clear the buffer for the intermediate result so that people
+       attaching to processes or reading core dumps cannot get any
+       information.  We do it in this way to clear correct_words[]
+       inside the SHA512 implementation as well.  */
+    sha512_init_ctx(&ctx);
+    sha512_finish_ctx(&ctx, alt_result);
+    memset(temp_result, '\0', sizeof(temp_result));
+    memset(p_bytes, '\0', key_len);
+    memset(s_bytes, '\0', salt_len);
+    memset(&ctx, '\0', sizeof(ctx));
+    memset(&alt_ctx, '\0', sizeof(alt_ctx));
+    if (copied_key != NULL)
+	memset(copied_key, '\0', key_len);
+    if (copied_salt != NULL)
+	memset(copied_salt, '\0', salt_len);
+
+    return buffer;
+}
+
+/* This entry point is equivalent to the `crypt' function in Unix
+   libcs.  */
+char *sha512_crypt(const char *key, const char *salt)
+{
+    /* We don't want to have an arbitrary limit in the size of the
+       password.  We can compute an upper bound for the size of the
+       result in advance and so we can prepare the buffer we pass to
+       `sha512_crypt_r'.  */
+    static char *buffer;
+    static int buflen;
+    int needed = (sizeof(sha512_salt_prefix) - 1
+		  + sizeof(sha512_rounds_prefix) + 9 + 1
+		  + strlen(salt) + 1 + 86 + 1);
+
+    if (buflen < needed) {
+	char *new_buffer = (char *)realloc(buffer, needed);
+	if (new_buffer == NULL)
+	    return NULL;
+
+	buffer = new_buffer;
+	buflen = needed;
+    }
+
+    return sha512_crypt_r(key, salt, buffer, buflen);
+}
+
+#ifdef TEST
+static const struct {
+    const char *input;
+    const char result[64];
+} tests[] = {
+    /* Test vectors from FIPS 180-2: appendix C.1.  */
+    {
+    "abc",
+	    "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31"
+	    "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
+	    "\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
+	    "\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"},
+	/* Test vectors from FIPS 180-2: appendix C.2.  */
+    {
+    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+	    "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+	    "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
+	    "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18"
+	    "\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
+	    "\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"},
+	/* Test vectors from the NESSIE project.  */
+    {
+    "", "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07"
+	    "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
+	    "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f"
+	    "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e"},
+    {
+    "a", "\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2"
+	    "\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53"
+	    "\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46"
+	    "\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75"},
+    {
+    "message digest",
+	    "\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51"
+	    "\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33"
+	    "\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20"
+	    "\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c"},
+    {
+    "abcdefghijklmnopqrstuvwxyz",
+	    "\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81"
+	    "\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29"
+	    "\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59"
+	    "\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1"},
+    {
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	    "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
+	    "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
+	    "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
+	    "\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45"},
+    {
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	    "\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93"
+	    "\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4"
+	    "\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab"
+	    "\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94"},
+    {
+    "123456789012345678901234567890123456789012345678901234567890"
+	    "12345678901234567890",
+	    "\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95"
+	    "\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a"
+	    "\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1"
+	    "\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43"}
+};
+
+#define ntests (sizeof (tests) / sizeof (tests[0]))
+
+static const struct {
+    const char *salt;
+    const char *input;
+    const char *expected;
+} tests2[] = {
+    {
+    "$6$saltstring", "Hello world!",
+	    "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu"
+	    "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"}, {
+    "$6$rounds=10000$saltstringsaltstring", "Hello world!",
+	    "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb"
+	    "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v."}, {
+    "$6$rounds=5000$toolongsaltstring", "This is just a test",
+	    "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ"
+	    "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0"}, {
+    "$6$rounds=1400$anotherlongsaltstring",
+	    "a very much longer text to encrypt.  This one even stretches over more"
+	    "than one line.",
+	    "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP"
+	    "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1"}, {
+    "$6$rounds=77777$short",
+	    "we have a short salt string but not a short password",
+	    "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g"
+	    "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0"}, {
+    "$6$rounds=123456$asaltof16chars..", "a short string",
+	    "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc"
+	    "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1"}, {
+"$6$rounds=10$roundstoolow", "the minimum number is still observed",
+	    "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x"
+	    "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX."},};
+#define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
+
+int main(void)
+{
+    struct sha512_ctx ctx;
+    char sum[64];
+    int result = 0;
+    int cnt;
+
+    for (cnt = 0; cnt < (int)ntests; ++cnt) {
+	sha512_init_ctx(&ctx);
+	sha512_process_bytes(tests[cnt].input, strlen(tests[cnt].input), &ctx);
+	sha512_finish_ctx(&ctx, sum);
+	if (memcmp(tests[cnt].result, sum, 64) != 0) {
+	    printf("test %d run %d failed\n", cnt, 1);
+	    result = 1;
+	}
+
+	sha512_init_ctx(&ctx);
+	for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
+	    sha512_process_bytes(&tests[cnt].input[i], 1, &ctx);
+	sha512_finish_ctx(&ctx, sum);
+	if (memcmp(tests[cnt].result, sum, 64) != 0) {
+	    printf("test %d run %d failed\n", cnt, 2);
+	    result = 1;
+	}
+    }
+
+    /* Test vector from FIPS 180-2: appendix C.3.  */
+    char buf[1000];
+    memset(buf, 'a', sizeof(buf));
+    sha512_init_ctx(&ctx);
+    for (int i = 0; i < 1000; ++i)
+	sha512_process_bytes(buf, sizeof(buf), &ctx);
+    sha512_finish_ctx(&ctx, sum);
+    static const char expected[64] =
+	"\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
+	"\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb"
+	"\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b"
+	"\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b";
+    if (memcmp(expected, sum, 64) != 0) {
+	printf("test %d failed\n", cnt);
+	result = 1;
+    }
+
+    for (cnt = 0; cnt < ntests2; ++cnt) {
+	char *cp = sha512_crypt(tests2[cnt].input, tests2[cnt].salt);
+
+	if (strcmp(cp, tests2[cnt].expected) != 0) {
+	    printf("test %d: expected \"%s\", got \"%s\"\n",
+		   cnt, tests2[cnt].expected, cp);
+	    result = 1;
+	}
+    }
+
+    if (result == 0)
+	puts("all tests OK");
+
+    return result;
+}
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/libutil/unbase64.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/libutil/unbase64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/libutil/unbase64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * unbase64.c
+ *
+ * Convert a string in base64 format to a byte array.
+ */
+
+#include <string.h>
+#include <base64.h>
+
+static const unsigned char _base64chars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+size_t unbase64(unsigned char *buffer, size_t bufsiz, const char *txt)
+{
+    unsigned int bits = 0;
+    int nbits = 0;
+    char base64tbl[256];
+    int i;
+    char v;
+    size_t nbytes = 0;
+
+    memset(base64tbl, -1, sizeof base64tbl);
+
+    for (i = 0; _base64chars[i]; i++) {
+	base64tbl[_base64chars[i]] = i;
+    }
+
+    /* Also support filesystem safe alternate base64 encoding */
+    base64tbl['.'] = 62;
+    base64tbl['-'] = 62;
+    base64tbl['_'] = 63;
+
+    while (*txt) {
+	if ((v = base64tbl[(unsigned char)*txt]) >= 0) {
+	    bits <<= 6;
+	    bits += v;
+	    nbits += 6;
+	    if (nbits >= 8) {
+		if (nbytes < bufsiz)
+		    *buffer++ = (bits >> (nbits - 8));
+		nbytes++;
+		nbits -= 8;
+	    }
+	}
+	txt++;
+    }
+
+    return nbytes;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,114 @@
+# Makefile for installing Lua
+# See doc/readme.html for installation and customization instructions.
+
+# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
+
+# Your platform. See PLATS for possible values.
+PLAT= none
+
+# Where to install. The installation starts in the src and doc directories,
+# so take care if INSTALL_TOP is not an absolute path. See the local target.
+# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
+# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
+INSTALL_TOP= /usr/local
+INSTALL_BIN= $(INSTALL_TOP)/bin
+INSTALL_INC= $(INSTALL_TOP)/include
+INSTALL_LIB= $(INSTALL_TOP)/lib
+INSTALL_MAN= $(INSTALL_TOP)/man/man1
+INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
+INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
+
+# How to install. If your install program does not support "-p", then
+# you may have to run ranlib on the installed liblua.a.
+INSTALL= install -p
+INSTALL_EXEC= $(INSTALL) -m 0755
+INSTALL_DATA= $(INSTALL) -m 0644
+#
+# If you don't have "install" you can use "cp" instead.
+# INSTALL= cp -p
+# INSTALL_EXEC= $(INSTALL)
+# INSTALL_DATA= $(INSTALL)
+
+# Other utilities.
+MKDIR= mkdir -p
+RM= rm -f
+
+# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
+
+# Convenience platforms targets.
+PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
+
+# What to install.
+TO_BIN= lua luac
+TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
+TO_LIB= liblua.a
+TO_MAN= lua.1 luac.1
+
+# Lua version and release.
+V= 5.2
+R= $V.3
+
+# Targets start here.
+all:	$(PLAT)
+
+$(PLATS) clean:
+	cd src && $(MAKE) $@
+
+test:	dummy
+	src/lua -v
+
+install: dummy
+	cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
+	cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
+	cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
+	cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
+	cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+
+uninstall:
+	cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)
+	cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC)
+	cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB)
+	cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
+
+local:
+	$(MAKE) install INSTALL_TOP=../install
+
+none:
+	@echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
+	@echo "   $(PLATS)"
+	@echo "See doc/readme.html for complete instructions."
+
+# make may get confused with test/ and install/
+dummy:
+
+# echo config parameters
+echo:
+	@cd src && $(MAKE) -s echo
+	@echo "PLAT= $(PLAT)"
+	@echo "V= $V"
+	@echo "R= $R"
+	@echo "TO_BIN= $(TO_BIN)"
+	@echo "TO_INC= $(TO_INC)"
+	@echo "TO_LIB= $(TO_LIB)"
+	@echo "TO_MAN= $(TO_MAN)"
+	@echo "INSTALL_TOP= $(INSTALL_TOP)"
+	@echo "INSTALL_BIN= $(INSTALL_BIN)"
+	@echo "INSTALL_INC= $(INSTALL_INC)"
+	@echo "INSTALL_LIB= $(INSTALL_LIB)"
+	@echo "INSTALL_MAN= $(INSTALL_MAN)"
+	@echo "INSTALL_LMOD= $(INSTALL_LMOD)"
+	@echo "INSTALL_CMOD= $(INSTALL_CMOD)"
+	@echo "INSTALL_EXEC= $(INSTALL_EXEC)"
+	@echo "INSTALL_DATA= $(INSTALL_DATA)"
+
+# echo pkg-config data
+pc:
+	@echo "version=$R"
+	@echo "prefix=$(INSTALL_TOP)"
+	@echo "libdir=$(INSTALL_LIB)"
+	@echo "includedir=$(INSTALL_INC)"
+
+# list targets that do not create files (but not all makes understand .PHONY)
+.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho
+
+# (end of Makefile)
Index: bootcd/isolinux/syslinux-6.03/com32/lua/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,6 @@
+
+This is Lua 5.2.3, released on 11 Nov 2013.
+
+For installation instructions, license details, and
+further information about Lua, see doc/readme.html.
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/contents.html
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/contents.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/contents.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,533 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+<HEAD>
+<TITLE>Lua 5.2 Reference Manual - contents</TITLE>
+<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+<STYLE TYPE="text/css">
+ul {
+	list-style-type: none ;
+	list-style-position: outside ;
+}
+</STYLE>
+</HEAD>
+
+<BODY>
+
+<HR>
+<H1>
+<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A>
+Lua 5.2 Reference Manual
+</H1>
+
+<P>
+The reference manual is the official definition of the Lua language.
+For a complete introduction to Lua programming, see the book
+<A HREF="http://www.lua.org/pil/">Programming in Lua</A>.
+
+<P>
+<A HREF="manual.html">start</A>
+&middot;
+<A HREF="#contents">contents</A>
+&middot;
+<A HREF="#index">index</A>
+<HR>
+<SMALL>
+Copyright &copy; 2011&ndash;2013 Lua.org, PUC-Rio.
+Freely available under the terms of the
+<A HREF="http://www.lua.org/license.html">Lua license</A>.
+</SMALL>
+
+<H2><A NAME="contents">Contents</A></H2>
+<UL style="padding: 0">
+<LI><A HREF="manual.html">1 &ndash; Introduction</A>
+<P>
+<LI><A HREF="manual.html#2">2 &ndash; Basic Concepts</A>
+<UL>
+<LI><A HREF="manual.html#2.1">2.1 &ndash; Values and Types</A>
+<LI><A HREF="manual.html#2.2">2.2 &ndash; Environments and the Global Environment</A>
+<LI><A HREF="manual.html#2.3">2.3 &ndash; Error Handling</A>
+<LI><A HREF="manual.html#2.4">2.4 &ndash; Metatables and Metamethods</A>
+<LI><A HREF="manual.html#2.5">2.5 &ndash; Garbage Collection</A>
+<UL>
+<LI><A HREF="manual.html#2.5.1">2.5.1 &ndash; Garbage-Collection Metamethods</A>
+<LI><A HREF="manual.html#2.5.2">2.5.2 &ndash; Weak Tables</A>
+</UL>
+<LI><A HREF="manual.html#2.6">2.6 &ndash; Coroutines</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#3">3 &ndash; The Language</A>
+<UL>
+<LI><A HREF="manual.html#3.1">3.1 &ndash; Lexical Conventions</A>
+<LI><A HREF="manual.html#3.2">3.2 &ndash; Variables</A>
+<LI><A HREF="manual.html#3.3">3.3 &ndash; Statements</A>
+<UL>
+<LI><A HREF="manual.html#3.3.1">3.3.1 &ndash; Blocks</A>
+<LI><A HREF="manual.html#3.3.2">3.3.2 &ndash; Chunks</A>
+<LI><A HREF="manual.html#3.3.3">3.3.3 &ndash; Assignment</A>
+<LI><A HREF="manual.html#3.3.4">3.3.4 &ndash; Control Structures</A>
+<LI><A HREF="manual.html#3.3.5">3.3.5 &ndash; For Statement</A>
+<LI><A HREF="manual.html#3.3.6">3.3.6 &ndash; Function Calls as Statements</A>
+<LI><A HREF="manual.html#3.3.7">3.3.7 &ndash; Local Declarations</A>
+</UL>
+<LI><A HREF="manual.html#3.4">3.4 &ndash; Expressions</A>
+<UL>
+<LI><A HREF="manual.html#3.4.1">3.4.1 &ndash; Arithmetic Operators</A>
+<LI><A HREF="manual.html#3.4.2">3.4.2 &ndash; Coercion</A>
+<LI><A HREF="manual.html#3.4.3">3.4.3 &ndash; Relational Operators</A>
+<LI><A HREF="manual.html#3.4.4">3.4.4 &ndash; Logical Operators</A>
+<LI><A HREF="manual.html#3.4.5">3.4.5 &ndash; Concatenation</A>
+<LI><A HREF="manual.html#3.4.6">3.4.6 &ndash; The Length Operator</A>
+<LI><A HREF="manual.html#3.4.7">3.4.7 &ndash; Precedence</A>
+<LI><A HREF="manual.html#3.4.8">3.4.8 &ndash; Table Constructors</A>
+<LI><A HREF="manual.html#3.4.9">3.4.9 &ndash; Function Calls</A>
+<LI><A HREF="manual.html#3.4.10">3.4.10 &ndash; Function Definitions</A>
+</UL>
+<LI><A HREF="manual.html#3.5">3.5 &ndash; Visibility Rules</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#4">4 &ndash; The Application Program Interface</A>
+<UL>
+<LI><A HREF="manual.html#4.1">4.1 &ndash; The Stack</A>
+<LI><A HREF="manual.html#4.2">4.2 &ndash; Stack Size</A>
+<LI><A HREF="manual.html#4.3">4.3 &ndash; Valid and Acceptable Indices</A>
+<LI><A HREF="manual.html#4.4">4.4 &ndash; C Closures</A>
+<LI><A HREF="manual.html#4.5">4.5 &ndash; Registry</A>
+<LI><A HREF="manual.html#4.6">4.6 &ndash; Error Handling in C</A>
+<LI><A HREF="manual.html#4.7">4.7 &ndash; Handling Yields in C</A>
+<LI><A HREF="manual.html#4.8">4.8 &ndash; Functions and Types</A>
+<LI><A HREF="manual.html#4.9">4.9 &ndash; The Debug Interface</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#5">5 &ndash; The Auxiliary Library</A>
+<UL>
+<LI><A HREF="manual.html#5.1">5.1 &ndash; Functions and Types</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#6">6 &ndash; Standard Libraries</A>
+<UL>
+<LI><A HREF="manual.html#6.1">6.1 &ndash; Basic Functions</A>
+<LI><A HREF="manual.html#6.2">6.2 &ndash; Coroutine Manipulation</A>
+<LI><A HREF="manual.html#6.3">6.3 &ndash; Modules</A>
+<LI><A HREF="manual.html#6.4">6.4 &ndash; String Manipulation</A>
+<UL>
+<LI><A HREF="manual.html#6.4.1">6.4.1 &ndash; Patterns</A>
+</UL>
+<LI><A HREF="manual.html#6.5">6.5 &ndash; Table Manipulation</A>
+<LI><A HREF="manual.html#6.6">6.6 &ndash; Mathematical Functions</A>
+<LI><A HREF="manual.html#6.7">6.7 &ndash; Bitwise Operations</A>
+<LI><A HREF="manual.html#6.8">6.8 &ndash; Input and Output Facilities</A>
+<LI><A HREF="manual.html#6.9">6.9 &ndash; Operating System Facilities</A>
+<LI><A HREF="manual.html#6.10">6.10 &ndash; The Debug Library</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#7">7 &ndash; Lua Standalone</A>
+<P>
+<LI><A HREF="manual.html#8">8 &ndash; Incompatibilities with the Previous Version</A>
+<UL>
+<LI><A HREF="manual.html#8.1">8.1 &ndash; Changes in the Language</A>
+<LI><A HREF="manual.html#8.2">8.2 &ndash; Changes in the Libraries</A>
+<LI><A HREF="manual.html#8.3">8.3 &ndash; Changes in the API</A>
+</UL>
+<P>
+<LI><A HREF="manual.html#9">9 &ndash; The Complete Syntax of Lua</A>
+</UL>
+
+<H2><A NAME="index">Index</A></H2>
+<TABLE WIDTH="100%">
+<TR VALIGN="top">
+<TD>
+<H3><A NAME="functions">Lua functions</A></H3>
+<P>
+<A HREF="manual.html#pdf-_G">_G</A><BR>
+<A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-assert">assert</A><BR>
+<A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR>
+<A HREF="manual.html#pdf-dofile">dofile</A><BR>
+<A HREF="manual.html#pdf-error">error</A><BR>
+<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
+<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
+<A HREF="manual.html#pdf-load">load</A><BR>
+<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
+<A HREF="manual.html#pdf-next">next</A><BR>
+<A HREF="manual.html#pdf-pairs">pairs</A><BR>
+<A HREF="manual.html#pdf-pcall">pcall</A><BR>
+<A HREF="manual.html#pdf-print">print</A><BR>
+<A HREF="manual.html#pdf-rawequal">rawequal</A><BR>
+<A HREF="manual.html#pdf-rawget">rawget</A><BR>
+<A HREF="manual.html#pdf-rawlen">rawlen</A><BR>
+<A HREF="manual.html#pdf-rawset">rawset</A><BR>
+<A HREF="manual.html#pdf-require">require</A><BR>
+<A HREF="manual.html#pdf-select">select</A><BR>
+<A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR>
+<A HREF="manual.html#pdf-tonumber">tonumber</A><BR>
+<A HREF="manual.html#pdf-tostring">tostring</A><BR>
+<A HREF="manual.html#pdf-type">type</A><BR>
+<A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-bit32.arshift">bit32.arshift</A><BR>
+<A HREF="manual.html#pdf-bit32.band">bit32.band</A><BR>
+<A HREF="manual.html#pdf-bit32.bnot">bit32.bnot</A><BR>
+<A HREF="manual.html#pdf-bit32.bor">bit32.bor</A><BR>
+<A HREF="manual.html#pdf-bit32.btest">bit32.btest</A><BR>
+<A HREF="manual.html#pdf-bit32.bxor">bit32.bxor</A><BR>
+<A HREF="manual.html#pdf-bit32.extract">bit32.extract</A><BR>
+<A HREF="manual.html#pdf-bit32.lrotate">bit32.lrotate</A><BR>
+<A HREF="manual.html#pdf-bit32.lshift">bit32.lshift</A><BR>
+<A HREF="manual.html#pdf-bit32.replace">bit32.replace</A><BR>
+<A HREF="manual.html#pdf-bit32.rrotate">bit32.rrotate</A><BR>
+<A HREF="manual.html#pdf-bit32.rshift">bit32.rshift</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
+<A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR>
+<A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR>
+<A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR>
+<A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR>
+<A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
+<A HREF="manual.html#pdf-debug.getuservalue">debug.getuservalue</A><BR>
+<A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR>
+<A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR>
+<A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR>
+<A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR>
+<A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR>
+<A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR>
+<A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR>
+<A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR>
+<A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR>
+<A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR>
+<A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR>
+<A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR>
+<A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR>
+<A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-file:close">file:close</A><BR>
+<A HREF="manual.html#pdf-file:flush">file:flush</A><BR>
+<A HREF="manual.html#pdf-file:lines">file:lines</A><BR>
+<A HREF="manual.html#pdf-file:read">file:read</A><BR>
+<A HREF="manual.html#pdf-file:seek">file:seek</A><BR>
+<A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR>
+<A HREF="manual.html#pdf-file:write">file:write</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-io.close">io.close</A><BR>
+<A HREF="manual.html#pdf-io.flush">io.flush</A><BR>
+<A HREF="manual.html#pdf-io.input">io.input</A><BR>
+<A HREF="manual.html#pdf-io.lines">io.lines</A><BR>
+<A HREF="manual.html#pdf-io.open">io.open</A><BR>
+<A HREF="manual.html#pdf-io.output">io.output</A><BR>
+<A HREF="manual.html#pdf-io.popen">io.popen</A><BR>
+<A HREF="manual.html#pdf-io.read">io.read</A><BR>
+<A HREF="manual.html#pdf-io.stderr">io.stderr</A><BR>
+<A HREF="manual.html#pdf-io.stdin">io.stdin</A><BR>
+<A HREF="manual.html#pdf-io.stdout">io.stdout</A><BR>
+<A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR>
+<A HREF="manual.html#pdf-io.type">io.type</A><BR>
+<A HREF="manual.html#pdf-io.write">io.write</A><BR>
+
+</TD>
+<TD>
+<H3>&nbsp;</H3>
+<P>
+<A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
+<A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
+<A HREF="manual.html#pdf-math.asin">math.asin</A><BR>
+<A HREF="manual.html#pdf-math.atan">math.atan</A><BR>
+<A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR>
+<A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR>
+<A HREF="manual.html#pdf-math.cos">math.cos</A><BR>
+<A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR>
+<A HREF="manual.html#pdf-math.deg">math.deg</A><BR>
+<A HREF="manual.html#pdf-math.exp">math.exp</A><BR>
+<A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
+<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
+<A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR>
+<A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
+<A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR>
+<A HREF="manual.html#pdf-math.log">math.log</A><BR>
+<A HREF="manual.html#pdf-math.max">math.max</A><BR>
+<A HREF="manual.html#pdf-math.min">math.min</A><BR>
+<A HREF="manual.html#pdf-math.modf">math.modf</A><BR>
+<A HREF="manual.html#pdf-math.pi">math.pi</A><BR>
+<A HREF="manual.html#pdf-math.pow">math.pow</A><BR>
+<A HREF="manual.html#pdf-math.rad">math.rad</A><BR>
+<A HREF="manual.html#pdf-math.random">math.random</A><BR>
+<A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR>
+<A HREF="manual.html#pdf-math.sin">math.sin</A><BR>
+<A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR>
+<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR>
+<A HREF="manual.html#pdf-math.tan">math.tan</A><BR>
+<A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
+<A HREF="manual.html#pdf-os.date">os.date</A><BR>
+<A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR>
+<A HREF="manual.html#pdf-os.execute">os.execute</A><BR>
+<A HREF="manual.html#pdf-os.exit">os.exit</A><BR>
+<A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR>
+<A HREF="manual.html#pdf-os.remove">os.remove</A><BR>
+<A HREF="manual.html#pdf-os.rename">os.rename</A><BR>
+<A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR>
+<A HREF="manual.html#pdf-os.time">os.time</A><BR>
+<A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-package.config">package.config</A><BR>
+<A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR>
+<A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR>
+<A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR>
+<A HREF="manual.html#pdf-package.path">package.path</A><BR>
+<A HREF="manual.html#pdf-package.preload">package.preload</A><BR>
+<A HREF="manual.html#pdf-package.searchers">package.searchers</A><BR>
+<A HREF="manual.html#pdf-package.searchpath">package.searchpath</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-string.byte">string.byte</A><BR>
+<A HREF="manual.html#pdf-string.char">string.char</A><BR>
+<A HREF="manual.html#pdf-string.dump">string.dump</A><BR>
+<A HREF="manual.html#pdf-string.find">string.find</A><BR>
+<A HREF="manual.html#pdf-string.format">string.format</A><BR>
+<A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR>
+<A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR>
+<A HREF="manual.html#pdf-string.len">string.len</A><BR>
+<A HREF="manual.html#pdf-string.lower">string.lower</A><BR>
+<A HREF="manual.html#pdf-string.match">string.match</A><BR>
+<A HREF="manual.html#pdf-string.rep">string.rep</A><BR>
+<A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR>
+<A HREF="manual.html#pdf-string.sub">string.sub</A><BR>
+<A HREF="manual.html#pdf-string.upper">string.upper</A><BR>
+
+<P>
+<A HREF="manual.html#pdf-table.concat">table.concat</A><BR>
+<A HREF="manual.html#pdf-table.insert">table.insert</A><BR>
+<A HREF="manual.html#pdf-table.pack">table.pack</A><BR>
+<A HREF="manual.html#pdf-table.remove">table.remove</A><BR>
+<A HREF="manual.html#pdf-table.sort">table.sort</A><BR>
+<A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR>
+
+</TD>
+<TD>
+<H3>C API</H3>
+<P>
+<A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR>
+<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR>
+<A HREF="manual.html#lua_Debug">lua_Debug</A><BR>
+<A HREF="manual.html#lua_Hook">lua_Hook</A><BR>
+<A HREF="manual.html#lua_Integer">lua_Integer</A><BR>
+<A HREF="manual.html#lua_Number">lua_Number</A><BR>
+<A HREF="manual.html#lua_Reader">lua_Reader</A><BR>
+<A HREF="manual.html#lua_State">lua_State</A><BR>
+<A HREF="manual.html#lua_Unsigned">lua_Unsigned</A><BR>
+<A HREF="manual.html#lua_Writer">lua_Writer</A><BR>
+
+<P>
+<A HREF="manual.html#lua_absindex">lua_absindex</A><BR>
+<A HREF="manual.html#lua_arith">lua_arith</A><BR>
+<A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR>
+<A HREF="manual.html#lua_call">lua_call</A><BR>
+<A HREF="manual.html#lua_callk">lua_callk</A><BR>
+<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR>
+<A HREF="manual.html#lua_close">lua_close</A><BR>
+<A HREF="manual.html#lua_compare">lua_compare</A><BR>
+<A HREF="manual.html#lua_concat">lua_concat</A><BR>
+<A HREF="manual.html#lua_copy">lua_copy</A><BR>
+<A HREF="manual.html#lua_createtable">lua_createtable</A><BR>
+<A HREF="manual.html#lua_dump">lua_dump</A><BR>
+<A HREF="manual.html#lua_error">lua_error</A><BR>
+<A HREF="manual.html#lua_gc">lua_gc</A><BR>
+<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR>
+<A HREF="manual.html#lua_getctx">lua_getctx</A><BR>
+<A HREF="manual.html#lua_getfield">lua_getfield</A><BR>
+<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR>
+<A HREF="manual.html#lua_gethook">lua_gethook</A><BR>
+<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR>
+<A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR>
+<A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR>
+<A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR>
+<A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR>
+<A HREF="manual.html#lua_getstack">lua_getstack</A><BR>
+<A HREF="manual.html#lua_gettable">lua_gettable</A><BR>
+<A HREF="manual.html#lua_gettop">lua_gettop</A><BR>
+<A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR>
+<A HREF="manual.html#lua_getuservalue">lua_getuservalue</A><BR>
+<A HREF="manual.html#lua_insert">lua_insert</A><BR>
+<A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR>
+<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR>
+<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR>
+<A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR>
+<A HREF="manual.html#lua_isnil">lua_isnil</A><BR>
+<A HREF="manual.html#lua_isnone">lua_isnone</A><BR>
+<A HREF="manual.html#lua_isnoneornil">lua_isnoneornil</A><BR>
+<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR>
+<A HREF="manual.html#lua_isstring">lua_isstring</A><BR>
+<A HREF="manual.html#lua_istable">lua_istable</A><BR>
+<A HREF="manual.html#lua_isthread">lua_isthread</A><BR>
+<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR>
+<A HREF="manual.html#lua_len">lua_len</A><BR>
+<A HREF="manual.html#lua_load">lua_load</A><BR>
+<A HREF="manual.html#lua_newstate">lua_newstate</A><BR>
+<A HREF="manual.html#lua_newtable">lua_newtable</A><BR>
+<A HREF="manual.html#lua_newthread">lua_newthread</A><BR>
+<A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR>
+<A HREF="manual.html#lua_next">lua_next</A><BR>
+<A HREF="manual.html#lua_pcall">lua_pcall</A><BR>
+<A HREF="manual.html#lua_pcallk">lua_pcallk</A><BR>
+<A HREF="manual.html#lua_pop">lua_pop</A><BR>
+<A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR>
+<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR>
+<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR>
+<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR>
+<A HREF="manual.html#lua_pushglobaltable">lua_pushglobaltable</A><BR>
+<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR>
+<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR>
+<A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR>
+<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR>
+<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR>
+<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR>
+<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR>
+<A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR>
+<A HREF="manual.html#lua_pushunsigned">lua_pushunsigned</A><BR>
+<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR>
+<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR>
+<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR>
+<A HREF="manual.html#lua_rawget">lua_rawget</A><BR>
+<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR>
+<A HREF="manual.html#lua_rawgetp">lua_rawgetp</A><BR>
+<A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR>
+<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
+<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
+<A HREF="manual.html#lua_rawsetp">lua_rawsetp</A><BR>
+<A HREF="manual.html#lua_register">lua_register</A><BR>
+<A HREF="manual.html#lua_remove">lua_remove</A><BR>
+<A HREF="manual.html#lua_replace">lua_replace</A><BR>
+<A HREF="manual.html#lua_resume">lua_resume</A><BR>
+<A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR>
+<A HREF="manual.html#lua_setfield">lua_setfield</A><BR>
+<A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR>
+<A HREF="manual.html#lua_sethook">lua_sethook</A><BR>
+<A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR>
+<A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR>
+<A HREF="manual.html#lua_settable">lua_settable</A><BR>
+<A HREF="manual.html#lua_settop">lua_settop</A><BR>
+<A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR>
+<A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR>
+<A HREF="manual.html#lua_status">lua_status</A><BR>
+<A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR>
+<A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR>
+<A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR>
+<A HREF="manual.html#lua_tointegerx">lua_tointegerx</A><BR>
+<A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR>
+<A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR>
+<A HREF="manual.html#lua_tonumberx">lua_tonumberx</A><BR>
+<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
+<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
+<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
+<A HREF="manual.html#lua_tounsigned">lua_tounsigned</A><BR>
+<A HREF="manual.html#lua_tounsignedx">lua_tounsignedx</A><BR>
+<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
+<A HREF="manual.html#lua_type">lua_type</A><BR>
+<A HREF="manual.html#lua_typename">lua_typename</A><BR>
+<A HREF="manual.html#lua_upvalueid">lua_upvalueid</A><BR>
+<A HREF="manual.html#lua_upvalueindex">lua_upvalueindex</A><BR>
+<A HREF="manual.html#lua_upvaluejoin">lua_upvaluejoin</A><BR>
+<A HREF="manual.html#lua_version">lua_version</A><BR>
+<A HREF="manual.html#lua_xmove">lua_xmove</A><BR>
+<A HREF="manual.html#lua_yield">lua_yield</A><BR>
+<A HREF="manual.html#lua_yieldk">lua_yieldk</A><BR>
+
+</TD>
+<TD>
+<H3>auxiliary library</H3>
+<P>
+<A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR>
+<A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR>
+
+<P>
+<A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR>
+<A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR>
+<A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR>
+<A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR>
+<A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR>
+<A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR>
+<A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR>
+<A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR>
+<A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR>
+<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
+<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
+<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
+<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
+<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR>
+<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
+<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
+<A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR>
+<A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR>
+<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
+<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
+<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
+<A HREF="manual.html#luaL_checkunsigned">luaL_checkunsigned</A><BR>
+<A HREF="manual.html#luaL_checkversion">luaL_checkversion</A><BR>
+<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
+<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
+<A HREF="manual.html#luaL_error">luaL_error</A><BR>
+<A HREF="manual.html#luaL_execresult">luaL_execresult</A><BR>
+<A HREF="manual.html#luaL_fileresult">luaL_fileresult</A><BR>
+<A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR>
+<A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR>
+<A HREF="manual.html#luaL_getsubtable">luaL_getsubtable</A><BR>
+<A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR>
+<A HREF="manual.html#luaL_len">luaL_len</A><BR>
+<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR>
+<A HREF="manual.html#luaL_loadbufferx">luaL_loadbufferx</A><BR>
+<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR>
+<A HREF="manual.html#luaL_loadfilex">luaL_loadfilex</A><BR>
+<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR>
+<A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR>
+<A HREF="manual.html#luaL_newlibtable">luaL_newlibtable</A><BR>
+<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
+<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
+<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
+<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
+<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
+<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR>
+<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
+<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
+<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
+<A HREF="manual.html#luaL_optunsigned">luaL_optunsigned</A><BR>
+<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
+<A HREF="manual.html#luaL_prepbuffsize">luaL_prepbuffsize</A><BR>
+<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
+<A HREF="manual.html#luaL_pushresultsize">luaL_pushresultsize</A><BR>
+<A HREF="manual.html#luaL_ref">luaL_ref</A><BR>
+<A HREF="manual.html#luaL_requiref">luaL_requiref</A><BR>
+<A HREF="manual.html#luaL_setfuncs">luaL_setfuncs</A><BR>
+<A HREF="manual.html#luaL_setmetatable">luaL_setmetatable</A><BR>
+<A HREF="manual.html#luaL_testudata">luaL_testudata</A><BR>
+<A HREF="manual.html#luaL_tolstring">luaL_tolstring</A><BR>
+<A HREF="manual.html#luaL_traceback">luaL_traceback</A><BR>
+<A HREF="manual.html#luaL_typename">luaL_typename</A><BR>
+<A HREF="manual.html#luaL_unref">luaL_unref</A><BR>
+<A HREF="manual.html#luaL_where">luaL_where</A><BR>
+
+</TD>
+</TR>
+</TABLE>
+
+<HR>
+<SMALL CLASS="footer">
+Last update:
+Tue Mar 12 11:22:18 BRT 2013
+</SMALL>
+<!--
+Last change: revised for Lua 5.2.2
+-->
+
+</BODY>
+</HTML>
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.1
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.1	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.1	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+.\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $
+.TH LUA 1 "$Date: 2011/11/16 17:16:53 $"
+.SH NAME
+lua \- Lua interpreter
+.SH SYNOPSIS
+.B lua
+[
+.I options
+]
+[
+.I script
+[
+.I args
+]
+]
+.SH DESCRIPTION
+.B lua
+is the standalone Lua interpreter.
+It loads and executes Lua programs,
+either in textual source form or
+in precompiled binary form.
+(Precompiled binaries are output by
+.BR luac ,
+the Lua compiler.)
+.B lua
+can be used as a batch interpreter and also interactively.
+.LP
+The given
+.I options
+are handled in order and then
+the Lua program in file
+.I script
+is loaded and executed.
+The given
+.I args
+are available to
+.I script
+as strings in a global table named
+.BR arg .
+If no options or arguments are given,
+then
+.B "\-v \-i"
+is assumed when the standard input is a terminal;
+otherwise,
+.B "\-"
+is assumed.
+.LP
+In interactive mode,
+.B lua
+prompts the user,
+reads lines from the standard input,
+and executes them as they are read.
+If a line does not contain a complete statement,
+then a secondary prompt is displayed and
+lines are read until a complete statement is formed or
+a syntax error is found.
+If a line starts with
+.BR '=' ,
+then
+.B lua
+evaluates and displays
+the values of the expressions in the remainder of the line.
+.LP
+At the very start,
+before even handling the command line,
+.B lua
+checks the contents of the environment variables
+.B LUA_INIT_5_2
+or
+.BR LUA_INIT ,
+in that order.
+If the contents is of the form
+.RI '@ filename ',
+then
+.I filename
+is executed.
+Otherwise, the string is assumed to be a Lua statement and is executed.
+.SH OPTIONS
+.TP
+.BI \-e " stat"
+execute statement
+.IR stat .
+.TP
+.B \-i
+enter interactive mode after executing
+.IR script .
+.TP
+.BI \-l " name"
+execute the equivalent of
+.IB name =require(' name ')
+before executing
+.IR script .
+.TP
+.B \-v
+show version information.
+.TP
+.B \-E
+ignore environment variables.
+.TP
+.B \-\-
+stop handling options.
+.TP
+.B \-
+stop handling options and execute the standard input as a file.
+.SH "SEE ALSO"
+.BR luac (1)
+.br
+The documentation at lua.org,
+especially section 7 of the reference manual.
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+R. Ierusalimschy,
+L. H. de Figueiredo,
+W. Celes
+.\" EOF
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.css
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.css	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/lua.css	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,96 @@
+html {
+	background-color: #F8F8F8 ;
+}
+
+body {
+	border: solid #a0a0a0 1px ;
+	border-radius: 20px ;
+	padding: 26px ;
+	margin: 16px ;
+	color: #000000 ;
+	background-color: #FFFFFF ;
+	font-family: Helvetica, Arial, sans-serif ;
+	text-align: justify ;
+}
+
+h1, h2, h3, h4 {
+	font-family: Verdana, Geneva, sans-serif ;
+	font-weight: normal ;
+	font-style: normal ;
+}
+
+h2 {
+	padding-top: 0.4em ;
+	padding-bottom: 0.4em ;
+	padding-left: 0.8em ;
+	padding-right: 0.8em ;
+	background-color: #D0D0FF ;
+	border-radius: 8px ;
+	border: solid #a0a0a0 1px ;
+}
+
+h3 {
+	padding-left: 0.5em ;
+	border-left: solid #D0D0FF 1em ;
+}
+
+table h3 {
+	padding-left: 0px ;
+	border-left: none ;
+}
+
+a:link {
+	color: #000080 ;
+	background-color: inherit ;
+	text-decoration: none ;
+}
+
+a:visited {
+	background-color: inherit ;
+	text-decoration: none ;
+}
+
+a:link:hover, a:visited:hover {
+	color: #000080 ;
+	background-color: #D0D0FF ;
+}
+
+a:link:active, a:visited:active {
+	color: #FF0000 ;
+}
+
+hr {
+	border: 0 ;
+	height: 1px ;
+	color: #a0a0a0 ;
+	background-color: #a0a0a0 ;
+	display: none ;
+}
+
+table hr {
+	display: block ;
+}
+
+:target {
+	background-color: #F8F8F8 ;
+	padding: 8px ;
+	border: solid #a0a0a0 2px ;
+	border-radius: 8px ;
+}
+
+.footer {
+	color: gray ;
+	font-size: x-small ;
+}
+
+input[type=text] {
+	border: solid #a0a0a0 2px ;
+	border-radius: 2em ;
+	-moz-border-radius: 2em ;
+	background-image: url('images/search.png') ;
+	background-repeat: no-repeat;
+	background-position: 4px center ;
+	padding-left: 20px ;
+	height: 2em ;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/luac.1
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/luac.1	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/luac.1	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,118 @@
+.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $
+.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $"
+.SH NAME
+luac \- Lua compiler
+.SH SYNOPSIS
+.B luac
+[
+.I options
+] [
+.I filenames
+]
+.SH DESCRIPTION
+.B luac
+is the Lua compiler.
+It translates programs written in the Lua programming language
+into binary files containing precompiled chunks
+that can be later loaded and executed.
+.LP
+The main advantages of precompiling chunks are:
+faster loading,
+protecting source code from accidental user changes,
+and
+off-line syntax checking.
+Precompiling does not imply faster execution
+because in Lua chunks are always compiled into bytecodes before being executed.
+.B luac
+simply allows those bytecodes to be saved in a file for later execution.
+Precompiled chunks are not necessarily smaller than the corresponding source.
+The main goal in precompiling is faster loading.
+.LP
+In the command line,
+you can mix
+text files containing Lua source and
+binary files containing precompiled chunks.
+.B luac
+produces a single output file containing the combined bytecodes
+for all files given.
+Executing the combined file is equivalent to executing the given files.
+By default,
+the output file is named
+.BR luac.out ,
+but you can change this with the
+.B \-o
+option.
+.LP
+Precompiled chunks are
+.I not
+portable across different architectures.
+Moreover,
+the internal format of precompiled chunks
+is likely to change when a new version of Lua is released.
+Make sure you save the source files of all Lua programs that you precompile.
+.LP
+.SH OPTIONS
+.TP
+.B \-l
+produce a listing of the compiled bytecode for Lua's virtual machine.
+Listing bytecodes is useful to learn about Lua's virtual machine.
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and lists its contents.
+Use
+.B \-l \-l
+for a full listing.
+.TP
+.BI \-o " file"
+output to
+.IR file ,
+instead of the default
+.BR luac.out .
+(You can use
+.B "'\-'"
+for standard output,
+but not on platforms that open standard output in text mode.)
+The output file may be one of the given files because
+all files are loaded before the output file is written.
+Be careful not to overwrite precious files.
+.TP
+.B \-p
+load files but do not generate any output file.
+Used mainly for syntax checking and for testing precompiled chunks:
+corrupted files will probably generate errors when loaded.
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and tests its contents.
+No messages are displayed if the file loads without errors.
+.TP
+.B \-s
+strip debug information before writing the output file.
+This saves some space in very large chunks,
+but if errors occur when running a stripped chunk,
+then the error messages may not contain the full information they usually do.
+In particular,
+line numbers and names of local variables are lost.
+.TP
+.B \-v
+show version information.
+.TP
+.B \-\-
+stop handling options.
+.TP
+.B \-
+stop handling options and process standard input.
+.SH "SEE ALSO"
+.BR lua (1)
+.br
+The documentation at lua.org.
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+R. Ierusalimschy,
+L. H. de Figueiredo,
+W. Celes
+.\" EOF
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.css
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.css	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.css	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,27 @@
+h3 code {
+	font-family: inherit ;
+	font-size: inherit ;
+}
+
+pre, code {
+	font-size: 12pt ;
+}
+
+span.apii {
+	float: right ;
+	font-family: inherit ;
+	font-style: normal ;
+	font-size: small ;
+	color: gray ;
+}
+
+p+h1, ul+h1 {
+	font-style: normal ;
+	padding-top: 0.4em ;
+	padding-bottom: 0.4em ;
+	padding-left: 16px ;
+	margin-left: -16px ;
+	background-color: #D0D0FF ;
+	border-radius: 8px ;
+	border: solid #000080 1px ;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.html
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/manual.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,10507 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<title>Lua 5.2 Reference Manual</title>
+<link rel="stylesheet" type="text/css" href="lua.css">
+<link rel="stylesheet" type="text/css" href="manual.css">
+<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+</head>
+
+<body>
+
+<hr>
+<h1>
+<a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a>
+Lua 5.2 Reference Manual
+</h1>
+
+by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
+<p>
+<small>
+Copyright &copy; 2011&ndash;2013 Lua.org, PUC-Rio.
+Freely available under the terms of the
+<a href="http://www.lua.org/license.html">Lua license</a>.
+</small>
+<hr>
+<p>
+
+<a href="contents.html#contents">contents</A>
+&middot;
+<a href="contents.html#index">index</A>
+
+<!-- ====================================================================== -->
+<p>
+
+<!-- $Id: manual.of,v 1.103 2013/03/14 18:51:56 roberto Exp $ -->
+
+
+
+
+<h1>1 &ndash; <a name="1">Introduction</a></h1>
+
+<p>
+Lua is an extension programming language designed to support
+general procedural programming with data description
+facilities.
+It also offers good support for object-oriented programming,
+functional programming, and data-driven programming.
+Lua is intended to be used as a powerful, lightweight,
+embeddable scripting language for any program that needs one.
+Lua is implemented as a library, written in <em>clean C</em>,
+the common subset of Standard&nbsp;C and C++.
+
+
+<p>
+Being an extension language, Lua has no notion of a "main" program:
+it only works <em>embedded</em> in a host client,
+called the <em>embedding program</em> or simply the <em>host</em>.
+The host program can invoke functions to execute a piece of Lua code,
+can write and read Lua variables,
+and can register C&nbsp;functions to be called by Lua code.
+Through the use of C&nbsp;functions, Lua can be augmented to cope with
+a wide range of different domains,
+thus creating customized programming languages sharing a syntactical framework.
+The Lua distribution includes a sample host program called <code>lua</code>,
+which uses the Lua library to offer a complete, standalone Lua interpreter,
+for interactive or batch use.
+
+
+<p>
+Lua is free software,
+and is provided as usual with no guarantees,
+as stated in its license.
+The implementation described in this manual is available
+at Lua's official web site, <code>www.lua.org</code>.
+
+
+<p>
+Like any other reference manual,
+this document is dry in places.
+For a discussion of the decisions behind the design of Lua,
+see the technical papers available at Lua's web site.
+For a detailed introduction to programming in Lua,
+see Roberto's book, <em>Programming in Lua</em>.
+
+
+
+<h1>2 &ndash; <a name="2">Basic Concepts</a></h1>
+
+<p>
+This section describes the basic concepts of the language.
+
+
+
+<h2>2.1 &ndash; <a name="2.1">Values and Types</a></h2>
+
+<p>
+Lua is a <em>dynamically typed language</em>.
+This means that
+variables do not have types; only values do.
+There are no type definitions in the language.
+All values carry their own type.
+
+
+<p>
+All values in Lua are <em>first-class values</em>.
+This means that all values can be stored in variables,
+passed as arguments to other functions, and returned as results.
+
+
+<p>
+There are eight basic types in Lua:
+<em>nil</em>, <em>boolean</em>, <em>number</em>,
+<em>string</em>, <em>function</em>, <em>userdata</em>,
+<em>thread</em>, and <em>table</em>.
+<em>Nil</em> is the type of the value <b>nil</b>,
+whose main property is to be different from any other value;
+it usually represents the absence of a useful value.
+<em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>.
+Both <b>nil</b> and <b>false</b> make a condition false;
+any other value makes it true.
+<em>Number</em> represents real (double-precision floating-point) numbers.
+Operations on numbers follow the same rules of
+the underlying C&nbsp;implementation,
+which, in turn, usually follows the IEEE 754 standard.
+(It is easy to build Lua interpreters that use other
+internal representations for numbers,
+such as single-precision floats or long integers;
+see file <code>luaconf.h</code>.)
+<em>String</em> represents immutable sequences of bytes.
+
+Lua is 8-bit clean:
+strings can contain any 8-bit value,
+including embedded zeros ('<code>\0</code>').
+
+
+<p>
+Lua can call (and manipulate) functions written in Lua and
+functions written in C
+(see <a href="#3.4.9">&sect;3.4.9</a>).
+
+
+<p>
+The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
+be stored in Lua variables.
+A userdata value is a pointer to a block of raw memory.
+There are two kinds of userdata:
+full userdata, where the block of memory is managed by Lua,
+and light userdata, where the block of memory is managed by the host.
+Userdata has no predefined operations in Lua,
+except assignment and identity test.
+By using <em>metatables</em>,
+the programmer can define operations for full userdata values
+(see <a href="#2.4">&sect;2.4</a>).
+Userdata values cannot be created or modified in Lua,
+only through the C&nbsp;API.
+This guarantees the integrity of data owned by the host program.
+
+
+<p>
+The type <em>thread</em> represents independent threads of execution
+and it is used to implement coroutines (see <a href="#2.6">&sect;2.6</a>).
+Do not confuse Lua threads with operating-system threads.
+Lua supports coroutines on all systems,
+even those that do not support threads.
+
+
+<p>
+The type <em>table</em> implements associative arrays,
+that is, arrays that can be indexed not only with numbers,
+but with any Lua value except <b>nil</b> and NaN
+(<em>Not a Number</em>, a special numeric value used to represent
+undefined or unrepresentable results, such as <code>0/0</code>).
+Tables can be <em>heterogeneous</em>;
+that is, they can contain values of all types (except <b>nil</b>).
+Any key with value <b>nil</b> is not considered part of the table.
+Conversely, any key that is not part of a table has
+an associated value <b>nil</b>.
+
+
+<p>
+Tables are the sole data structuring mechanism in Lua;
+they can be used to represent ordinary arrays, sequences,
+symbol tables, sets, records, graphs, trees, etc.
+To represent records, Lua uses the field name as an index.
+The language supports this representation by
+providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>.
+There are several convenient ways to create tables in Lua
+(see <a href="#3.4.8">&sect;3.4.8</a>).
+
+
+<p>
+We use the term <em>sequence</em> to denote a table where
+the set of all positive numeric keys is equal to <em>{1..n}</em>
+for some integer <em>n</em>,
+which is called the length of the sequence (see <a href="#3.4.6">&sect;3.4.6</a>).
+
+
+<p>
+Like indices,
+the values of table fields can be of any type.
+In particular,
+because functions are first-class values,
+table fields can contain functions.
+Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">&sect;3.4.10</a>).
+
+
+<p>
+The indexing of tables follows
+the definition of raw equality in the language.
+The expressions <code>a[i]</code> and <code>a[j]</code>
+denote the same table element
+if and only if <code>i</code> and <code>j</code> are raw equal
+(that is, equal without metamethods).
+
+
+<p>
+Tables, functions, threads, and (full) userdata values are <em>objects</em>:
+variables do not actually <em>contain</em> these values,
+only <em>references</em> to them.
+Assignment, parameter passing, and function returns
+always manipulate references to such values;
+these operations do not imply any kind of copy.
+
+
+<p>
+The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type
+of a given value (see <a href="#6.1">&sect;6.1</a>).
+
+
+
+
+
+<h2>2.2 &ndash; <a name="2.2">Environments and the Global Environment</a></h2>
+
+<p>
+As will be discussed in <a href="#3.2">&sect;3.2</a> and <a href="#3.3.3">&sect;3.3.3</a>,
+any reference to a global name <code>var</code> is syntactically translated
+to <code>_ENV.var</code>.
+Moreover, every chunk is compiled in the scope of
+an external local variable called <code>_ENV</code> (see <a href="#3.3.2">&sect;3.3.2</a>),
+so <code>_ENV</code> itself is never a global name in a chunk.
+
+
+<p>
+Despite the existence of this external <code>_ENV</code> variable and
+the translation of global names,
+<code>_ENV</code> is a completely regular name.
+In particular,
+you can define new variables and parameters with that name.
+Each reference to a global name uses the <code>_ENV</code> that is
+visible at that point in the program,
+following the usual visibility rules of Lua (see <a href="#3.5">&sect;3.5</a>).
+
+
+<p>
+Any table used as the value of <code>_ENV</code> is called an <em>environment</em>.
+
+
+<p>
+Lua keeps a distinguished environment called the <em>global environment</em>.
+This value is kept at a special index in the C registry (see <a href="#4.5">&sect;4.5</a>).
+In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value.
+
+
+<p>
+When Lua compiles a chunk,
+it initializes the value of its <code>_ENV</code> upvalue
+with the global environment (see <a href="#pdf-load"><code>load</code></a>).
+Therefore, by default,
+global variables in Lua code refer to entries in the global environment.
+Moreover, all standard libraries are loaded in the global environment
+and several functions there operate on that environment.
+You can use <a href="#pdf-load"><code>load</code></a> (or <a href="#pdf-loadfile"><code>loadfile</code></a>)
+to load a chunk with a different environment.
+(In C, you have to load the chunk and then change the value
+of its first upvalue.)
+
+
+<p>
+If you change the global environment in the registry
+(through C code or the debug library),
+all chunks loaded after the change will get the new environment.
+Previously loaded chunks are not affected, however,
+as each has its own reference to the environment in its <code>_ENV</code> variable.
+Moreover, the variable <a href="#pdf-_G"><code>_G</code></a>
+(which is stored in the original global environment)
+is never updated by Lua.
+
+
+
+
+
+<h2>2.3 &ndash; <a name="2.3">Error Handling</a></h2>
+
+<p>
+Because Lua is an embedded extension language,
+all Lua actions start from C&nbsp;code in the host program
+calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
+Whenever an error occurs during
+the compilation or execution of a Lua chunk,
+control returns to the host,
+which can take appropriate measures
+(such as printing an error message).
+
+
+<p>
+Lua code can explicitly generate an error by calling the
+<a href="#pdf-error"><code>error</code></a> function.
+If you need to catch errors in Lua,
+you can use <a href="#pdf-pcall"><code>pcall</code></a> or <a href="#pdf-xpcall"><code>xpcall</code></a>
+to call a given function in <em>protected mode</em>.
+
+
+<p>
+Whenever there is an error,
+an <em>error object</em> (also called an <em>error message</em>)
+is propagated with information about the error.
+Lua itself only generates errors where the error object is a string,
+but programs may generate errors with
+any value for the error object.
+
+
+<p>
+When you use <a href="#pdf-xpcall"><code>xpcall</code></a> or <a href="#lua_pcall"><code>lua_pcall</code></a>,
+you may give a <em>message handler</em>
+to be called in case of errors.
+This function is called with the original error message
+and returns a new error message.
+It is called before the error unwinds the stack,
+so that it can gather more information about the error,
+for instance by inspecting the stack and creating a stack traceback.
+This message handler is still protected by the protected call;
+so, an error inside the message handler
+will call the message handler again.
+If this loop goes on, Lua breaks it and returns an appropriate message.
+
+
+
+
+
+<h2>2.4 &ndash; <a name="2.4">Metatables and Metamethods</a></h2>
+
+<p>
+Every value in Lua can have a <em>metatable</em>.
+This <em>metatable</em> is an ordinary Lua table
+that defines the behavior of the original value
+under certain special operations.
+You can change several aspects of the behavior
+of operations over a value by setting specific fields in its metatable.
+For instance, when a non-numeric value is the operand of an addition,
+Lua checks for a function in the field "<code>__add</code>" of the value's metatable.
+If it finds one,
+Lua calls this function to perform the addition.
+
+
+<p>
+The keys in a metatable are derived from the <em>event</em> names;
+the corresponding values are called <em>metamethods</em>.
+In the previous example, the event is <code>"add"</code>
+and the metamethod is the function that performs the addition.
+
+
+<p>
+You can query the metatable of any value
+using the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
+
+
+<p>
+You can replace the metatable of tables
+using the <a href="#pdf-setmetatable"><code>setmetatable</code></a> function.
+You cannot change the metatable of other types from Lua
+(except by using the debug library);
+you must use the C&nbsp;API for that.
+
+
+<p>
+Tables and full userdata have individual metatables
+(although multiple tables and userdata can share their metatables).
+Values of all other types share one single metatable per type;
+that is, there is one single metatable for all numbers,
+one for all strings, etc.
+By default, a value has no metatable,
+but the string library sets a metatable for the string type (see <a href="#6.4">&sect;6.4</a>).
+
+
+<p>
+A metatable controls how an object behaves in arithmetic operations,
+order comparisons, concatenation, length operation, and indexing.
+A metatable also can define a function to be called
+when a userdata or a table is garbage collected.
+When Lua performs one of these operations over a value,
+it checks whether this value has a metatable with the corresponding event.
+If so, the value associated with that key (the metamethod)
+controls how Lua will perform the operation.
+
+
+<p>
+Metatables control the operations listed next.
+Each operation is identified by its corresponding name.
+The key for each operation is a string with its name prefixed by
+two underscores, '<code>__</code>';
+for instance, the key for operation "add" is the
+string "<code>__add</code>".
+
+
+<p>
+The semantics of these operations is better explained by a Lua function
+describing how the interpreter executes the operation.
+The code shown here in Lua is only illustrative;
+the real behavior is hard coded in the interpreter
+and it is much more efficient than this simulation.
+All functions used in these descriptions
+(<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.)
+are described in <a href="#6.1">&sect;6.1</a>.
+In particular, to retrieve the metamethod of a given object,
+we use the expression
+
+<pre>
+     metatable(obj)[event]
+</pre><p>
+This should be read as
+
+<pre>
+     rawget(getmetatable(obj) or {}, event)
+</pre><p>
+This means that the access to a metamethod does not invoke other metamethods,
+and access to objects with no metatables does not fail
+(it simply results in <b>nil</b>).
+
+
+<p>
+For the unary <code>-</code> and <code>#</code> operators,
+the metamethod is called with a dummy second argument.
+This extra argument is only to simplify Lua's internals;
+it may be removed in future versions and therefore it is not present
+in the following code.
+(For most uses this extra argument is irrelevant.)
+
+
+
+<ul>
+
+<li><b>"add": </b>
+the <code>+</code> operation.
+
+
+
+<p>
+The function <code>getbinhandler</code> below defines how Lua chooses a handler
+for a binary operation.
+First, Lua tries the first operand.
+If its type does not define a handler for the operation,
+then Lua tries the second operand.
+
+<pre>
+     function getbinhandler (op1, op2, event)
+       return metatable(op1)[event] or metatable(op2)[event]
+     end
+</pre><p>
+By using this function,
+the behavior of the <code>op1 + op2</code> is
+
+<pre>
+     function add_event (op1, op2)
+       local o1, o2 = tonumber(op1), tonumber(op2)
+       if o1 and o2 then  -- both operands are numeric?
+         return o1 + o2   -- '+' here is the primitive 'add'
+       else  -- at least one of the operands is not numeric
+         local h = getbinhandler(op1, op2, "__add")
+         if h then
+           -- call the handler with both operands
+           return (h(op1, op2))
+         else  -- no handler available: default behavior
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+</li>
+
+<li><b>"sub": </b>
+the <code>-</code> operation.
+
+Behavior similar to the "add" operation.
+</li>
+
+<li><b>"mul": </b>
+the <code>*</code> operation.
+
+Behavior similar to the "add" operation.
+</li>
+
+<li><b>"div": </b>
+the <code>/</code> operation.
+
+Behavior similar to the "add" operation.
+</li>
+
+<li><b>"mod": </b>
+the <code>%</code> operation.
+
+Behavior similar to the "add" operation,
+with the operation
+<code>o1 - floor(o1/o2)*o2</code> as the primitive operation.
+</li>
+
+<li><b>"pow": </b>
+the <code>^</code> (exponentiation) operation.
+
+Behavior similar to the "add" operation,
+with the function <code>pow</code> (from the C&nbsp;math library)
+as the primitive operation.
+</li>
+
+<li><b>"unm": </b>
+the unary <code>-</code> operation.
+
+
+<pre>
+     function unm_event (op)
+       local o = tonumber(op)
+       if o then  -- operand is numeric?
+         return -o  -- '-' here is the primitive 'unm'
+       else  -- the operand is not numeric.
+         -- Try to get a handler from the operand
+         local h = metatable(op).__unm
+         if h then
+           -- call the handler with the operand
+           return (h(op))
+         else  -- no handler available: default behavior
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+</li>
+
+<li><b>"concat": </b>
+the <code>..</code> (concatenation) operation.
+
+
+<pre>
+     function concat_event (op1, op2)
+       if (type(op1) == "string" or type(op1) == "number") and
+          (type(op2) == "string" or type(op2) == "number") then
+         return op1 .. op2  -- primitive string concatenation
+       else
+         local h = getbinhandler(op1, op2, "__concat")
+         if h then
+           return (h(op1, op2))
+         else
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+</li>
+
+<li><b>"len": </b>
+the <code>#</code> operation.
+
+
+<pre>
+     function len_event (op)
+       if type(op) == "string" then
+         return strlen(op)      -- primitive string length
+       else
+         local h = metatable(op).__len
+         if h then
+           return (h(op))       -- call handler with the operand
+         elseif type(op) == "table" then
+           return #op              -- primitive table length
+         else  -- no handler available: error
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+See <a href="#3.4.6">&sect;3.4.6</a> for a description of the length of a table.
+</li>
+
+<li><b>"eq": </b>
+the <code>==</code> operation.
+
+The function <code>getequalhandler</code> defines how Lua chooses a metamethod
+for equality.
+A metamethod is selected only when both values
+being compared have the same type
+and the same metamethod for the selected operation,
+and the values are either tables or full userdata.
+
+<pre>
+     function getequalhandler (op1, op2)
+       if type(op1) ~= type(op2) or
+          (type(op1) ~= "table" and type(op1) ~= "userdata") then
+         return nil     -- different values
+       end
+       local mm1 = metatable(op1).__eq
+       local mm2 = metatable(op2).__eq
+       if mm1 == mm2 then return mm1 else return nil end
+     end
+</pre><p>
+The "eq" event is defined as follows:
+
+<pre>
+     function eq_event (op1, op2)
+       if op1 == op2 then   -- primitive equal?
+         return true   -- values are equal
+       end
+       -- try metamethod
+       local h = getequalhandler(op1, op2)
+       if h then
+         return not not h(op1, op2)
+       else
+         return false
+       end
+     end
+</pre><p>
+Note that the result is always a boolean.
+</li>
+
+<li><b>"lt": </b>
+the <code>&lt;</code> operation.
+
+
+<pre>
+     function lt_event (op1, op2)
+       if type(op1) == "number" and type(op2) == "number" then
+         return op1 &lt; op2   -- numeric comparison
+       elseif type(op1) == "string" and type(op2) == "string" then
+         return op1 &lt; op2   -- lexicographic comparison
+       else
+         local h = getbinhandler(op1, op2, "__lt")
+         if h then
+           return not not h(op1, op2)
+         else
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+Note that the result is always a boolean.
+</li>
+
+<li><b>"le": </b>
+the <code>&lt;=</code> operation.
+
+
+<pre>
+     function le_event (op1, op2)
+       if type(op1) == "number" and type(op2) == "number" then
+         return op1 &lt;= op2   -- numeric comparison
+       elseif type(op1) == "string" and type(op2) == "string" then
+         return op1 &lt;= op2   -- lexicographic comparison
+       else
+         local h = getbinhandler(op1, op2, "__le")
+         if h then
+           return not not h(op1, op2)
+         else
+           h = getbinhandler(op1, op2, "__lt")
+           if h then
+             return not h(op2, op1)
+           else
+             error(&middot;&middot;&middot;)
+           end
+         end
+       end
+     end
+</pre><p>
+Note that, in the absence of a "le" metamethod,
+Lua tries the "lt", assuming that <code>a &lt;= b</code> is
+equivalent to <code>not (b &lt; a)</code>.
+
+
+<p>
+As with the other comparison operators,
+the result is always a boolean.
+</li>
+
+<li><b>"index": </b>
+The indexing access <code>table[key]</code>.
+Note that the metamethod is tried only
+when <code>key</code> is not present in <code>table</code>.
+(When <code>table</code> is not a table,
+no key is ever present,
+so the metamethod is always tried.)
+
+
+<pre>
+     function gettable_event (table, key)
+       local h
+       if type(table) == "table" then
+         local v = rawget(table, key)
+         -- if key is present, return raw value
+         if v ~= nil then return v end
+         h = metatable(table).__index
+         if h == nil then return nil end
+       else
+         h = metatable(table).__index
+         if h == nil then
+           error(&middot;&middot;&middot;)
+         end
+       end
+       if type(h) == "function" then
+         return (h(table, key))     -- call the handler
+       else return h[key]           -- or repeat operation on it
+       end
+     end
+</pre><p>
+</li>
+
+<li><b>"newindex": </b>
+The indexing assignment <code>table[key] = value</code>.
+Note that the metamethod is tried only
+when <code>key</code> is not present in <code>table</code>.
+
+
+<pre>
+     function settable_event (table, key, value)
+       local h
+       if type(table) == "table" then
+         local v = rawget(table, key)
+         -- if key is present, do raw assignment
+         if v ~= nil then rawset(table, key, value); return end
+         h = metatable(table).__newindex
+         if h == nil then rawset(table, key, value); return end
+       else
+         h = metatable(table).__newindex
+         if h == nil then
+           error(&middot;&middot;&middot;)
+         end
+       end
+       if type(h) == "function" then
+         h(table, key,value)           -- call the handler
+       else h[key] = value             -- or repeat operation on it
+       end
+     end
+</pre><p>
+</li>
+
+<li><b>"call": </b>
+called when Lua calls a value.
+
+
+<pre>
+     function function_event (func, ...)
+       if type(func) == "function" then
+         return func(...)   -- primitive call
+       else
+         local h = metatable(func).__call
+         if h then
+           return h(func, ...)
+         else
+           error(&middot;&middot;&middot;)
+         end
+       end
+     end
+</pre><p>
+</li>
+
+</ul>
+
+
+
+
+<h2>2.5 &ndash; <a name="2.5">Garbage Collection</a></h2>
+
+<p>
+Lua performs automatic memory management.
+This means that
+you have to worry neither about allocating memory for new objects
+nor about freeing it when the objects are no longer needed.
+Lua manages memory automatically by running
+a <em>garbage collector</em> to collect all <em>dead objects</em>
+(that is, objects that are no longer accessible from Lua).
+All memory used by Lua is subject to automatic management:
+strings, tables, userdata, functions, threads, internal structures, etc.
+
+
+<p>
+Lua implements an incremental mark-and-sweep collector.
+It uses two numbers to control its garbage-collection cycles:
+the <em>garbage-collector pause</em> and
+the <em>garbage-collector step multiplier</em>.
+Both use percentage points as units
+(e.g., a value of 100 means an internal value of 1).
+
+
+<p>
+The garbage-collector pause
+controls how long the collector waits before starting a new cycle.
+Larger values make the collector less aggressive.
+Values smaller than 100 mean the collector will not wait to
+start a new cycle.
+A value of 200 means that the collector waits for the total memory in use
+to double before starting a new cycle.
+
+
+<p>
+The garbage-collector step multiplier
+controls the relative speed of the collector relative to
+memory allocation.
+Larger values make the collector more aggressive but also increase
+the size of each incremental step.
+Values smaller than 100 make the collector too slow and
+can result in the collector never finishing a cycle.
+The default is 200,
+which means that the collector runs at "twice"
+the speed of memory allocation.
+
+
+<p>
+If you set the step multiplier to a very large number
+(larger than 10% of the maximum number of
+bytes that the program may use),
+the collector behaves like a stop-the-world collector.
+If you then set the pause to 200,
+the collector behaves as in old Lua versions,
+doing a complete collection every time Lua doubles its
+memory usage.
+
+
+<p>
+You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C
+or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua.
+You can also use these functions to control
+the collector directly (e.g., stop and restart it).
+
+
+<p>
+As an experimental feature in Lua 5.2,
+you can change the collector's operation mode
+from incremental to <em>generational</em>.
+A <em>generational collector</em> assumes that most objects die young,
+and therefore it traverses only young (recently created) objects.
+This behavior can reduce the time used by the collector,
+but also increases memory usage (as old dead objects may accumulate).
+To mitigate this second problem,
+from time to time the generational collector performs a full collection.
+Remember that this is an experimental feature;
+you are welcome to try it,
+but check your gains.
+
+
+
+<h3>2.5.1 &ndash; <a name="2.5.1">Garbage-Collection Metamethods</a></h3>
+
+<p>
+You can set garbage-collector metamethods for tables
+and, using the C&nbsp;API,
+for full userdata (see <a href="#2.4">&sect;2.4</a>).
+These metamethods are also called <em>finalizers</em>.
+Finalizers allow you to coordinate Lua's garbage collection
+with external resource management
+(such as closing files, network or database connections,
+or freeing your own memory).
+
+
+<p>
+For an object (table or userdata) to be finalized when collected,
+you must <em>mark</em> it for finalization.
+
+You mark an object for finalization when you set its metatable
+and the metatable has a field indexed by the string "<code>__gc</code>".
+Note that if you set a metatable without a <code>__gc</code> field
+and later create that field in the metatable,
+the object will not be marked for finalization.
+However, after an object is marked,
+you can freely change the <code>__gc</code> field of its metatable.
+
+
+<p>
+When a marked object becomes garbage,
+it is not collected immediately by the garbage collector.
+Instead, Lua puts it in a list.
+After the collection,
+Lua does the equivalent of the following function
+for each object in that list:
+
+<pre>
+     function gc_event (obj)
+       local h = metatable(obj).__gc
+       if type(h) == "function" then
+         h(obj)
+       end
+     end
+</pre>
+
+<p>
+At the end of each garbage-collection cycle,
+the finalizers for objects are called in
+the reverse order that they were marked for collection,
+among those collected in that cycle;
+that is, the first finalizer to be called is the one associated
+with the object marked last in the program.
+The execution of each finalizer may occur at any point during
+the execution of the regular code.
+
+
+<p>
+Because the object being collected must still be used by the finalizer,
+it (and other objects accessible only through it)
+must be <em>resurrected</em> by Lua.
+Usually, this resurrection is transient,
+and the object memory is freed in the next garbage-collection cycle.
+However, if the finalizer stores the object in some global place
+(e.g., a global variable),
+then there is a permanent resurrection.
+In any case,
+the object memory is freed only when it becomes completely inaccessible;
+its finalizer will never be called twice.
+
+
+<p>
+When you close a state (see <a href="#lua_close"><code>lua_close</code></a>),
+Lua calls the finalizers of all objects marked for finalization,
+following the reverse order that they were marked.
+If any finalizer marks new objects for collection during that phase,
+these new objects will not be finalized.
+
+
+
+
+
+<h3>2.5.2 &ndash; <a name="2.5.2">Weak Tables</a></h3>
+
+<p>
+A <em>weak table</em> is a table whose elements are
+<em>weak references</em>.
+A weak reference is ignored by the garbage collector.
+In other words,
+if the only references to an object are weak references,
+then the garbage collector will collect that object.
+
+
+<p>
+A weak table can have weak keys, weak values, or both.
+A table with weak keys allows the collection of its keys,
+but prevents the collection of its values.
+A table with both weak keys and weak values allows the collection of
+both keys and values.
+In any case, if either the key or the value is collected,
+the whole pair is removed from the table.
+The weakness of a table is controlled by the
+<code>__mode</code> field of its metatable.
+If the <code>__mode</code> field is a string containing the character&nbsp;'<code>k</code>',
+the keys in the table are weak.
+If <code>__mode</code> contains '<code>v</code>',
+the values in the table are weak.
+
+
+<p>
+A table with weak keys and strong values
+is also called an <em>ephemeron table</em>.
+In an ephemeron table,
+a value is considered reachable only if its key is reachable.
+In particular,
+if the only reference to a key comes through its value,
+the pair is removed.
+
+
+<p>
+Any change in the weakness of a table may take effect only
+at the next collect cycle.
+In particular, if you change the weakness to a stronger mode,
+Lua may still collect some items from that table
+before the change takes effect.
+
+
+<p>
+Only objects that have an explicit construction
+are removed from weak tables.
+Values, such as numbers and light C functions,
+are not subject to garbage collection,
+and therefore are not removed from weak tables
+(unless its associated value is collected).
+Although strings are subject to garbage collection,
+they do not have an explicit construction,
+and therefore are not removed from weak tables.
+
+
+<p>
+Resurrected objects
+(that is, objects being finalized
+and objects accessible only through objects being finalized)
+have a special behavior in weak tables.
+They are removed from weak values before running their finalizers,
+but are removed from weak keys only in the next collection
+after running their finalizers, when such objects are actually freed.
+This behavior allows the finalizer to access properties
+associated with the object through weak tables.
+
+
+<p>
+If a weak table is among the resurrected objects in a collection cycle,
+it may not be properly cleared until the next cycle.
+
+
+
+
+
+
+
+<h2>2.6 &ndash; <a name="2.6">Coroutines</a></h2>
+
+<p>
+Lua supports coroutines,
+also called <em>collaborative multithreading</em>.
+A coroutine in Lua represents an independent thread of execution.
+Unlike threads in multithread systems, however,
+a coroutine only suspends its execution by explicitly calling
+a yield function.
+
+
+<p>
+You create a coroutine by calling <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>.
+Its sole argument is a function
+that is the main function of the coroutine.
+The <code>create</code> function only creates a new coroutine and
+returns a handle to it (an object of type <em>thread</em>);
+it does not start the coroutine.
+
+
+<p>
+You execute a coroutine by calling <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+passing as its first argument
+a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
+the coroutine starts its execution,
+at the first line of its main function.
+Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on
+to the coroutine main function.
+After the coroutine starts running,
+it runs until it terminates or <em>yields</em>.
+
+
+<p>
+A coroutine can terminate its execution in two ways:
+normally, when its main function returns
+(explicitly or implicitly, after the last instruction);
+and abnormally, if there is an unprotected error.
+In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
+plus any values returned by the coroutine main function.
+In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b>
+plus an error message.
+
+
+<p>
+A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
+When a coroutine yields,
+the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately,
+even if the yield happens inside nested function calls
+(that is, not in the main function,
+but in a function directly or indirectly called by the main function).
+In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>,
+plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
+The next time you resume the same coroutine,
+it continues its execution from the point where it yielded,
+with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra
+arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+
+
+<p>
+Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
+the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine,
+but instead of returning the coroutine itself,
+it returns a function that, when called, resumes the coroutine.
+Any arguments passed to this function
+go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
+<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+except the first one (the boolean error code).
+Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
+<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors;
+any error is propagated to the caller.
+
+
+<p>
+As an example of how coroutines work,
+consider the following code:
+
+<pre>
+     function foo (a)
+       print("foo", a)
+       return coroutine.yield(2*a)
+     end
+     
+     co = coroutine.create(function (a,b)
+           print("co-body", a, b)
+           local r = foo(a+1)
+           print("co-body", r)
+           local r, s = coroutine.yield(a+b, a-b)
+           print("co-body", r, s)
+           return b, "end"
+     end)
+     
+     print("main", coroutine.resume(co, 1, 10))
+     print("main", coroutine.resume(co, "r"))
+     print("main", coroutine.resume(co, "x", "y"))
+     print("main", coroutine.resume(co, "x", "y"))
+</pre><p>
+When you run it, it produces the following output:
+
+<pre>
+     co-body 1       10
+     foo     2
+     main    true    4
+     co-body r
+     main    true    11      -9
+     co-body x       y
+     main    true    10      end
+     main    false   cannot resume dead coroutine
+</pre>
+
+<p>
+You can also create and manipulate coroutines through the C API:
+see functions <a href="#lua_newthread"><code>lua_newthread</code></a>, <a href="#lua_resume"><code>lua_resume</code></a>,
+and <a href="#lua_yield"><code>lua_yield</code></a>.
+
+
+
+
+
+<h1>3 &ndash; <a name="3">The Language</a></h1>
+
+<p>
+This section describes the lexis, the syntax, and the semantics of Lua.
+In other words,
+this section describes
+which tokens are valid,
+how they can be combined,
+and what their combinations mean.
+
+
+<p>
+Language constructs will be explained using the usual extended BNF notation,
+in which
+{<em>a</em>}&nbsp;means&nbsp;0 or more <em>a</em>'s, and
+[<em>a</em>]&nbsp;means an optional <em>a</em>.
+Non-terminals are shown like non-terminal,
+keywords are shown like <b>kword</b>,
+and other terminal symbols are shown like &lsquo;<b>=</b>&rsquo;.
+The complete syntax of Lua can be found in <a href="#9">&sect;9</a>
+at the end of this manual.
+
+
+
+<h2>3.1 &ndash; <a name="3.1">Lexical Conventions</a></h2>
+
+<p>
+Lua is a free-form language.
+It ignores spaces (including new lines) and comments
+between lexical elements (tokens),
+except as delimiters between names and keywords.
+
+
+<p>
+<em>Names</em>
+(also called <em>identifiers</em>)
+in Lua can be any string of letters,
+digits, and underscores,
+not beginning with a digit.
+Identifiers are used to name variables, table fields, and labels.
+
+
+<p>
+The following <em>keywords</em> are reserved
+and cannot be used as names:
+
+
+<pre>
+     and       break     do        else      elseif    end
+     false     for       function  goto      if        in
+     local     nil       not       or        repeat    return
+     then      true      until     while
+</pre>
+
+<p>
+Lua is a case-sensitive language:
+<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code>
+are two different, valid names.
+As a convention, names starting with an underscore followed by
+uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>)
+are reserved for variables used by Lua.
+
+
+<p>
+The following strings denote other tokens:
+
+<pre>
+     +     -     *     /     %     ^     #
+     ==    ~=    &lt;=    &gt;=    &lt;     &gt;     =
+     (     )     {     }     [     ]     ::
+     ;     :     ,     .     ..    ...
+</pre>
+
+<p>
+<em>Literal strings</em>
+can be delimited by matching single or double quotes,
+and can contain the following C-like escape sequences:
+'<code>\a</code>' (bell),
+'<code>\b</code>' (backspace),
+'<code>\f</code>' (form feed),
+'<code>\n</code>' (newline),
+'<code>\r</code>' (carriage return),
+'<code>\t</code>' (horizontal tab),
+'<code>\v</code>' (vertical tab),
+'<code>\\</code>' (backslash),
+'<code>\"</code>' (quotation mark [double quote]),
+and '<code>\'</code>' (apostrophe [single quote]).
+A backslash followed by a real newline
+results in a newline in the string.
+The escape sequence '<code>\z</code>' skips the following span
+of white-space characters,
+including line breaks;
+it is particularly useful to break and indent a long literal string
+into multiple lines without adding the newlines and spaces
+into the string contents.
+
+
+<p>
+A byte in a literal string can also be specified by its numerical value.
+This can be done with the escape sequence <code>\x<em>XX</em></code>,
+where <em>XX</em> is a sequence of exactly two hexadecimal digits,
+or with the escape sequence <code>\<em>ddd</em></code>,
+where <em>ddd</em> is a sequence of up to three decimal digits.
+(Note that if a decimal escape is to be followed by a digit,
+it must be expressed using exactly three digits.)
+Strings in Lua can contain any 8-bit value, including embedded zeros,
+which can be specified as '<code>\0</code>'.
+
+
+<p>
+Literal strings can also be defined using a long format
+enclosed by <em>long brackets</em>.
+We define an <em>opening long bracket of level <em>n</em></em> as an opening
+square bracket followed by <em>n</em> equal signs followed by another
+opening square bracket.
+So, an opening long bracket of level&nbsp;0 is written as <code>[[</code>,
+an opening long bracket of level&nbsp;1 is written as <code>[=[</code>,
+and so on.
+A <em>closing long bracket</em> is defined similarly;
+for instance, a closing long bracket of level&nbsp;4 is written as <code>]====]</code>.
+A <em>long literal</em> starts with an opening long bracket of any level and
+ends at the first closing long bracket of the same level.
+It can contain any text except a closing bracket of the proper level.
+Literals in this bracketed form can run for several lines,
+do not interpret any escape sequences,
+and ignore long brackets of any other level.
+Any kind of end-of-line sequence
+(carriage return, newline, carriage return followed by newline,
+or newline followed by carriage return)
+is converted to a simple newline.
+
+
+<p>
+Any byte in a literal string not
+explicitly affected by the previous rules represents itself.
+However, Lua opens files for parsing in text mode,
+and the system file functions may have problems with
+some control characters.
+So, it is safer to represent
+non-text data as a quoted literal with
+explicit escape sequences for non-text characters.
+
+
+<p>
+For convenience,
+when the opening long bracket is immediately followed by a newline,
+the newline is not included in the string.
+As an example, in a system using ASCII
+(in which '<code>a</code>' is coded as&nbsp;97,
+newline is coded as&nbsp;10, and '<code>1</code>' is coded as&nbsp;49),
+the five literal strings below denote the same string:
+
+<pre>
+     a = 'alo\n123"'
+     a = "alo\n123\""
+     a = '\97lo\10\04923"'
+     a = [[alo
+     123"]]
+     a = [==[
+     alo
+     123"]==]
+</pre>
+
+<p>
+A <em>numerical constant</em> can be written with an optional fractional part
+and an optional decimal exponent,
+marked by a letter '<code>e</code>' or '<code>E</code>'.
+Lua also accepts hexadecimal constants,
+which start with <code>0x</code> or <code>0X</code>.
+Hexadecimal constants also accept an optional fractional part
+plus an optional binary exponent,
+marked by a letter '<code>p</code>' or '<code>P</code>'.
+Examples of valid numerical constants are
+
+<pre>
+     3     3.0     3.1416     314.16e-2     0.31416E1
+     0xff  0x0.1E  0xA23p-4   0X1.921FB54442D18P+1
+</pre>
+
+<p>
+A <em>comment</em> starts with a double hyphen (<code>--</code>)
+anywhere outside a string.
+If the text immediately after <code>--</code> is not an opening long bracket,
+the comment is a <em>short comment</em>,
+which runs until the end of the line.
+Otherwise, it is a <em>long comment</em>,
+which runs until the corresponding closing long bracket.
+Long comments are frequently used to disable code temporarily.
+
+
+
+
+
+<h2>3.2 &ndash; <a name="3.2">Variables</a></h2>
+
+<p>
+Variables are places that store values.
+There are three kinds of variables in Lua:
+global variables, local variables, and table fields.
+
+
+<p>
+A single name can denote a global variable or a local variable
+(or a function's formal parameter,
+which is a particular kind of local variable):
+
+<pre>
+	var ::= Name
+</pre><p>
+Name denotes identifiers, as defined in <a href="#3.1">&sect;3.1</a>.
+
+
+<p>
+Any variable name is assumed to be global unless explicitly declared
+as a local (see <a href="#3.3.7">&sect;3.3.7</a>).
+Local variables are <em>lexically scoped</em>:
+local variables can be freely accessed by functions
+defined inside their scope (see <a href="#3.5">&sect;3.5</a>).
+
+
+<p>
+Before the first assignment to a variable, its value is <b>nil</b>.
+
+
+<p>
+Square brackets are used to index a table:
+
+<pre>
+	var ::= prefixexp &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo;
+</pre><p>
+The meaning of accesses to table fields can be changed via metatables.
+An access to an indexed variable <code>t[i]</code> is equivalent to
+a call <code>gettable_event(t,i)</code>.
+(See <a href="#2.4">&sect;2.4</a> for a complete description of the
+<code>gettable_event</code> function.
+This function is not defined or callable in Lua.
+We use it here only for explanatory purposes.)
+
+
+<p>
+The syntax <code>var.Name</code> is just syntactic sugar for
+<code>var["Name"]</code>:
+
+<pre>
+	var ::= prefixexp &lsquo;<b>.</b>&rsquo; Name
+</pre>
+
+<p>
+An access to a global variable <code>x</code>
+is equivalent to <code>_ENV.x</code>.
+Due to the way that chunks are compiled,
+<code>_ENV</code> is never a global name (see <a href="#2.2">&sect;2.2</a>).
+
+
+
+
+
+<h2>3.3 &ndash; <a name="3.3">Statements</a></h2>
+
+<p>
+Lua supports an almost conventional set of statements,
+similar to those in Pascal or C.
+This set includes
+assignments, control structures, function calls,
+and variable declarations.
+
+
+
+<h3>3.3.1 &ndash; <a name="3.3.1">Blocks</a></h3>
+
+<p>
+A block is a list of statements,
+which are executed sequentially:
+
+<pre>
+	block ::= {stat}
+</pre><p>
+Lua has <em>empty statements</em>
+that allow you to separate statements with semicolons,
+start a block with a semicolon
+or write two semicolons in sequence:
+
+<pre>
+	stat ::= &lsquo;<b>;</b>&rsquo;
+</pre>
+
+<p>
+Function calls and assignments
+can start with an open parenthesis.
+This possibility leads to an ambiguity in Lua's grammar.
+Consider the following fragment:
+
+<pre>
+     a = b + c
+     (print or io.write)('done')
+</pre><p>
+The grammar could see it in two ways:
+
+<pre>
+     a = b + c(print or io.write)('done')
+     
+     a = b + c; (print or io.write)('done')
+</pre><p>
+The current parser always sees such constructions
+in the first way,
+interpreting the open parenthesis
+as the start of the arguments to a call.
+To avoid this ambiguity,
+it is a good practice to always precede with a semicolon
+statements that start with a parenthesis:
+
+<pre>
+     ;(print or io.write)('done')
+</pre>
+
+<p>
+A block can be explicitly delimited to produce a single statement:
+
+<pre>
+	stat ::= <b>do</b> block <b>end</b>
+</pre><p>
+Explicit blocks are useful
+to control the scope of variable declarations.
+Explicit blocks are also sometimes used to
+add a <b>return</b> statement in the middle
+of another block (see <a href="#3.3.4">&sect;3.3.4</a>).
+
+
+
+
+
+<h3>3.3.2 &ndash; <a name="3.3.2">Chunks</a></h3>
+
+<p>
+The unit of compilation of Lua is called a <em>chunk</em>.
+Syntactically,
+a chunk is simply a block:
+
+<pre>
+	chunk ::= block
+</pre>
+
+<p>
+Lua handles a chunk as the body of an anonymous function
+with a variable number of arguments
+(see <a href="#3.4.10">&sect;3.4.10</a>).
+As such, chunks can define local variables,
+receive arguments, and return values.
+Moreover, such anonymous function is compiled as in the
+scope of an external local variable called <code>_ENV</code> (see <a href="#2.2">&sect;2.2</a>).
+The resulting function always has <code>_ENV</code> as its only upvalue,
+even if it does not use that variable.
+
+
+<p>
+A chunk can be stored in a file or in a string inside the host program.
+To execute a chunk,
+Lua first precompiles the chunk into instructions for a virtual machine,
+and then it executes the compiled code
+with an interpreter for the virtual machine.
+
+
+<p>
+Chunks can also be precompiled into binary form;
+see program <code>luac</code> for details.
+Programs in source and compiled forms are interchangeable;
+Lua automatically detects the file type and acts accordingly.
+
+
+
+
+
+
+<h3>3.3.3 &ndash; <a name="3.3.3">Assignment</a></h3>
+
+<p>
+Lua allows multiple assignments.
+Therefore, the syntax for assignment
+defines a list of variables on the left side
+and a list of expressions on the right side.
+The elements in both lists are separated by commas:
+
+<pre>
+	stat ::= varlist &lsquo;<b>=</b>&rsquo; explist
+	varlist ::= var {&lsquo;<b>,</b>&rsquo; var}
+	explist ::= exp {&lsquo;<b>,</b>&rsquo; exp}
+</pre><p>
+Expressions are discussed in <a href="#3.4">&sect;3.4</a>.
+
+
+<p>
+Before the assignment,
+the list of values is <em>adjusted</em> to the length of
+the list of variables.
+If there are more values than needed,
+the excess values are thrown away.
+If there are fewer values than needed,
+the list is extended with as many  <b>nil</b>'s as needed.
+If the list of expressions ends with a function call,
+then all values returned by that call enter the list of values,
+before the adjustment
+(except when the call is enclosed in parentheses; see <a href="#3.4">&sect;3.4</a>).
+
+
+<p>
+The assignment statement first evaluates all its expressions
+and only then are the assignments performed.
+Thus the code
+
+<pre>
+     i = 3
+     i, a[i] = i+1, 20
+</pre><p>
+sets <code>a[3]</code> to 20, without affecting <code>a[4]</code>
+because the <code>i</code> in <code>a[i]</code> is evaluated (to 3)
+before it is assigned&nbsp;4.
+Similarly, the line
+
+<pre>
+     x, y = y, x
+</pre><p>
+exchanges the values of <code>x</code> and <code>y</code>,
+and
+
+<pre>
+     x, y, z = y, z, x
+</pre><p>
+cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>.
+
+
+<p>
+The meaning of assignments to global variables
+and table fields can be changed via metatables.
+An assignment to an indexed variable <code>t[i] = val</code> is equivalent to
+<code>settable_event(t,i,val)</code>.
+(See <a href="#2.4">&sect;2.4</a> for a complete description of the
+<code>settable_event</code> function.
+This function is not defined or callable in Lua.
+We use it here only for explanatory purposes.)
+
+
+<p>
+An assignment to a global variable <code>x = val</code>
+is equivalent to the assignment
+<code>_ENV.x = val</code> (see <a href="#2.2">&sect;2.2</a>).
+
+
+
+
+
+<h3>3.3.4 &ndash; <a name="3.3.4">Control Structures</a></h3><p>
+The control structures
+<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and
+familiar syntax:
+
+
+
+
+<pre>
+	stat ::= <b>while</b> exp <b>do</b> block <b>end</b>
+	stat ::= <b>repeat</b> block <b>until</b> exp
+	stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b>
+</pre><p>
+Lua also has a <b>for</b> statement, in two flavors (see <a href="#3.3.5">&sect;3.3.5</a>).
+
+
+<p>
+The condition expression of a
+control structure can return any value.
+Both <b>false</b> and <b>nil</b> are considered false.
+All values different from <b>nil</b> and <b>false</b> are considered true
+(in particular, the number 0 and the empty string are also true).
+
+
+<p>
+In the <b>repeat</b>&ndash;<b>until</b> loop,
+the inner block does not end at the <b>until</b> keyword,
+but only after the condition.
+So, the condition can refer to local variables
+declared inside the loop block.
+
+
+<p>
+The <b>goto</b> statement transfers the program control to a label.
+For syntactical reasons,
+labels in Lua are considered statements too:
+
+
+
+<pre>
+	stat ::= <b>goto</b> Name
+	stat ::= label
+	label ::= &lsquo;<b>::</b>&rsquo; Name &lsquo;<b>::</b>&rsquo;
+</pre>
+
+<p>
+A label is visible in the entire block where it is defined,
+except
+inside nested blocks where a label with the same name is defined and
+inside nested functions.
+A goto may jump to any visible label as long as it does not
+enter into the scope of a local variable.
+
+
+<p>
+Labels and empty statements are called <em>void statements</em>,
+as they perform no actions.
+
+
+<p>
+The <b>break</b> statement terminates the execution of a
+<b>while</b>, <b>repeat</b>, or <b>for</b> loop,
+skipping to the next statement after the loop:
+
+
+<pre>
+	stat ::= <b>break</b>
+</pre><p>
+A <b>break</b> ends the innermost enclosing loop.
+
+
+<p>
+The <b>return</b> statement is used to return values
+from a function or a chunk (which is a function in disguise).
+
+Functions can return more than one value,
+so the syntax for the <b>return</b> statement is
+
+<pre>
+	stat ::= <b>return</b> [explist] [&lsquo;<b>;</b>&rsquo;]
+</pre>
+
+<p>
+The <b>return</b> statement can only be written
+as the last statement of a block.
+If it is really necessary to <b>return</b> in the middle of a block,
+then an explicit inner block can be used,
+as in the idiom <code>do return end</code>,
+because now <b>return</b> is the last statement in its (inner) block.
+
+
+
+
+
+<h3>3.3.5 &ndash; <a name="3.3.5">For Statement</a></h3>
+
+<p>
+
+The <b>for</b> statement has two forms:
+one numeric and one generic.
+
+
+<p>
+The numeric <b>for</b> loop repeats a block of code while a
+control variable runs through an arithmetic progression.
+It has the following syntax:
+
+<pre>
+	stat ::= <b>for</b> Name &lsquo;<b>=</b>&rsquo; exp &lsquo;<b>,</b>&rsquo; exp [&lsquo;<b>,</b>&rsquo; exp] <b>do</b> block <b>end</b>
+</pre><p>
+The <em>block</em> is repeated for <em>name</em> starting at the value of
+the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the
+third <em>exp</em>.
+More precisely, a <b>for</b> statement like
+
+<pre>
+     for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end
+</pre><p>
+is equivalent to the code:
+
+<pre>
+     do
+       local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>)
+       if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end
+       while (<em>step</em> &gt; 0 and <em>var</em> &lt;= <em>limit</em>) or (<em>step</em> &lt;= 0 and <em>var</em> &gt;= <em>limit</em>) do
+         local v = <em>var</em>
+         <em>block</em>
+         <em>var</em> = <em>var</em> + <em>step</em>
+       end
+     end
+</pre><p>
+Note the following:
+
+<ul>
+
+<li>
+All three control expressions are evaluated only once,
+before the loop starts.
+They must all result in numbers.
+</li>
+
+<li>
+<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables.
+The names shown here are for explanatory purposes only.
+</li>
+
+<li>
+If the third expression (the step) is absent,
+then a step of&nbsp;1 is used.
+</li>
+
+<li>
+You can use <b>break</b> to exit a <b>for</b> loop.
+</li>
+
+<li>
+The loop variable <code>v</code> is local to the loop;
+you cannot use its value after the <b>for</b> ends or is broken.
+If you need this value,
+assign it to another variable before breaking or exiting the loop.
+</li>
+
+</ul>
+
+<p>
+The generic <b>for</b> statement works over functions,
+called <em>iterators</em>.
+On each iteration, the iterator function is called to produce a new value,
+stopping when this new value is <b>nil</b>.
+The generic <b>for</b> loop has the following syntax:
+
+<pre>
+	stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b>
+	namelist ::= Name {&lsquo;<b>,</b>&rsquo; Name}
+</pre><p>
+A <b>for</b> statement like
+
+<pre>
+     for <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> in <em>explist</em> do <em>block</em> end
+</pre><p>
+is equivalent to the code:
+
+<pre>
+     do
+       local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em>
+       while true do
+         local <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>)
+         if <em>var_1</em> == nil then break end
+         <em>var</em> = <em>var_1</em>
+         <em>block</em>
+       end
+     end
+</pre><p>
+Note the following:
+
+<ul>
+
+<li>
+<code><em>explist</em></code> is evaluated only once.
+Its results are an <em>iterator</em> function,
+a <em>state</em>,
+and an initial value for the first <em>iterator variable</em>.
+</li>
+
+<li>
+<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables.
+The names are here for explanatory purposes only.
+</li>
+
+<li>
+You can use <b>break</b> to exit a <b>for</b> loop.
+</li>
+
+<li>
+The loop variables <code><em>var_i</em></code> are local to the loop;
+you cannot use their values after the <b>for</b> ends.
+If you need these values,
+then assign them to other variables before breaking or exiting the loop.
+</li>
+
+</ul>
+
+
+
+
+<h3>3.3.6 &ndash; <a name="3.3.6">Function Calls as Statements</a></h3><p>
+To allow possible side-effects,
+function calls can be executed as statements:
+
+<pre>
+	stat ::= functioncall
+</pre><p>
+In this case, all returned values are thrown away.
+Function calls are explained in <a href="#3.4.9">&sect;3.4.9</a>.
+
+
+
+
+
+<h3>3.3.7 &ndash; <a name="3.3.7">Local Declarations</a></h3><p>
+Local variables can be declared anywhere inside a block.
+The declaration can include an initial assignment:
+
+<pre>
+	stat ::= <b>local</b> namelist [&lsquo;<b>=</b>&rsquo; explist]
+</pre><p>
+If present, an initial assignment has the same semantics
+of a multiple assignment (see <a href="#3.3.3">&sect;3.3.3</a>).
+Otherwise, all variables are initialized with <b>nil</b>.
+
+
+<p>
+A chunk is also a block (see <a href="#3.3.2">&sect;3.3.2</a>),
+and so local variables can be declared in a chunk outside any explicit block.
+
+
+<p>
+The visibility rules for local variables are explained in <a href="#3.5">&sect;3.5</a>.
+
+
+
+
+
+
+
+<h2>3.4 &ndash; <a name="3.4">Expressions</a></h2>
+
+<p>
+The basic expressions in Lua are the following:
+
+<pre>
+	exp ::= prefixexp
+	exp ::= <b>nil</b> | <b>false</b> | <b>true</b>
+	exp ::= Number
+	exp ::= String
+	exp ::= functiondef
+	exp ::= tableconstructor
+	exp ::= &lsquo;<b>...</b>&rsquo;
+	exp ::= exp binop exp
+	exp ::= unop exp
+	prefixexp ::= var | functioncall | &lsquo;<b>(</b>&rsquo; exp &lsquo;<b>)</b>&rsquo;
+</pre>
+
+<p>
+Numbers and literal strings are explained in <a href="#3.1">&sect;3.1</a>;
+variables are explained in <a href="#3.2">&sect;3.2</a>;
+function definitions are explained in <a href="#3.4.10">&sect;3.4.10</a>;
+function calls are explained in <a href="#3.4.9">&sect;3.4.9</a>;
+table constructors are explained in <a href="#3.4.8">&sect;3.4.8</a>.
+Vararg expressions,
+denoted by three dots ('<code>...</code>'), can only be used when
+directly inside a vararg function;
+they are explained in <a href="#3.4.10">&sect;3.4.10</a>.
+
+
+<p>
+Binary operators comprise arithmetic operators (see <a href="#3.4.1">&sect;3.4.1</a>),
+relational operators (see <a href="#3.4.3">&sect;3.4.3</a>), logical operators (see <a href="#3.4.4">&sect;3.4.4</a>),
+and the concatenation operator (see <a href="#3.4.5">&sect;3.4.5</a>).
+Unary operators comprise the unary minus (see <a href="#3.4.1">&sect;3.4.1</a>),
+the unary <b>not</b> (see <a href="#3.4.4">&sect;3.4.4</a>),
+and the unary <em>length operator</em> (see <a href="#3.4.6">&sect;3.4.6</a>).
+
+
+<p>
+Both function calls and vararg expressions can result in multiple values.
+If a function call is used as a statement (see <a href="#3.3.6">&sect;3.3.6</a>),
+then its return list is adjusted to zero elements,
+thus discarding all returned values.
+If an expression is used as the last (or the only) element
+of a list of expressions,
+then no adjustment is made
+(unless the expression is enclosed in parentheses).
+In all other contexts,
+Lua adjusts the result list to one element,
+either discarding all values except the first one
+or adding a single <b>nil</b> if there are no values.
+
+
+<p>
+Here are some examples:
+
+<pre>
+     f()                -- adjusted to 0 results
+     g(f(), x)          -- f() is adjusted to 1 result
+     g(x, f())          -- g gets x plus all results from f()
+     a,b,c = f(), x     -- f() is adjusted to 1 result (c gets nil)
+     a,b = ...          -- a gets the first vararg parameter, b gets
+                        -- the second (both a and b can get nil if there
+                        -- is no corresponding vararg parameter)
+     
+     a,b,c = x, f()     -- f() is adjusted to 2 results
+     a,b,c = f()        -- f() is adjusted to 3 results
+     return f()         -- returns all results from f()
+     return ...         -- returns all received vararg parameters
+     return x,y,f()     -- returns x, y, and all results from f()
+     {f()}              -- creates a list with all results from f()
+     {...}              -- creates a list with all vararg parameters
+     {f(), nil}         -- f() is adjusted to 1 result
+</pre>
+
+<p>
+Any expression enclosed in parentheses always results in only one value.
+Thus,
+<code>(f(x,y,z))</code> is always a single value,
+even if <code>f</code> returns several values.
+(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code>
+or <b>nil</b> if <code>f</code> does not return any values.)
+
+
+
+<h3>3.4.1 &ndash; <a name="3.4.1">Arithmetic Operators</a></h3><p>
+Lua supports the usual arithmetic operators:
+the binary <code>+</code> (addition),
+<code>-</code> (subtraction), <code>*</code> (multiplication),
+<code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation);
+and unary <code>-</code> (mathematical negation).
+If the operands are numbers, or strings that can be converted to
+numbers (see <a href="#3.4.2">&sect;3.4.2</a>),
+then all operations have the usual meaning.
+Exponentiation works for any exponent.
+For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>.
+Modulo is defined as
+
+<pre>
+     a % b == a - math.floor(a/b)*b
+</pre><p>
+That is, it is the remainder of a division that rounds
+the quotient towards minus infinity.
+
+
+
+
+
+<h3>3.4.2 &ndash; <a name="3.4.2">Coercion</a></h3>
+
+<p>
+Lua provides automatic conversion between
+string and number values at run time.
+Any arithmetic operation applied to a string tries to convert
+this string to a number, following the rules of the Lua lexer.
+(The string may have leading and trailing spaces and a sign.)
+Conversely, whenever a number is used where a string is expected,
+the number is converted to a string, in a reasonable format.
+For complete control over how numbers are converted to strings,
+use the <code>format</code> function from the string library
+(see <a href="#pdf-string.format"><code>string.format</code></a>).
+
+
+
+
+
+<h3>3.4.3 &ndash; <a name="3.4.3">Relational Operators</a></h3><p>
+The relational operators in Lua are
+
+<pre>
+     ==    ~=    &lt;     &gt;     &lt;=    &gt;=
+</pre><p>
+These operators always result in <b>false</b> or <b>true</b>.
+
+
+<p>
+Equality (<code>==</code>) first compares the type of its operands.
+If the types are different, then the result is <b>false</b>.
+Otherwise, the values of the operands are compared.
+Numbers and strings are compared in the usual way.
+Tables, userdata, and threads
+are compared by reference:
+two objects are considered equal only if they are the same object.
+Every time you create a new object
+(a table, userdata, or thread),
+this new object is different from any previously existing object.
+Closures with the same reference are always equal.
+Closures with any detectable difference
+(different behavior, different definition) are always different.
+
+
+<p>
+You can change the way that Lua compares tables and userdata
+by using the "eq" metamethod (see <a href="#2.4">&sect;2.4</a>).
+
+
+<p>
+The conversion rules of <a href="#3.4.2">&sect;3.4.2</a>
+do not apply to equality comparisons.
+Thus, <code>"0"==0</code> evaluates to <b>false</b>,
+and <code>t[0]</code> and <code>t["0"]</code> denote different
+entries in a table.
+
+
+<p>
+The operator <code>~=</code> is exactly the negation of equality (<code>==</code>).
+
+
+<p>
+The order operators work as follows.
+If both arguments are numbers, then they are compared as such.
+Otherwise, if both arguments are strings,
+then their values are compared according to the current locale.
+Otherwise, Lua tries to call the "lt" or the "le"
+metamethod (see <a href="#2.4">&sect;2.4</a>).
+A comparison <code>a &gt; b</code> is translated to <code>b &lt; a</code>
+and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
+
+
+
+
+
+<h3>3.4.4 &ndash; <a name="3.4.4">Logical Operators</a></h3><p>
+The logical operators in Lua are
+<b>and</b>, <b>or</b>, and <b>not</b>.
+Like the control structures (see <a href="#3.3.4">&sect;3.3.4</a>),
+all logical operators consider both <b>false</b> and <b>nil</b> as false
+and anything else as true.
+
+
+<p>
+The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>.
+The conjunction operator <b>and</b> returns its first argument
+if this value is <b>false</b> or <b>nil</b>;
+otherwise, <b>and</b> returns its second argument.
+The disjunction operator <b>or</b> returns its first argument
+if this value is different from <b>nil</b> and <b>false</b>;
+otherwise, <b>or</b> returns its second argument.
+Both <b>and</b> and <b>or</b> use short-cut evaluation;
+that is,
+the second operand is evaluated only if necessary.
+Here are some examples:
+
+<pre>
+     10 or 20            --&gt; 10
+     10 or error()       --&gt; 10
+     nil or "a"          --&gt; "a"
+     nil and 10          --&gt; nil
+     false and error()   --&gt; false
+     false and nil       --&gt; false
+     false or nil        --&gt; nil
+     10 and 20           --&gt; 20
+</pre><p>
+(In this manual,
+<code>--&gt;</code> indicates the result of the preceding expression.)
+
+
+
+
+
+<h3>3.4.5 &ndash; <a name="3.4.5">Concatenation</a></h3><p>
+The string concatenation operator in Lua is
+denoted by two dots ('<code>..</code>').
+If both operands are strings or numbers, then they are converted to
+strings according to the rules mentioned in <a href="#3.4.2">&sect;3.4.2</a>.
+Otherwise, the <code>__concat</code> metamethod is called (see <a href="#2.4">&sect;2.4</a>).
+
+
+
+
+
+<h3>3.4.6 &ndash; <a name="3.4.6">The Length Operator</a></h3>
+
+<p>
+The length operator is denoted by the unary prefix operator <code>#</code>.
+The length of a string is its number of bytes
+(that is, the usual meaning of string length when each
+character is one byte).
+
+
+<p>
+A program can modify the behavior of the length operator for
+any value but strings through the <code>__len</code> metamethod (see <a href="#2.4">&sect;2.4</a>).
+
+
+<p>
+Unless a <code>__len</code> metamethod is given,
+the length of a table <code>t</code> is only defined if the
+table is a <em>sequence</em>,
+that is,
+the set of its positive numeric keys is equal to <em>{1..n}</em>
+for some integer <em>n</em>.
+In that case, <em>n</em> is its length.
+Note that a table like
+
+<pre>
+     {10, 20, nil, 40}
+</pre><p>
+is not a sequence, because it has the key <code>4</code>
+but does not have the key <code>3</code>.
+(So, there is no <em>n</em> such that the set <em>{1..n}</em> is equal
+to the set of positive numeric keys of that table.)
+Note, however, that non-numeric keys do not interfere
+with whether a table is a sequence.
+
+
+
+
+
+<h3>3.4.7 &ndash; <a name="3.4.7">Precedence</a></h3><p>
+Operator precedence in Lua follows the table below,
+from lower to higher priority:
+
+<pre>
+     or
+     and
+     &lt;     &gt;     &lt;=    &gt;=    ~=    ==
+     ..
+     +     -
+     *     /     %
+     not   #     - (unary)
+     ^
+</pre><p>
+As usual,
+you can use parentheses to change the precedences of an expression.
+The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>')
+operators are right associative.
+All other binary operators are left associative.
+
+
+
+
+
+<h3>3.4.8 &ndash; <a name="3.4.8">Table Constructors</a></h3><p>
+Table constructors are expressions that create tables.
+Every time a constructor is evaluated, a new table is created.
+A constructor can be used to create an empty table
+or to create a table and initialize some of its fields.
+The general syntax for constructors is
+
+<pre>
+	tableconstructor ::= &lsquo;<b>{</b>&rsquo; [fieldlist] &lsquo;<b>}</b>&rsquo;
+	fieldlist ::= field {fieldsep field} [fieldsep]
+	field ::= &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; &lsquo;<b>=</b>&rsquo; exp | Name &lsquo;<b>=</b>&rsquo; exp | exp
+	fieldsep ::= &lsquo;<b>,</b>&rsquo; | &lsquo;<b>;</b>&rsquo;
+</pre>
+
+<p>
+Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry
+with key <code>exp1</code> and value <code>exp2</code>.
+A field of the form <code>name = exp</code> is equivalent to
+<code>["name"] = exp</code>.
+Finally, fields of the form <code>exp</code> are equivalent to
+<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers,
+starting with 1.
+Fields in the other formats do not affect this counting.
+For example,
+
+<pre>
+     a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
+</pre><p>
+is equivalent to
+
+<pre>
+     do
+       local t = {}
+       t[f(1)] = g
+       t[1] = "x"         -- 1st exp
+       t[2] = "y"         -- 2nd exp
+       t.x = 1            -- t["x"] = 1
+       t[3] = f(x)        -- 3rd exp
+       t[30] = 23
+       t[4] = 45          -- 4th exp
+       a = t
+     end
+</pre>
+
+<p>
+If the last field in the list has the form <code>exp</code>
+and the expression is a function call or a vararg expression,
+then all values returned by this expression enter the list consecutively
+(see <a href="#3.4.9">&sect;3.4.9</a>).
+
+
+<p>
+The field list can have an optional trailing separator,
+as a convenience for machine-generated code.
+
+
+
+
+
+<h3>3.4.9 &ndash; <a name="3.4.9">Function Calls</a></h3><p>
+A function call in Lua has the following syntax:
+
+<pre>
+	functioncall ::= prefixexp args
+</pre><p>
+In a function call,
+first prefixexp and args are evaluated.
+If the value of prefixexp has type <em>function</em>,
+then this function is called
+with the given arguments.
+Otherwise, the prefixexp "call" metamethod is called,
+having as first parameter the value of prefixexp,
+followed by the original call arguments
+(see <a href="#2.4">&sect;2.4</a>).
+
+
+<p>
+The form
+
+<pre>
+	functioncall ::= prefixexp &lsquo;<b>:</b>&rsquo; Name args
+</pre><p>
+can be used to call "methods".
+A call <code>v:name(<em>args</em>)</code>
+is syntactic sugar for <code>v.name(v,<em>args</em>)</code>,
+except that <code>v</code> is evaluated only once.
+
+
+<p>
+Arguments have the following syntax:
+
+<pre>
+	args ::= &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo;
+	args ::= tableconstructor
+	args ::= String
+</pre><p>
+All argument expressions are evaluated before the call.
+A call of the form <code>f{<em>fields</em>}</code> is
+syntactic sugar for <code>f({<em>fields</em>})</code>;
+that is, the argument list is a single new table.
+A call of the form <code>f'<em>string</em>'</code>
+(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>)
+is syntactic sugar for <code>f('<em>string</em>')</code>;
+that is, the argument list is a single literal string.
+
+
+<p>
+A call of the form <code>return <em>functioncall</em></code> is called
+a <em>tail call</em>.
+Lua implements <em>proper tail calls</em>
+(or <em>proper tail recursion</em>):
+in a tail call,
+the called function reuses the stack entry of the calling function.
+Therefore, there is no limit on the number of nested tail calls that
+a program can execute.
+However, a tail call erases any debug information about the
+calling function.
+Note that a tail call only happens with a particular syntax,
+where the <b>return</b> has one single function call as argument;
+this syntax makes the calling function return exactly
+the returns of the called function.
+So, none of the following examples are tail calls:
+
+<pre>
+     return (f(x))        -- results adjusted to 1
+     return 2 * f(x)
+     return x, f(x)       -- additional results
+     f(x); return         -- results discarded
+     return x or f(x)     -- results adjusted to 1
+</pre>
+
+
+
+
+<h3>3.4.10 &ndash; <a name="3.4.10">Function Definitions</a></h3>
+
+<p>
+The syntax for function definition is
+
+<pre>
+	functiondef ::= <b>function</b> funcbody
+	funcbody ::= &lsquo;<b>(</b>&rsquo; [parlist] &lsquo;<b>)</b>&rsquo; block <b>end</b>
+</pre>
+
+<p>
+The following syntactic sugar simplifies function definitions:
+
+<pre>
+	stat ::= <b>function</b> funcname funcbody
+	stat ::= <b>local</b> <b>function</b> Name funcbody
+	funcname ::= Name {&lsquo;<b>.</b>&rsquo; Name} [&lsquo;<b>:</b>&rsquo; Name]
+</pre><p>
+The statement
+
+<pre>
+     function f () <em>body</em> end
+</pre><p>
+translates to
+
+<pre>
+     f = function () <em>body</em> end
+</pre><p>
+The statement
+
+<pre>
+     function t.a.b.c.f () <em>body</em> end
+</pre><p>
+translates to
+
+<pre>
+     t.a.b.c.f = function () <em>body</em> end
+</pre><p>
+The statement
+
+<pre>
+     local function f () <em>body</em> end
+</pre><p>
+translates to
+
+<pre>
+     local f; f = function () <em>body</em> end
+</pre><p>
+not to
+
+<pre>
+     local f = function () <em>body</em> end
+</pre><p>
+(This only makes a difference when the body of the function
+contains references to <code>f</code>.)
+
+
+<p>
+A function definition is an executable expression,
+whose value has type <em>function</em>.
+When Lua precompiles a chunk,
+all its function bodies are precompiled too.
+Then, whenever Lua executes the function definition,
+the function is <em>instantiated</em> (or <em>closed</em>).
+This function instance (or <em>closure</em>)
+is the final value of the expression.
+
+
+<p>
+Parameters act as local variables that are
+initialized with the argument values:
+
+<pre>
+	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+</pre><p>
+When a function is called,
+the list of arguments is adjusted to
+the length of the list of parameters,
+unless the function is a <em>vararg function</em>,
+which is indicated by three dots ('<code>...</code>')
+at the end of its parameter list.
+A vararg function does not adjust its argument list;
+instead, it collects all extra arguments and supplies them
+to the function through a <em>vararg expression</em>,
+which is also written as three dots.
+The value of this expression is a list of all actual extra arguments,
+similar to a function with multiple results.
+If a vararg expression is used inside another expression
+or in the middle of a list of expressions,
+then its return list is adjusted to one element.
+If the expression is used as the last element of a list of expressions,
+then no adjustment is made
+(unless that last expression is enclosed in parentheses).
+
+
+<p>
+As an example, consider the following definitions:
+
+<pre>
+     function f(a, b) end
+     function g(a, b, ...) end
+     function r() return 1,2,3 end
+</pre><p>
+Then, we have the following mapping from arguments to parameters and
+to the vararg expression:
+
+<pre>
+     CALL            PARAMETERS
+     
+     f(3)             a=3, b=nil
+     f(3, 4)          a=3, b=4
+     f(3, 4, 5)       a=3, b=4
+     f(r(), 10)       a=1, b=10
+     f(r())           a=1, b=2
+     
+     g(3)             a=3, b=nil, ... --&gt;  (nothing)
+     g(3, 4)          a=3, b=4,   ... --&gt;  (nothing)
+     g(3, 4, 5, 8)    a=3, b=4,   ... --&gt;  5  8
+     g(5, r())        a=5, b=1,   ... --&gt;  2  3
+</pre>
+
+<p>
+Results are returned using the <b>return</b> statement (see <a href="#3.3.4">&sect;3.3.4</a>).
+If control reaches the end of a function
+without encountering a <b>return</b> statement,
+then the function returns with no results.
+
+
+<p>
+
+There is a system-dependent limit on the number of values
+that a function may return.
+This limit is guaranteed to be larger than 1000.
+
+
+<p>
+The <em>colon</em> syntax
+is used for defining <em>methods</em>,
+that is, functions that have an implicit extra parameter <code>self</code>.
+Thus, the statement
+
+<pre>
+     function t.a.b.c:f (<em>params</em>) <em>body</em> end
+</pre><p>
+is syntactic sugar for
+
+<pre>
+     t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
+</pre>
+
+
+
+
+
+
+<h2>3.5 &ndash; <a name="3.5">Visibility Rules</a></h2>
+
+<p>
+
+Lua is a lexically scoped language.
+The scope of a local variable begins at the first statement after
+its declaration and lasts until the last non-void statement
+of the innermost block that includes the declaration.
+Consider the following example:
+
+<pre>
+     x = 10                -- global variable
+     do                    -- new block
+       local x = x         -- new 'x', with value 10
+       print(x)            --&gt; 10
+       x = x+1
+       do                  -- another block
+         local x = x+1     -- another 'x'
+         print(x)          --&gt; 12
+       end
+       print(x)            --&gt; 11
+     end
+     print(x)              --&gt; 10  (the global one)
+</pre>
+
+<p>
+Notice that, in a declaration like <code>local x = x</code>,
+the new <code>x</code> being declared is not in scope yet,
+and so the second <code>x</code> refers to the outside variable.
+
+
+<p>
+Because of the lexical scoping rules,
+local variables can be freely accessed by functions
+defined inside their scope.
+A local variable used by an inner function is called
+an <em>upvalue</em>, or <em>external local variable</em>,
+inside the inner function.
+
+
+<p>
+Notice that each execution of a <b>local</b> statement
+defines new local variables.
+Consider the following example:
+
+<pre>
+     a = {}
+     local x = 20
+     for i=1,10 do
+       local y = 0
+       a[i] = function () y=y+1; return x+y end
+     end
+</pre><p>
+The loop creates ten closures
+(that is, ten instances of the anonymous function).
+Each of these closures uses a different <code>y</code> variable,
+while all of them share the same <code>x</code>.
+
+
+
+
+
+<h1>4 &ndash; <a name="4">The Application Program Interface</a></h1>
+
+<p>
+
+This section describes the C&nbsp;API for Lua, that is,
+the set of C&nbsp;functions available to the host program to communicate
+with Lua.
+All API functions and related types and constants
+are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>.
+
+
+<p>
+Even when we use the term "function",
+any facility in the API may be provided as a macro instead.
+Except where stated otherwise,
+all such macros use each of their arguments exactly once
+(except for the first argument, which is always a Lua state),
+and so do not generate any hidden side-effects.
+
+
+<p>
+As in most C&nbsp;libraries,
+the Lua API functions do not check their arguments for validity or consistency.
+However, you can change this behavior by compiling Lua
+with the macro <a name="pdf-LUA_USE_APICHECK"><code>LUA_USE_APICHECK</code></a> defined.
+
+
+
+<h2>4.1 &ndash; <a name="4.1">The Stack</a></h2>
+
+<p>
+Lua uses a <em>virtual stack</em> to pass values to and from C.
+Each element in this stack represents a Lua value
+(<b>nil</b>, number, string, etc.).
+
+
+<p>
+Whenever Lua calls C, the called function gets a new stack,
+which is independent of previous stacks and of stacks of
+C&nbsp;functions that are still active.
+This stack initially contains any arguments to the C&nbsp;function
+and it is where the C&nbsp;function pushes its results
+to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+
+
+<p>
+For convenience,
+most query operations in the API do not follow a strict stack discipline.
+Instead, they can refer to any element in the stack
+by using an <em>index</em>:
+A positive index represents an absolute stack position
+(starting at&nbsp;1);
+a negative index represents an offset relative to the top of the stack.
+More specifically, if the stack has <em>n</em> elements,
+then index&nbsp;1 represents the first element
+(that is, the element that was pushed onto the stack first)
+and
+index&nbsp;<em>n</em> represents the last element;
+index&nbsp;-1 also represents the last element
+(that is, the element at the&nbsp;top)
+and index <em>-n</em> represents the first element.
+
+
+
+
+
+<h2>4.2 &ndash; <a name="4.2">Stack Size</a></h2>
+
+<p>
+When you interact with the Lua API,
+you are responsible for ensuring consistency.
+In particular,
+<em>you are responsible for controlling stack overflow</em>.
+You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a>
+to ensure that the stack has extra slots when pushing new elements.
+
+
+<p>
+Whenever Lua calls C,
+it ensures that the stack has at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots.
+<code>LUA_MINSTACK</code> is defined as 20,
+so that usually you do not have to worry about stack space
+unless your code has loops pushing elements onto the stack.
+
+
+<p>
+When you call a Lua function
+without a fixed number of results (see <a href="#lua_call"><code>lua_call</code></a>),
+Lua ensures that the stack has enough size for all results,
+but it does not ensure any extra space.
+So, before pushing anything in the stack after such a call
+you should use <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
+
+
+
+
+
+<h2>4.3 &ndash; <a name="4.3">Valid and Acceptable Indices</a></h2>
+
+<p>
+Any function in the API that receives stack indices
+works only with <em>valid indices</em> or <em>acceptable indices</em>.
+
+
+<p>
+A <em>valid index</em> is an index that refers to a
+real position within the stack, that is,
+its position lies between&nbsp;1 and the stack top
+(<code>1 &le; abs(index) &le; top</code>).
+
+Usually, functions that can modify the value at an index
+require valid indices.
+
+
+<p>
+Unless otherwise noted,
+any function that accepts valid indices also accepts <em>pseudo-indices</em>,
+which represent some Lua values that are accessible to C&nbsp;code
+but which are not in the stack.
+Pseudo-indices are used to access the registry
+and the upvalues of a C&nbsp;function (see <a href="#4.4">&sect;4.4</a>).
+
+
+<p>
+Functions that do not need a specific stack position,
+but only a value in the stack (e.g., query functions),
+can be called with acceptable indices.
+An <em>acceptable index</em> can be any valid index,
+including the pseudo-indices,
+but it also can be any positive index after the stack top
+within the space allocated for the stack,
+that is, indices up to the stack size.
+(Note that 0 is never an acceptable index.)
+Except when noted otherwise,
+functions in the API work with acceptable indices.
+
+
+<p>
+Acceptable indices serve to avoid extra tests
+against the stack top when querying the stack.
+For instance, a C&nbsp;function can query its third argument
+without the need to first check whether there is a third argument,
+that is, without the need to check whether 3 is a valid index.
+
+
+<p>
+For functions that can be called with acceptable indices,
+any non-valid index is treated as if it
+contains a value of a virtual type <a name="pdf-LUA_TNONE"><code>LUA_TNONE</code></a>,
+which behaves like a nil value.
+
+
+
+
+
+<h2>4.4 &ndash; <a name="4.4">C Closures</a></h2>
+
+<p>
+When a C&nbsp;function is created,
+it is possible to associate some values with it,
+thus creating a <em>C&nbsp;closure</em>
+(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>);
+these values are called <em>upvalues</em> and are
+accessible to the function whenever it is called.
+
+
+<p>
+Whenever a C&nbsp;function is called,
+its upvalues are located at specific pseudo-indices.
+These pseudo-indices are produced by the macro
+<a href="#lua_upvalueindex"><code>lua_upvalueindex</code></a>.
+The first value associated with a function is at position
+<code>lua_upvalueindex(1)</code>, and so on.
+Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
+where <em>n</em> is greater than the number of upvalues of the
+current function (but not greater than 256),
+produces an acceptable but invalid index.
+
+
+
+
+
+<h2>4.5 &ndash; <a name="4.5">Registry</a></h2>
+
+<p>
+Lua provides a <em>registry</em>,
+a predefined table that can be used by any C&nbsp;code to
+store whatever Lua values it needs to store.
+The registry table is always located at pseudo-index
+<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>,
+which is a valid index.
+Any C&nbsp;library can store data into this table,
+but it should take care to choose keys
+that are different from those used
+by other libraries, to avoid collisions.
+Typically, you should use as key a string containing your library name,
+or a light userdata with the address of a C&nbsp;object in your code,
+or any Lua object created by your code.
+As with global names,
+string keys starting with an underscore followed by
+uppercase letters are reserved for Lua.
+
+
+<p>
+The integer keys in the registry are used by the reference mechanism,
+implemented by the auxiliary library,
+and by some predefined values.
+Therefore, integer keys should not be used for other purposes.
+
+
+<p>
+When you create a new Lua state,
+its registry comes with some predefined values.
+These predefined values are indexed with integer keys
+defined as constants in <code>lua.h</code>.
+The following constants are defined:
+
+<ul>
+<li><b><a name="pdf-LUA_RIDX_MAINTHREAD"><code>LUA_RIDX_MAINTHREAD</code></a>: </b> At this index the registry has
+the main thread of the state.
+(The main thread is the one created together with the state.)
+</li>
+
+<li><b><a name="pdf-LUA_RIDX_GLOBALS"><code>LUA_RIDX_GLOBALS</code></a>: </b> At this index the registry has
+the global environment.
+</li>
+</ul>
+
+
+
+
+<h2>4.6 &ndash; <a name="4.6">Error Handling in C</a></h2>
+
+<p>
+Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
+(You can also choose to use exceptions if you compile Lua as C++;
+search for <code>LUAI_THROW</code> in the source code.)
+When Lua faces any error
+(such as a memory allocation error, type errors, syntax errors,
+and runtime errors)
+it <em>raises</em> an error;
+that is, it does a long jump.
+A <em>protected environment</em> uses <code>setjmp</code>
+to set a recovery point;
+any error jumps to the most recent active recovery point.
+
+
+<p>
+If an error happens outside any protected environment,
+Lua calls a <em>panic function</em> (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>)
+and then calls <code>abort</code>,
+thus exiting the host application.
+Your panic function can avoid this exit by
+never returning
+(e.g., doing a long jump to your own recovery point outside Lua).
+
+
+<p>
+The panic function runs as if it were a message handler (see <a href="#2.3">&sect;2.3</a>);
+in particular, the error message is at the top of the stack.
+However, there is no guarantees about stack space.
+To push anything on the stack,
+the panic function should first check the available space (see <a href="#4.2">&sect;4.2</a>).
+
+
+<p>
+Most functions in the API can throw an error,
+for instance due to a memory allocation error.
+The documentation for each function indicates whether
+it can throw errors.
+
+
+<p>
+Inside a C&nbsp;function you can throw an error by calling <a href="#lua_error"><code>lua_error</code></a>.
+
+
+
+
+
+<h2>4.7 &ndash; <a name="4.7">Handling Yields in C</a></h2>
+
+<p>
+Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine.
+Therefore, if a function <code>foo</code> calls an API function
+and this API function yields
+(directly or indirectly by calling another function that yields),
+Lua cannot return to <code>foo</code> any more,
+because the <code>longjmp</code> removes its frame from the C stack.
+
+
+<p>
+To avoid this kind of problem,
+Lua raises an error whenever it tries to yield across an API call,
+except for three functions:
+<a href="#lua_yieldk"><code>lua_yieldk</code></a>, <a href="#lua_callk"><code>lua_callk</code></a>, and <a href="#lua_pcallk"><code>lua_pcallk</code></a>.
+All those functions receive a <em>continuation function</em>
+(as a parameter called <code>k</code>) to continue execution after a yield.
+
+
+<p>
+We need to set some terminology to explain continuations.
+We have a C function called from Lua which we will call
+the <em>original function</em>.
+This original function then calls one of those three functions in the C API,
+which we will call the <em>callee function</em>,
+that then yields the current thread.
+(This can happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+or when the callee function is either <a href="#lua_callk"><code>lua_callk</code></a> or <a href="#lua_pcallk"><code>lua_pcallk</code></a>
+and the function called by them yields.)
+
+
+<p>
+Suppose the running thread yields while executing the callee function.
+After the thread resumes,
+it eventually will finish running the callee function.
+However,
+the callee function cannot return to the original function,
+because its frame in the C stack was destroyed by the yield.
+Instead, Lua calls a <em>continuation function</em>,
+which was given as an argument to the callee function.
+As the name implies,
+the continuation function should continue the task
+of the original function.
+
+
+<p>
+Lua treats the continuation function as if it were the original function.
+The continuation function receives the same Lua stack
+from the original function,
+in the same state it would be if the callee function had returned.
+(For instance,
+after a <a href="#lua_callk"><code>lua_callk</code></a> the function and its arguments are
+removed from the stack and replaced by the results from the call.)
+It also has the same upvalues.
+Whatever it returns is handled by Lua as if it were the return
+of the original function.
+
+
+<p>
+The only difference in the Lua state between the original function
+and its continuation is the result of a call to <a href="#lua_getctx"><code>lua_getctx</code></a>.
+
+
+
+
+
+<h2>4.8 &ndash; <a name="4.8">Functions and Types</a></h2>
+
+<p>
+Here we list all functions and types from the C&nbsp;API in
+alphabetical order.
+Each function has an indicator like this:
+<span class="apii">[-o, +p, <em>x</em>]</span>
+
+
+<p>
+The first field, <code>o</code>,
+is how many elements the function pops from the stack.
+The second field, <code>p</code>,
+is how many elements the function pushes onto the stack.
+(Any function always pushes its results after popping its arguments.)
+A field in the form <code>x|y</code> means the function can push (or pop)
+<code>x</code> or <code>y</code> elements,
+depending on the situation;
+an interrogation mark '<code>?</code>' means that
+we cannot know how many elements the function pops/pushes
+by looking only at its arguments
+(e.g., they may depend on what is on the stack).
+The third field, <code>x</code>,
+tells whether the function may throw errors:
+'<code>-</code>' means the function never throws any error;
+'<code>e</code>' means the function may throw errors;
+'<code>v</code>' means the function may throw an error on purpose.
+
+
+
+<hr><h3><a name="lua_absindex"><code>lua_absindex</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_absindex (lua_State *L, int idx);</pre>
+
+<p>
+Converts the acceptable index <code>idx</code> into an absolute index
+(that is, one that does not depend on the stack top).
+
+
+
+
+
+<hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3>
+<pre>typedef void * (*lua_Alloc) (void *ud,
+                             void *ptr,
+                             size_t osize,
+                             size_t nsize);</pre>
+
+<p>
+The type of the memory-allocation function used by Lua states.
+The allocator function must provide a
+functionality similar to <code>realloc</code>,
+but not exactly the same.
+Its arguments are
+<code>ud</code>, an opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>;
+<code>ptr</code>, a pointer to the block being allocated/reallocated/freed;
+<code>osize</code>, the original size of the block or some code about what
+is being allocated;
+<code>nsize</code>, the new size of the block.
+
+
+<p>
+When <code>ptr</code> is not <code>NULL</code>,
+<code>osize</code> is the size of the block pointed by <code>ptr</code>,
+that is, the size given when it was allocated or reallocated.
+
+
+<p>
+When <code>ptr</code> is <code>NULL</code>,
+<code>osize</code> encodes the kind of object that Lua is allocating.
+<code>osize</code> is any of
+<a href="#pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>, <a href="#pdf-LUA_TTABLE"><code>LUA_TTABLE</code></a>, <a href="#pdf-LUA_TFUNCTION"><code>LUA_TFUNCTION</code></a>,
+<a href="#pdf-LUA_TUSERDATA"><code>LUA_TUSERDATA</code></a>, or <a href="#pdf-LUA_TTHREAD"><code>LUA_TTHREAD</code></a> when (and only when)
+Lua is creating a new object of that type.
+When <code>osize</code> is some other value,
+Lua is allocating memory for something else.
+
+
+<p>
+Lua assumes the following behavior from the allocator function:
+
+
+<p>
+When <code>nsize</code> is zero,
+the allocator should behave like <code>free</code>
+and return <code>NULL</code>.
+
+
+<p>
+When <code>nsize</code> is not zero,
+the allocator should behave like <code>realloc</code>.
+The allocator returns <code>NULL</code>
+if and only if it cannot fulfill the request.
+Lua assumes that the allocator never fails when
+<code>osize &gt;= nsize</code>.
+
+
+<p>
+Here is a simple implementation for the allocator function.
+It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>.
+
+<pre>
+     static void *l_alloc (void *ud, void *ptr, size_t osize,
+                                                size_t nsize) {
+       (void)ud;  (void)osize;  /* not used */
+       if (nsize == 0) {
+         free(ptr);
+         return NULL;
+       }
+       else
+         return realloc(ptr, nsize);
+     }
+</pre><p>
+Note that Standard&nbsp;C ensures
+that <code>free(NULL)</code> has no effect and that
+<code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>.
+This code assumes that <code>realloc</code> does not fail when shrinking a block.
+(Although Standard&nbsp;C does not ensure this behavior,
+it seems to be a safe assumption.)
+
+
+
+
+
+<hr><h3><a name="lua_arith"><code>lua_arith</code></a></h3><p>
+<span class="apii">[-(2|1), +1, <em>e</em>]</span>
+<pre>void lua_arith (lua_State *L, int op);</pre>
+
+<p>
+Performs an arithmetic operation over the two values
+(or one, in the case of negation)
+at the top of the stack,
+with the value at the top being the second operand,
+pops these values, and pushes the result of the operation.
+The function follows the semantics of the corresponding Lua operator
+(that is, it may call metamethods).
+
+
+<p>
+The value of <code>op</code> must be one of the following constants:
+
+<ul>
+
+<li><b><a name="pdf-LUA_OPADD"><code>LUA_OPADD</code></a>: </b> performs addition (<code>+</code>)</li>
+<li><b><a name="pdf-LUA_OPSUB"><code>LUA_OPSUB</code></a>: </b> performs subtraction (<code>-</code>)</li>
+<li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>: </b> performs multiplication (<code>*</code>)</li>
+<li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs division (<code>/</code>)</li>
+<li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li>
+<li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li>
+<li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li>
+
+</ul>
+
+
+
+
+<hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre>
+
+<p>
+Sets a new panic function and returns the old one (see <a href="#4.6">&sect;4.6</a>).
+
+
+
+
+
+<hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p>
+<span class="apii">[-(nargs+1), +nresults, <em>e</em>]</span>
+<pre>void lua_call (lua_State *L, int nargs, int nresults);</pre>
+
+<p>
+Calls a function.
+
+
+<p>
+To call a function you must use the following protocol:
+first, the function to be called is pushed onto the stack;
+then, the arguments to the function are pushed
+in direct order;
+that is, the first argument is pushed first.
+Finally you call <a href="#lua_call"><code>lua_call</code></a>;
+<code>nargs</code> is the number of arguments that you pushed onto the stack.
+All arguments and the function value are popped from the stack
+when the function is called.
+The function results are pushed onto the stack when the function returns.
+The number of results is adjusted to <code>nresults</code>,
+unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>.
+In this case, all results from the function are pushed.
+Lua takes care that the returned values fit into the stack space.
+The function results are pushed onto the stack in direct order
+(the first result is pushed first),
+so that after the call the last result is on the top of the stack.
+
+
+<p>
+Any error inside the called function is propagated upwards
+(with a <code>longjmp</code>).
+
+
+<p>
+The following example shows how the host program can do the
+equivalent to this Lua code:
+
+<pre>
+     a = f("how", t.x, 14)
+</pre><p>
+Here it is in&nbsp;C:
+
+<pre>
+     lua_getglobal(L, "f");                  /* function to be called */
+     lua_pushstring(L, "how");                        /* 1st argument */
+     lua_getglobal(L, "t");                    /* table to be indexed */
+     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
+     lua_remove(L, -2);                  /* remove 't' from the stack */
+     lua_pushinteger(L, 14);                          /* 3rd argument */
+     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
+     lua_setglobal(L, "a");                         /* set global 'a' */
+</pre><p>
+Note that the code above is "balanced":
+at its end, the stack is back to its original configuration.
+This is considered good programming practice.
+
+
+
+
+
+<hr><h3><a name="lua_callk"><code>lua_callk</code></a></h3><p>
+<span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span>
+<pre>void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
+                lua_CFunction k);</pre>
+
+<p>
+This function behaves exactly like <a href="#lua_call"><code>lua_call</code></a>,
+but allows the called function to yield (see <a href="#4.7">&sect;4.7</a>).
+
+
+
+
+
+<hr><h3><a name="lua_CFunction"><code>lua_CFunction</code></a></h3>
+<pre>typedef int (*lua_CFunction) (lua_State *L);</pre>
+
+<p>
+Type for C&nbsp;functions.
+
+
+<p>
+In order to communicate properly with Lua,
+a C&nbsp;function must use the following protocol,
+which defines the way parameters and results are passed:
+a C&nbsp;function receives its arguments from Lua in its stack
+in direct order (the first argument is pushed first).
+So, when the function starts,
+<code>lua_gettop(L)</code> returns the number of arguments received by the function.
+The first argument (if any) is at index 1
+and its last argument is at index <code>lua_gettop(L)</code>.
+To return values to Lua, a C&nbsp;function just pushes them onto the stack,
+in direct order (the first result is pushed first),
+and returns the number of results.
+Any other value in the stack below the results will be properly
+discarded by Lua.
+Like a Lua function, a C&nbsp;function called by Lua can also return
+many results.
+
+
+<p>
+As an example, the following function receives a variable number
+of numerical arguments and returns their average and sum:
+
+<pre>
+     static int foo (lua_State *L) {
+       int n = lua_gettop(L);    /* number of arguments */
+       lua_Number sum = 0;
+       int i;
+       for (i = 1; i &lt;= n; i++) {
+         if (!lua_isnumber(L, i)) {
+           lua_pushstring(L, "incorrect argument");
+           lua_error(L);
+         }
+         sum += lua_tonumber(L, i);
+       }
+       lua_pushnumber(L, sum/n);        /* first result */
+       lua_pushnumber(L, sum);         /* second result */
+       return 2;                   /* number of results */
+     }
+</pre>
+
+
+
+
+<hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_checkstack (lua_State *L, int extra);</pre>
+
+<p>
+Ensures that there are at least <code>extra</code> free stack slots in the stack.
+It returns false if it cannot fulfill the request,
+because it would cause the stack to be larger than a fixed maximum size
+(typically at least a few thousand elements) or
+because it cannot allocate memory for the new stack size.
+This function never shrinks the stack;
+if the stack is already larger than the new size,
+it is left unchanged.
+
+
+
+
+
+<hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void lua_close (lua_State *L);</pre>
+
+<p>
+Destroys all objects in the given Lua state
+(calling the corresponding garbage-collection metamethods, if any)
+and frees all dynamic memory used by this state.
+On several platforms, you may not need to call this function,
+because all resources are naturally released when the host program ends.
+On the other hand, long-running programs that create multiple states,
+such as daemons or web servers,
+might need to close states as soon as they are not needed.
+
+
+
+
+
+<hr><h3><a name="lua_compare"><code>lua_compare</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>int lua_compare (lua_State *L, int index1, int index2, int op);</pre>
+
+<p>
+Compares two Lua values.
+Returns 1 if the value at index <code>index1</code> satisfies <code>op</code>
+when compared with the value at index <code>index2</code>,
+following the semantics of the corresponding Lua operator
+(that is, it may call metamethods).
+Otherwise returns&nbsp;0.
+Also returns&nbsp;0 if any of the indices is non valid.
+
+
+<p>
+The value of <code>op</code> must be one of the following constants:
+
+<ul>
+
+<li><b><a name="pdf-LUA_OPEQ"><code>LUA_OPEQ</code></a>: </b> compares for equality (<code>==</code>)</li>
+<li><b><a name="pdf-LUA_OPLT"><code>LUA_OPLT</code></a>: </b> compares for less than (<code>&lt;</code>)</li>
+<li><b><a name="pdf-LUA_OPLE"><code>LUA_OPLE</code></a>: </b> compares for less or equal (<code>&lt;=</code>)</li>
+
+</ul>
+
+
+
+
+<hr><h3><a name="lua_concat"><code>lua_concat</code></a></h3><p>
+<span class="apii">[-n, +1, <em>e</em>]</span>
+<pre>void lua_concat (lua_State *L, int n);</pre>
+
+<p>
+Concatenates the <code>n</code> values at the top of the stack,
+pops them, and leaves the result at the top.
+If <code>n</code>&nbsp;is&nbsp;1, the result is the single value on the stack
+(that is, the function does nothing);
+if <code>n</code> is 0, the result is the empty string.
+Concatenation is performed following the usual semantics of Lua
+(see <a href="#3.4.5">&sect;3.4.5</a>).
+
+
+
+
+
+<hr><h3><a name="lua_copy"><code>lua_copy</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre>
+
+<p>
+Moves the element at index <code>fromidx</code>
+into the valid index <code>toidx</code>
+without shifting any element
+(therefore replacing the value at that position).
+
+
+
+
+
+<hr><h3><a name="lua_createtable"><code>lua_createtable</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre>
+
+<p>
+Creates a new empty table and pushes it onto the stack.
+Parameter <code>narr</code> is a hint for how many elements the table
+will have as a sequence;
+parameter <code>nrec</code> is a hint for how many other elements
+the table will have.
+Lua may use these hints to preallocate memory for the new table.
+This pre-allocation is useful for performance when you know in advance
+how many elements the table will have.
+Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>.
+
+
+
+
+
+<hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>int lua_dump (lua_State *L, lua_Writer writer, void *data);</pre>
+
+<p>
+Dumps a function as a binary chunk.
+Receives a Lua function on the top of the stack
+and produces a binary chunk that,
+if loaded again,
+results in a function equivalent to the one dumped.
+As it produces parts of the chunk,
+<a href="#lua_dump"><code>lua_dump</code></a> calls function <code>writer</code> (see <a href="#lua_Writer"><code>lua_Writer</code></a>)
+with the given <code>data</code>
+to write them.
+
+
+<p>
+The value returned is the error code returned by the last
+call to the writer;
+0&nbsp;means no errors.
+
+
+<p>
+This function does not pop the Lua function from the stack.
+
+
+
+
+
+<hr><h3><a name="lua_error"><code>lua_error</code></a></h3><p>
+<span class="apii">[-1, +0, <em>v</em>]</span>
+<pre>int lua_error (lua_State *L);</pre>
+
+<p>
+Generates a Lua error.
+The error message (which can actually be a Lua value of any type)
+must be on the stack top.
+This function does a long jump,
+and therefore never returns
+(see <a href="#luaL_error"><code>luaL_error</code></a>).
+
+
+
+
+
+<hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>int lua_gc (lua_State *L, int what, int data);</pre>
+
+<p>
+Controls the garbage collector.
+
+
+<p>
+This function performs several tasks,
+according to the value of the parameter <code>what</code>:
+
+<ul>
+
+<li><b><code>LUA_GCSTOP</code>: </b>
+stops the garbage collector.
+</li>
+
+<li><b><code>LUA_GCRESTART</code>: </b>
+restarts the garbage collector.
+</li>
+
+<li><b><code>LUA_GCCOLLECT</code>: </b>
+performs a full garbage-collection cycle.
+</li>
+
+<li><b><code>LUA_GCCOUNT</code>: </b>
+returns the current amount of memory (in Kbytes) in use by Lua.
+</li>
+
+<li><b><code>LUA_GCCOUNTB</code>: </b>
+returns the remainder of dividing the current amount of bytes of
+memory in use by Lua by 1024.
+</li>
+
+<li><b><code>LUA_GCSTEP</code>: </b>
+performs an incremental step of garbage collection.
+The step "size" is controlled by <code>data</code>
+(larger values mean more steps) in a non-specified way.
+If you want to control the step size
+you must experimentally tune the value of <code>data</code>.
+The function returns 1 if the step finished a
+garbage-collection cycle.
+</li>
+
+<li><b><code>LUA_GCSETPAUSE</code>: </b>
+sets <code>data</code> as the new value
+for the <em>pause</em> of the collector (see <a href="#2.5">&sect;2.5</a>).
+The function returns the previous value of the pause.
+</li>
+
+<li><b><code>LUA_GCSETSTEPMUL</code>: </b>
+sets <code>data</code> as the new value for the <em>step multiplier</em> of
+the collector (see <a href="#2.5">&sect;2.5</a>).
+The function returns the previous value of the step multiplier.
+</li>
+
+<li><b><code>LUA_GCISRUNNING</code>: </b>
+returns a boolean that tells whether the collector is running
+(i.e., not stopped).
+</li>
+
+<li><b><code>LUA_GCGEN</code>: </b>
+changes the collector to generational mode
+(see <a href="#2.5">&sect;2.5</a>).
+</li>
+
+<li><b><code>LUA_GCINC</code>: </b>
+changes the collector to incremental mode.
+This is the default mode.
+</li>
+
+</ul>
+
+<p>
+For more details about these options,
+see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>.
+
+
+
+
+
+<hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
+
+<p>
+Returns the memory-allocation function of a given state.
+If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the
+opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>.
+
+
+
+
+
+<hr><h3><a name="lua_getctx"><code>lua_getctx</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_getctx (lua_State *L, int *ctx);</pre>
+
+<p>
+This function is called by a continuation function (see <a href="#4.7">&sect;4.7</a>)
+to retrieve the status of the thread and a context information.
+
+
+<p>
+When called in the original function,
+<a href="#lua_getctx"><code>lua_getctx</code></a> always returns <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
+and does not change the value of its argument <code>ctx</code>.
+When called inside a continuation function,
+<a href="#lua_getctx"><code>lua_getctx</code></a> returns <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> and sets
+the value of <code>ctx</code> to be the context information
+(the value passed as the <code>ctx</code> argument
+to the callee together with the continuation function).
+
+
+<p>
+When the callee is <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
+Lua may also call its continuation function
+to handle errors during the call.
+That is, upon an error in the function called by <a href="#lua_pcallk"><code>lua_pcallk</code></a>,
+Lua may not return to the original function
+but instead may call the continuation function.
+In that case, a call to <a href="#lua_getctx"><code>lua_getctx</code></a> will return the error code
+(the value that would be returned by <a href="#lua_pcallk"><code>lua_pcallk</code></a>);
+the value of <code>ctx</code> will be set to the context information,
+as in the case of a yield.
+
+
+
+
+
+<hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void lua_getfield (lua_State *L, int index, const char *k);</pre>
+
+<p>
+Pushes onto the stack the value <code>t[k]</code>,
+where <code>t</code> is the value at the given index.
+As in Lua, this function may trigger a metamethod
+for the "index" event (see <a href="#2.4">&sect;2.4</a>).
+
+
+
+
+
+<hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void lua_getglobal (lua_State *L, const char *name);</pre>
+
+<p>
+Pushes onto the stack the value of the global <code>name</code>.
+
+
+
+
+
+<hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
+<pre>int lua_getmetatable (lua_State *L, int index);</pre>
+
+<p>
+Pushes onto the stack the metatable of the value at the given index.
+If the value does not have a metatable,
+the function returns&nbsp;0 and pushes nothing on the stack.
+
+
+
+
+
+<hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p>
+<span class="apii">[-1, +1, <em>e</em>]</span>
+<pre>void lua_gettable (lua_State *L, int index);</pre>
+
+<p>
+Pushes onto the stack the value <code>t[k]</code>,
+where <code>t</code> is the value at the given index
+and <code>k</code> is the value at the top of the stack.
+
+
+<p>
+This function pops the key from the stack
+(putting the resulting value in its place).
+As in Lua, this function may trigger a metamethod
+for the "index" event (see <a href="#2.4">&sect;2.4</a>).
+
+
+
+
+
+<hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_gettop (lua_State *L);</pre>
+
+<p>
+Returns the index of the top element in the stack.
+Because indices start at&nbsp;1,
+this result is equal to the number of elements in the stack
+(and so 0&nbsp;means an empty stack).
+
+
+
+
+
+<hr><h3><a name="lua_getuservalue"><code>lua_getuservalue</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_getuservalue (lua_State *L, int index);</pre>
+
+<p>
+Pushes onto the stack the Lua value associated with the userdata
+at the given index.
+This Lua value must be a table or <b>nil</b>.
+
+
+
+
+
+<hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p>
+<span class="apii">[-1, +1, &ndash;]</span>
+<pre>void lua_insert (lua_State *L, int index);</pre>
+
+<p>
+Moves the top element into the given valid index,
+shifting up the elements above this index to open space.
+This function cannot be called with a pseudo-index,
+because a pseudo-index is not an actual stack position.
+
+
+
+
+
+<hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3>
+<pre>typedef ptrdiff_t lua_Integer;</pre>
+
+<p>
+The type used by the Lua API to represent signed integral values.
+
+
+<p>
+By default it is a <code>ptrdiff_t</code>,
+which is usually the largest signed integral type the machine handles
+"comfortably".
+
+
+
+
+
+<hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isboolean (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a boolean,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_iscfunction (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a C&nbsp;function,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isfunction (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a function
+(either C or Lua), and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a light userdata,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isnil (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is <b>nil</b>,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isnone (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the given index is not valid,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the given index is not valid
+or if the value at this index is <b>nil</b>,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isnumber (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a number
+or a string convertible to a number,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isstring (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a string
+or a number (which is always convertible to a string),
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_istable (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a table,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isthread (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a thread,
+and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_isuserdata (lua_State *L, int index);</pre>
+
+<p>
+Returns 1 if the value at the given index is a userdata
+(either full or light), and 0&nbsp;otherwise.
+
+
+
+
+
+<hr><h3><a name="lua_len"><code>lua_len</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void lua_len (lua_State *L, int index);</pre>
+
+<p>
+Returns the "length" of the value at the given index;
+it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">&sect;3.4.6</a>).
+The result is pushed on the stack.
+
+
+
+
+
+<hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>int lua_load (lua_State *L,
+              lua_Reader reader,
+              void *data,
+              const char *source,
+              const char *mode);</pre>
+
+<p>
+Loads a Lua chunk (without running it).
+If there are no errors,
+<code>lua_load</code> pushes the compiled chunk as a Lua
+function on top of the stack.
+Otherwise, it pushes an error message.
+
+
+<p>
+The return values of <code>lua_load</code> are:
+
+<ul>
+
+<li><b><a href="#pdf-LUA_OK"><code>LUA_OK</code></a>: </b> no errors;</li>
+
+<li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>: </b>
+syntax error during precompilation;</li>
+
+<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
+memory allocation error;</li>
+
+<li><b><a href="#pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
+error while running a <code>__gc</code> metamethod.
+(This error has no relation with the chunk being loaded.
+It is generated by the garbage collector.)
+</li>
+
+</ul>
+
+<p>
+The <code>lua_load</code> function uses a user-supplied <code>reader</code> function
+to read the chunk (see <a href="#lua_Reader"><code>lua_Reader</code></a>).
+The <code>data</code> argument is an opaque value passed to the reader function.
+
+
+<p>
+The <code>source</code> argument gives a name to the chunk,
+which is used for error messages and in debug information (see <a href="#4.9">&sect;4.9</a>).
+
+
+<p>
+<code>lua_load</code> automatically detects whether the chunk is text or binary
+and loads it accordingly (see program <code>luac</code>).
+The string <code>mode</code> works as in function <a href="#pdf-load"><code>load</code></a>,
+with the addition that
+a <code>NULL</code> value is equivalent to the string "<code>bt</code>".
+
+
+<p>
+<code>lua_load</code> uses the stack internally,
+so the reader function should always leave the stack
+unmodified when returning.
+
+
+<p>
+If the resulting function has one upvalue,
+this upvalue is set to the value of the global environment
+stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">&sect;4.5</a>).
+When loading main chunks,
+this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
+
+
+
+
+
+<hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre>
+
+<p>
+Creates a new thread running in a new, independent state.
+Returns <code>NULL</code> if cannot create the thread or the state
+(due to lack of memory).
+The argument <code>f</code> is the allocator function;
+Lua does all memory allocation for this state through this function.
+The second argument, <code>ud</code>, is an opaque pointer that Lua
+passes to the allocator in every call.
+
+
+
+
+
+<hr><h3><a name="lua_newtable"><code>lua_newtable</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void lua_newtable (lua_State *L);</pre>
+
+<p>
+Creates a new empty table and pushes it onto the stack.
+It is equivalent to <code>lua_createtable(L, 0, 0)</code>.
+
+
+
+
+
+<hr><h3><a name="lua_newthread"><code>lua_newthread</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>lua_State *lua_newthread (lua_State *L);</pre>
+
+<p>
+Creates a new thread, pushes it on the stack,
+and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread.
+The new thread returned by this function shares with the original thread
+its global environment,
+but has an independent execution stack.
+
+
+<p>
+There is no explicit function to close or to destroy a thread.
+Threads are subject to garbage collection,
+like any Lua object.
+
+
+
+
+
+<hr><h3><a name="lua_newuserdata"><code>lua_newuserdata</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void *lua_newuserdata (lua_State *L, size_t size);</pre>
+
+<p>
+This function allocates a new block of memory with the given size,
+pushes onto the stack a new full userdata with the block address,
+and returns this address.
+The host program can freely use this memory.
+
+
+
+
+
+<hr><h3><a name="lua_next"><code>lua_next</code></a></h3><p>
+<span class="apii">[-1, +(2|0), <em>e</em>]</span>
+<pre>int lua_next (lua_State *L, int index);</pre>
+
+<p>
+Pops a key from the stack,
+and pushes a key&ndash;value pair from the table at the given index
+(the "next" pair after the given key).
+If there are no more elements in the table,
+then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing).
+
+
+<p>
+A typical traversal looks like this:
+
+<pre>
+     /* table is in the stack at index 't' */
+     lua_pushnil(L);  /* first key */
+     while (lua_next(L, t) != 0) {
+       /* uses 'key' (at index -2) and 'value' (at index -1) */
+       printf("%s - %s\n",
+              lua_typename(L, lua_type(L, -2)),
+              lua_typename(L, lua_type(L, -1)));
+       /* removes 'value'; keeps 'key' for next iteration */
+       lua_pop(L, 1);
+     }
+</pre>
+
+<p>
+While traversing a table,
+do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key,
+unless you know that the key is actually a string.
+Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> may change
+the value at the given index;
+this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>.
+
+
+<p>
+See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
+the table during its traversal.
+
+
+
+
+
+<hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3>
+<pre>typedef double lua_Number;</pre>
+
+<p>
+The type of numbers in Lua.
+By default, it is double, but that can be changed in <code>luaconf.h</code>.
+Through this configuration file you can change
+Lua to operate with another type for numbers (e.g., float or long).
+
+
+
+
+
+<hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p>
+<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
+<pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre>
+
+<p>
+Calls a function in protected mode.
+
+
+<p>
+Both <code>nargs</code> and <code>nresults</code> have the same meaning as
+in <a href="#lua_call"><code>lua_call</code></a>.
+If there are no errors during the call,
+<a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>.
+However, if there is any error,
+<a href="#lua_pcall"><code>lua_pcall</code></a> catches it,
+pushes a single value on the stack (the error message),
+and returns an error code.
+Like <a href="#lua_call"><code>lua_call</code></a>,
+<a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function
+and its arguments from the stack.
+
+
+<p>
+If <code>msgh</code> is 0,
+then the error message returned on the stack
+is exactly the original error message.
+Otherwise, <code>msgh</code> is the stack index of a
+<em>message handler</em>.
+(In the current implementation, this index cannot be a pseudo-index.)
+In case of runtime errors,
+this function will be called with the error message
+and its return value will be the message
+returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>.
+
+
+<p>
+Typically, the message handler is used to add more debug
+information to the error message, such as a stack traceback.
+Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>,
+since by then the stack has unwound.
+
+
+<p>
+The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns one of the following codes
+(defined in <code>lua.h</code>):
+
+<ul>
+
+<li><b><a name="pdf-LUA_OK"><code>LUA_OK</code></a> (0): </b>
+success.</li>
+
+<li><b><a name="pdf-LUA_ERRRUN"><code>LUA_ERRRUN</code></a>: </b>
+a runtime error.
+</li>
+
+<li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>: </b>
+memory allocation error.
+For such errors, Lua does not call the message handler.
+</li>
+
+<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>: </b>
+error while running the message handler.
+</li>
+
+<li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b>
+error while running a <code>__gc</code> metamethod.
+(This error typically has no relation with the function being called.
+It is generated by the garbage collector.)
+</li>
+
+</ul>
+
+
+
+
+<hr><h3><a name="lua_pcallk"><code>lua_pcallk</code></a></h3><p>
+<span class="apii">[-(nargs + 1), +(nresults|1), &ndash;]</span>
+<pre>int lua_pcallk (lua_State *L,
+                int nargs,
+                int nresults,
+                int errfunc,
+                int ctx,
+                lua_CFunction k);</pre>
+
+<p>
+This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>,
+but allows the called function to yield (see <a href="#4.7">&sect;4.7</a>).
+
+
+
+
+
+<hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p>
+<span class="apii">[-n, +0, &ndash;]</span>
+<pre>void lua_pop (lua_State *L, int n);</pre>
+
+<p>
+Pops <code>n</code> elements from the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushboolean (lua_State *L, int b);</pre>
+
+<p>
+Pushes a boolean value with value <code>b</code> onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushcclosure"><code>lua_pushcclosure</code></a></h3><p>
+<span class="apii">[-n, +1, <em>e</em>]</span>
+<pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre>
+
+<p>
+Pushes a new C&nbsp;closure onto the stack.
+
+
+<p>
+When a C&nbsp;function is created,
+it is possible to associate some values with it,
+thus creating a C&nbsp;closure (see <a href="#4.4">&sect;4.4</a>);
+these values are then accessible to the function whenever it is called.
+To associate values with a C&nbsp;function,
+first these values should be pushed onto the stack
+(when there are multiple values, the first value is pushed first).
+Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>
+is called to create and push the C&nbsp;function onto the stack,
+with the argument <code>n</code> telling how many values should be
+associated with the function.
+<a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack.
+
+
+<p>
+The maximum value for <code>n</code> is 255.
+
+
+<p>
+When <code>n</code> is zero,
+this function creates a <em>light C function</em>,
+which is just a pointer to the C&nbsp;function.
+In that case, it never throws a memory error.
+
+
+
+
+
+<hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre>
+
+<p>
+Pushes a C&nbsp;function onto the stack.
+This function receives a pointer to a C function
+and pushes onto the stack a Lua value of type <code>function</code> that,
+when called, invokes the corresponding C&nbsp;function.
+
+
+<p>
+Any function to be registered in Lua must
+follow the correct protocol to receive its parameters
+and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+
+
+<p>
+<code>lua_pushcfunction</code> is defined as a macro:
+
+<pre>
+     #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)
+</pre><p>
+Note that <code>f</code> is used twice.
+
+
+
+
+
+<hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
+
+<p>
+Pushes onto the stack a formatted string
+and returns a pointer to this string.
+It is similar to the ANSI&nbsp;C function <code>sprintf</code>,
+but has some important differences:
+
+<ul>
+
+<li>
+You do not have to allocate space for the result:
+the result is a Lua string and Lua takes care of memory allocation
+(and deallocation, through garbage collection).
+</li>
+
+<li>
+The conversion specifiers are quite restricted.
+There are no flags, widths, or precisions.
+The conversion specifiers can only be
+'<code>%%</code>' (inserts a '<code>%</code>' in the string),
+'<code>%s</code>' (inserts a zero-terminated string, with no size restrictions),
+'<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
+'<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
+'<code>%d</code>' (inserts an <code>int</code>), and
+'<code>%c</code>' (inserts an <code>int</code> as a byte).
+</li>
+
+</ul>
+
+
+
+
+<hr><h3><a name="lua_pushglobaltable"><code>lua_pushglobaltable</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushglobaltable (lua_State *L);</pre>
+
+<p>
+Pushes the global environment onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
+
+<p>
+Pushes a number with value <code>n</code> onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre>
+
+<p>
+Pushes a light userdata onto the stack.
+
+
+<p>
+Userdata represent C&nbsp;values in Lua.
+A <em>light userdata</em> represents a pointer, a <code>void*</code>.
+It is a value (like a number):
+you do not create it, it has no individual metatable,
+and it is not collected (as it was never created).
+A light userdata is equal to "any"
+light userdata with the same C&nbsp;address.
+
+
+
+
+
+<hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *lua_pushliteral (lua_State *L, const char *s);</pre>
+
+<p>
+This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
+but can be used only when <code>s</code> is a literal string.
+It automatically provides the string length.
+
+
+
+
+
+<hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *lua_pushlstring (lua_State *L, const char *s, size_t len);</pre>
+
+<p>
+Pushes the string pointed to by <code>s</code> with size <code>len</code>
+onto the stack.
+Lua makes (or reuses) an internal copy of the given string,
+so the memory at <code>s</code> can be freed or reused immediately after
+the function returns.
+The string can contain any binary data,
+including embedded zeros.
+
+
+<p>
+Returns a pointer to the internal copy of the string.
+
+
+
+
+
+<hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushnil (lua_State *L);</pre>
+
+<p>
+Pushes a nil value onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre>
+
+<p>
+Pushes a number with value <code>n</code> onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushstring"><code>lua_pushstring</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *lua_pushstring (lua_State *L, const char *s);</pre>
+
+<p>
+Pushes the zero-terminated string pointed to by <code>s</code>
+onto the stack.
+Lua makes (or reuses) an internal copy of the given string,
+so the memory at <code>s</code> can be freed or reused immediately after
+the function returns.
+
+
+<p>
+Returns a pointer to the internal copy of the string.
+
+
+<p>
+If <code>s</code> is <code>NULL</code>, pushes <b>nil</b> and returns <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>int lua_pushthread (lua_State *L);</pre>
+
+<p>
+Pushes the thread represented by <code>L</code> onto the stack.
+Returns 1 if this thread is the main thread of its state.
+
+
+
+
+
+<hr><h3><a name="lua_pushunsigned"><code>lua_pushunsigned</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre>
+
+<p>
+Pushes a number with value <code>n</code> onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_pushvalue (lua_State *L, int index);</pre>
+
+<p>
+Pushes a copy of the element at the given index
+onto the stack.
+
+
+
+
+
+<hr><h3><a name="lua_pushvfstring"><code>lua_pushvfstring</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *lua_pushvfstring (lua_State *L,
+                              const char *fmt,
+                              va_list argp);</pre>
+
+<p>
+Equivalent to <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, except that it receives a <code>va_list</code>
+instead of a variable number of arguments.
+
+
+
+
+
+<hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
+
+<p>
+Returns 1 if the two values in indices <code>index1</code> and
+<code>index2</code> are primitively equal
+(that is, without calling metamethods).
+Otherwise returns&nbsp;0.
+Also returns&nbsp;0 if any of the indices are non valid.
+
+
+
+
+
+<hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p>
+<span class="apii">[-1, +1, &ndash;]</span>
+<pre>void lua_rawget (lua_State *L, int index);</pre>
+
+<p>
+Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access
+(i.e., without metamethods).
+
+
+
+
+
+<hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_rawgeti (lua_State *L, int index, int n);</pre>
+
+<p>
+Pushes onto the stack the value <code>t[n]</code>,
+where <code>t</code> is the table at the given index.
+The access is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
+<hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void lua_rawgetp (lua_State *L, int index, const void *p);</pre>
+
+<p>
+Pushes onto the stack the value <code>t[k]</code>,
+where <code>t</code> is the table at the given index and
+<code>k</code> is the pointer <code>p</code> represented as a light userdata.
+The access is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
+<hr><h3><a name="lua_rawlen"><code>lua_rawlen</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>size_t lua_rawlen (lua_State *L, int index);</pre>
+
+<p>
+Returns the raw "length" of the value at the given index:
+for strings, this is the string length;
+for tables, this is the result of the length operator ('<code>#</code>')
+with no metamethods;
+for userdata, this is the size of the block of memory allocated
+for the userdata;
+for other values, it is&nbsp;0.
+
+
+
+
+
+<hr><h3><a name="lua_rawset"><code>lua_rawset</code></a></h3><p>
+<span class="apii">[-2, +0, <em>e</em>]</span>
+<pre>void lua_rawset (lua_State *L, int index);</pre>
+
+<p>
+Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw assignment
+(i.e., without metamethods).
+
+
+
+
+
+<hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p>
+<span class="apii">[-1, +0, <em>e</em>]</span>
+<pre>void lua_rawseti (lua_State *L, int index, int n);</pre>
+
+<p>
+Does the equivalent of <code>t[n] = v</code>,
+where <code>t</code> is the table at the given index
+and <code>v</code> is the value at the top of the stack.
+
+
+<p>
+This function pops the value from the stack.
+The assignment is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
+<hr><h3><a name="lua_rawsetp"><code>lua_rawsetp</code></a></h3><p>
+<span class="apii">[-1, +0, <em>e</em>]</span>
+<pre>void lua_rawsetp (lua_State *L, int index, const void *p);</pre>
+
+<p>
+Does the equivalent of <code>t[k] = v</code>,
+where <code>t</code> is the table at the given index,
+<code>k</code> is the pointer <code>p</code> represented as a light userdata,
+and <code>v</code> is the value at the top of the stack.
+
+
+<p>
+This function pops the value from the stack.
+The assignment is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
+<hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3>
+<pre>typedef const char * (*lua_Reader) (lua_State *L,
+                                    void *data,
+                                    size_t *size);</pre>
+
+<p>
+The reader function used by <a href="#lua_load"><code>lua_load</code></a>.
+Every time it needs another piece of the chunk,
+<a href="#lua_load"><code>lua_load</code></a> calls the reader,
+passing along its <code>data</code> parameter.
+The reader must return a pointer to a block of memory
+with a new piece of the chunk
+and set <code>size</code> to the block size.
+The block must exist until the reader function is called again.
+To signal the end of the chunk,
+the reader must return <code>NULL</code> or set <code>size</code> to zero.
+The reader function may return pieces of any size greater than zero.
+
+
+
+
+
+<hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>void lua_register (lua_State *L, const char *name, lua_CFunction f);</pre>
+
+<p>
+Sets the C function <code>f</code> as the new value of global <code>name</code>.
+It is defined as a macro:
+
+<pre>
+     #define lua_register(L,n,f) \
+            (lua_pushcfunction(L, f), lua_setglobal(L, n))
+</pre>
+
+
+
+
+<hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p>
+<span class="apii">[-1, +0, &ndash;]</span>
+<pre>void lua_remove (lua_State *L, int index);</pre>
+
+<p>
+Removes the element at the given valid index,
+shifting down the elements above this index to fill the gap.
+This function cannot be called with a pseudo-index,
+because a pseudo-index is not an actual stack position.
+
+
+
+
+
+<hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p>
+<span class="apii">[-1, +0, &ndash;]</span>
+<pre>void lua_replace (lua_State *L, int index);</pre>
+
+<p>
+Moves the top element into the given valid index
+without shifting any element
+(therefore replacing the value at the given index),
+and then pops the top element.
+
+
+
+
+
+<hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>int lua_resume (lua_State *L, lua_State *from, int nargs);</pre>
+
+<p>
+Starts and resumes a coroutine in a given thread.
+
+
+<p>
+To start a coroutine,
+you push onto the thread stack the main function plus any arguments;
+then you call <a href="#lua_resume"><code>lua_resume</code></a>,
+with <code>nargs</code> being the number of arguments.
+This call returns when the coroutine suspends or finishes its execution.
+When it returns, the stack contains all values passed to <a href="#lua_yield"><code>lua_yield</code></a>,
+or all values returned by the body function.
+<a href="#lua_resume"><code>lua_resume</code></a> returns
+<a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields,
+<a href="#pdf-LUA_OK"><code>LUA_OK</code></a> if the coroutine finishes its execution
+without errors,
+or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
+
+
+<p>
+In case of errors,
+the stack is not unwound,
+so you can use the debug API over it.
+The error message is on the top of the stack.
+
+
+<p>
+To resume a coroutine,
+you remove any results from the last <a href="#lua_yield"><code>lua_yield</code></a>,
+put on its stack only the values to
+be passed as results from <code>yield</code>,
+and then call <a href="#lua_resume"><code>lua_resume</code></a>.
+
+
+<p>
+The parameter <code>from</code> represents the coroutine that is resuming <code>L</code>.
+If there is no such coroutine,
+this parameter can be <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre>
+
+<p>
+Changes the allocator function of a given state to <code>f</code>
+with user data <code>ud</code>.
+
+
+
+
+
+<hr><h3><a name="lua_setfield"><code>lua_setfield</code></a></h3><p>
+<span class="apii">[-1, +0, <em>e</em>]</span>
+<pre>void lua_setfield (lua_State *L, int index, const char *k);</pre>
+
+<p>
+Does the equivalent to <code>t[k] = v</code>,
+where <code>t</code> is the value at the given index
+and <code>v</code> is the value at the top of the stack.
+
+
+<p>
+This function pops the value from the stack.
+As in Lua, this function may trigger a metamethod
+for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
+
+
+
+
+
+<hr><h3><a name="lua_setglobal"><code>lua_setglobal</code></a></h3><p>
+<span class="apii">[-1, +0, <em>e</em>]</span>
+<pre>void lua_setglobal (lua_State *L, const char *name);</pre>
+
+<p>
+Pops a value from the stack and
+sets it as the new value of global <code>name</code>.
+
+
+
+
+
+<hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p>
+<span class="apii">[-1, +0, &ndash;]</span>
+<pre>void lua_setmetatable (lua_State *L, int index);</pre>
+
+<p>
+Pops a table from the stack and
+sets it as the new metatable for the value at the given index.
+
+
+
+
+
+<hr><h3><a name="lua_settable"><code>lua_settable</code></a></h3><p>
+<span class="apii">[-2, +0, <em>e</em>]</span>
+<pre>void lua_settable (lua_State *L, int index);</pre>
+
+<p>
+Does the equivalent to <code>t[k] = v</code>,
+where <code>t</code> is the value at the given index,
+<code>v</code> is the value at the top of the stack,
+and <code>k</code> is the value just below the top.
+
+
+<p>
+This function pops both the key and the value from the stack.
+As in Lua, this function may trigger a metamethod
+for the "newindex" event (see <a href="#2.4">&sect;2.4</a>).
+
+
+
+
+
+<hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>void lua_settop (lua_State *L, int index);</pre>
+
+<p>
+Accepts any index, or&nbsp;0,
+and sets the stack top to this index.
+If the new top is larger than the old one,
+then the new elements are filled with <b>nil</b>.
+If <code>index</code> is&nbsp;0, then all stack elements are removed.
+
+
+
+
+
+<hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p>
+<span class="apii">[-1, +0, &ndash;]</span>
+<pre>void lua_setuservalue (lua_State *L, int index);</pre>
+
+<p>
+Pops a table or <b>nil</b> from the stack and sets it as
+the new value associated to the userdata at the given index.
+
+
+
+
+
+<hr><h3><a name="lua_State"><code>lua_State</code></a></h3>
+<pre>typedef struct lua_State lua_State;</pre>
+
+<p>
+An opaque structure that points to a thread and indirectly
+(through the thread) to the whole state of a Lua interpreter.
+The Lua library is fully reentrant:
+it has no global variables.
+All information about a state is accessible through this structure.
+
+
+<p>
+A pointer to this structure must be passed as the first argument to
+every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
+which creates a Lua state from scratch.
+
+
+
+
+
+<hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_status (lua_State *L);</pre>
+
+<p>
+Returns the status of the thread <code>L</code>.
+
+
+<p>
+The status can be 0 (<a href="#pdf-LUA_OK"><code>LUA_OK</code></a>) for a normal thread,
+an error code if the thread finished the execution
+of a <a href="#lua_resume"><code>lua_resume</code></a> with an error,
+or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended.
+
+
+<p>
+You can only call functions in threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>.
+You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>
+(to start a new coroutine) or <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a>
+(to resume a coroutine).
+
+
+
+
+
+<hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_toboolean (lua_State *L, int index);</pre>
+
+<p>
+Converts the Lua value at the given index to a C&nbsp;boolean
+value (0&nbsp;or&nbsp;1).
+Like all tests in Lua,
+<a href="#lua_toboolean"><code>lua_toboolean</code></a> returns true for any Lua value
+different from <b>false</b> and <b>nil</b>;
+otherwise it returns false.
+(If you want to accept only actual boolean values,
+use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.)
+
+
+
+
+
+<hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
+
+<p>
+Converts a value at the given index to a C&nbsp;function.
+That value must be a C&nbsp;function;
+otherwise, returns <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre>
+
+<p>
+Equivalent to <a href="#lua_tointegerx"><code>lua_tointegerx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tointegerx"><code>lua_tointegerx</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);</pre>
+
+<p>
+Converts the Lua value at the given index
+to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
+The Lua value must be a number or a string convertible to a number
+(see <a href="#3.4.2">&sect;3.4.2</a>);
+otherwise, <code>lua_tointegerx</code> returns&nbsp;0.
+
+
+<p>
+If the number is not an integer,
+it is truncated in some non-specified way.
+
+
+<p>
+If <code>isnum</code> is not <code>NULL</code>,
+its referent is assigned a boolean value that
+indicates whether the operation succeeded.
+
+
+
+
+
+<hr><h3><a name="lua_tolstring"><code>lua_tolstring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre>
+
+<p>
+Converts the Lua value at the given index to a C&nbsp;string.
+If <code>len</code> is not <code>NULL</code>,
+it also sets <code>*len</code> with the string length.
+The Lua value must be a string or a number;
+otherwise, the function returns <code>NULL</code>.
+If the value is a number,
+then <code>lua_tolstring</code> also
+<em>changes the actual value in the stack to a string</em>.
+(This change confuses <a href="#lua_next"><code>lua_next</code></a>
+when <code>lua_tolstring</code> is applied to keys during a table traversal.)
+
+
+<p>
+<code>lua_tolstring</code> returns a fully aligned pointer
+to a string inside the Lua state.
+This string always has a zero ('<code>\0</code>')
+after its last character (as in&nbsp;C),
+but can contain other zeros in its body.
+Because Lua has garbage collection,
+there is no guarantee that the pointer returned by <code>lua_tolstring</code>
+will be valid after the corresponding value is removed from the stack.
+
+
+
+
+
+<hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Number lua_tonumber (lua_State *L, int index);</pre>
+
+<p>
+Equivalent to <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tonumberx"><code>lua_tonumberx</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);</pre>
+
+<p>
+Converts the Lua value at the given index
+to the C&nbsp;type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>).
+The Lua value must be a number or a string convertible to a number
+(see <a href="#3.4.2">&sect;3.4.2</a>);
+otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns&nbsp;0.
+
+
+<p>
+If <code>isnum</code> is not <code>NULL</code>,
+its referent is assigned a boolean value that
+indicates whether the operation succeeded.
+
+
+
+
+
+<hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>const void *lua_topointer (lua_State *L, int index);</pre>
+
+<p>
+Converts the value at the given index to a generic
+C&nbsp;pointer (<code>void*</code>).
+The value can be a userdata, a table, a thread, or a function;
+otherwise, <code>lua_topointer</code> returns <code>NULL</code>.
+Different objects will give different pointers.
+There is no way to convert the pointer back to its original value.
+
+
+<p>
+Typically this function is used only for debug information.
+
+
+
+
+
+<hr><h3><a name="lua_tostring"><code>lua_tostring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>const char *lua_tostring (lua_State *L, int index);</pre>
+
+<p>
+Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
+
+<p>
+Converts the value at the given index to a Lua thread
+(represented as <code>lua_State*</code>).
+This value must be a thread;
+otherwise, the function returns <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tounsigned"><code>lua_tounsigned</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Unsigned lua_tounsigned (lua_State *L, int index);</pre>
+
+<p>
+Equivalent to <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> with <code>isnum</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_tounsignedx"><code>lua_tounsignedx</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre>
+
+<p>
+Converts the Lua value at the given index
+to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+The Lua value must be a number or a string convertible to a number
+(see <a href="#3.4.2">&sect;3.4.2</a>);
+otherwise, <code>lua_tounsignedx</code> returns&nbsp;0.
+
+
+<p>
+If the number is not an integer,
+it is truncated in some non-specified way.
+If the number is outside the range of representable values,
+it is normalized to the remainder of its division by
+one more than the maximum representable value.
+
+
+<p>
+If <code>isnum</code> is not <code>NULL</code>,
+its referent is assigned a boolean value that
+indicates whether the operation succeeded.
+
+
+
+
+
+<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void *lua_touserdata (lua_State *L, int index);</pre>
+
+<p>
+If the value at the given index is a full userdata,
+returns its block address.
+If the value is a light userdata,
+returns its pointer.
+Otherwise, returns <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_type (lua_State *L, int index);</pre>
+
+<p>
+Returns the type of the value in the given valid index,
+or <code>LUA_TNONE</code> for a non-valid (but acceptable) index.
+The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
+defined in <code>lua.h</code>:
+<a name="pdf-LUA_TNIL"><code>LUA_TNIL</code></a>,
+<a name="pdf-LUA_TNUMBER"><code>LUA_TNUMBER</code></a>,
+<a name="pdf-LUA_TBOOLEAN"><code>LUA_TBOOLEAN</code></a>,
+<a name="pdf-LUA_TSTRING"><code>LUA_TSTRING</code></a>,
+<a name="pdf-LUA_TTABLE"><code>LUA_TTABLE</code></a>,
+<a name="pdf-LUA_TFUNCTION"><code>LUA_TFUNCTION</code></a>,
+<a name="pdf-LUA_TUSERDATA"><code>LUA_TUSERDATA</code></a>,
+<a name="pdf-LUA_TTHREAD"><code>LUA_TTHREAD</code></a>,
+and
+<a name="pdf-LUA_TLIGHTUSERDATA"><code>LUA_TLIGHTUSERDATA</code></a>.
+
+
+
+
+
+<hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>const char *lua_typename (lua_State *L, int tp);</pre>
+
+<p>
+Returns the name of the type encoded by the value <code>tp</code>,
+which must be one the values returned by <a href="#lua_type"><code>lua_type</code></a>.
+
+
+
+
+
+<hr><h3><a name="lua_Unsigned"><code>lua_Unsigned</code></a></h3>
+<pre>typedef unsigned long lua_Unsigned;</pre>
+
+<p>
+The type used by the Lua API to represent unsigned integral values.
+It must have at least 32 bits.
+
+
+<p>
+By default it is an <code>unsigned int</code> or an <code>unsigned long</code>,
+whichever can hold 32-bit values.
+
+
+
+
+
+<hr><h3><a name="lua_upvalueindex"><code>lua_upvalueindex</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_upvalueindex (int i);</pre>
+
+<p>
+Returns the pseudo-index that represents the <code>i</code>-th upvalue of
+the running function (see <a href="#4.4">&sect;4.4</a>).
+
+
+
+
+
+<hr><h3><a name="lua_version"><code>lua_version</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>const lua_Number *lua_version (lua_State *L);</pre>
+
+<p>
+Returns the address of the version number stored in the Lua core.
+When called with a valid <a href="#lua_State"><code>lua_State</code></a>,
+returns the address of the version used to create that state.
+When called with <code>NULL</code>,
+returns the address of the version running the call.
+
+
+
+
+
+<hr><h3><a name="lua_Writer"><code>lua_Writer</code></a></h3>
+<pre>typedef int (*lua_Writer) (lua_State *L,
+                           const void* p,
+                           size_t sz,
+                           void* ud);</pre>
+
+<p>
+The type of the writer function used by <a href="#lua_dump"><code>lua_dump</code></a>.
+Every time it produces another piece of chunk,
+<a href="#lua_dump"><code>lua_dump</code></a> calls the writer,
+passing along the buffer to be written (<code>p</code>),
+its size (<code>sz</code>),
+and the <code>data</code> parameter supplied to <a href="#lua_dump"><code>lua_dump</code></a>.
+
+
+<p>
+The writer returns an error code:
+0&nbsp;means no errors;
+any other value means an error and stops <a href="#lua_dump"><code>lua_dump</code></a> from
+calling the writer again.
+
+
+
+
+
+<hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre>
+
+<p>
+Exchange values between different threads of the same state.
+
+
+<p>
+This function pops <code>n</code> values from the stack <code>from</code>,
+and pushes them onto the stack <code>to</code>.
+
+
+
+
+
+<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>int lua_yield (lua_State *L, int nresults);</pre>
+
+<p>
+This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+but it has no continuation (see <a href="#4.7">&sect;4.7</a>).
+Therefore, when the thread resumes,
+it returns to the function that called
+the function calling <code>lua_yield</code>.
+
+
+
+
+
+<hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p>
+<span class="apii">[-?, +?, &ndash;]</span>
+<pre>int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);</pre>
+
+<p>
+Yields a coroutine.
+
+
+<p>
+This function should only be called as the
+return expression of a C&nbsp;function, as follows:
+
+<pre>
+     return lua_yieldk (L, n, i, k);
+</pre><p>
+When a C&nbsp;function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a> in that way,
+the running coroutine suspends its execution,
+and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns.
+The parameter <code>nresults</code> is the number of values from the stack
+that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>.
+
+
+<p>
+When the coroutine is resumed again,
+Lua calls the given continuation function <code>k</code> to continue
+the execution of the C function that yielded (see <a href="#4.7">&sect;4.7</a>).
+This continuation function receives the same stack
+from the previous function,
+with the results removed and
+replaced by the arguments passed to <a href="#lua_resume"><code>lua_resume</code></a>.
+Moreover,
+the continuation function may access the value <code>ctx</code>
+by calling <a href="#lua_getctx"><code>lua_getctx</code></a>.
+
+
+
+
+
+
+
+<h2>4.9 &ndash; <a name="4.9">The Debug Interface</a></h2>
+
+<p>
+Lua has no built-in debugging facilities.
+Instead, it offers a special interface
+by means of functions and <em>hooks</em>.
+This interface allows the construction of different
+kinds of debuggers, profilers, and other tools
+that need "inside information" from the interpreter.
+
+
+
+<hr><h3><a name="lua_Debug"><code>lua_Debug</code></a></h3>
+<pre>typedef struct lua_Debug {
+  int event;
+  const char *name;           /* (n) */
+  const char *namewhat;       /* (n) */
+  const char *what;           /* (S) */
+  const char *source;         /* (S) */
+  int currentline;            /* (l) */
+  int linedefined;            /* (S) */
+  int lastlinedefined;        /* (S) */
+  unsigned char nups;         /* (u) number of upvalues */
+  unsigned char nparams;      /* (u) number of parameters */
+  char isvararg;              /* (u) */
+  char istailcall;            /* (t) */
+  char short_src[LUA_IDSIZE]; /* (S) */
+  /* private part */
+  <em>other fields</em>
+} lua_Debug;</pre>
+
+<p>
+A structure used to carry different pieces of
+information about a function or an activation record.
+<a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part
+of this structure, for later use.
+To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information,
+call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
+
+
+<p>
+The fields of <a href="#lua_Debug"><code>lua_Debug</code></a> have the following meaning:
+
+<ul>
+
+<li><b><code>source</code>: </b>
+the source of the chunk that created the function.
+If <code>source</code> starts with a '<code>@</code>',
+it means that the function was defined in a file where
+the file name follows the '<code>@</code>'.
+If <code>source</code> starts with a '<code>=</code>',
+the remainder of its contents describe the source in a user-dependent manner.
+Otherwise,
+the function was defined in a string where
+<code>source</code> is that string.
+</li>
+
+<li><b><code>short_src</code>: </b>
+a "printable" version of <code>source</code>, to be used in error messages.
+</li>
+
+<li><b><code>linedefined</code>: </b>
+the line number where the definition of the function starts.
+</li>
+
+<li><b><code>lastlinedefined</code>: </b>
+the line number where the definition of the function ends.
+</li>
+
+<li><b><code>what</code>: </b>
+the string <code>"Lua"</code> if the function is a Lua function,
+<code>"C"</code> if it is a C&nbsp;function,
+<code>"main"</code> if it is the main part of a chunk.
+</li>
+
+<li><b><code>currentline</code>: </b>
+the current line where the given function is executing.
+When no line information is available,
+<code>currentline</code> is set to -1.
+</li>
+
+<li><b><code>name</code>: </b>
+a reasonable name for the given function.
+Because functions in Lua are first-class values,
+they do not have a fixed name:
+some functions can be the value of multiple global variables,
+while others can be stored only in a table field.
+The <code>lua_getinfo</code> function checks how the function was
+called to find a suitable name.
+If it cannot find a name,
+then <code>name</code> is set to <code>NULL</code>.
+</li>
+
+<li><b><code>namewhat</code>: </b>
+explains the <code>name</code> field.
+The value of <code>namewhat</code> can be
+<code>"global"</code>, <code>"local"</code>, <code>"method"</code>,
+<code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string),
+according to how the function was called.
+(Lua uses the empty string when no other option seems to apply.)
+</li>
+
+<li><b><code>istailcall</code>: </b>
+true if this function invocation was called by a tail call.
+In this case, the caller of this level is not in the stack.
+</li>
+
+<li><b><code>nups</code>: </b>
+the number of upvalues of the function.
+</li>
+
+<li><b><code>nparams</code>: </b>
+the number of fixed parameters of the function
+(always 0&nbsp;for C&nbsp;functions).
+</li>
+
+<li><b><code>isvararg</code>: </b>
+true if the function is a vararg function
+(always true for C&nbsp;functions).
+</li>
+
+</ul>
+
+
+
+
+<hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_Hook lua_gethook (lua_State *L);</pre>
+
+<p>
+Returns the current hook function.
+
+
+
+
+
+<hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_gethookcount (lua_State *L);</pre>
+
+<p>
+Returns the current hook count.
+
+
+
+
+
+<hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_gethookmask (lua_State *L);</pre>
+
+<p>
+Returns the current hook mask.
+
+
+
+
+
+<hr><h3><a name="lua_getinfo"><code>lua_getinfo</code></a></h3><p>
+<span class="apii">[-(0|1), +(0|1|2), <em>e</em>]</span>
+<pre>int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);</pre>
+
+<p>
+Gets information about a specific function or function invocation.
+
+
+<p>
+To get information about a function invocation,
+the parameter <code>ar</code> must be a valid activation record that was
+filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
+given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
+
+
+<p>
+To get information about a function you push it onto the stack
+and start the <code>what</code> string with the character '<code>&gt;</code>'.
+(In that case,
+<code>lua_getinfo</code> pops the function from the top of the stack.)
+For instance, to know in which line a function <code>f</code> was defined,
+you can write the following code:
+
+<pre>
+     lua_Debug ar;
+     lua_getglobal(L, "f");  /* get global 'f' */
+     lua_getinfo(L, "&gt;S", &amp;ar);
+     printf("%d\n", ar.linedefined);
+</pre>
+
+<p>
+Each character in the string <code>what</code>
+selects some fields of the structure <code>ar</code> to be filled or
+a value to be pushed on the stack:
+
+<ul>
+
+<li><b>'<code>n</code>': </b> fills in the field <code>name</code> and <code>namewhat</code>;
+</li>
+
+<li><b>'<code>S</code>': </b>
+fills in the fields <code>source</code>, <code>short_src</code>,
+<code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>;
+</li>
+
+<li><b>'<code>l</code>': </b> fills in the field <code>currentline</code>;
+</li>
+
+<li><b>'<code>t</code>': </b> fills in the field <code>istailcall</code>;
+</li>
+
+<li><b>'<code>u</code>': </b> fills in the fields
+<code>nups</code>, <code>nparams</code>, and <code>isvararg</code>;
+</li>
+
+<li><b>'<code>f</code>': </b>
+pushes onto the stack the function that is
+running at the given level;
+</li>
+
+<li><b>'<code>L</code>': </b>
+pushes onto the stack a table whose indices are the
+numbers of the lines that are valid on the function.
+(A <em>valid line</em> is a line with some associated code,
+that is, a line where you can put a break point.
+Non-valid lines include empty lines and comments.)
+</li>
+
+</ul>
+
+<p>
+This function returns 0 on error
+(for instance, an invalid option in <code>what</code>).
+
+
+
+
+
+<hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
+<pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre>
+
+<p>
+Gets information about a local variable of
+a given activation record or a given function.
+
+
+<p>
+In the first case,
+the parameter <code>ar</code> must be a valid activation record that was
+filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
+given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
+The index <code>n</code> selects which local variable to inspect;
+see <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for details about variable indices
+and names.
+
+
+<p>
+<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack
+and returns its name.
+
+
+<p>
+In the second case, <code>ar</code> should be <code>NULL</code> and the function
+to be inspected must be at the top of the stack.
+In this case, only parameters of Lua functions are visible
+(as there is no information about what variables are active)
+and no values are pushed onto the stack.
+
+
+<p>
+Returns <code>NULL</code> (and pushes nothing)
+when the index is greater than
+the number of active local variables.
+
+
+
+
+
+<hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre>
+
+<p>
+Gets information about the interpreter runtime stack.
+
+
+<p>
+This function fills parts of a <a href="#lua_Debug"><code>lua_Debug</code></a> structure with
+an identification of the <em>activation record</em>
+of the function executing at a given level.
+Level&nbsp;0 is the current running function,
+whereas level <em>n+1</em> is the function that has called level <em>n</em>
+(except for tail calls, which do not count on the stack).
+When there are no errors, <a href="#lua_getstack"><code>lua_getstack</code></a> returns 1;
+when called with a level greater than the stack depth,
+it returns 0.
+
+
+
+
+
+<hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p>
+<span class="apii">[-0, +(0|1), &ndash;]</span>
+<pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
+
+<p>
+Gets information about a closure's upvalue.
+(For Lua functions,
+upvalues are the external local variables that the function uses,
+and that are consequently included in its closure.)
+<a href="#lua_getupvalue"><code>lua_getupvalue</code></a> gets the index <code>n</code> of an upvalue,
+pushes the upvalue's value onto the stack,
+and returns its name.
+<code>funcindex</code> points to the closure in the stack.
+(Upvalues have no particular order,
+as they are active through the whole function.
+So, they are numbered in an arbitrary order.)
+
+
+<p>
+Returns <code>NULL</code> (and pushes nothing)
+when the index is greater than the number of upvalues.
+For C&nbsp;functions, this function uses the empty string <code>""</code>
+as a name for all upvalues.
+
+
+
+
+
+<hr><h3><a name="lua_Hook"><code>lua_Hook</code></a></h3>
+<pre>typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);</pre>
+
+<p>
+Type for debugging hook functions.
+
+
+<p>
+Whenever a hook is called, its <code>ar</code> argument has its field
+<code>event</code> set to the specific event that triggered the hook.
+Lua identifies these events with the following constants:
+<a name="pdf-LUA_HOOKCALL"><code>LUA_HOOKCALL</code></a>, <a name="pdf-LUA_HOOKRET"><code>LUA_HOOKRET</code></a>,
+<a name="pdf-LUA_HOOKTAILCALL"><code>LUA_HOOKTAILCALL</code></a>, <a name="pdf-LUA_HOOKLINE"><code>LUA_HOOKLINE</code></a>,
+and <a name="pdf-LUA_HOOKCOUNT"><code>LUA_HOOKCOUNT</code></a>.
+Moreover, for line events, the field <code>currentline</code> is also set.
+To get the value of any other field in <code>ar</code>,
+the hook must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
+
+
+<p>
+For call events, <code>event</code> can be <code>LUA_HOOKCALL</code>,
+the normal value, or <code>LUA_HOOKTAILCALL</code>, for a tail call;
+in this case, there will be no corresponding return event.
+
+
+<p>
+While Lua is running a hook, it disables other calls to hooks.
+Therefore, if a hook calls back Lua to execute a function or a chunk,
+this execution occurs without any calls to hooks.
+
+
+<p>
+Hook functions cannot have continuations,
+that is, they cannot call <a href="#lua_yieldk"><code>lua_yieldk</code></a>,
+<a href="#lua_pcallk"><code>lua_pcallk</code></a>, or <a href="#lua_callk"><code>lua_callk</code></a> with a non-null <code>k</code>.
+
+
+<p>
+Hook functions can yield under the following conditions:
+Only count and line events can yield
+and they cannot yield any value;
+to yield a hook function must finish its execution
+calling <a href="#lua_yield"><code>lua_yield</code></a> with <code>nresults</code> equal to zero.
+
+
+
+
+
+<hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre>
+
+<p>
+Sets the debugging hook function.
+
+
+<p>
+Argument <code>f</code> is the hook function.
+<code>mask</code> specifies on which events the hook will be called:
+it is formed by a bitwise or of the constants
+<a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>,
+<a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>,
+<a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>,
+and <a name="pdf-LUA_MASKCOUNT"><code>LUA_MASKCOUNT</code></a>.
+The <code>count</code> argument is only meaningful when the mask
+includes <code>LUA_MASKCOUNT</code>.
+For each event, the hook is called as explained below:
+
+<ul>
+
+<li><b>The call hook: </b> is called when the interpreter calls a function.
+The hook is called just after Lua enters the new function,
+before the function gets its arguments.
+</li>
+
+<li><b>The return hook: </b> is called when the interpreter returns from a function.
+The hook is called just before Lua leaves the function.
+There is no standard way to access the values
+to be returned by the function.
+</li>
+
+<li><b>The line hook: </b> is called when the interpreter is about to
+start the execution of a new line of code,
+or when it jumps back in the code (even to the same line).
+(This event only happens while Lua is executing a Lua function.)
+</li>
+
+<li><b>The count hook: </b> is called after the interpreter executes every
+<code>count</code> instructions.
+(This event only happens while Lua is executing a Lua function.)
+</li>
+
+</ul>
+
+<p>
+A hook is disabled by setting <code>mask</code> to zero.
+
+
+
+
+
+<hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p>
+<span class="apii">[-(0|1), +0, &ndash;]</span>
+<pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre>
+
+<p>
+Sets the value of a local variable of a given activation record.
+Parameters <code>ar</code> and <code>n</code> are as in <a href="#lua_getlocal"><code>lua_getlocal</code></a>
+(see <a href="#lua_getlocal"><code>lua_getlocal</code></a>).
+<a href="#lua_setlocal"><code>lua_setlocal</code></a> assigns the value at the top of the stack
+to the variable and returns its name.
+It also pops the value from the stack.
+
+
+<p>
+Returns <code>NULL</code> (and pops nothing)
+when the index is greater than
+the number of active local variables.
+
+
+
+
+
+<hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p>
+<span class="apii">[-(0|1), +0, &ndash;]</span>
+<pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre>
+
+<p>
+Sets the value of a closure's upvalue.
+It assigns the value at the top of the stack
+to the upvalue and returns its name.
+It also pops the value from the stack.
+Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
+(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>).
+
+
+<p>
+Returns <code>NULL</code> (and pops nothing)
+when the index is greater than the number of upvalues.
+
+
+
+
+
+<hr><h3><a name="lua_upvalueid"><code>lua_upvalueid</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void *lua_upvalueid (lua_State *L, int funcindex, int n);</pre>
+
+<p>
+Returns an unique identifier for the upvalue numbered <code>n</code>
+from the closure at index <code>funcindex</code>.
+Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
+(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>)
+(but <code>n</code> cannot be greater than the number of upvalues).
+
+
+<p>
+These unique identifiers allow a program to check whether different
+closures share upvalues.
+Lua closures that share an upvalue
+(that is, that access a same external local variable)
+will return identical ids for those upvalue indices.
+
+
+
+
+
+<hr><h3><a name="lua_upvaluejoin"><code>lua_upvaluejoin</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
+                                    int funcindex2, int n2);</pre>
+
+<p>
+Make the <code>n1</code>-th upvalue of the Lua closure at index <code>funcindex1</code>
+refer to the <code>n2</code>-th upvalue of the Lua closure at index <code>funcindex2</code>.
+
+
+
+
+
+
+
+<h1>5 &ndash; <a name="5">The Auxiliary Library</a></h1>
+
+<p>
+
+The <em>auxiliary library</em> provides several convenient functions
+to interface C with Lua.
+While the basic API provides the primitive functions for all
+interactions between C and Lua,
+the auxiliary library provides higher-level functions for some
+common tasks.
+
+
+<p>
+All functions and types from the auxiliary library
+are defined in header file <code>lauxlib.h</code> and
+have a prefix <code>luaL_</code>.
+
+
+<p>
+All functions in the auxiliary library are built on
+top of the basic API,
+and so they provide nothing that cannot be done with that API.
+Nevertheless, the use of the auxiliary library ensures
+more consistency to your code.
+
+
+<p>
+Several functions in the auxiliary library use internally some
+extra stack slots.
+When a function in the auxiliary library uses less than five slots,
+it does not check the stack size;
+it simply assumes that there are enough slots.
+
+
+<p>
+Several functions in the auxiliary library are used to
+check C&nbsp;function arguments.
+Because the error message is formatted for arguments
+(e.g., "<code>bad argument #1</code>"),
+you should not use these functions for other stack values.
+
+
+<p>
+Functions called <code>luaL_check*</code>
+always throw an error if the check is not satisfied.
+
+
+
+<h2>5.1 &ndash; <a name="5.1">Functions and Types</a></h2>
+
+<p>
+Here we list all functions and types from the auxiliary library
+in alphabetical order.
+
+
+
+<hr><h3><a name="luaL_addchar"><code>luaL_addchar</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>void luaL_addchar (luaL_Buffer *B, char c);</pre>
+
+<p>
+Adds the byte <code>c</code> to the buffer <code>B</code>
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_addlstring"><code>luaL_addlstring</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);</pre>
+
+<p>
+Adds the string pointed to by <code>s</code> with length <code>l</code> to
+the buffer <code>B</code>
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+The string can contain embedded zeros.
+
+
+
+
+
+<hr><h3><a name="luaL_addsize"><code>luaL_addsize</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>void luaL_addsize (luaL_Buffer *B, size_t n);</pre>
+
+<p>
+Adds to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>)
+a string of length <code>n</code> previously copied to the
+buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_addstring"><code>luaL_addstring</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>void luaL_addstring (luaL_Buffer *B, const char *s);</pre>
+
+<p>
+Adds the zero-terminated string pointed to by <code>s</code>
+to the buffer <code>B</code>
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+The string cannot contain embedded zeros.
+
+
+
+
+
+<hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p>
+<span class="apii">[-1, +?, <em>e</em>]</span>
+<pre>void luaL_addvalue (luaL_Buffer *B);</pre>
+
+<p>
+Adds the value at the top of the stack
+to the buffer <code>B</code>
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+Pops the value.
+
+
+<p>
+This is the only function on string buffers that can (and must)
+be called with an extra element on the stack,
+which is the value to be added to the buffer.
+
+
+
+
+
+<hr><h3><a name="luaL_argcheck"><code>luaL_argcheck</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>void luaL_argcheck (lua_State *L,
+                    int cond,
+                    int arg,
+                    const char *extramsg);</pre>
+
+<p>
+Checks whether <code>cond</code> is true.
+If not, raises an error with a standard message.
+
+
+
+
+
+<hr><h3><a name="luaL_argerror"><code>luaL_argerror</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>int luaL_argerror (lua_State *L, int arg, const char *extramsg);</pre>
+
+<p>
+Raises an error with a standard message
+that includes <code>extramsg</code> as a comment.
+
+
+<p>
+This function never returns,
+but it is an idiom to use it in C&nbsp;functions
+as <code>return luaL_argerror(<em>args</em>)</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3>
+<pre>typedef struct luaL_Buffer luaL_Buffer;</pre>
+
+<p>
+Type for a <em>string buffer</em>.
+
+
+<p>
+A string buffer allows C&nbsp;code to build Lua strings piecemeal.
+Its pattern of use is as follows:
+
+<ul>
+
+<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+
+<li>Then initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
+
+<li>
+Then add string pieces to the buffer calling any of
+the <code>luaL_add*</code> functions.
+</li>
+
+<li>
+Finish by calling <code>luaL_pushresult(&amp;b)</code>.
+This call leaves the final string on the top of the stack.
+</li>
+
+</ul>
+
+<p>
+If you know beforehand the total size of the resulting string,
+you can use the buffer like this:
+
+<ul>
+
+<li>First declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
+
+<li>Then initialize it and preallocate a space of
+size <code>sz</code> with a call <code>luaL_buffinitsize(L, &amp;b, sz)</code>.</li>
+
+<li>Then copy the string into that space.</li>
+
+<li>
+Finish by calling <code>luaL_pushresultsize(&amp;b, sz)</code>,
+where <code>sz</code> is the total size of the resulting string
+copied into that space.
+</li>
+
+</ul>
+
+<p>
+During its normal operation,
+a string buffer uses a variable number of stack slots.
+So, while using a buffer, you cannot assume that you know where
+the top of the stack is.
+You can use the stack between successive calls to buffer operations
+as long as that use is balanced;
+that is,
+when you call a buffer operation,
+the stack is at the same level
+it was immediately after the previous buffer operation.
+(The only exception to this rule is <a href="#luaL_addvalue"><code>luaL_addvalue</code></a>.)
+After calling <a href="#luaL_pushresult"><code>luaL_pushresult</code></a> the stack is back to its
+level when the buffer was initialized,
+plus the final string on its top.
+
+
+
+
+
+<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>
+
+<p>
+Initializes a buffer <code>B</code>.
+This function does not allocate any space;
+the buffer must be declared as a variable
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_buffinitsize"><code>luaL_buffinitsize</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);</pre>
+
+<p>
+Equivalent to the sequence
+<a href="#luaL_buffinit"><code>luaL_buffinit</code></a>, <a href="#luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_callmeta"><code>luaL_callmeta</code></a></h3><p>
+<span class="apii">[-0, +(0|1), <em>e</em>]</span>
+<pre>int luaL_callmeta (lua_State *L, int obj, const char *e);</pre>
+
+<p>
+Calls a metamethod.
+
+
+<p>
+If the object at index <code>obj</code> has a metatable and this
+metatable has a field <code>e</code>,
+this function calls this field passing the object as its only argument.
+In this case this function returns true and pushes onto the
+stack the value returned by the call.
+If there is no metatable or no metamethod,
+this function returns false (without pushing any value on the stack).
+
+
+
+
+
+<hr><h3><a name="luaL_checkany"><code>luaL_checkany</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>void luaL_checkany (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function has an argument
+of any type (including <b>nil</b>) at position <code>arg</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>int luaL_checkint (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a number
+and returns this number cast to an <code>int</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Integer luaL_checkinteger (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a number
+and returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>long luaL_checklong (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a number
+and returns this number cast to a <code>long</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>const char *luaL_checklstring (lua_State *L, int arg, size_t *l);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a string
+and returns this string;
+if <code>l</code> is not <code>NULL</code> fills <code>*l</code>
+with the string's length.
+
+
+<p>
+This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+so all conversions and caveats of that function apply here.
+
+
+
+
+
+<hr><h3><a name="luaL_checknumber"><code>luaL_checknumber</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Number luaL_checknumber (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a number
+and returns this number.
+
+
+
+
+
+<hr><h3><a name="luaL_checkoption"><code>luaL_checkoption</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>int luaL_checkoption (lua_State *L,
+                      int arg,
+                      const char *def,
+                      const char *const lst[]);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a string and
+searches for this string in the array <code>lst</code>
+(which must be NULL-terminated).
+Returns the index in the array where the string was found.
+Raises an error if the argument is not a string or
+if the string cannot be found.
+
+
+<p>
+If <code>def</code> is not <code>NULL</code>,
+the function uses <code>def</code> as a default value when
+there is no argument <code>arg</code> or when this argument is <b>nil</b>.
+
+
+<p>
+This is a useful function for mapping strings to C&nbsp;enums.
+(The usual convention in Lua libraries is
+to use strings instead of numbers to select options.)
+
+
+
+
+
+<hr><h3><a name="luaL_checkstack"><code>luaL_checkstack</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>void luaL_checkstack (lua_State *L, int sz, const char *msg);</pre>
+
+<p>
+Grows the stack size to <code>top + sz</code> elements,
+raising an error if the stack cannot grow to that size.
+<code>msg</code> is an additional text to go into the error message
+(or <code>NULL</code> for no additional text).
+
+
+
+
+
+<hr><h3><a name="luaL_checkstring"><code>luaL_checkstring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>const char *luaL_checkstring (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a string
+and returns this string.
+
+
+<p>
+This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
+so all conversions and caveats of that function apply here.
+
+
+
+
+
+<hr><h3><a name="luaL_checktype"><code>luaL_checktype</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>void luaL_checktype (lua_State *L, int arg, int t);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> has type <code>t</code>.
+See <a href="#lua_type"><code>lua_type</code></a> for the encoding of types for <code>t</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_checkudata"><code>luaL_checkudata</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>void *luaL_checkudata (lua_State *L, int arg, const char *tname);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a userdata
+of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>) and
+returns the userdata address (see <a href="#lua_touserdata"><code>lua_touserdata</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_checkunsigned"><code>luaL_checkunsigned</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);</pre>
+
+<p>
+Checks whether the function argument <code>arg</code> is a number
+and returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void luaL_checkversion (lua_State *L);</pre>
+
+<p>
+Checks whether the core running the call,
+the core that created the Lua state,
+and the code making the call are all using the same version of Lua.
+Also checks whether the core running the call
+and the core that created the Lua state
+are using the same address space.
+
+
+
+
+
+<hr><h3><a name="luaL_dofile"><code>luaL_dofile</code></a></h3><p>
+<span class="apii">[-0, +?, <em>e</em>]</span>
+<pre>int luaL_dofile (lua_State *L, const char *filename);</pre>
+
+<p>
+Loads and runs the given file.
+It is defined as the following macro:
+
+<pre>
+     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
+</pre><p>
+It returns false if there are no errors
+or true in case of errors.
+
+
+
+
+
+<hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p>
+<span class="apii">[-0, +?, &ndash;]</span>
+<pre>int luaL_dostring (lua_State *L, const char *str);</pre>
+
+<p>
+Loads and runs the given string.
+It is defined as the following macro:
+
+<pre>
+     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
+</pre><p>
+It returns false if there are no errors
+or true in case of errors.
+
+
+
+
+
+<hr><h3><a name="luaL_error"><code>luaL_error</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>int luaL_error (lua_State *L, const char *fmt, ...);</pre>
+
+<p>
+Raises an error.
+The error message format is given by <code>fmt</code>
+plus any extra arguments,
+following the same rules of <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>.
+It also adds at the beginning of the message the file name and
+the line number where the error occurred,
+if this information is available.
+
+
+<p>
+This function never returns,
+but it is an idiom to use it in C&nbsp;functions
+as <code>return luaL_error(<em>args</em>)</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_execresult"><code>luaL_execresult</code></a></h3><p>
+<span class="apii">[-0, +3, <em>e</em>]</span>
+<pre>int luaL_execresult (lua_State *L, int stat);</pre>
+
+<p>
+This function produces the return values for
+process-related functions in the standard library
+(<a href="#pdf-os.execute"><code>os.execute</code></a> and <a href="#pdf-io.close"><code>io.close</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_fileresult"><code>luaL_fileresult</code></a></h3><p>
+<span class="apii">[-0, +(1|3), <em>e</em>]</span>
+<pre>int luaL_fileresult (lua_State *L, int stat, const char *fname);</pre>
+
+<p>
+This function produces the return values for
+file-related functions in the standard library
+(<a href="#pdf-io.open"><code>io.open</code></a>, <a href="#pdf-os.rename"><code>os.rename</code></a>, <a href="#pdf-file:seek"><code>file:seek</code></a>, etc.).
+
+
+
+
+
+<hr><h3><a name="luaL_getmetafield"><code>luaL_getmetafield</code></a></h3><p>
+<span class="apii">[-0, +(0|1), <em>e</em>]</span>
+<pre>int luaL_getmetafield (lua_State *L, int obj, const char *e);</pre>
+
+<p>
+Pushes onto the stack the field <code>e</code> from the metatable
+of the object at index <code>obj</code>.
+If the object does not have a metatable,
+or if the metatable does not have this field,
+returns false and pushes nothing.
+
+
+
+
+
+<hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre>
+
+<p>
+Pushes onto the stack the metatable associated with name <code>tname</code>
+in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_getsubtable"><code>luaL_getsubtable</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>int luaL_getsubtable (lua_State *L, int idx, const char *fname);</pre>
+
+<p>
+Ensures that the value <code>t[fname]</code>,
+where <code>t</code> is the value at index <code>idx</code>,
+is a table,
+and pushes that table onto the stack.
+Returns true if it finds a previous table there
+and false if it creates a new table.
+
+
+
+
+
+<hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *luaL_gsub (lua_State *L,
+                       const char *s,
+                       const char *p,
+                       const char *r);</pre>
+
+<p>
+Creates a copy of string <code>s</code> by replacing
+any occurrence of the string <code>p</code>
+with the string <code>r</code>.
+Pushes the resulting string on the stack and returns it.
+
+
+
+
+
+<hr><h3><a name="luaL_len"><code>luaL_len</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>int luaL_len (lua_State *L, int index);</pre>
+
+<p>
+Returns the "length" of the value at the given index
+as a number;
+it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">&sect;3.4.6</a>).
+Raises an error if the result of the operation is not a number.
+(This case only can happen through metamethods.)
+
+
+
+
+
+<hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>int luaL_loadbuffer (lua_State *L,
+                     const char *buff,
+                     size_t sz,
+                     const char *name);</pre>
+
+<p>
+Equivalent to <a href="#luaL_loadbufferx"><code>luaL_loadbufferx</code></a> with <code>mode</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_loadbufferx"><code>luaL_loadbufferx</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>int luaL_loadbufferx (lua_State *L,
+                      const char *buff,
+                      size_t sz,
+                      const char *name,
+                      const char *mode);</pre>
+
+<p>
+Loads a buffer as a Lua chunk.
+This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the
+buffer pointed to by <code>buff</code> with size <code>sz</code>.
+
+
+<p>
+This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
+<code>name</code> is the chunk name,
+used for debug information and error messages.
+The string <code>mode</code> works as in function <a href="#lua_load"><code>lua_load</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
+
+<p>
+Equivalent to <a href="#luaL_loadfilex"><code>luaL_loadfilex</code></a> with <code>mode</code> equal to <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_loadfilex"><code>luaL_loadfilex</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>int luaL_loadfilex (lua_State *L, const char *filename,
+                                            const char *mode);</pre>
+
+<p>
+Loads a file as a Lua chunk.
+This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the file
+named <code>filename</code>.
+If <code>filename</code> is <code>NULL</code>,
+then it loads from the standard input.
+The first line in the file is ignored if it starts with a <code>#</code>.
+
+
+<p>
+The string <code>mode</code> works as in function <a href="#lua_load"><code>lua_load</code></a>.
+
+
+<p>
+This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
+but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
+if it cannot open/read the file or the file has a wrong mode.
+
+
+<p>
+As <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
+it does not run it.
+
+
+
+
+
+<hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p>
+<span class="apii">[-0, +1, &ndash;]</span>
+<pre>int luaL_loadstring (lua_State *L, const char *s);</pre>
+
+<p>
+Loads a string as a Lua chunk.
+This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in
+the zero-terminated string <code>s</code>.
+
+
+<p>
+This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
+
+
+<p>
+Also as <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
+it does not run it.
+
+
+
+
+
+<hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void luaL_newlib (lua_State *L, const luaL_Reg *l);</pre>
+
+<p>
+Creates a new table and registers there
+the functions in list <code>l</code>.
+It is implemented as the following macro:
+
+<pre>
+     (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+</pre>
+
+
+
+
+<hr><h3><a name="luaL_newlibtable"><code>luaL_newlibtable</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);</pre>
+
+<p>
+Creates a new table with a size optimized
+to store all entries in the array <code>l</code>
+(but does not actually store them).
+It is intended to be used in conjunction with <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a>
+(see <a href="#luaL_newlib"><code>luaL_newlib</code></a>).
+
+
+<p>
+It is implemented as a macro.
+The array <code>l</code> must be the actual array,
+not a pointer to it.
+
+
+
+
+
+<hr><h3><a name="luaL_newmetatable"><code>luaL_newmetatable</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>int luaL_newmetatable (lua_State *L, const char *tname);</pre>
+
+<p>
+If the registry already has the key <code>tname</code>,
+returns 0.
+Otherwise,
+creates a new table to be used as a metatable for userdata,
+adds it to the registry with key <code>tname</code>,
+and returns 1.
+
+
+<p>
+In both cases pushes onto the stack the final value associated
+with <code>tname</code> in the registry.
+
+
+
+
+
+<hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>lua_State *luaL_newstate (void);</pre>
+
+<p>
+Creates a new Lua state.
+It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an
+allocator based on the standard&nbsp;C <code>realloc</code> function
+and then sets a panic function (see <a href="#4.6">&sect;4.6</a>) that prints
+an error message to the standard error output in case of fatal
+errors.
+
+
+<p>
+Returns the new state,
+or <code>NULL</code> if there is a memory allocation error.
+
+
+
+
+
+<hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>void luaL_openlibs (lua_State *L);</pre>
+
+<p>
+Opens all standard Lua libraries into the given state.
+
+
+
+
+
+<hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>int luaL_optint (lua_State *L, int arg, int d);</pre>
+
+<p>
+If the function argument <code>arg</code> is a number,
+returns this number cast to an <code>int</code>.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Integer luaL_optinteger (lua_State *L,
+                             int arg,
+                             lua_Integer d);</pre>
+
+<p>
+If the function argument <code>arg</code> is a number,
+returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>long luaL_optlong (lua_State *L, int arg, long d);</pre>
+
+<p>
+If the function argument <code>arg</code> is a number,
+returns this number cast to a <code>long</code>.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>const char *luaL_optlstring (lua_State *L,
+                             int arg,
+                             const char *d,
+                             size_t *l);</pre>
+
+<p>
+If the function argument <code>arg</code> is a string,
+returns this string.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+<p>
+If <code>l</code> is not <code>NULL</code>,
+fills the position <code>*l</code> with the result's length.
+
+
+
+
+
+<hr><h3><a name="luaL_optnumber"><code>luaL_optnumber</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);</pre>
+
+<p>
+If the function argument <code>arg</code> is a number,
+returns this number.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_optstring"><code>luaL_optstring</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>const char *luaL_optstring (lua_State *L,
+                            int arg,
+                            const char *d);</pre>
+
+<p>
+If the function argument <code>arg</code> is a string,
+returns this string.
+If this argument is absent or is <b>nil</b>,
+returns <code>d</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_optunsigned"><code>luaL_optunsigned</code></a></h3><p>
+<span class="apii">[-0, +0, <em>v</em>]</span>
+<pre>lua_Unsigned luaL_optunsigned (lua_State *L,
+                               int arg,
+                               lua_Unsigned u);</pre>
+
+<p>
+If the function argument <code>arg</code> is a number,
+returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>.
+If this argument is absent or is <b>nil</b>,
+returns <code>u</code>.
+Otherwise, raises an error.
+
+
+
+
+
+<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
+
+<p>
+Equivalent to <a href="#luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a>
+with the predefined size <a name="pdf-LUAL_BUFFERSIZE"><code>LUAL_BUFFERSIZE</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_prepbuffsize"><code>luaL_prepbuffsize</code></a></h3><p>
+<span class="apii">[-?, +?, <em>e</em>]</span>
+<pre>char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);</pre>
+
+<p>
+Returns an address to a space of size <code>sz</code>
+where you can copy a string to be added to buffer <code>B</code>
+(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
+After copying the string into this space you must call
+<a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add
+it to the buffer.
+
+
+
+
+
+<hr><h3><a name="luaL_pushresult"><code>luaL_pushresult</code></a></h3><p>
+<span class="apii">[-?, +1, <em>e</em>]</span>
+<pre>void luaL_pushresult (luaL_Buffer *B);</pre>
+
+<p>
+Finishes the use of buffer <code>B</code> leaving the final string on
+the top of the stack.
+
+
+
+
+
+<hr><h3><a name="luaL_pushresultsize"><code>luaL_pushresultsize</code></a></h3><p>
+<span class="apii">[-?, +1, <em>e</em>]</span>
+<pre>void luaL_pushresultsize (luaL_Buffer *B, size_t sz);</pre>
+
+<p>
+Equivalent to the sequence <a href="#luaL_addsize"><code>luaL_addsize</code></a>, <a href="#luaL_pushresult"><code>luaL_pushresult</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_ref"><code>luaL_ref</code></a></h3><p>
+<span class="apii">[-1, +0, <em>e</em>]</span>
+<pre>int luaL_ref (lua_State *L, int t);</pre>
+
+<p>
+Creates and returns a <em>reference</em>,
+in the table at index <code>t</code>,
+for the object at the top of the stack (and pops the object).
+
+
+<p>
+A reference is a unique integer key.
+As long as you do not manually add integer keys into table <code>t</code>,
+<a href="#luaL_ref"><code>luaL_ref</code></a> ensures the uniqueness of the key it returns.
+You can retrieve an object referred by reference <code>r</code>
+by calling <code>lua_rawgeti(L, t, r)</code>.
+Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object.
+
+
+<p>
+If the object at the top of the stack is <b>nil</b>,
+<a href="#luaL_ref"><code>luaL_ref</code></a> returns the constant <a name="pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>.
+The constant <a name="pdf-LUA_NOREF"><code>LUA_NOREF</code></a> is guaranteed to be different
+from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>.
+
+
+
+
+
+<hr><h3><a name="luaL_Reg"><code>luaL_Reg</code></a></h3>
+<pre>typedef struct luaL_Reg {
+  const char *name;
+  lua_CFunction func;
+} luaL_Reg;</pre>
+
+<p>
+Type for arrays of functions to be registered by
+<a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a>.
+<code>name</code> is the function name and <code>func</code> is a pointer to
+the function.
+Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry
+in which both <code>name</code> and <code>func</code> are <code>NULL</code>.
+
+
+
+
+
+<hr><h3><a name="luaL_requiref"><code>luaL_requiref</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void luaL_requiref (lua_State *L, const char *modname,
+                    lua_CFunction openf, int glb);</pre>
+
+<p>
+Calls function <code>openf</code> with string <code>modname</code> as an argument
+and sets the call result in <code>package.loaded[modname]</code>,
+as if that function has been called through <a href="#pdf-require"><code>require</code></a>.
+
+
+<p>
+If <code>glb</code> is true,
+also stores the result into global <code>modname</code>.
+
+
+<p>
+Leaves a copy of that result on the stack.
+
+
+
+
+
+<hr><h3><a name="luaL_setfuncs"><code>luaL_setfuncs</code></a></h3><p>
+<span class="apii">[-nup, +0, <em>e</em>]</span>
+<pre>void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);</pre>
+
+<p>
+Registers all functions in the array <code>l</code>
+(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack
+(below optional upvalues, see next).
+
+
+<p>
+When <code>nup</code> is not zero,
+all functions are created sharing <code>nup</code> upvalues,
+which must be previously pushed on the stack
+on top of the library table.
+These values are popped from the stack after the registration.
+
+
+
+
+
+<hr><h3><a name="luaL_setmetatable"><code>luaL_setmetatable</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void luaL_setmetatable (lua_State *L, const char *tname);</pre>
+
+<p>
+Sets the metatable of the object at the top of the stack
+as the metatable associated with name <code>tname</code>
+in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
+
+
+
+
+
+<hr><h3><a name="luaL_testudata"><code>luaL_testudata</code></a></h3><p>
+<span class="apii">[-0, +0, <em>e</em>]</span>
+<pre>void *luaL_testudata (lua_State *L, int arg, const char *tname);</pre>
+
+<p>
+This function works like <a href="#luaL_checkudata"><code>luaL_checkudata</code></a>,
+except that, when the test fails,
+it returns <code>NULL</code> instead of throwing an error.
+
+
+
+
+
+<hr><h3><a name="luaL_tolstring"><code>luaL_tolstring</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>const char *luaL_tolstring (lua_State *L, int idx, size_t *len);</pre>
+
+<p>
+Converts any Lua value at the given index to a C&nbsp;string
+in a reasonable format.
+The resulting string is pushed onto the stack and also
+returned by the function.
+If <code>len</code> is not <code>NULL</code>,
+the function also sets <code>*len</code> with the string length.
+
+
+<p>
+If the value has a metatable with a <code>"__tostring"</code> field,
+then <code>luaL_tolstring</code> calls the corresponding metamethod
+with the value as argument,
+and uses the result of the call as its result.
+
+
+
+
+
+<hr><h3><a name="luaL_traceback"><code>luaL_traceback</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
+                     int level);</pre>
+
+<p>
+Creates and pushes a traceback of the stack <code>L1</code>.
+If <code>msg</code> is not <code>NULL</code> it is appended
+at the beginning of the traceback.
+The <code>level</code> parameter tells at which level
+to start the traceback.
+
+
+
+
+
+<hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>const char *luaL_typename (lua_State *L, int index);</pre>
+
+<p>
+Returns the name of the type of the value at the given index.
+
+
+
+
+
+<hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p>
+<span class="apii">[-0, +0, &ndash;]</span>
+<pre>void luaL_unref (lua_State *L, int t, int ref);</pre>
+
+<p>
+Releases reference <code>ref</code> from the table at index <code>t</code>
+(see <a href="#luaL_ref"><code>luaL_ref</code></a>).
+The entry is removed from the table,
+so that the referred object can be collected.
+The reference <code>ref</code> is also freed to be used again.
+
+
+<p>
+If <code>ref</code> is <a href="#pdf-LUA_NOREF"><code>LUA_NOREF</code></a> or <a href="#pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>,
+<a href="#luaL_unref"><code>luaL_unref</code></a> does nothing.
+
+
+
+
+
+<hr><h3><a name="luaL_where"><code>luaL_where</code></a></h3><p>
+<span class="apii">[-0, +1, <em>e</em>]</span>
+<pre>void luaL_where (lua_State *L, int lvl);</pre>
+
+<p>
+Pushes onto the stack a string identifying the current position
+of the control at level <code>lvl</code> in the call stack.
+Typically this string has the following format:
+
+<pre>
+     <em>chunkname</em>:<em>currentline</em>:
+</pre><p>
+Level&nbsp;0 is the running function,
+level&nbsp;1 is the function that called the running function,
+etc.
+
+
+<p>
+This function is used to build a prefix for error messages.
+
+
+
+
+
+
+
+<h1>6 &ndash; <a name="6">Standard Libraries</a></h1>
+
+<p>
+The standard Lua libraries provide useful functions
+that are implemented directly through the C&nbsp;API.
+Some of these functions provide essential services to the language
+(e.g., <a href="#pdf-type"><code>type</code></a> and <a href="#pdf-getmetatable"><code>getmetatable</code></a>);
+others provide access to "outside" services (e.g., I/O);
+and others could be implemented in Lua itself,
+but are quite useful or have critical performance requirements that
+deserve an implementation in C (e.g., <a href="#pdf-table.sort"><code>table.sort</code></a>).
+
+
+<p>
+All libraries are implemented through the official C&nbsp;API
+and are provided as separate C&nbsp;modules.
+Currently, Lua has the following standard libraries:
+
+<ul>
+
+<li>basic library (<a href="#6.1">&sect;6.1</a>);</li>
+
+<li>coroutine library (<a href="#6.2">&sect;6.2</a>);</li>
+
+<li>package library (<a href="#6.3">&sect;6.3</a>);</li>
+
+<li>string manipulation (<a href="#6.4">&sect;6.4</a>);</li>
+
+<li>table manipulation (<a href="#6.5">&sect;6.5</a>);</li>
+
+<li>mathematical functions (<a href="#6.6">&sect;6.6</a>) (sin, log, etc.);</li>
+
+<li>bitwise operations (<a href="#6.7">&sect;6.7</a>);</li>
+
+<li>input and output (<a href="#6.8">&sect;6.8</a>);</li>
+
+<li>operating system facilities (<a href="#6.9">&sect;6.9</a>);</li>
+
+<li>debug facilities (<a href="#6.10">&sect;6.10</a>).</li>
+
+</ul><p>
+Except for the basic and the package libraries,
+each library provides all its functions as fields of a global table
+or as methods of its objects.
+
+
+<p>
+To have access to these libraries,
+the C&nbsp;host program should call the <a href="#luaL_openlibs"><code>luaL_openlibs</code></a> function,
+which opens all standard libraries.
+Alternatively,
+the host program can open them individually by using
+<a href="#luaL_requiref"><code>luaL_requiref</code></a> to call
+<a name="pdf-luaopen_base"><code>luaopen_base</code></a> (for the basic library),
+<a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library),
+<a name="pdf-luaopen_coroutine"><code>luaopen_coroutine</code></a> (for the coroutine library),
+<a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library),
+<a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library),
+<a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library),
+<a name="pdf-luaopen_bit32"><code>luaopen_bit32</code></a> (for the bit library),
+<a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library),
+<a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library),
+and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library).
+These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a>.
+
+
+
+<h2>6.1 &ndash; <a name="6.1">Basic Functions</a></h2>
+
+<p>
+The basic library provides core functions to Lua.
+If you do not include this library in your application,
+you should check carefully whether you need to provide
+implementations for some of its facilities.
+
+
+<p>
+<hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3>
+Issues an  error when
+the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>);
+otherwise, returns all its arguments.
+<code>message</code> is an error message;
+when absent, it defaults to "assertion failed!"
+
+
+
+
+<p>
+<hr><h3><a name="pdf-collectgarbage"><code>collectgarbage ([opt [, arg]])</code></a></h3>
+
+
+<p>
+This function is a generic interface to the garbage collector.
+It performs different functions according to its first argument, <code>opt</code>:
+
+<ul>
+
+<li><b>"<code>collect</code>": </b>
+performs a full garbage-collection cycle.
+This is the default option.
+</li>
+
+<li><b>"<code>stop</code>": </b>
+stops automatic execution of the garbage collector.
+The collector will run only when explicitly invoked,
+until a call to restart it.
+</li>
+
+<li><b>"<code>restart</code>": </b>
+restarts automatic execution of the garbage collector.
+</li>
+
+<li><b>"<code>count</code>": </b>
+returns the total memory in use by Lua (in Kbytes) and
+a second value with the total memory in bytes modulo 1024.
+The first value has a fractional part,
+so the following equality is always true:
+
+<pre>
+     k, b = collectgarbage("count")
+     assert(k*1024 == math.floor(k)*1024 + b)
+</pre><p>
+(The second result is useful when Lua is compiled
+with a non floating-point type for numbers.)
+</li>
+
+<li><b>"<code>step</code>": </b>
+performs a garbage-collection step.
+The step "size" is controlled by <code>arg</code>
+(larger values mean more steps) in a non-specified way.
+If you want to control the step size
+you must experimentally tune the value of <code>arg</code>.
+Returns <b>true</b> if the step finished a collection cycle.
+</li>
+
+<li><b>"<code>setpause</code>": </b>
+sets <code>arg</code> as the new value for the <em>pause</em> of
+the collector (see <a href="#2.5">&sect;2.5</a>).
+Returns the previous value for <em>pause</em>.
+</li>
+
+<li><b>"<code>setstepmul</code>": </b>
+sets <code>arg</code> as the new value for the <em>step multiplier</em> of
+the collector (see <a href="#2.5">&sect;2.5</a>).
+Returns the previous value for <em>step</em>.
+</li>
+
+<li><b>"<code>isrunning</code>": </b>
+returns a boolean that tells whether the collector is running
+(i.e., not stopped).
+</li>
+
+<li><b>"<code>generational</code>": </b>
+changes the collector to generational mode.
+This is an experimental feature (see <a href="#2.5">&sect;2.5</a>).
+</li>
+
+<li><b>"<code>incremental</code>": </b>
+changes the collector to incremental mode.
+This is the default mode.
+</li>
+
+</ul>
+
+
+
+<p>
+<hr><h3><a name="pdf-dofile"><code>dofile ([filename])</code></a></h3>
+Opens the named file and executes its contents as a Lua chunk.
+When called without arguments,
+<code>dofile</code> executes the contents of the standard input (<code>stdin</code>).
+Returns all values returned by the chunk.
+In case of errors, <code>dofile</code> propagates the error
+to its caller (that is, <code>dofile</code> does not run in protected mode).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3>
+Terminates the last protected function called
+and returns <code>message</code> as the error message.
+Function <code>error</code> never returns.
+
+
+<p>
+Usually, <code>error</code> adds some information about the error position
+at the beginning of the message, if the message is a string.
+The <code>level</code> argument specifies how to get the error position.
+With level&nbsp;1 (the default), the error position is where the
+<code>error</code> function was called.
+Level&nbsp;2 points the error to where the function
+that called <code>error</code> was called; and so on.
+Passing a level&nbsp;0 avoids the addition of error position information
+to the message.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-_G"><code>_G</code></a></h3>
+A global variable (not a function) that
+holds the global environment (see <a href="#2.2">&sect;2.2</a>).
+Lua itself does not use this variable;
+changing its value does not affect any environment,
+nor vice-versa.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-getmetatable"><code>getmetatable (object)</code></a></h3>
+
+
+<p>
+If <code>object</code> does not have a metatable, returns <b>nil</b>.
+Otherwise,
+if the object's metatable has a <code>"__metatable"</code> field,
+returns the associated value.
+Otherwise, returns the metatable of the given object.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3>
+
+
+<p>
+If <code>t</code> has a metamethod <code>__ipairs</code>,
+calls it with <code>t</code> as argument and returns the first three
+results from the call.
+
+
+<p>
+Otherwise,
+returns three values: an iterator function, the table <code>t</code>, and 0,
+so that the construction
+
+<pre>
+     for i,v in ipairs(t) do <em>body</em> end
+</pre><p>
+will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ...,
+up to the first integer key absent from the table.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-load"><code>load (ld [, source [, mode [, env]]])</code></a></h3>
+
+
+<p>
+Loads a chunk.
+
+
+<p>
+If <code>ld</code> is a string, the chunk is this string.
+If <code>ld</code> is a function,
+<code>load</code> calls it repeatedly to get the chunk pieces.
+Each call to <code>ld</code> must return a string that concatenates
+with previous results.
+A return of an empty string, <b>nil</b>, or no value signals the end of the chunk.
+
+
+<p>
+If there are no syntactic errors,
+returns the compiled chunk as a function;
+otherwise, returns <b>nil</b> plus the error message.
+
+
+<p>
+If the resulting function has upvalues,
+the first upvalue is set to the value of <code>env</code>,
+if that parameter is given,
+or to the value of the global environment.
+(When you load a main chunk,
+the resulting function will always have exactly one upvalue,
+the <code>_ENV</code> variable (see <a href="#2.2">&sect;2.2</a>).
+When you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>),
+the resulting function can have arbitrary upvalues.)
+
+
+<p>
+<code>source</code> is used as the source of the chunk for error messages
+and debug information (see <a href="#4.9">&sect;4.9</a>).
+When absent,
+it defaults to <code>ld</code>, if <code>ld</code> is a string,
+or to "<code>=(load)</code>" otherwise.
+
+
+<p>
+The string <code>mode</code> controls whether the chunk can be text or binary
+(that is, a precompiled chunk).
+It may be the string "<code>b</code>" (only binary chunks),
+"<code>t</code>" (only text chunks),
+or "<code>bt</code>" (both binary and text).
+The default is "<code>bt</code>".
+
+
+
+
+<p>
+<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename [, mode [, env]]])</code></a></h3>
+
+
+<p>
+Similar to <a href="#pdf-load"><code>load</code></a>,
+but gets the chunk from file <code>filename</code>
+or from the standard input,
+if no file name is given.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3>
+
+
+<p>
+Allows a program to traverse all fields of a table.
+Its first argument is a table and its second argument
+is an index in this table.
+<code>next</code> returns the next index of the table
+and its associated value.
+When called with <b>nil</b> as its second argument,
+<code>next</code> returns an initial index
+and its associated value.
+When called with the last index,
+or with <b>nil</b> in an empty table,
+<code>next</code> returns <b>nil</b>.
+If the second argument is absent, then it is interpreted as <b>nil</b>.
+In particular,
+you can use <code>next(t)</code> to check whether a table is empty.
+
+
+<p>
+The order in which the indices are enumerated is not specified,
+<em>even for numeric indices</em>.
+(To traverse a table in numeric order,
+use a numerical <b>for</b>.)
+
+
+<p>
+The behavior of <code>next</code> is undefined if,
+during the traversal,
+you assign any value to a non-existent field in the table.
+You may however modify existing fields.
+In particular, you may clear existing fields.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-pairs"><code>pairs (t)</code></a></h3>
+
+
+<p>
+If <code>t</code> has a metamethod <code>__pairs</code>,
+calls it with <code>t</code> as argument and returns the first three
+results from the call.
+
+
+<p>
+Otherwise,
+returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>,
+so that the construction
+
+<pre>
+     for k,v in pairs(t) do <em>body</em> end
+</pre><p>
+will iterate over all key&ndash;value pairs of table <code>t</code>.
+
+
+<p>
+See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
+the table during its traversal.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-pcall"><code>pcall (f [, arg1, &middot;&middot;&middot;])</code></a></h3>
+
+
+<p>
+Calls function <code>f</code> with
+the given arguments in <em>protected mode</em>.
+This means that any error inside&nbsp;<code>f</code> is not propagated;
+instead, <code>pcall</code> catches the error
+and returns a status code.
+Its first result is the status code (a boolean),
+which is true if the call succeeds without errors.
+In such case, <code>pcall</code> also returns all results from the call,
+after this first result.
+In case of any error, <code>pcall</code> returns <b>false</b> plus the error message.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-print"><code>print (&middot;&middot;&middot;)</code></a></h3>
+Receives any number of arguments
+and prints their values to <code>stdout</code>,
+using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert each argument to a string.
+<code>print</code> is not intended for formatted output,
+but only as a quick way to show a value,
+for instance for debugging.
+For complete control over the output,
+use <a href="#pdf-string.format"><code>string.format</code></a> and <a href="#pdf-io.write"><code>io.write</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3>
+Checks whether <code>v1</code> is equal to <code>v2</code>,
+without invoking any metamethod.
+Returns a boolean.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3>
+Gets the real value of <code>table[index]</code>,
+without invoking any metamethod.
+<code>table</code> must be a table;
+<code>index</code> may be any value.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-rawlen"><code>rawlen (v)</code></a></h3>
+Returns the length of the object <code>v</code>,
+which must be a table or a string,
+without invoking any metamethod.
+Returns an integer number.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3>
+Sets the real value of <code>table[index]</code> to <code>value</code>,
+without invoking any metamethod.
+<code>table</code> must be a table,
+<code>index</code> any value different from <b>nil</b> and NaN,
+and <code>value</code> any Lua value.
+
+
+<p>
+This function returns <code>table</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-select"><code>select (index, &middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+If <code>index</code> is a number,
+returns all arguments after argument number <code>index</code>;
+a negative number indexes from the end (-1 is the last argument).
+Otherwise, <code>index</code> must be the string <code>"#"</code>,
+and <code>select</code> returns the total number of extra arguments it received.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-setmetatable"><code>setmetatable (table, metatable)</code></a></h3>
+
+
+<p>
+Sets the metatable for the given table.
+(You cannot change the metatable of other types from Lua, only from&nbsp;C.)
+If <code>metatable</code> is <b>nil</b>,
+removes the metatable of the given table.
+If the original metatable has a <code>"__metatable"</code> field,
+raises an error.
+
+
+<p>
+This function returns <code>table</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3>
+
+
+<p>
+When called with no <code>base</code>,
+<code>tonumber</code> tries to convert its argument to a number.
+If the argument is already a number or
+a string convertible to a number (see <a href="#3.4.2">&sect;3.4.2</a>),
+then <code>tonumber</code> returns this number;
+otherwise, it returns <b>nil</b>.
+
+
+<p>
+When called with <code>base</code>,
+then <code>e</code> should be a string to be interpreted as
+an integer numeral in that base.
+The base may be any integer between 2 and 36, inclusive.
+In bases above&nbsp;10, the letter '<code>A</code>' (in either upper or lower case)
+represents&nbsp;10, '<code>B</code>' represents&nbsp;11, and so forth,
+with '<code>Z</code>' representing 35.
+If the string <code>e</code> is not a valid numeral in the given base,
+the function returns <b>nil</b>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3>
+Receives a value of any type and
+converts it to a string in a reasonable format.
+(For complete control of how numbers are converted,
+use <a href="#pdf-string.format"><code>string.format</code></a>.)
+
+
+<p>
+If the metatable of <code>v</code> has a <code>"__tostring"</code> field,
+then <code>tostring</code> calls the corresponding value
+with <code>v</code> as argument,
+and uses the result of the call as its result.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-type"><code>type (v)</code></a></h3>
+Returns the type of its only argument, coded as a string.
+The possible results of this function are
+"<code>nil</code>" (a string, not the value <b>nil</b>),
+"<code>number</code>",
+"<code>string</code>",
+"<code>boolean</code>",
+"<code>table</code>",
+"<code>function</code>",
+"<code>thread</code>",
+and "<code>userdata</code>".
+
+
+
+
+<p>
+<hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3>
+A global variable (not a function) that
+holds a string containing the current interpreter version.
+The current contents of this variable is "<code>Lua 5.2</code>".
+
+
+
+
+<p>
+<hr><h3><a name="pdf-xpcall"><code>xpcall (f, msgh [, arg1, &middot;&middot;&middot;])</code></a></h3>
+
+
+<p>
+This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>,
+except that it sets a new message handler <code>msgh</code>.
+
+
+
+
+
+
+
+<h2>6.2 &ndash; <a name="6.2">Coroutine Manipulation</a></h2>
+
+<p>
+The operations related to coroutines comprise a sub-library of
+the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
+See <a href="#2.6">&sect;2.6</a> for a general description of coroutines.
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.create"><code>coroutine.create (f)</code></a></h3>
+
+
+<p>
+Creates a new coroutine, with body <code>f</code>.
+<code>f</code> must be a Lua function.
+Returns this new coroutine,
+an object with type <code>"thread"</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, &middot;&middot;&middot;])</code></a></h3>
+
+
+<p>
+Starts or continues the execution of coroutine <code>co</code>.
+The first time you resume a coroutine,
+it starts running its body.
+The values <code>val1</code>, ... are passed
+as the arguments to the body function.
+If the coroutine has yielded,
+<code>resume</code> restarts it;
+the values <code>val1</code>, ... are passed
+as the results from the yield.
+
+
+<p>
+If the coroutine runs without any errors,
+<code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code>
+(if the coroutine yields) or any values returned by the body function
+(if the coroutine terminates).
+If there is any error,
+<code>resume</code> returns <b>false</b> plus the error message.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.running"><code>coroutine.running ()</code></a></h3>
+
+
+<p>
+Returns the running coroutine plus a boolean,
+true when the running coroutine is the main one.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.status"><code>coroutine.status (co)</code></a></h3>
+
+
+<p>
+Returns the status of coroutine <code>co</code>, as a string:
+<code>"running"</code>,
+if the coroutine is running (that is, it called <code>status</code>);
+<code>"suspended"</code>, if the coroutine is suspended in a call to <code>yield</code>,
+or if it has not started running yet;
+<code>"normal"</code> if the coroutine is active but not running
+(that is, it has resumed another coroutine);
+and <code>"dead"</code> if the coroutine has finished its body function,
+or if it has stopped with an error.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.wrap"><code>coroutine.wrap (f)</code></a></h3>
+
+
+<p>
+Creates a new coroutine, with body <code>f</code>.
+<code>f</code> must be a Lua function.
+Returns a function that resumes the coroutine each time it is called.
+Any arguments passed to the function behave as the
+extra arguments to <code>resume</code>.
+Returns the same values returned by <code>resume</code>,
+except the first boolean.
+In case of error, propagates the error.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-coroutine.yield"><code>coroutine.yield (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Suspends the execution of the calling coroutine.
+Any arguments to <code>yield</code> are passed as extra results to <code>resume</code>.
+
+
+
+
+
+
+
+<h2>6.3 &ndash; <a name="6.3">Modules</a></h2>
+
+<p>
+The package library provides basic
+facilities for loading modules in Lua.
+It exports one function directly in the global environment:
+<a href="#pdf-require"><code>require</code></a>.
+Everything else is exported in a table <a name="pdf-package"><code>package</code></a>.
+
+
+<p>
+<hr><h3><a name="pdf-require"><code>require (modname)</code></a></h3>
+
+
+<p>
+Loads the given module.
+The function starts by looking into the <a href="#pdf-package.loaded"><code>package.loaded</code></a> table
+to determine whether <code>modname</code> is already loaded.
+If it is, then <code>require</code> returns the value stored
+at <code>package.loaded[modname]</code>.
+Otherwise, it tries to find a <em>loader</em> for the module.
+
+
+<p>
+To find a loader,
+<code>require</code> is guided by the <a href="#pdf-package.searchers"><code>package.searchers</code></a> sequence.
+By changing this sequence,
+we can change how <code>require</code> looks for a module.
+The following explanation is based on the default configuration
+for <a href="#pdf-package.searchers"><code>package.searchers</code></a>.
+
+
+<p>
+First <code>require</code> queries <code>package.preload[modname]</code>.
+If it has a value,
+this value (which should be a function) is the loader.
+Otherwise <code>require</code> searches for a Lua loader using the
+path stored in <a href="#pdf-package.path"><code>package.path</code></a>.
+If that also fails, it searches for a C&nbsp;loader using the
+path stored in <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
+If that also fails,
+it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.searchers"><code>package.searchers</code></a>).
+
+
+<p>
+Once a loader is found,
+<code>require</code> calls the loader with two arguments:
+<code>modname</code> and an extra value dependent on how it got the loader.
+(If the loader came from a file,
+this extra value is the file name.)
+If the loader returns any non-nil value,
+<code>require</code> assigns the returned value to <code>package.loaded[modname]</code>.
+If the loader does not return a non-nil value and
+has not assigned any value to <code>package.loaded[modname]</code>,
+then <code>require</code> assigns <b>true</b> to this entry.
+In any case, <code>require</code> returns the
+final value of <code>package.loaded[modname]</code>.
+
+
+<p>
+If there is any error loading or running the module,
+or if it cannot find any loader for the module,
+then <code>require</code> raises an error.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.config"><code>package.config</code></a></h3>
+
+
+<p>
+A string describing some compile-time configurations for packages.
+This string is a sequence of lines:
+
+<ul>
+
+<li>The first line is the directory separator string.
+Default is '<code>\</code>' for Windows and '<code>/</code>' for all other systems.</li>
+
+<li>The second line is the character that separates templates in a path.
+Default is '<code>;</code>'.</li>
+
+<li>The third line is the string that marks the
+substitution points in a template.
+Default is '<code>?</code>'.</li>
+
+<li>The fourth line is a string that, in a path in Windows,
+is replaced by the executable's directory.
+Default is '<code>!</code>'.</li>
+
+<li>The fifth line is a mark to ignore all text before it
+when building the <code>luaopen_</code> function name.
+Default is '<code>-</code>'.</li>
+
+</ul>
+
+
+
+<p>
+<hr><h3><a name="pdf-package.cpath"><code>package.cpath</code></a></h3>
+
+
+<p>
+The path used by <a href="#pdf-require"><code>require</code></a> to search for a C&nbsp;loader.
+
+
+<p>
+Lua initializes the C&nbsp;path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way
+it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>,
+using the environment variable <a name="pdf-LUA_CPATH_5_2"><code>LUA_CPATH_5_2</code></a>
+or the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>
+or a default path defined in <code>luaconf.h</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3>
+
+
+<p>
+A table used by <a href="#pdf-require"><code>require</code></a> to control which
+modules are already loaded.
+When you require a module <code>modname</code> and
+<code>package.loaded[modname]</code> is not false,
+<a href="#pdf-require"><code>require</code></a> simply returns the value stored there.
+
+
+<p>
+This variable is only a reference to the real table;
+assignments to this variable do not change the
+table used by <a href="#pdf-require"><code>require</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.loadlib"><code>package.loadlib (libname, funcname)</code></a></h3>
+
+
+<p>
+Dynamically links the host program with the C&nbsp;library <code>libname</code>.
+
+
+<p>
+If <code>funcname</code> is "<code>*</code>",
+then it only links with the library,
+making the symbols exported by the library
+available to other dynamically linked libraries.
+Otherwise,
+it looks for a function <code>funcname</code> inside the library
+and returns this function as a C&nbsp;function.
+So, <code>funcname</code> must follow the <a href="#lua_CFunction"><code>lua_CFunction</code></a> prototype
+(see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
+
+
+<p>
+This is a low-level function.
+It completely bypasses the package and module system.
+Unlike <a href="#pdf-require"><code>require</code></a>,
+it does not perform any path searching and
+does not automatically adds extensions.
+<code>libname</code> must be the complete file name of the C&nbsp;library,
+including if necessary a path and an extension.
+<code>funcname</code> must be the exact name exported by the C&nbsp;library
+(which may depend on the C&nbsp;compiler and linker used).
+
+
+<p>
+This function is not supported by Standard&nbsp;C.
+As such, it is only available on some platforms
+(Windows, Linux, Mac OS X, Solaris, BSD,
+plus other Unix systems that support the <code>dlfcn</code> standard).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.path"><code>package.path</code></a></h3>
+
+
+<p>
+The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader.
+
+
+<p>
+At start-up, Lua initializes this variable with
+the value of the environment variable <a name="pdf-LUA_PATH_5_2"><code>LUA_PATH_5_2</code></a> or
+the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or
+with a default path defined in <code>luaconf.h</code>,
+if those environment variables are not defined.
+Any "<code>;;</code>" in the value of the environment variable
+is replaced by the default path.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.preload"><code>package.preload</code></a></h3>
+
+
+<p>
+A table to store loaders for specific modules
+(see <a href="#pdf-require"><code>require</code></a>).
+
+
+<p>
+This variable is only a reference to the real table;
+assignments to this variable do not change the
+table used by <a href="#pdf-require"><code>require</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.searchers"><code>package.searchers</code></a></h3>
+
+
+<p>
+A table used by <a href="#pdf-require"><code>require</code></a> to control how to load modules.
+
+
+<p>
+Each entry in this table is a <em>searcher function</em>.
+When looking for a module,
+<a href="#pdf-require"><code>require</code></a> calls each of these searchers in ascending order,
+with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its
+sole parameter.
+The function can return another function (the module <em>loader</em>)
+plus an extra value that will be passed to that loader,
+or a string explaining why it did not find that module
+(or <b>nil</b> if it has nothing to say).
+
+
+<p>
+Lua initializes this table with four searcher functions.
+
+
+<p>
+The first searcher simply looks for a loader in the
+<a href="#pdf-package.preload"><code>package.preload</code></a> table.
+
+
+<p>
+The second searcher looks for a loader as a Lua library,
+using the path stored at <a href="#pdf-package.path"><code>package.path</code></a>.
+The search is done as described in function <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+
+
+<p>
+The third searcher looks for a loader as a C&nbsp;library,
+using the path given by the variable <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
+Again,
+the search is done as described in function <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+For instance,
+if the C&nbsp;path is the string
+
+<pre>
+     "./?.so;./?.dll;/usr/local/?/init.so"
+</pre><p>
+the searcher for module <code>foo</code>
+will try to open the files <code>./foo.so</code>, <code>./foo.dll</code>,
+and <code>/usr/local/foo/init.so</code>, in that order.
+Once it finds a C&nbsp;library,
+this searcher first uses a dynamic link facility to link the
+application with the library.
+Then it tries to find a C&nbsp;function inside the library to
+be used as the loader.
+The name of this C&nbsp;function is the string "<code>luaopen_</code>"
+concatenated with a copy of the module name where each dot
+is replaced by an underscore.
+Moreover, if the module name has a hyphen,
+its prefix up to (and including) the first hyphen is removed.
+For instance, if the module name is <code>a.v1-b.c</code>,
+the function name will be <code>luaopen_b_c</code>.
+
+
+<p>
+The fourth searcher tries an <em>all-in-one loader</em>.
+It searches the C&nbsp;path for a library for
+the root name of the given module.
+For instance, when requiring <code>a.b.c</code>,
+it will search for a C&nbsp;library for <code>a</code>.
+If found, it looks into it for an open function for
+the submodule;
+in our example, that would be <code>luaopen_a_b_c</code>.
+With this facility, a package can pack several C&nbsp;submodules
+into one single library,
+with each submodule keeping its original open function.
+
+
+<p>
+All searchers except the first one (preload) return as the extra value
+the file name where the module was found,
+as returned by <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>.
+The first searcher returns no extra value.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path [, sep [, rep]])</code></a></h3>
+
+
+<p>
+Searches for the given <code>name</code> in the given <code>path</code>.
+
+
+<p>
+A path is a string containing a sequence of
+<em>templates</em> separated by semicolons.
+For each template,
+the function replaces each interrogation mark (if any)
+in the template with a copy of <code>name</code>
+wherein all occurrences of <code>sep</code>
+(a dot, by default)
+were replaced by <code>rep</code>
+(the system's directory separator, by default),
+and then tries to open the resulting file name.
+
+
+<p>
+For instance, if the path is the string
+
+<pre>
+     "./?.lua;./?.lc;/usr/local/?/init.lua"
+</pre><p>
+the search for the name <code>foo.a</code>
+will try to open the files
+<code>./foo/a.lua</code>, <code>./foo/a.lc</code>, and
+<code>/usr/local/foo/a/init.lua</code>, in that order.
+
+
+<p>
+Returns the resulting name of the first file that it can
+open in read mode (after closing the file),
+or <b>nil</b> plus an error message if none succeeds.
+(This error message lists all file names it tried to open.)
+
+
+
+
+
+
+
+<h2>6.4 &ndash; <a name="6.4">String Manipulation</a></h2>
+
+<p>
+This library provides generic functions for string manipulation,
+such as finding and extracting substrings, and pattern matching.
+When indexing a string in Lua, the first character is at position&nbsp;1
+(not at&nbsp;0, as in C).
+Indices are allowed to be negative and are interpreted as indexing backwards,
+from the end of the string.
+Thus, the last character is at position -1, and so on.
+
+
+<p>
+The string library provides all its functions inside the table
+<a name="pdf-string"><code>string</code></a>.
+It also sets a metatable for strings
+where the <code>__index</code> field points to the <code>string</code> table.
+Therefore, you can use the string functions in object-oriented style.
+For instance, <code>string.byte(s,i)</code>
+can be written as <code>s:byte(i)</code>.
+
+
+<p>
+The string library assumes one-byte character encodings.
+
+
+<p>
+<hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
+Returns the internal numerical codes of the characters <code>s[i]</code>,
+<code>s[i+1]</code>, ..., <code>s[j]</code>.
+The default value for <code>i</code> is&nbsp;1;
+the default value for <code>j</code> is&nbsp;<code>i</code>.
+These indices are corrected
+following the same rules of function <a href="#pdf-string.sub"><code>string.sub</code></a>.
+
+
+<p>
+Numerical codes are not necessarily portable across platforms.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.char"><code>string.char (&middot;&middot;&middot;)</code></a></h3>
+Receives zero or more integers.
+Returns a string with length equal to the number of arguments,
+in which each character has the internal numerical code equal
+to its corresponding argument.
+
+
+<p>
+Numerical codes are not necessarily portable across platforms.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3>
+
+
+<p>
+Returns a string containing a binary representation of the given function,
+so that a later <a href="#pdf-load"><code>load</code></a> on this string returns
+a copy of the function (but with new upvalues).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3>
+
+
+<p>
+Looks for the first match of
+<code>pattern</code> in the string <code>s</code>.
+If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
+where this occurrence starts and ends;
+otherwise, it returns <b>nil</b>.
+A third, optional numerical argument <code>init</code> specifies
+where to start the search;
+its default value is&nbsp;1 and can be negative.
+A value of <b>true</b> as a fourth, optional argument <code>plain</code>
+turns off the pattern matching facilities,
+so the function does a plain "find substring" operation,
+with no characters in <code>pattern</code> being considered magic.
+Note that if <code>plain</code> is given, then <code>init</code> must be given as well.
+
+
+<p>
+If the pattern has captures,
+then in a successful match
+the captured values are also returned,
+after the two indices.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.format"><code>string.format (formatstring, &middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns a formatted version of its variable number of arguments
+following the description given in its first argument (which must be a string).
+The format string follows the same rules as the ANSI&nbsp;C function <code>sprintf</code>.
+The only differences are that the options/modifiers
+<code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, <code>n</code>,
+and <code>p</code> are not supported
+and that there is an extra option, <code>q</code>.
+The <code>q</code> option formats a string between double quotes,
+using escape sequences when necessary to ensure that
+it can safely be read back by the Lua interpreter.
+For instance, the call
+
+<pre>
+     string.format('%q', 'a string with "quotes" and \n new line')
+</pre><p>
+may produce the string:
+
+<pre>
+     "a string with \"quotes\" and \
+      new line"
+</pre>
+
+<p>
+Options
+<code>A</code> and <code>a</code> (when available),
+<code>E</code>, <code>e</code>, <code>f</code>,
+<code>G</code>, and <code>g</code> all expect a number as argument.
+Options <code>c</code>, <code>d</code>,
+<code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>
+also expect a number,
+but the range of that number may be limited by
+the underlying C&nbsp;implementation.
+For options <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>,
+the number cannot be negative.
+Option <code>q</code> expects a string;
+option <code>s</code> expects a string without embedded zeros.
+If the argument to option <code>s</code> is not a string,
+it is converted to one following the same rules of <a href="#pdf-tostring"><code>tostring</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
+Returns an iterator function that,
+each time it is called,
+returns the next captures from <code>pattern</code> over the string <code>s</code>.
+If <code>pattern</code> specifies no captures,
+then the whole match is produced in each call.
+
+
+<p>
+As an example, the following loop
+will iterate over all the words from string <code>s</code>,
+printing one per line:
+
+<pre>
+     s = "hello world from Lua"
+     for w in string.gmatch(s, "%a+") do
+       print(w)
+     end
+</pre><p>
+The next example collects all pairs <code>key=value</code> from the
+given string into a table:
+
+<pre>
+     t = {}
+     s = "from=world, to=Lua"
+     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
+       t[k] = v
+     end
+</pre>
+
+<p>
+For this function, a caret '<code>^</code>' at the start of a pattern does not
+work as an anchor, as this would prevent the iteration.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3>
+Returns a copy of <code>s</code>
+in which all (or the first <code>n</code>, if given)
+occurrences of the <code>pattern</code> have been
+replaced by a replacement string specified by <code>repl</code>,
+which can be a string, a table, or a function.
+<code>gsub</code> also returns, as its second value,
+the total number of matches that occurred.
+The name <code>gsub</code> comes from <em>Global SUBstitution</em>.
+
+
+<p>
+If <code>repl</code> is a string, then its value is used for replacement.
+The character&nbsp;<code>%</code> works as an escape character:
+any sequence in <code>repl</code> of the form <code>%<em>d</em></code>,
+with <em>d</em> between 1 and 9,
+stands for the value of the <em>d</em>-th captured substring.
+The sequence <code>%0</code> stands for the whole match.
+The sequence <code>%%</code> stands for a single&nbsp;<code>%</code>.
+
+
+<p>
+If <code>repl</code> is a table, then the table is queried for every match,
+using the first capture as the key.
+
+
+<p>
+If <code>repl</code> is a function, then this function is called every time a
+match occurs, with all captured substrings passed as arguments,
+in order.
+
+
+<p>
+In any case,
+if the pattern specifies no captures,
+then it behaves as if the whole pattern was inside a capture.
+
+
+<p>
+If the value returned by the table query or by the function call
+is a string or a number,
+then it is used as the replacement string;
+otherwise, if it is <b>false</b> or <b>nil</b>,
+then there is no replacement
+(that is, the original match is kept in the string).
+
+
+<p>
+Here are some examples:
+
+<pre>
+     x = string.gsub("hello world", "(%w+)", "%1 %1")
+     --&gt; x="hello hello world world"
+     
+     x = string.gsub("hello world", "%w+", "%0 %0", 1)
+     --&gt; x="hello hello world"
+     
+     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
+     --&gt; x="world hello Lua from"
+     
+     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
+     --&gt; x="home = /home/roberto, user = roberto"
+     
+     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
+           return load(s)()
+         end)
+     --&gt; x="4+5 = 9"
+     
+     local t = {name="lua", version="5.2"}
+     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
+     --&gt; x="lua-5.2.tar.gz"
+</pre>
+
+
+
+<p>
+<hr><h3><a name="pdf-string.len"><code>string.len (s)</code></a></h3>
+Receives a string and returns its length.
+The empty string <code>""</code> has length 0.
+Embedded zeros are counted,
+so <code>"a\000bc\000"</code> has length 5.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.lower"><code>string.lower (s)</code></a></h3>
+Receives a string and returns a copy of this string with all
+uppercase letters changed to lowercase.
+All other characters are left unchanged.
+The definition of what an uppercase letter is depends on the current locale.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3>
+Looks for the first <em>match</em> of
+<code>pattern</code> in the string <code>s</code>.
+If it finds one, then <code>match</code> returns
+the captures from the pattern;
+otherwise it returns <b>nil</b>.
+If <code>pattern</code> specifies no captures,
+then the whole match is returned.
+A third, optional numerical argument <code>init</code> specifies
+where to start the search;
+its default value is&nbsp;1 and can be negative.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3>
+Returns a string that is the concatenation of <code>n</code> copies of
+the string <code>s</code> separated by the string <code>sep</code>.
+The default value for <code>sep</code> is the empty string
+(that is, no separator).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.reverse"><code>string.reverse (s)</code></a></h3>
+Returns a string that is the string <code>s</code> reversed.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.sub"><code>string.sub (s, i [, j])</code></a></h3>
+Returns the substring of <code>s</code> that
+starts at <code>i</code>  and continues until <code>j</code>;
+<code>i</code> and <code>j</code> can be negative.
+If <code>j</code> is absent, then it is assumed to be equal to -1
+(which is the same as the string length).
+In particular,
+the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code>
+with length <code>j</code>,
+and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code>
+with length <code>i</code>.
+
+
+<p>
+If, after the translation of negative indices,
+<code>i</code> is less than 1,
+it is corrected to 1.
+If <code>j</code> is greater than the string length,
+it is corrected to that length.
+If, after these corrections,
+<code>i</code> is greater than <code>j</code>,
+the function returns the empty string.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3>
+Receives a string and returns a copy of this string with all
+lowercase letters changed to uppercase.
+All other characters are left unchanged.
+The definition of what a lowercase letter is depends on the current locale.
+
+
+
+<h3>6.4.1 &ndash; <a name="6.4.1">Patterns</a></h3>
+
+
+<h4>Character Class:</h4><p>
+A <em>character class</em> is used to represent a set of characters.
+The following combinations are allowed in describing a character class:
+
+<ul>
+
+<li><b><em>x</em>: </b>
+(where <em>x</em> is not one of the <em>magic characters</em>
+<code>^$()%.[]*+-?</code>)
+represents the character <em>x</em> itself.
+</li>
+
+<li><b><code>.</code>: </b> (a dot) represents all characters.</li>
+
+<li><b><code>%a</code>: </b> represents all letters.</li>
+
+<li><b><code>%c</code>: </b> represents all control characters.</li>
+
+<li><b><code>%d</code>: </b> represents all digits.</li>
+
+<li><b><code>%g</code>: </b> represents all printable characters except space.</li>
+
+<li><b><code>%l</code>: </b> represents all lowercase letters.</li>
+
+<li><b><code>%p</code>: </b> represents all punctuation characters.</li>
+
+<li><b><code>%s</code>: </b> represents all space characters.</li>
+
+<li><b><code>%u</code>: </b> represents all uppercase letters.</li>
+
+<li><b><code>%w</code>: </b> represents all alphanumeric characters.</li>
+
+<li><b><code>%x</code>: </b> represents all hexadecimal digits.</li>
+
+<li><b><code>%<em>x</em></code>: </b> (where <em>x</em> is any non-alphanumeric character)
+represents the character <em>x</em>.
+This is the standard way to escape the magic characters.
+Any punctuation character (even the non magic)
+can be preceded by a '<code>%</code>'
+when used to represent itself in a pattern.
+</li>
+
+<li><b><code>[<em>set</em>]</code>: </b>
+represents the class which is the union of all
+characters in <em>set</em>.
+A range of characters can be specified by
+separating the end characters of the range,
+in ascending order, with a '<code>-</code>',
+All classes <code>%</code><em>x</em> described above can also be used as
+components in <em>set</em>.
+All other characters in <em>set</em> represent themselves.
+For example, <code>[%w_]</code> (or <code>[_%w]</code>)
+represents all alphanumeric characters plus the underscore,
+<code>[0-7]</code> represents the octal digits,
+and <code>[0-7%l%-]</code> represents the octal digits plus
+the lowercase letters plus the '<code>-</code>' character.
+
+
+<p>
+The interaction between ranges and classes is not defined.
+Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code>
+have no meaning.
+</li>
+
+<li><b><code>[^<em>set</em>]</code>: </b>
+represents the complement of <em>set</em>,
+where <em>set</em> is interpreted as above.
+</li>
+
+</ul><p>
+For all classes represented by single letters (<code>%a</code>, <code>%c</code>, etc.),
+the corresponding uppercase letter represents the complement of the class.
+For instance, <code>%S</code> represents all non-space characters.
+
+
+<p>
+The definitions of letter, space, and other character groups
+depend on the current locale.
+In particular, the class <code>[a-z]</code> may not be equivalent to <code>%l</code>.
+
+
+
+
+
+<h4>Pattern Item:</h4><p>
+A <em>pattern item</em> can be
+
+<ul>
+
+<li>
+a single character class,
+which matches any single character in the class;
+</li>
+
+<li>
+a single character class followed by '<code>*</code>',
+which matches 0 or more repetitions of characters in the class.
+These repetition items will always match the longest possible sequence;
+</li>
+
+<li>
+a single character class followed by '<code>+</code>',
+which matches 1 or more repetitions of characters in the class.
+These repetition items will always match the longest possible sequence;
+</li>
+
+<li>
+a single character class followed by '<code>-</code>',
+which also matches 0 or more repetitions of characters in the class.
+Unlike '<code>*</code>',
+these repetition items will always match the shortest possible sequence;
+</li>
+
+<li>
+a single character class followed by '<code>?</code>',
+which matches 0 or 1 occurrence of a character in the class;
+</li>
+
+<li>
+<code>%<em>n</em></code>, for <em>n</em> between 1 and 9;
+such item matches a substring equal to the <em>n</em>-th captured string
+(see below);
+</li>
+
+<li>
+<code>%b<em>xy</em></code>, where <em>x</em> and <em>y</em> are two distinct characters;
+such item matches strings that start with&nbsp;<em>x</em>, end with&nbsp;<em>y</em>,
+and where the <em>x</em> and <em>y</em> are <em>balanced</em>.
+This means that, if one reads the string from left to right,
+counting <em>+1</em> for an <em>x</em> and <em>-1</em> for a <em>y</em>,
+the ending <em>y</em> is the first <em>y</em> where the count reaches 0.
+For instance, the item <code>%b()</code> matches expressions with
+balanced parentheses.
+</li>
+
+<li>
+<code>%f[<em>set</em>]</code>, a <em>frontier pattern</em>;
+such item matches an empty string at any position such that
+the next character belongs to <em>set</em>
+and the previous character does not belong to <em>set</em>.
+The set <em>set</em> is interpreted as previously described.
+The beginning and the end of the subject are handled as if
+they were the character '<code>\0</code>'.
+</li>
+
+</ul>
+
+
+
+
+<h4>Pattern:</h4><p>
+A <em>pattern</em> is a sequence of pattern items.
+A caret '<code>^</code>' at the beginning of a pattern anchors the match at the
+beginning of the subject string.
+A '<code>$</code>' at the end of a pattern anchors the match at the
+end of the subject string.
+At other positions,
+'<code>^</code>' and '<code>$</code>' have no special meaning and represent themselves.
+
+
+
+
+
+<h4>Captures:</h4><p>
+A pattern can contain sub-patterns enclosed in parentheses;
+they describe <em>captures</em>.
+When a match succeeds, the substrings of the subject string
+that match captures are stored (<em>captured</em>) for future use.
+Captures are numbered according to their left parentheses.
+For instance, in the pattern <code>"(a*(.)%w(%s*))"</code>,
+the part of the string matching <code>"a*(.)%w(%s*)"</code> is
+stored as the first capture (and therefore has number&nbsp;1);
+the character matching "<code>.</code>" is captured with number&nbsp;2,
+and the part matching "<code>%s*</code>" has number&nbsp;3.
+
+
+<p>
+As a special case, the empty capture <code>()</code> captures
+the current string position (a number).
+For instance, if we apply the pattern <code>"()aa()"</code> on the
+string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
+
+
+
+
+
+
+
+
+
+
+
+<h2>6.5 &ndash; <a name="6.5">Table Manipulation</a></h2>
+
+<p>
+This library provides generic functions for table manipulation.
+It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>.
+
+
+<p>
+Remember that, whenever an operation needs the length of a table,
+the table should be a proper sequence
+or have a <code>__len</code> metamethod (see <a href="#3.4.6">&sect;3.4.6</a>).
+All functions ignore non-numeric keys
+in tables given as arguments.
+
+
+<p>
+For performance reasons,
+all table accesses (get/set) performed by these functions are raw.
+
+
+<p>
+<hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3>
+
+
+<p>
+Given a list where all elements are strings or numbers,
+returns the string <code>list[i]..sep..list[i+1] &middot;&middot;&middot; sep..list[j]</code>.
+The default value for <code>sep</code> is the empty string,
+the default for <code>i</code> is 1,
+and the default for <code>j</code> is <code>#list</code>.
+If <code>i</code> is greater than <code>j</code>, returns the empty string.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3>
+
+
+<p>
+Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>,
+shifting up the elements
+<code>list[pos], list[pos+1], &middot;&middot;&middot;, list[#list]</code>.
+The default value for <code>pos</code> is <code>#list+1</code>,
+so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end
+of list <code>t</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-table.pack"><code>table.pack (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns a new table with all parameters stored into keys 1, 2, etc.
+and with a field "<code>n</code>" with the total number of parameters.
+Note that the resulting table may not be a sequence.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-table.remove"><code>table.remove (list [, pos])</code></a></h3>
+
+
+<p>
+Removes from <code>list</code> the element at position <code>pos</code>,
+returning the value of the removed element.
+When <code>pos</code> is an integer between 1 and <code>#list</code>,
+it shifts down the elements
+<code>list[pos+1], list[pos+2], &middot;&middot;&middot;, list[#list]</code>
+and erases element <code>list[#list]</code>;
+The index <code>pos</code> can also be 0 when <code>#list</code> is 0,
+or <code>#list + 1</code>;
+in those cases, the function erases the element <code>list[pos]</code>.
+
+
+<p>
+The default value for <code>pos</code> is <code>#list</code>,
+so that a call <code>table.remove(t)</code> removes the last element
+of list <code>t</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-table.sort"><code>table.sort (list [, comp])</code></a></h3>
+
+
+<p>
+Sorts list elements in a given order, <em>in-place</em>,
+from <code>list[1]</code> to <code>list[#list]</code>.
+If <code>comp</code> is given,
+then it must be a function that receives two list elements
+and returns true when the first element must come
+before the second in the final order
+(so that <code>not comp(list[i+1],list[i])</code> will be true after the sort).
+If <code>comp</code> is not given,
+then the standard Lua operator <code>&lt;</code> is used instead.
+
+
+<p>
+The sort algorithm is not stable;
+that is, elements considered equal by the given order
+may have their relative positions changed by the sort.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-table.unpack"><code>table.unpack (list [, i [, j]])</code></a></h3>
+
+
+<p>
+Returns the elements from the given table.
+This function is equivalent to
+
+<pre>
+     return list[i], list[i+1], &middot;&middot;&middot;, list[j]
+</pre><p>
+By default, <code>i</code> is&nbsp;1 and <code>j</code> is <code>#list</code>.
+
+
+
+
+
+
+
+<h2>6.6 &ndash; <a name="6.6">Mathematical Functions</a></h2>
+
+<p>
+This library is an interface to the standard C&nbsp;math library.
+It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>.
+
+
+<p>
+<hr><h3><a name="pdf-math.abs"><code>math.abs (x)</code></a></h3>
+
+
+<p>
+Returns the absolute value of <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.acos"><code>math.acos (x)</code></a></h3>
+
+
+<p>
+Returns the arc cosine of <code>x</code> (in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.asin"><code>math.asin (x)</code></a></h3>
+
+
+<p>
+Returns the arc sine of <code>x</code> (in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.atan"><code>math.atan (x)</code></a></h3>
+
+
+<p>
+Returns the arc tangent of <code>x</code> (in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.atan2"><code>math.atan2 (y, x)</code></a></h3>
+
+
+<p>
+Returns the arc tangent of <code>y/x</code> (in radians),
+but uses the signs of both parameters to find the
+quadrant of the result.
+(It also handles correctly the case of <code>x</code> being zero.)
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3>
+
+
+<p>
+Returns the smallest integer larger than or equal to <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.cos"><code>math.cos (x)</code></a></h3>
+
+
+<p>
+Returns the cosine of <code>x</code> (assumed to be in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.cosh"><code>math.cosh (x)</code></a></h3>
+
+
+<p>
+Returns the hyperbolic cosine of <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3>
+
+
+<p>
+Returns the angle <code>x</code> (given in radians) in degrees.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3>
+
+
+<p>
+Returns the value <em>e<sup>x</sup></em>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3>
+
+
+<p>
+Returns the largest integer smaller than or equal to <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.fmod"><code>math.fmod (x, y)</code></a></h3>
+
+
+<p>
+Returns the remainder of the division of <code>x</code> by <code>y</code>
+that rounds the quotient towards zero.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3>
+
+
+<p>
+Returns <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>,
+<code>e</code> is an integer and the absolute value of <code>m</code> is
+in the range <em>[0.5, 1)</em>
+(or zero when <code>x</code> is zero).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3>
+
+
+<p>
+The value <code>HUGE_VAL</code>,
+a value larger than or equal to any other numerical value.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3>
+
+
+<p>
+Returns <em>m2<sup>e</sup></em> (<code>e</code> should be an integer).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.log"><code>math.log (x [, base])</code></a></h3>
+
+
+<p>
+Returns the logarithm of <code>x</code> in the given base.
+The default for <code>base</code> is <em>e</em>
+(so that the function returns the natural logarithm of <code>x</code>).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.max"><code>math.max (x, &middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns the maximum value among its arguments.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.min"><code>math.min (x, &middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns the minimum value among its arguments.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3>
+
+
+<p>
+Returns two numbers,
+the integral part of <code>x</code> and the fractional part of <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.pi"><code>math.pi</code></a></h3>
+
+
+<p>
+The value of <em>&pi;</em>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.pow"><code>math.pow (x, y)</code></a></h3>
+
+
+<p>
+Returns <em>x<sup>y</sup></em>.
+(You can also use the expression <code>x^y</code> to compute this value.)
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3>
+
+
+<p>
+Returns the angle <code>x</code> (given in degrees) in radians.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.random"><code>math.random ([m [, n]])</code></a></h3>
+
+
+<p>
+This function is an interface to the simple
+pseudo-random generator function <code>rand</code> provided by Standard&nbsp;C.
+(No guarantees can be given for its statistical properties.)
+
+
+<p>
+When called without arguments,
+returns a uniform pseudo-random real number
+in the range <em>[0,1)</em>.  
+When called with an integer number <code>m</code>,
+<code>math.random</code> returns
+a uniform pseudo-random integer in the range <em>[1, m]</em>.
+When called with two integer numbers <code>m</code> and <code>n</code>,
+<code>math.random</code> returns a uniform pseudo-random
+integer in the range <em>[m, n]</em>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.randomseed"><code>math.randomseed (x)</code></a></h3>
+
+
+<p>
+Sets <code>x</code> as the "seed"
+for the pseudo-random generator:
+equal seeds produce equal sequences of numbers.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.sin"><code>math.sin (x)</code></a></h3>
+
+
+<p>
+Returns the sine of <code>x</code> (assumed to be in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.sinh"><code>math.sinh (x)</code></a></h3>
+
+
+<p>
+Returns the hyperbolic sine of <code>x</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3>
+
+
+<p>
+Returns the square root of <code>x</code>.
+(You can also use the expression <code>x^0.5</code> to compute this value.)
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.tan"><code>math.tan (x)</code></a></h3>
+
+
+<p>
+Returns the tangent of <code>x</code> (assumed to be in radians).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-math.tanh"><code>math.tanh (x)</code></a></h3>
+
+
+<p>
+Returns the hyperbolic tangent of <code>x</code>.
+
+
+
+
+
+
+
+<h2>6.7 &ndash; <a name="6.7">Bitwise Operations</a></h2>
+
+<p>
+This library provides bitwise operations.
+It provides all its functions inside the table <a name="pdf-bit32"><code>bit32</code></a>.
+
+
+<p>
+Unless otherwise stated,
+all functions accept numeric arguments in the range
+<em>(-2<sup>51</sup>,+2<sup>51</sup>)</em>;
+each argument is normalized to
+the remainder of its division by <em>2<sup>32</sup></em>
+and truncated to an integer (in some unspecified way),
+so that its final value falls in the range <em>[0,2<sup>32</sup> - 1]</em>.
+Similarly, all results are in the range <em>[0,2<sup>32</sup> - 1]</em>.
+Note that <code>bit32.bnot(0)</code> is <code>0xFFFFFFFF</code>,
+which is different from <code>-1</code>.
+
+
+<p>
+<hr><h3><a name="pdf-bit32.arshift"><code>bit32.arshift (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> shifted <code>disp</code> bits to the right.
+The number <code>disp</code> may be any representable integer.
+Negative displacements shift to the left.
+
+
+<p>
+This shift operation is what is called arithmetic shift.
+Vacant bits on the left are filled
+with copies of the higher bit of <code>x</code>;
+vacant bits on the right are filled with zeros.
+In particular,
+displacements with absolute values higher than 31
+result in zero or <code>0xFFFFFFFF</code> (all original bits are shifted out).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.band"><code>bit32.band (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns the bitwise <em>and</em> of its operands.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.bnot"><code>bit32.bnot (x)</code></a></h3>
+
+
+<p>
+Returns the bitwise negation of <code>x</code>.
+For any integer <code>x</code>,
+the following identity holds:
+
+<pre>
+     assert(bit32.bnot(x) == (-1 - x) % 2^32)
+</pre>
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.bor"><code>bit32.bor (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns the bitwise <em>or</em> of its operands.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.btest"><code>bit32.btest (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns a boolean signaling
+whether the bitwise <em>and</em> of its operands is different from zero.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.bxor"><code>bit32.bxor (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns the bitwise <em>exclusive or</em> of its operands.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.extract"><code>bit32.extract (n, field [, width])</code></a></h3>
+
+
+<p>
+Returns the unsigned number formed by the bits
+<code>field</code> to <code>field + width - 1</code> from <code>n</code>.
+Bits are numbered from 0 (least significant) to 31 (most significant).
+All accessed bits must be in the range <em>[0, 31]</em>.
+
+
+<p>
+The default for <code>width</code> is 1.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.replace"><code>bit32.replace (n, v, field [, width])</code></a></h3>
+
+
+<p>
+Returns a copy of <code>n</code> with
+the bits <code>field</code> to <code>field + width - 1</code>
+replaced by the value <code>v</code>.
+See <a href="#pdf-bit32.extract"><code>bit32.extract</code></a> for details about <code>field</code> and <code>width</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.lrotate"><code>bit32.lrotate (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> rotated <code>disp</code> bits to the left.
+The number <code>disp</code> may be any representable integer.
+
+
+<p>
+For any valid displacement,
+the following identity holds:
+
+<pre>
+     assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32))
+</pre><p>
+In particular,
+negative displacements rotate to the right.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.lshift"><code>bit32.lshift (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> shifted <code>disp</code> bits to the left.
+The number <code>disp</code> may be any representable integer.
+Negative displacements shift to the right.
+In any direction, vacant bits are filled with zeros.
+In particular,
+displacements with absolute values higher than 31
+result in zero (all bits are shifted out).
+
+
+<p>
+For positive displacements,
+the following equality holds:
+
+<pre>
+     assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)
+</pre>
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.rrotate"><code>bit32.rrotate (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> rotated <code>disp</code> bits to the right.
+The number <code>disp</code> may be any representable integer.
+
+
+<p>
+For any valid displacement,
+the following identity holds:
+
+<pre>
+     assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32))
+</pre><p>
+In particular,
+negative displacements rotate to the left.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-bit32.rshift"><code>bit32.rshift (x, disp)</code></a></h3>
+
+
+<p>
+Returns the number <code>x</code> shifted <code>disp</code> bits to the right.
+The number <code>disp</code> may be any representable integer.
+Negative displacements shift to the left.
+In any direction, vacant bits are filled with zeros.
+In particular,
+displacements with absolute values higher than 31
+result in zero (all bits are shifted out).
+
+
+<p>
+For positive displacements,
+the following equality holds:
+
+<pre>
+     assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))
+</pre>
+
+<p>
+This shift operation is what is called logical shift.
+
+
+
+
+
+
+
+<h2>6.8 &ndash; <a name="6.8">Input and Output Facilities</a></h2>
+
+<p>
+The I/O library provides two different styles for file manipulation.
+The first one uses implicit file descriptors;
+that is, there are operations to set a default input file and a
+default output file,
+and all input/output operations are over these default files.
+The second style uses explicit file descriptors.
+
+
+<p>
+When using implicit file descriptors,
+all operations are supplied by table <a name="pdf-io"><code>io</code></a>.
+When using explicit file descriptors,
+the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor
+and then all operations are supplied as methods of the file descriptor.
+
+
+<p>
+The table <code>io</code> also provides
+three predefined file descriptors with their usual meanings from C:
+<a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>.
+The I/O library never closes these files.
+
+
+<p>
+Unless otherwise stated,
+all I/O functions return <b>nil</b> on failure
+(plus an error message as a second result and
+a system-dependent error code as a third result)
+and some value different from <b>nil</b> on success.
+On non-Posix systems,
+the computation of the error message and error code
+in case of errors
+may be not thread safe,
+because they rely on the global C variable <code>errno</code>.
+
+
+<p>
+<hr><h3><a name="pdf-io.close"><code>io.close ([file])</code></a></h3>
+
+
+<p>
+Equivalent to <code>file:close()</code>.
+Without a <code>file</code>, closes the default output file.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.flush"><code>io.flush ()</code></a></h3>
+
+
+<p>
+Equivalent to <code>io.output():flush()</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.input"><code>io.input ([file])</code></a></h3>
+
+
+<p>
+When called with a file name, it opens the named file (in text mode),
+and sets its handle as the default input file.
+When called with a file handle,
+it simply sets this file handle as the default input file.
+When called without parameters,
+it returns the current default input file.
+
+
+<p>
+In case of errors this function raises the error,
+instead of returning an error code.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename &middot;&middot;&middot;])</code></a></h3>
+
+
+<p>
+Opens the given file name in read mode
+and returns an iterator function that
+works like <code>file:lines(&middot;&middot;&middot;)</code> over the opened file.
+When the iterator function detects the end of file,
+it returns <b>nil</b> (to finish the loop) and automatically closes the file.
+
+
+<p>
+The call <code>io.lines()</code> (with no file name) is equivalent
+to <code>io.input():lines()</code>;
+that is, it iterates over the lines of the default input file.
+In this case it does not close the file when the loop ends.
+
+
+<p>
+In case of errors this function raises the error,
+instead of returning an error code.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.open"><code>io.open (filename [, mode])</code></a></h3>
+
+
+<p>
+This function opens a file,
+in the mode specified in the string <code>mode</code>.
+It returns a new file handle,
+or, in case of errors, <b>nil</b> plus an error message.
+
+
+<p>
+The <code>mode</code> string can be any of the following:
+
+<ul>
+<li><b>"<code>r</code>": </b> read mode (the default);</li>
+<li><b>"<code>w</code>": </b> write mode;</li>
+<li><b>"<code>a</code>": </b> append mode;</li>
+<li><b>"<code>r+</code>": </b> update mode, all previous data is preserved;</li>
+<li><b>"<code>w+</code>": </b> update mode, all previous data is erased;</li>
+<li><b>"<code>a+</code>": </b> append update mode, previous data is preserved,
+  writing is only allowed at the end of file.</li>
+</ul><p>
+The <code>mode</code> string can also have a '<code>b</code>' at the end,
+which is needed in some systems to open the file in binary mode.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.output"><code>io.output ([file])</code></a></h3>
+
+
+<p>
+Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3>
+
+
+<p>
+This function is system dependent and is not available
+on all platforms.
+
+
+<p>
+Starts program <code>prog</code> in a separated process and returns
+a file handle that you can use to read data from this program
+(if <code>mode</code> is <code>"r"</code>, the default)
+or to write data to this program
+(if <code>mode</code> is <code>"w"</code>).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.read"><code>io.read (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Equivalent to <code>io.input():read(&middot;&middot;&middot;)</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.tmpfile"><code>io.tmpfile ()</code></a></h3>
+
+
+<p>
+Returns a handle for a temporary file.
+This file is opened in update mode
+and it is automatically removed when the program ends.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.type"><code>io.type (obj)</code></a></h3>
+
+
+<p>
+Checks whether <code>obj</code> is a valid file handle.
+Returns the string <code>"file"</code> if <code>obj</code> is an open file handle,
+<code>"closed file"</code> if <code>obj</code> is a closed file handle,
+or <b>nil</b> if <code>obj</code> is not a file handle.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-io.write"><code>io.write (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Equivalent to <code>io.output():write(&middot;&middot;&middot;)</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:close"><code>file:close ()</code></a></h3>
+
+
+<p>
+Closes <code>file</code>.
+Note that files are automatically closed when
+their handles are garbage collected,
+but that takes an unpredictable amount of time to happen.
+
+
+<p>
+When closing a file handle created with <a href="#pdf-io.popen"><code>io.popen</code></a>,
+<a href="#pdf-file:close"><code>file:close</code></a> returns the same values
+returned by <a href="#pdf-os.execute"><code>os.execute</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:flush"><code>file:flush ()</code></a></h3>
+
+
+<p>
+Saves any written data to <code>file</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:lines"><code>file:lines (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Returns an iterator function that,
+each time it is called,
+reads the file according to the given formats.
+When no format is given,
+uses "*l" as a default.
+As an example, the construction
+
+<pre>
+     for c in file:lines(1) do <em>body</em> end
+</pre><p>
+will iterate over all characters of the file,
+starting at the current position.
+Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
+when the loop ends.
+
+
+<p>
+In case of errors this function raises the error,
+instead of returning an error code.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:read"><code>file:read (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Reads the file <code>file</code>,
+according to the given formats, which specify what to read.
+For each format,
+the function returns a string (or a number) with the characters read,
+or <b>nil</b> if it cannot read data with the specified format.
+When called without formats,
+it uses a default format that reads the next line
+(see below).
+
+
+<p>
+The available formats are
+
+<ul>
+
+<li><b>"<code>*n</code>": </b>
+reads a number;
+this is the only format that returns a number instead of a string.
+</li>
+
+<li><b>"<code>*a</code>": </b>
+reads the whole file, starting at the current position.
+On end of file, it returns the empty string.
+</li>
+
+<li><b>"<code>*l</code>": </b>
+reads the next line skipping the end of line,
+returning <b>nil</b> on end of file.
+This is the default format.
+</li>
+
+<li><b>"<code>*L</code>": </b>
+reads the next line keeping the end of line (if present),
+returning <b>nil</b> on end of file.
+</li>
+
+<li><b><em>number</em>: </b>
+reads a string with up to this number of bytes,
+returning <b>nil</b> on end of file.
+If number is zero,
+it reads nothing and returns an empty string,
+or <b>nil</b> on end of file.
+</li>
+
+</ul>
+
+
+
+<p>
+<hr><h3><a name="pdf-file:seek"><code>file:seek ([whence [, offset]])</code></a></h3>
+
+
+<p>
+Sets and gets the file position,
+measured from the beginning of the file,
+to the position given by <code>offset</code> plus a base
+specified by the string <code>whence</code>, as follows:
+
+<ul>
+<li><b>"<code>set</code>": </b> base is position 0 (beginning of the file);</li>
+<li><b>"<code>cur</code>": </b> base is current position;</li>
+<li><b>"<code>end</code>": </b> base is end of file;</li>
+</ul><p>
+In case of success, <code>seek</code> returns the final file position,
+measured in bytes from the beginning of the file.
+If <code>seek</code> fails, it returns <b>nil</b>,
+plus a string describing the error.
+
+
+<p>
+The default value for <code>whence</code> is <code>"cur"</code>,
+and for <code>offset</code> is 0.
+Therefore, the call <code>file:seek()</code> returns the current
+file position, without changing it;
+the call <code>file:seek("set")</code> sets the position to the
+beginning of the file (and returns 0);
+and the call <code>file:seek("end")</code> sets the position to the
+end of the file, and returns its size.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:setvbuf"><code>file:setvbuf (mode [, size])</code></a></h3>
+
+
+<p>
+Sets the buffering mode for an output file.
+There are three available modes:
+
+<ul>
+
+<li><b>"<code>no</code>": </b>
+no buffering; the result of any output operation appears immediately.
+</li>
+
+<li><b>"<code>full</code>": </b>
+full buffering; output operation is performed only
+when the buffer is full or when
+you explicitly <code>flush</code> the file (see <a href="#pdf-io.flush"><code>io.flush</code></a>).
+</li>
+
+<li><b>"<code>line</code>": </b>
+line buffering; output is buffered until a newline is output
+or there is any input from some special files
+(such as a terminal device).
+</li>
+
+</ul><p>
+For the last two cases, <code>size</code>
+specifies the size of the buffer, in bytes.
+The default is an appropriate size.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-file:write"><code>file:write (&middot;&middot;&middot;)</code></a></h3>
+
+
+<p>
+Writes the value of each of its arguments to <code>file</code>.
+The arguments must be strings or numbers.
+
+
+<p>
+In case of success, this function returns <code>file</code>.
+Otherwise it returns <b>nil</b> plus a string describing the error.
+
+
+
+
+
+
+
+<h2>6.9 &ndash; <a name="6.9">Operating System Facilities</a></h2>
+
+<p>
+This library is implemented through table <a name="pdf-os"><code>os</code></a>.
+
+
+<p>
+<hr><h3><a name="pdf-os.clock"><code>os.clock ()</code></a></h3>
+
+
+<p>
+Returns an approximation of the amount in seconds of CPU time
+used by the program.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.date"><code>os.date ([format [, time]])</code></a></h3>
+
+
+<p>
+Returns a string or a table containing date and time,
+formatted according to the given string <code>format</code>.
+
+
+<p>
+If the <code>time</code> argument is present,
+this is the time to be formatted
+(see the <a href="#pdf-os.time"><code>os.time</code></a> function for a description of this value).
+Otherwise, <code>date</code> formats the current time.
+
+
+<p>
+If <code>format</code> starts with '<code>!</code>',
+then the date is formatted in Coordinated Universal Time.
+After this optional character,
+if <code>format</code> is the string "<code>*t</code>",
+then <code>date</code> returns a table with the following fields:
+<code>year</code> (four digits), <code>month</code> (1&ndash;12), <code>day</code> (1&ndash;31),
+<code>hour</code> (0&ndash;23), <code>min</code> (0&ndash;59), <code>sec</code> (0&ndash;61),
+<code>wday</code> (weekday, Sunday is&nbsp;1),
+<code>yday</code> (day of the year),
+and <code>isdst</code> (daylight saving flag, a boolean).
+This last field may be absent
+if the information is not available.
+
+
+<p>
+If <code>format</code> is not "<code>*t</code>",
+then <code>date</code> returns the date as a string,
+formatted according to the same rules as the ANSI&nbsp;C function <code>strftime</code>.
+
+
+<p>
+When called without arguments,
+<code>date</code> returns a reasonable date and time representation that depends on
+the host system and on the current locale
+(that is, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>).
+
+
+<p>
+On non-Posix systems,
+this function may be not thread safe
+because of its reliance on C&nbsp;function <code>gmtime</code> and C&nbsp;function <code>localtime</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.difftime"><code>os.difftime (t2, t1)</code></a></h3>
+
+
+<p>
+Returns the number of seconds from time <code>t1</code> to time <code>t2</code>.
+In POSIX, Windows, and some other systems,
+this value is exactly <code>t2</code><em>-</em><code>t1</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.execute"><code>os.execute ([command])</code></a></h3>
+
+
+<p>
+This function is equivalent to the ANSI&nbsp;C function <code>system</code>.
+It passes <code>command</code> to be executed by an operating system shell.
+Its first result is <b>true</b>
+if the command terminated successfully,
+or <b>nil</b> otherwise.
+After this first result
+the function returns a string and a number,
+as follows:
+
+<ul>
+
+<li><b>"<code>exit</code>": </b>
+the command terminated normally;
+the following number is the exit status of the command.
+</li>
+
+<li><b>"<code>signal</code>": </b>
+the command was terminated by a signal;
+the following number is the signal that terminated the command.
+</li>
+
+</ul>
+
+<p>
+When called without a <code>command</code>,
+<code>os.execute</code> returns a boolean that is true if a shell is available.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.exit"><code>os.exit ([code [, close])</code></a></h3>
+
+
+<p>
+Calls the ANSI&nbsp;C function <code>exit</code> to terminate the host program.
+If <code>code</code> is <b>true</b>,
+the returned status is <code>EXIT_SUCCESS</code>;
+if <code>code</code> is <b>false</b>,
+the returned status is <code>EXIT_FAILURE</code>;
+if <code>code</code> is a number,
+the returned status is this number.
+The default value for <code>code</code> is <b>true</b>.
+
+
+<p>
+If the optional second argument <code>close</code> is true,
+closes the Lua state before exiting.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.getenv"><code>os.getenv (varname)</code></a></h3>
+
+
+<p>
+Returns the value of the process environment variable <code>varname</code>,
+or <b>nil</b> if the variable is not defined.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.remove"><code>os.remove (filename)</code></a></h3>
+
+
+<p>
+Deletes the file (or empty directory, on POSIX systems)
+with the given name.
+If this function fails, it returns <b>nil</b>,
+plus a string describing the error and the error code.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.rename"><code>os.rename (oldname, newname)</code></a></h3>
+
+
+<p>
+Renames file or directory named <code>oldname</code> to <code>newname</code>.
+If this function fails, it returns <b>nil</b>,
+plus a string describing the error and the error code.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.setlocale"><code>os.setlocale (locale [, category])</code></a></h3>
+
+
+<p>
+Sets the current locale of the program.
+<code>locale</code> is a system-dependent string specifying a locale;
+<code>category</code> is an optional string describing which category to change:
+<code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>,
+<code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>;
+the default category is <code>"all"</code>.
+The function returns the name of the new locale,
+or <b>nil</b> if the request cannot be honored.
+
+
+<p>
+If <code>locale</code> is the empty string,
+the current locale is set to an implementation-defined native locale.
+If <code>locale</code> is the string "<code>C</code>",
+the current locale is set to the standard C locale.
+
+
+<p>
+When called with <b>nil</b> as the first argument,
+this function only returns the name of the current locale
+for the given category.
+
+
+<p>
+This function may be not thread safe
+because of its reliance on C&nbsp;function <code>setlocale</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.time"><code>os.time ([table])</code></a></h3>
+
+
+<p>
+Returns the current time when called without arguments,
+or a time representing the date and time specified by the given table.
+This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
+and may have fields
+<code>hour</code> (default is 12),
+<code>min</code> (default is 0),
+<code>sec</code> (default is 0),
+and <code>isdst</code> (default is <b>nil</b>).
+For a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function.
+
+
+<p>
+The returned value is a number, whose meaning depends on your system.
+In POSIX, Windows, and some other systems,
+this number counts the number
+of seconds since some given start time (the "epoch").
+In other systems, the meaning is not specified,
+and the number returned by <code>time</code> can be used only as an argument to
+<a href="#pdf-os.date"><code>os.date</code></a> and <a href="#pdf-os.difftime"><code>os.difftime</code></a>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-os.tmpname"><code>os.tmpname ()</code></a></h3>
+
+
+<p>
+Returns a string with a file name that can
+be used for a temporary file.
+The file must be explicitly opened before its use
+and explicitly removed when no longer needed.
+
+
+<p>
+On POSIX systems,
+this function also creates a file with that name,
+to avoid security risks.
+(Someone else might create the file with wrong permissions
+in the time between getting the name and creating the file.)
+You still have to open the file to use it
+and to remove it (even if you do not use it).
+
+
+<p>
+When possible,
+you may prefer to use <a href="#pdf-io.tmpfile"><code>io.tmpfile</code></a>,
+which automatically removes the file when the program ends.
+
+
+
+
+
+
+
+<h2>6.10 &ndash; <a name="6.10">The Debug Library</a></h2>
+
+<p>
+This library provides
+the functionality of the debug interface (<a href="#4.9">&sect;4.9</a>) to Lua programs.
+You should exert care when using this library.
+Several of its functions
+violate basic assumptions about Lua code
+(e.g., that variables local to a function
+cannot be accessed from outside;
+that userdata metatables cannot be changed by Lua code;
+that Lua programs do not crash)
+and therefore can compromise otherwise secure code.
+Moreover, some functions in this library may be slow.
+
+
+<p>
+All functions in this library are provided
+inside the <a name="pdf-debug"><code>debug</code></a> table.
+All functions that operate over a thread
+have an optional first argument which is the
+thread to operate over.
+The default is always the current thread.
+
+
+<p>
+<hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3>
+
+
+<p>
+Enters an interactive mode with the user,
+running each string that the user enters.
+Using simple commands and other debug facilities,
+the user can inspect global and local variables,
+change their values, evaluate expressions, and so on.
+A line containing only the word <code>cont</code> finishes this function,
+so that the caller continues its execution.
+
+
+<p>
+Note that commands for <code>debug.debug</code> are not lexically nested
+within any function and so have no direct access to local variables.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.gethook"><code>debug.gethook ([thread])</code></a></h3>
+
+
+<p>
+Returns the current hook settings of the thread, as three values:
+the current hook function, the current hook mask,
+and the current hook count
+(as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] f [, what])</code></a></h3>
+
+
+<p>
+Returns a table with information about a function.
+You can give the function directly
+or you can give a number as the value of <code>f</code>,
+which means the function running at level <code>f</code> of the call stack
+of the given thread:
+level&nbsp;0 is the current function (<code>getinfo</code> itself);
+level&nbsp;1 is the function that called <code>getinfo</code>
+(except for tail calls, which do not count on the stack);
+and so on.
+If <code>f</code> is a number larger than the number of active functions,
+then <code>getinfo</code> returns <b>nil</b>.
+
+
+<p>
+The returned table can contain all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>,
+with the string <code>what</code> describing which fields to fill in.
+The default for <code>what</code> is to get all information available,
+except the table of valid lines.
+If present,
+the option '<code>f</code>'
+adds a field named <code>func</code> with the function itself.
+If present,
+the option '<code>L</code>'
+adds a field named <code>activelines</code> with the table of
+valid lines.
+
+
+<p>
+For instance, the expression <code>debug.getinfo(1,"n").name</code> returns
+a table with a name for the current function,
+if a reasonable name can be found,
+and the expression <code>debug.getinfo(print)</code>
+returns a table with all available information
+about the <a href="#pdf-print"><code>print</code></a> function.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getlocal"><code>debug.getlocal ([thread,] f, local)</code></a></h3>
+
+
+<p>
+This function returns the name and the value of the local variable
+with index <code>local</code> of the function at level <code>f</code> of the stack.
+This function accesses not only explicit local variables,
+but also parameters, temporaries, etc.
+
+
+<p>
+The first parameter or local variable has index&nbsp;1, and so on,
+until the last active variable.
+Negative indices refer to vararg parameters;
+-1 is the first vararg parameter.
+The function returns <b>nil</b> if there is no variable with the given index,
+and raises an error when called with a level out of range.
+(You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.)
+
+
+<p>
+Variable names starting with '<code>(</code>' (open parenthesis)
+represent internal variables
+(loop control variables, temporaries, varargs, and C&nbsp;function locals).
+
+
+<p>
+The parameter <code>f</code> may also be a function.
+In that case, <code>getlocal</code> returns only the name of function parameters.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (value)</code></a></h3>
+
+
+<p>
+Returns the metatable of the given <code>value</code>
+or <b>nil</b> if it does not have a metatable.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getregistry"><code>debug.getregistry ()</code></a></h3>
+
+
+<p>
+Returns the registry table (see <a href="#4.5">&sect;4.5</a>).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (f, up)</code></a></h3>
+
+
+<p>
+This function returns the name and the value of the upvalue
+with index <code>up</code> of the function <code>f</code>.
+The function returns <b>nil</b> if there is no upvalue with the given index.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.getuservalue"><code>debug.getuservalue (u)</code></a></h3>
+
+
+<p>
+Returns the Lua value associated to <code>u</code>.
+If <code>u</code> is not a userdata,
+returns <b>nil</b>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.sethook"><code>debug.sethook ([thread,] hook, mask [, count])</code></a></h3>
+
+
+<p>
+Sets the given function as a hook.
+The string <code>mask</code> and the number <code>count</code> describe
+when the hook will be called.
+The string mask may have the following characters,
+with the given meaning:
+
+<ul>
+<li><b>'<code>c</code>': </b> the hook is called every time Lua calls a function;</li>
+<li><b>'<code>r</code>': </b> the hook is called every time Lua returns from a function;</li>
+<li><b>'<code>l</code>': </b> the hook is called every time Lua enters a new line of code.</li>
+</ul><p>
+With a <code>count</code> different from zero,
+the hook is called after every <code>count</code> instructions.
+
+
+<p>
+When called without arguments,
+<a href="#pdf-debug.sethook"><code>debug.sethook</code></a> turns off the hook.
+
+
+<p>
+When the hook is called, its first parameter is a string
+describing the event that has triggered its call:
+<code>"call"</code> (or <code>"tail call"</code>),
+<code>"return"</code>,
+<code>"line"</code>, and <code>"count"</code>.
+For line events,
+the hook also gets the new line number as its second parameter.
+Inside a hook,
+you can call <code>getinfo</code> with level&nbsp;2 to get more information about
+the running function
+(level&nbsp;0 is the <code>getinfo</code> function,
+and level&nbsp;1 is the hook function).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.setlocal"><code>debug.setlocal ([thread,] level, local, value)</code></a></h3>
+
+
+<p>
+This function assigns the value <code>value</code> to the local variable
+with index <code>local</code> of the function at level <code>level</code> of the stack.
+The function returns <b>nil</b> if there is no local
+variable with the given index,
+and raises an error when called with a <code>level</code> out of range.
+(You can call <code>getinfo</code> to check whether the level is valid.)
+Otherwise, it returns the name of the local variable.
+
+
+<p>
+See <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for more information about
+variable indices and names.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (value, table)</code></a></h3>
+
+
+<p>
+Sets the metatable for the given <code>value</code> to the given <code>table</code>
+(which can be <b>nil</b>).
+Returns <code>value</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (f, up, value)</code></a></h3>
+
+
+<p>
+This function assigns the value <code>value</code> to the upvalue
+with index <code>up</code> of the function <code>f</code>.
+The function returns <b>nil</b> if there is no upvalue
+with the given index.
+Otherwise, it returns the name of the upvalue.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.setuservalue"><code>debug.setuservalue (udata, value)</code></a></h3>
+
+
+<p>
+Sets the given <code>value</code> as
+the Lua value associated to the given <code>udata</code>.
+<code>value</code> must be a table or <b>nil</b>;
+<code>udata</code> must be a full userdata.
+
+
+<p>
+Returns <code>udata</code>.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message [, level]])</code></a></h3>
+
+
+<p>
+If <code>message</code> is present but is neither a string nor <b>nil</b>,
+this function returns <code>message</code> without further processing.
+Otherwise,
+it returns a string with a traceback of the call stack.
+An optional <code>message</code> string is appended
+at the beginning of the traceback.
+An optional <code>level</code> number tells at which level
+to start the traceback
+(default is 1, the function calling <code>traceback</code>).
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.upvalueid"><code>debug.upvalueid (f, n)</code></a></h3>
+
+
+<p>
+Returns an unique identifier (as a light userdata)
+for the upvalue numbered <code>n</code>
+from the given function.
+
+
+<p>
+These unique identifiers allow a program to check whether different
+closures share upvalues.
+Lua closures that share an upvalue
+(that is, that access a same external local variable)
+will return identical ids for those upvalue indices.
+
+
+
+
+<p>
+<hr><h3><a name="pdf-debug.upvaluejoin"><code>debug.upvaluejoin (f1, n1, f2, n2)</code></a></h3>
+
+
+<p>
+Make the <code>n1</code>-th upvalue of the Lua closure <code>f1</code>
+refer to the <code>n2</code>-th upvalue of the Lua closure <code>f2</code>.
+
+
+
+
+
+
+
+<h1>7 &ndash; <a name="7">Lua Standalone</a></h1>
+
+<p>
+Although Lua has been designed as an extension language,
+to be embedded in a host C&nbsp;program,
+it is also frequently used as a standalone language.
+An interpreter for Lua as a standalone language,
+called simply <code>lua</code>,
+is provided with the standard distribution.
+The standalone interpreter includes
+all standard libraries, including the debug library.
+Its usage is:
+
+<pre>
+     lua [options] [script [args]]
+</pre><p>
+The options are:
+
+<ul>
+<li><b><code>-e <em>stat</em></code>: </b> executes string <em>stat</em>;</li>
+<li><b><code>-l <em>mod</em></code>: </b> "requires" <em>mod</em>;</li>
+<li><b><code>-i</code>: </b> enters interactive mode after running <em>script</em>;</li>
+<li><b><code>-v</code>: </b> prints version information;</li>
+<li><b><code>-E</code>: </b> ignores environment variables;</li>
+<li><b><code>--</code>: </b> stops handling options;</li>
+<li><b><code>-</code>: </b> executes <code>stdin</code> as a file and stops handling options.</li>
+</ul><p>
+After handling its options, <code>lua</code> runs the given <em>script</em>,
+passing to it the given <em>args</em> as string arguments.
+When called without arguments,
+<code>lua</code> behaves as <code>lua -v -i</code>
+when the standard input (<code>stdin</code>) is a terminal,
+and as <code>lua -</code> otherwise.
+
+
+<p>
+When called without option <code>-E</code>, 
+the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_2"><code>LUA_INIT_5_2</code></a>
+(or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if it is not defined)
+before running any argument.
+If the variable content has the format <code>@<em>filename</em></code>,
+then <code>lua</code> executes the file.
+Otherwise, <code>lua</code> executes the string itself.
+
+
+<p>
+When called with option <code>-E</code>,
+besides ignoring <code>LUA_INIT</code>,
+Lua also ignores
+the values of <code>LUA_PATH</code> and <code>LUA_CPATH</code>,
+setting the values of
+<a href="#pdf-package.path"><code>package.path</code></a> and <a href="#pdf-package.cpath"><code>package.cpath</code></a>
+with the default paths defined in <code>luaconf.h</code>.
+
+
+<p>
+All options are handled in order, except <code>-i</code> and <code>-E</code>.
+For instance, an invocation like
+
+<pre>
+     $ lua -e'a=1' -e 'print(a)' script.lua
+</pre><p>
+will first set <code>a</code> to 1, then print the value of <code>a</code>,
+and finally run the file <code>script.lua</code> with no arguments.
+(Here <code>$</code> is the shell prompt. Your prompt may be different.)
+
+
+<p>
+Before starting to run the script,
+<code>lua</code> collects all arguments in the command line
+in a global table called <code>arg</code>.
+The script name is stored at index 0,
+the first argument after the script name goes to index 1,
+and so on.
+Any arguments before the script name
+(that is, the interpreter name plus the options)
+go to negative indices.
+For instance, in the call
+
+<pre>
+     $ lua -la b.lua t1 t2
+</pre><p>
+the interpreter first runs the file <code>a.lua</code>,
+then creates a table
+
+<pre>
+     arg = { [-2] = "lua", [-1] = "-la",
+             [0] = "b.lua",
+             [1] = "t1", [2] = "t2" }
+</pre><p>
+and finally runs the file <code>b.lua</code>.
+The script is called with <code>arg[1]</code>, <code>arg[2]</code>, ...
+as arguments;
+it can also access these arguments with the vararg expression '<code>...</code>'.
+
+
+<p>
+In interactive mode,
+if you write an incomplete statement,
+the interpreter waits for its completion
+by issuing a different prompt.
+
+
+<p>
+In case of unprotected errors in the script,
+the interpreter reports the error to the standard error stream.
+If the error object is a string,
+the interpreter adds a stack traceback to it.
+Otherwise, if the error object has a metamethod <code>__tostring</code>,
+the interpreter calls this metamethod to produce the final message.
+Finally, if the error object is <b>nil</b>,
+the interpreter does not report the error.
+
+
+<p>
+When finishing normally,
+the interpreter closes its main Lua state
+(see <a href="#lua_close"><code>lua_close</code></a>).
+The script can avoid this step by
+calling <a href="#pdf-os.exit"><code>os.exit</code></a> to terminate.
+
+
+<p>
+To allow the use of Lua as a
+script interpreter in Unix systems,
+the standalone interpreter skips
+the first line of a chunk if it starts with <code>#</code>.
+Therefore, Lua scripts can be made into executable programs
+by using <code>chmod +x</code> and the&nbsp;<code>#!</code> form,
+as in
+
+<pre>
+     #!/usr/local/bin/lua
+</pre><p>
+(Of course,
+the location of the Lua interpreter may be different in your machine.
+If <code>lua</code> is in your <code>PATH</code>,
+then
+
+<pre>
+     #!/usr/bin/env lua
+</pre><p>
+is a more portable solution.)
+
+
+
+<h1>8 &ndash; <a name="8">Incompatibilities with the Previous Version</a></h1>
+
+<p>
+Here we list the incompatibilities that you may find when moving a program
+from Lua&nbsp;5.1 to Lua&nbsp;5.2.
+You can avoid some incompatibilities by compiling Lua with
+appropriate options (see file <code>luaconf.h</code>).
+However,
+all these compatibility options will be removed in the next version of Lua.
+Similarly,
+all features marked as deprecated in Lua&nbsp;5.1
+have been removed in Lua&nbsp;5.2.
+
+
+
+<h2>8.1 &ndash; <a name="8.1">Changes in the Language</a></h2>
+<ul>
+
+<li>
+The concept of <em>environment</em> changed.
+Only Lua functions have environments.
+To set the environment of a Lua function,
+use the variable <code>_ENV</code> or the function <a href="#pdf-load"><code>load</code></a>.
+
+
+<p>
+C functions no longer have environments.
+Use an upvalue with a shared table if you need to keep
+shared state among several C functions.
+(You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library
+with all functions sharing a common upvalue.)
+
+
+<p>
+To manipulate the "environment" of a userdata
+(which is now called user value),
+use the new functions
+<a href="#lua_getuservalue"><code>lua_getuservalue</code></a> and <a href="#lua_setuservalue"><code>lua_setuservalue</code></a>.
+</li>
+
+<li>
+Lua identifiers cannot use locale-dependent letters.
+</li>
+
+<li>
+Doing a step or a full collection in the garbage collector
+does not restart the collector if it has been stopped.
+</li>
+
+<li>
+Weak tables with weak keys now perform like <em>ephemeron tables</em>.
+</li>
+
+<li>
+The event <em>tail return</em> in debug hooks was removed.
+Instead, tail calls generate a special new event,
+<em>tail call</em>, so that the debugger can know that
+there will not be a corresponding return event.
+</li>
+
+<li>
+Equality between function values has changed.
+Now, a function definition may not create a new value;
+it may reuse some previous value if there is no
+observable difference to the new function.
+</li>
+
+</ul>
+
+
+
+
+<h2>8.2 &ndash; <a name="8.2">Changes in the Libraries</a></h2>
+<ul>
+
+<li>
+Function <code>module</code> is deprecated.
+It is easy to set up a module with regular Lua code.
+Modules are not expected to set global variables.
+</li>
+
+<li>
+Functions <code>setfenv</code> and <code>getfenv</code> were removed,
+because of the changes in environments.
+</li>
+
+<li>
+Function <code>math.log10</code> is deprecated.
+Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead.
+</li>
+
+<li>
+Function <code>loadstring</code> is deprecated.
+Use <code>load</code> instead; it now accepts string arguments
+and are exactly equivalent to <code>loadstring</code>.
+</li>
+
+<li>
+Function <code>table.maxn</code> is deprecated.
+Write it in Lua if you really need it.
+</li>
+
+<li>
+Function <code>os.execute</code> now returns <b>true</b> when command
+terminates successfully and <b>nil</b> plus error information
+otherwise.
+</li>
+
+<li>
+Function <code>unpack</code> was moved into the table library
+and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>.
+</li>
+
+<li>
+Character class <code>%z</code> in patterns is deprecated,
+as now patterns may contain '<code>\0</code>' as a regular character.
+</li>
+
+<li>
+The table <code>package.loaders</code> was renamed <code>package.searchers</code>.
+</li>
+
+<li>
+Lua does not have bytecode verification anymore.
+So, all functions that load code
+(<a href="#pdf-load"><code>load</code></a> and <a href="#pdf-loadfile"><code>loadfile</code></a>)
+are potentially insecure when loading untrusted binary data.
+(Actually, those functions were already insecure because
+of flaws in the verification algorithm.)
+When in doubt,
+use the <code>mode</code> argument of those functions
+to restrict them to loading textual chunks.
+</li>
+
+<li>
+The standard paths in the official distribution may
+change between versions.
+</li>
+
+</ul>
+
+
+
+
+<h2>8.3 &ndash; <a name="8.3">Changes in the API</a></h2>
+<ul>
+
+<li>
+Pseudoindex <code>LUA_GLOBALSINDEX</code> was removed.
+You must get the global environment from the registry
+(see <a href="#4.5">&sect;4.5</a>).
+</li>
+
+<li>
+Pseudoindex <code>LUA_ENVIRONINDEX</code>
+and functions <code>lua_getfenv</code>/<code>lua_setfenv</code>
+were removed,
+as C&nbsp;functions no longer have environments.
+</li>
+
+<li>
+Function <code>luaL_register</code> is deprecated.
+Use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> so that your module does not create globals.
+(Modules are not expected to set global variables anymore.)
+</li>
+
+<li>
+The <code>osize</code> argument to the allocation function
+may not be zero when creating a new block,
+that is, when <code>ptr</code> is <code>NULL</code>
+(see <a href="#lua_Alloc"><code>lua_Alloc</code></a>).
+Use only the test <code>ptr == NULL</code> to check whether
+the block is new.
+</li>
+
+<li>
+Finalizers (<code>__gc</code> metamethods) for userdata are called in the
+reverse order that they were marked for finalization,
+not that they were created (see <a href="#2.5.1">&sect;2.5.1</a>).
+(Most userdata are marked immediately after they are created.)
+Moreover,
+if the metatable does not have a <code>__gc</code> field when set,
+the finalizer will not be called,
+even if it is set later.
+</li>
+
+<li>
+<code>luaL_typerror</code> was removed.
+Write your own version if you need it.
+</li>
+
+<li>
+Function <code>lua_cpcall</code> is deprecated.
+You can simply push the function with <a href="#lua_pushcfunction"><code>lua_pushcfunction</code></a>
+and call it with <a href="#lua_pcall"><code>lua_pcall</code></a>.
+</li>
+
+<li>
+Functions <code>lua_equal</code> and <code>lua_lessthan</code> are deprecated.
+Use the new <a href="#lua_compare"><code>lua_compare</code></a> with appropriate options instead.
+</li>
+
+<li>
+Function <code>lua_objlen</code> was renamed <a href="#lua_rawlen"><code>lua_rawlen</code></a>.
+</li>
+
+<li>
+Function <a href="#lua_load"><code>lua_load</code></a> has an extra parameter, <code>mode</code>.
+Pass <code>NULL</code> to simulate the old behavior.
+</li>
+
+<li>
+Function <a href="#lua_resume"><code>lua_resume</code></a> has an extra parameter, <code>from</code>.
+Pass <code>NULL</code> or the thread doing the call.
+</li>
+
+</ul>
+
+
+
+
+<h1>9 &ndash; <a name="9">The Complete Syntax of Lua</a></h1>
+
+<p>
+Here is the complete syntax of Lua in extended BNF.
+(It does not describe operator precedences.)
+
+
+
+
+<pre>
+
+	chunk ::= block
+
+	block ::= {stat} [retstat]
+
+	stat ::=  &lsquo;<b>;</b>&rsquo; | 
+		 varlist &lsquo;<b>=</b>&rsquo; explist | 
+		 functioncall | 
+		 label | 
+		 <b>break</b> | 
+		 <b>goto</b> Name | 
+		 <b>do</b> block <b>end</b> | 
+		 <b>while</b> exp <b>do</b> block <b>end</b> | 
+		 <b>repeat</b> block <b>until</b> exp | 
+		 <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | 
+		 <b>for</b> Name &lsquo;<b>=</b>&rsquo; exp &lsquo;<b>,</b>&rsquo; exp [&lsquo;<b>,</b>&rsquo; exp] <b>do</b> block <b>end</b> | 
+		 <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | 
+		 <b>function</b> funcname funcbody | 
+		 <b>local</b> <b>function</b> Name funcbody | 
+		 <b>local</b> namelist [&lsquo;<b>=</b>&rsquo; explist] 
+
+	retstat ::= <b>return</b> [explist] [&lsquo;<b>;</b>&rsquo;]
+
+	label ::= &lsquo;<b>::</b>&rsquo; Name &lsquo;<b>::</b>&rsquo;
+
+	funcname ::= Name {&lsquo;<b>.</b>&rsquo; Name} [&lsquo;<b>:</b>&rsquo; Name]
+
+	varlist ::= var {&lsquo;<b>,</b>&rsquo; var}
+
+	var ::=  Name | prefixexp &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; | prefixexp &lsquo;<b>.</b>&rsquo; Name 
+
+	namelist ::= Name {&lsquo;<b>,</b>&rsquo; Name}
+
+	explist ::= exp {&lsquo;<b>,</b>&rsquo; exp}
+
+	exp ::=  <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | &lsquo;<b>...</b>&rsquo; | functiondef | 
+		 prefixexp | tableconstructor | exp binop exp | unop exp 
+
+	prefixexp ::= var | functioncall | &lsquo;<b>(</b>&rsquo; exp &lsquo;<b>)</b>&rsquo;
+
+	functioncall ::=  prefixexp args | prefixexp &lsquo;<b>:</b>&rsquo; Name args 
+
+	args ::=  &lsquo;<b>(</b>&rsquo; [explist] &lsquo;<b>)</b>&rsquo; | tableconstructor | String 
+
+	functiondef ::= <b>function</b> funcbody
+
+	funcbody ::= &lsquo;<b>(</b>&rsquo; [parlist] &lsquo;<b>)</b>&rsquo; block <b>end</b>
+
+	parlist ::= namelist [&lsquo;<b>,</b>&rsquo; &lsquo;<b>...</b>&rsquo;] | &lsquo;<b>...</b>&rsquo;
+
+	tableconstructor ::= &lsquo;<b>{</b>&rsquo; [fieldlist] &lsquo;<b>}</b>&rsquo;
+
+	fieldlist ::= field {fieldsep field} [fieldsep]
+
+	field ::= &lsquo;<b>[</b>&rsquo; exp &lsquo;<b>]</b>&rsquo; &lsquo;<b>=</b>&rsquo; exp | Name &lsquo;<b>=</b>&rsquo; exp | exp
+
+	fieldsep ::= &lsquo;<b>,</b>&rsquo; | &lsquo;<b>;</b>&rsquo;
+
+	binop ::= &lsquo;<b>+</b>&rsquo; | &lsquo;<b>-</b>&rsquo; | &lsquo;<b>*</b>&rsquo; | &lsquo;<b>/</b>&rsquo; | &lsquo;<b>^</b>&rsquo; | &lsquo;<b>%</b>&rsquo; | &lsquo;<b>..</b>&rsquo; | 
+		 &lsquo;<b>&lt;</b>&rsquo; | &lsquo;<b>&lt;=</b>&rsquo; | &lsquo;<b>&gt;</b>&rsquo; | &lsquo;<b>&gt;=</b>&rsquo; | &lsquo;<b>==</b>&rsquo; | &lsquo;<b>~=</b>&rsquo; | 
+		 <b>and</b> | <b>or</b>
+
+	unop ::= &lsquo;<b>-</b>&rsquo; | <b>not</b> | &lsquo;<b>#</b>&rsquo;
+
+</pre>
+
+<p>
+
+
+
+
+
+
+
+<HR>
+<SMALL CLASS="footer">
+Last update:
+Thu Mar 21 12:58:59 BRT 2013
+</SMALL>
+<!--
+Last change: revised for Lua 5.2.2
+-->
+
+</body></html>
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/readme.html
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/readme.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/readme.html	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,413 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+<HEAD>
+<TITLE>Lua 5.2 readme</TITLE>
+<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
+<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
+<STYLE TYPE="text/css">
+blockquote, .display {
+	border: solid #a0a0a0 2px ;
+	border-radius: 8px ;
+	padding: 1em ;
+	margin: 0px ;
+}
+
+.display {
+	word-spacing: 0.25em ;
+}
+
+dl.display dd {
+	padding-bottom: 0.2em ;
+}
+
+tt, kbd, code {
+	font-size: 12pt ;
+}
+</STYLE>
+</HEAD>
+
+<BODY>
+
+<HR>
+<H1>
+<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
+Welcome to Lua 5.2
+</H1>
+
+<P>
+<A HREF="#about">about</A>
+&middot;
+<A HREF="#install">installation</A>
+&middot;
+<A HREF="#changes">changes</A>
+&middot;
+<A HREF="#license">license</A>
+&middot;
+<A HREF="contents.html">reference manual</A>
+
+<H2><A NAME="about">About Lua</A></H2>
+
+<P>
+Lua is a powerful, fast, lightweight, embeddable scripting language
+developed by a
+<A HREF="http://www.lua.org/authors.html">team</A>
+at
+<A HREF="http://www.puc-rio.br/">PUC-Rio</A>,
+the Pontifical Catholic University of Rio de Janeiro in Brazil.
+Lua is
+<A HREF="#license">free software</A>
+used in many products and projects around the world.
+
+<P>
+Lua's
+<A HREF="http://www.lua.org/">official web site</A>
+provides complete information
+about Lua,
+including
+an
+<A HREF="http://www.lua.org/about.html">executive summary</A>
+and
+updated
+<A HREF="http://www.lua.org/docs.html">documentation</A>,
+especially the
+<A HREF="http://www.lua.org/manual/5.2/">reference manual</A>,
+which may differ slightly from the
+<A HREF="contents.html">local copy</A>
+distributed in this package.
+
+<H2><A NAME="install">Installing Lua</A></H2>
+
+<P>
+Lua is distributed in
+<A HREF="http://www.lua.org/ftp/">source</A>
+form.
+You need to build it before using it.
+Building Lua should be straightforward
+because
+Lua is implemented in pure ANSI C and compiles unmodified in all known
+platforms that have an ANSI C compiler.
+Lua also compiles unmodified as C++.
+The instructions given below for building Lua are for Unix-like platforms.
+See also
+<A HREF="#other">instructions for other systems</A>
+and
+<A HREF="#customization">customization options</A>.
+
+<P>
+If you don't have the time or the inclination to compile Lua yourself,
+get a binary from
+<A HREF="http://lua-users.org/wiki/LuaBinaries">LuaBinaries</A>.
+Try also
+<A HREF="http://luaforwindows.luaforge.net/">Lua for Windows</A>,
+an easy-to-use distribution of Lua that includes many useful libraries.
+
+<H3>Building Lua</H3>
+
+<P>
+In most Unix-like platforms, simply do "<KBD>make</KBD>" with a suitable target.
+Here are the details.
+
+<OL>
+<LI>
+Open a terminal window and move to
+the top-level directory, which is named <TT>lua-5.2.3</TT>.
+The Makefile there controls both the build process and the installation process.
+<P>
+<LI>
+  Do "<KBD>make</KBD>" and see if your platform is listed.
+  The platforms currently supported are:
+<P>
+<P CLASS="display">
+   aix ansi bsd freebsd generic linux macosx mingw posix solaris
+</P>
+<P>
+  If your platform is listed, just do "<KBD>make xxx</KBD>", where xxx
+  is your platform name.
+<P>
+  If your platform is not listed, try the closest one or posix, generic,
+  ansi, in this order.
+<P>
+<LI>
+The compilation takes only a few moments
+and produces three files in the <TT>src</TT> directory:
+lua (the interpreter),
+luac (the compiler),
+and liblua.a (the library).
+<P>
+<LI>
+  To check that Lua has been built correctly, do "<KBD>make test</KBD>"
+  after building Lua. This will run the interpreter and print its version string.
+</OL>
+<P>
+If you're running Linux and get compilation errors,
+make sure you have installed the <TT>readline</TT> development package.
+If you get link errors after that,
+then try "<KBD>make linux MYLIBS=-ltermcap</KBD>".
+
+<H3>Installing Lua</H3>
+<P>
+  Once you have built Lua, you may want to install it in an official
+  place in your system. In this case, do "<KBD>make install</KBD>". The official
+  place and the way to install files are defined in the Makefile. You'll
+  probably need the right permissions to install files.
+
+<P>
+  To build and install Lua in one step, do "<KBD>make xxx install</KBD>",
+  where xxx is your platform name.
+
+<P>
+  To install Lua locally, do "<KBD>make local</KBD>".
+  This will create a directory <TT>install</TT> with subdirectories
+  <TT>bin</TT>, <TT>include</TT>, <TT>lib</TT>, <TT>man</TT>,
+  and install Lua as listed below.
+
+  To install Lua locally, but in some other directory, do
+  "<KBD>make install INSTALL_TOP=xxx</KBD>", where xxx is your chosen directory.
+
+<DL CLASS="display">
+<DT>
+    bin:
+<DD>
+    lua luac
+<DT>
+    include:
+<DD>
+    lua.h luaconf.h lualib.h lauxlib.h lua.hpp
+<DT>
+    lib:
+<DD>
+    liblua.a
+<DT>
+    man/man1:
+<DD>
+    lua.1 luac.1
+</DL>
+
+<P>
+  These are the only directories you need for development.
+  If you only want to run Lua programs,
+  you only need the files in bin and man.
+  The files in include and lib are needed for
+  embedding Lua in C or C++ programs.
+
+<H3><A NAME="customization">Customization</A></H3>
+<P>
+  Three kinds of things can be customized by editing a file:
+<UL>
+    <LI> Where and how to install Lua &mdash; edit <TT>Makefile</TT>.
+    <LI> How to build Lua &mdash; edit <TT>src/Makefile</TT>.
+    <LI> Lua features &mdash; edit <TT>src/luaconf.h</TT>.
+</UL>
+
+<P>
+  You don't actually need to edit the Makefiles because you may set the
+  relevant variables in the command line when invoking make.
+  Nevertheless, it's probably best to edit and save the Makefiles to
+  record the changes you need.
+
+<P>
+  On the other hand, if you need to customize some Lua features, you'll need
+  to edit <TT>src/luaconf.h</TT> before building and installing Lua.
+  The edited file will be the one installed, and
+  it will be used by any Lua clients that you build, to ensure consistency.
+  Further customization is available to experts by editing the Lua sources.
+
+<P>
+  We strongly recommend that you enable dynamic loading in <TT>src/luaconf.h</TT>.
+  This is done automatically for all platforms listed above that have
+  this feature and also for Windows.
+
+<H3><A NAME="other">Building Lua on other systems</A></H3>
+
+<P>
+  If you're not using the usual Unix tools, then the instructions for
+  building Lua depend on the compiler you use. You'll need to create
+  projects (or whatever your compiler uses) for building the library,
+  the interpreter, and the compiler, as follows:
+
+<DL CLASS="display">
+<DT>
+library:
+<DD>
+lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c
+lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c
+ltm.c lundump.c lvm.c lzio.c
+lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c
+lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c
+<DT>
+interpreter:
+<DD>
+  library, lua.c
+<DT>
+compiler:
+<DD>
+  library, luac.c
+</DL>
+
+<P>
+  To use Lua as a library in your own programs you'll need to know how to
+  create and use libraries with your compiler. Moreover, to dynamically load
+  C libraries for Lua you'll need to know how to create dynamic libraries
+  and you'll need to make sure that the Lua API functions are accessible to
+  those dynamic libraries &mdash; but <EM>don't</EM> link the Lua library
+  into each dynamic library. For Unix, we recommend that the Lua library
+  be linked statically into the host program and its symbols exported for
+  dynamic linking; <TT>src/Makefile</TT> does this for the Lua interpreter.
+  For Windows, we recommend that the Lua library be a DLL.
+
+<P>
+  As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize
+  some features before building Lua.
+
+<H2><A NAME="changes">Changes since Lua 5.1</A></H2>
+
+<P>
+Here are the main changes introduced in Lua 5.2.
+The
+<A HREF="contents.html">reference manual</A>
+lists the
+<A HREF="manual.html#8">incompatibilities</A> that had to be introduced.
+
+<H3>Main changes</H3>
+<UL>
+<LI> yieldable pcall and metamethods
+<LI> new lexical scheme for globals
+<LI> ephemeron tables
+<LI> new library for bitwise operations
+<LI> light C functions
+<LI> emergency garbage collector
+<LI> <CODE>goto</CODE> statement
+<LI> finalizers for tables
+</UL>
+
+Here are the other changes introduced in Lua 5.2:
+<H3>Language</H3>
+<UL>
+<LI> no more fenv for threads or functions
+<LI> tables honor the <CODE>__len</CODE> metamethod
+<LI> hex and <CODE>\z</CODE> escapes in strings
+<LI> support for hexadecimal floats
+<LI> order metamethods work for different types
+<LI> no more verification of opcode consistency
+<LI> hook event "tail return" replaced by "tail call"
+<LI> empty statement
+<LI> <CODE>break</CODE> statement may appear in the middle of a block
+</UL>
+
+<H3>Libraries</H3>
+<UL>
+<LI> arguments for function called through <CODE>xpcall</CODE>
+<LI> optional 'mode' argument to load and loadfile (to control binary x text)
+<LI> optional 'env' argument to load and loadfile (environment for loaded chunk)
+<LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL)
+<LI> new function <CODE>package.searchpath</CODE>
+<LI> modules receive their paths when loaded
+<LI> optional base in <CODE>math.log</CODE>
+<LI> optional separator in <CODE>string.rep</CODE>
+<LI> <CODE>file:write</CODE> returns <CODE>file</CODE>
+<LI> closing a pipe returns exit status
+<LI> <CODE>os.exit</CODE> may close state
+<LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE>
+<LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>
+<LI> frontier patterns
+<LI> <CODE>\0</CODE> in patterns
+<LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE>
+<LI> options for <CODE>io.lines</CODE>
+<LI> <CODE>debug.getlocal</CODE> can access function varargs
+</UL>
+
+<H3>C API</H3>
+<UL>
+<LI> main thread predefined in the registry
+<LI> new functions
+<CODE>lua_absindex</CODE>,
+<CODE>lua_arith</CODE>,
+<CODE>lua_compare</CODE>,
+<CODE>lua_copy</CODE>,
+<CODE>lua_len</CODE>,
+<CODE>lua_rawgetp</CODE>,
+<CODE>lua_rawsetp</CODE>,
+<CODE>lua_upvalueid</CODE>,
+<CODE>lua_upvaluejoin</CODE>,
+<CODE>lua_version</CODE>.
+<LI> new functions
+<CODE>luaL_checkversion</CODE>,
+<CODE>luaL_setmetatable</CODE>,
+<CODE>luaL_testudata</CODE>,
+<CODE>luaL_tolstring</CODE>.
+<LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string
+<LI> <CODE>nparams</CODE> and <CODE>isvararg</CODE> available in debug API
+<LI> new <CODE>lua_Unsigned</CODE>
+</UL>
+
+<H3>Implementation</H3>
+<UL>
+<LI> max constants per function raised to 2<SUP>26</SUP>
+<LI> generational mode for garbage collection (experimental)
+<LI> NaN trick (experimental)
+<LI> internal (immutable) version of ctypes
+<LI> simpler implementation for string buffers
+<LI> parser uses much less C-stack space (no more auto arrays)
+</UL>
+
+<H3>Lua standalone interpreter</H3>
+<UL>
+<LI> new <CODE>-E</CODE> option to avoid environment variables
+<LI> handling of non-string error messages
+</UL>
+
+<H2><A NAME="license">License</A></H2>
+<A HREF="http://www.opensource.org/docs/definition.php">
+<IMG SRC="osi-certified-72x60.png" ALIGN="right" BORDER="0" ALT="[osi certified]" STYLE="padding-left: 30px ;">
+</A>
+
+<P>
+Lua is free software distributed under the terms of the
+<A HREF="http://www.opensource.org/licenses/mit-license.html">MIT license</A>
+reproduced below;
+it may be used for any purpose, including commercial purposes,
+at absolutely no cost without having to ask us.
+
+The only requirement is that if you do use Lua,
+then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.
+
+For details, see
+<A HREF="http://www.lua.org/license.html">this</A>.
+
+<BLOCKQUOTE STYLE="padding-bottom: 0em">
+Copyright &copy; 1994&ndash;2013 Lua.org, PUC-Rio.
+
+<P>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+<P>
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+<P>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+</BLOCKQUOTE>
+<P>
+
+<HR>
+<SMALL CLASS="footer">
+Last update:
+Sat Nov  9 22:39:16 BRST 2013
+</SMALL>
+<!--
+Last change: revised for Lua 5.2.3
+-->
+
+</BODY>
+</HTML>
Index: bootcd/isolinux/syslinux-6.03/com32/lua/doc/syslinux.asc
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/doc/syslinux.asc	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/doc/syslinux.asc	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,292 @@
+Syslinux LUA User Guide
+=======================
+Marcel Ritter <Marcel.Ritter@rrze.uni-erlangen.de>
+
+Invocation
+----------
+
+Running +lua.c32+ only results in an interactive shell.
+......................................................
+KERNEL lua.c32
+......................................................
+
+By using the +APPEND+ parameter you can specify a lua
+script to be executed:
+......................................................
+KERNEL lua.c32
+APPEND /testit.lua
+......................................................
+
+Modules
+-------
+
+Modules must be explicitly loaded into the namespace
+before use, for example:
+......................................................
+syslinux = require ("syslinux")
+......................................................
+
+SYSLINUX
+~~~~~~~~
+
+.syslinux.version()
+
+Returns version string
+
+.syslinux.derivative()
+
+Returns running Syslinux's derivative (ISOLINUX, PXELINUX or SYSLINUX).
+See com32/lua/test/syslinux-derivative.lua for an example.
+
+.syslinux.sleep(s)
+
+Sleep for +s+ seconds
+
+.syslinux.msleep(ms)
+
+Sleep for +ms+ milliseconds
+
+.run_command(command)
+
+Execute syslinux command line +command+.
+
+_Example_:
+......................................................
+	syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+......................................................
+
+.run_default()
+
+FIXME
+
+.local_boot()
+
+FIXME
+
+.final_cleanup()
+
+FIXME
+
+.boot_linux(kernel, cmdline, [mem_limit], [videomode])
+
+FIXME
+
+.run_kernel_image(kernel, cmdline, ipappend_flags, type)
+
+FIXME
+
+.loadfile(filname)
+
+Load file +filename+ (via TFTP)
+
+.filesize(file)
+
+Return size of +file+ (loaded by loadfile())
+
+.filename(file)
+
+Return name of +file+ (loaded by loadfile())
+
+.in itramfs_init()
+
+Return empty initramfs object
+
+.initramfs_load_archive(initramfs, filename)
+
+Load contents of +filename+ into +initramfs+. Initialize
++initramfs+ with initramfs_init() before use.
+
+.initramfs_add_file(initramfs, file)
+
+Adds +file+ to +initramfs+. +initramfs+ needs to be
+initialized, +file+ has been loaded by loadfile().
+
+_Example_:
+......................................................
+	-- get nice output
+	printf = function(s,...)
+	           return io.write(s:format(...))
+	         end -- function
+	
+	kernel = syslinux.loadfile("/SuSE-11.1/x86_64/linux")
+	
+	printf("Filename/size: %s %d\n", syslinux.filename(kernel), syslinux.filesize(kernel))
+	
+	initrd = syslinux.loadfile("/SuSE-11.1/x86_64/initrd")
+	
+	printf("Filename/size: %s %d\n", syslinux.filename(initrd), syslinux.filesize(initrd))
+	
+	initrd = syslinux.initramfs_init()
+	syslinux.initramfs_load_archive(initrd, "/SuSE-11.1/x86_64/initrd");
+	
+	syslinux.boot_it(kernel, initrd, "init=/bin/bash")
+	
+	syslinux.sleep(20)
+	
+......................................................
+
+
+
+DMI
+~~~
+
+.dmi_supported()
+
+Returns +true+ if DMI is supported on machine, +false+ otherwise.
+
+.dmi_gettable()
+
+Returns a list if key-value pairs. The key is one of the DMI property strings:
+FIXME list
+
+_Example_:
+......................................................
+	if (dmi.supported()) then
+	
+	  dmitable = dmi.gettable()
+	
+	  for k,v in pairs(dmitable) do
+	    print(k, v)
+	  end
+	
+	  print(dmitable["system.manufacturer"])
+	  print(dmitable["system.product_name"])
+	  print(dmitable["bios.bios_revision"])
+	
+	  if ( string.match(dmitable["system.product_name"], "ESPRIMO P7935") ) then
+	    print("Matches")
+	    syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+	  else
+	    print("Does not match")
+	    syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+	  end
+	
+	end
+
+......................................................
+
+
+PCI
+~~~
+
+.pci_getinfo()
+
+Return list of value pairs (device_index, device) of all PCI devices.
+
+.pci_getidlist(filename)
+
+Load a tab separated list of PCI IDs and their description. 
+Sample files can be found here: http://pciids.sourceforge.net/
+
+
+_Example_:
+......................................................
+-- get nice output
+printf = function(s,...)
+           return io.write(s:format(...))
+         end
+
+-- get device info
+pciinfo = pci.getinfo()
+
+-- get plain text device description
+pciids = pci.getidlist("/pci.ids")
+
+-- list all pci busses
+for dind,device in pairs(pciinfo) do
+
+  -- search for device description
+  search = string.format("%04x%04x", device['vendor'], device['product'])
+
+  printf(" %04x:%04x:%04x:%04x = ", device['vendor'], device['product'],
+			device['sub_vendor'], device['sub_product'])
+
+  if ( pciids[search] ) then
+         printf("%s\n", pciids[search])
+  else
+         printf("Unknown\n")
+  end
+end
+
+-- print(pciids["8086"])
+-- print(pciids["10543009"])
+-- print(pciids["00700003"])
+-- print(pciids["0070e817"])
+-- print(pciids["1002437a1002437a"])
+......................................................
+
+
+VESA
+~~~~
+
+.getmodes()
+
+Return list of available VESA modes.
+
+_Example_:
+......................................................
+	-- get nice output
+	printf = function(s,...)
+	           return io.write(s:format(...))
+	         end
+	
+	-- list available vesa modes
+	-- only one supported right now, not of much use
+	modes = vesa.getmodes()
+	
+	for mind,mode in pairs(modes) do
+	   printf("%04x: %dx%dx%d\n", mode['mode'], mode['hres'], mode['vres'], mode['bpp'])
+	end
+......................................................
+
+
+.setmode()
+
+Set (only currently supported) VESA mode.
+
+.load_background(filename)
+
+Load +filename+ from TFTP, and use it as background image.
+
+_Example_:
+......................................................
+	-- get nice output
+	printf = function(s,...)
+	           return io.write(s:format(...))
+	         end
+	
+	-- lets go to graphics land
+	vesa.setmode()
+	
+	printf("Hello World! - VESA mode")
+	
+	-- some text to display "typing style"
+	textline=[[
+	From syslinux GSOC 2009 home page:
+	
+	Finish the Lua engine
+	
+	We already have a Lua interpreter integrated with the Syslinux build. However, right now it is not very useful. We need to create a set of bindings to the Syslinux functionality, and have an array of documentation and examples so users can use them.
+	
+	This is not a documentation project, but the documentation deliverable will be particularly important for this one, since the intended target is system administrators, not developers.
+	]]
+	
+	
+	-- do display loop
+	-- keep in mind: background change will not erase text!
+	while ( true ) do
+	
+	vesa.load_background("/background1.jpg")
+	
+	syslinux.sleep(1)
+	
+	for i = 1, #textline do
+	    local c = textline:sub(i,i)
+	    printf("%s", c)
+	    syslinux.msleep(200)
+	end
+	
+	syslinux.sleep(10)
+
+......................................................
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,75 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+##
+##   This program is free software; you can redistribute it and/or modify
+##   it under the terms of the GNU General Public License as published by
+##   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Lua Makefile
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LNXLIBS	   = 
+
+# Temporarily allow warnings not being treated as errors
+#GCCWARN	  += -Wno-error
+
+CFLAGS    += -DSYSLINUX
+MODULES	  = lua.c32
+MODULES   += cpu.c32
+MODULES   += dhcp.c32
+MODULES   += dmi.c32
+MODULES   += lfs.c32
+MODULES   += pci.c32
+MODULES   += syslinux.c32
+MODULES   += vesa.c32
+MODULES   += cmenu.c32
+TESTFILES =
+
+OBJS	  = lua.o
+
+LIBLUA    = liblua.c32
+
+LIBLUA_OBJS := lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o
+LIBLUA_OBJS += lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o
+LIBLUA_OBJS += lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o
+
+LIBLUA_OBJS += lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o
+LIBLUA_OBJS += loslib.o lstrlib.o ltablib.o loadlib.o linit.o
+
+CFLAGS += -DLUA_ANSI
+
+all: $(MODULES) $(TESTFILES)
+
+liblua.elf : $(LIBLUA_OBJS)
+	$(LD) $(LDFLAGS) -shared -soname $(patsubst %.elf,%.c32,$(@F)) \
+		-o $@ $^
+
+lua.elf : $(OBJS) $(LIBLUA) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+cmenu.o : CFLAGS += -I$(com32)/cmenu/libmenu
+cmenu.elf : $(objdir)/com32/cmenu/libmenu/libmenu.c32
+
+tidy dist:
+	rm -f *.o *.lo *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/cmenu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/cmenu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/cmenu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,90 @@
+#include "cmenu.h"
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+
+static int l_init (lua_State *L)
+{
+  init_menusystem (luaL_optstring (L, 1, NULL));
+  return 0;
+}
+
+static int l_set_window_size (lua_State *L)
+{
+  set_window_size (luaL_checkint (L, 1), luaL_checkint (L, 2),
+                   luaL_checkint (L, 3), luaL_checkint (L, 4));
+  return 0;
+}
+
+static int l_add_menu (lua_State *L)
+{
+  lua_pushinteger (L, add_menu (luaL_checkstring (L, 1),
+                                luaL_optint (L, 2, -1)));
+  return 1;
+}
+
+static int l_add_named_menu (lua_State *L)
+{
+  lua_pushinteger (L, add_named_menu (luaL_checkstring (L, 1),
+                                      luaL_checkstring (L, 2),
+                                      luaL_optint (L, 3, -1)));
+  return 1;
+}
+
+static int l_add_item (lua_State *L)
+{
+  add_item (luaL_checkstring (L, 1), luaL_checkstring (L, 2), luaL_checkint (L, 3),
+            luaL_optstring (L, 4, NULL), luaL_optint (L, 5, 0));
+  return 0; /* FIXME return menuitem for advanced functions */
+}
+
+static int l_add_sep (lua_State *L)
+{
+  add_sep ();
+  return 0; /* FIXME return menuitem for advanced functions */
+}
+
+static int l_find_menu_num (lua_State *L)
+{
+  lua_pushinteger (L, find_menu_num (luaL_checkstring (L, 1)));
+  return 1;
+}
+
+static int l_showmenus (lua_State *L)
+{
+  t_menuitem *reply = showmenus (luaL_checkint (L, 1));
+  if (!reply) return 0;
+  lua_pushinteger (L, reply->action);
+  lua_pushstring (L, reply->data);
+  return 2;
+}
+
+static const luaL_Reg menulib[] = {
+  {"init", l_init},
+  {"set_window_size", l_set_window_size},
+  {"add_menu", l_add_menu},
+  {"add_named_menu", l_add_named_menu},
+  {"add_item", l_add_item},
+  {"add_sep", l_add_sep},
+  {"find_menu_num", l_find_menu_num},
+  {"showmenus", l_showmenus},
+  {NULL, NULL}
+};
+
+LUALIB_API int luaopen_cmenu (lua_State *L) {
+  luaL_newlib(L, menulib);
+  lua_newtable (L);
+#define export_opt(x) lua_pushinteger (L, OPT_##x); lua_setfield (L, -2, #x);
+  export_opt (INACTIVE);
+  export_opt (SUBMENU);
+  export_opt (RUN);
+  export_opt (EXITMENU);
+  export_opt (CHECKBOX);
+  export_opt (RADIOMENU);
+  export_opt (SEP);
+  export_opt (INVISIBLE);
+  export_opt (RADIOITEM);
+  lua_setfield (L, -2, "action");
+  return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/cpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,158 @@
+#include <stdlib.h>
+#include <string.h>
+
+#define llua_cpu       /* Define the library */
+
+/* Include the Lua API header files */
+#include"lua.h"
+#include"lauxlib.h"
+#include"lualib.h"
+#include"cpuid.h"
+
+static void add_string_item(lua_State *L, const char *item, const char *value_str) {
+ lua_pushstring(L,item);
+ lua_pushstring(L,value_str);
+ lua_settable(L,-3);
+}
+
+static void add_int_item(lua_State *L, const char *item, int value_int) {
+ lua_pushstring(L,item);
+ lua_pushnumber(L,value_int);
+ lua_settable(L,-3);
+}
+
+static void add_flag(lua_State *L, bool value, const char *value_str) {
+ char buffer[32] = { 0 };
+ snprintf(buffer,sizeof(buffer), "flags.%s",value_str);
+ lua_pushstring(L,buffer);
+// printf("%s=%d\n",value_str,value);
+
+ if (value == true) {
+  lua_pushstring(L,"yes");
+ } else {
+  lua_pushstring(L,"no");
+ }
+
+ lua_settable(L,-3);
+}
+
+static int cpu_getflags(lua_State *L)
+{
+  s_cpu lua_cpu;
+  
+  detect_cpu(&lua_cpu);
+
+  lua_newtable(L);
+
+  add_string_item(L, "vendor", lua_cpu.vendor);
+  add_string_item(L, "model", lua_cpu.model);
+  add_int_item(L, "cores", lua_cpu.num_cores);
+  add_int_item(L, "l1_instruction_cache", lua_cpu.l1_instruction_cache_size);
+  add_int_item(L, "l1_data_cache", lua_cpu.l1_data_cache_size);
+  add_int_item(L, "l2_cache", lua_cpu.l2_cache_size);
+  add_int_item(L, "family_id", lua_cpu.family);
+  add_int_item(L, "model_id", lua_cpu.model_id);
+  add_int_item(L, "stepping", lua_cpu.stepping);
+
+  add_flag(L, lua_cpu.flags.fpu, "fpu");
+  add_flag(L, lua_cpu.flags.vme, "vme");
+  add_flag(L, lua_cpu.flags.de, "de");
+  add_flag(L, lua_cpu.flags.pse, "pse");
+  add_flag(L, lua_cpu.flags.tsc, "tsc");
+  add_flag(L, lua_cpu.flags.msr, "msr");
+  add_flag(L, lua_cpu.flags.pae, "pae");
+  add_flag(L, lua_cpu.flags.mce, "mce");
+  add_flag(L, lua_cpu.flags.cx8, "cx8");
+  add_flag(L, lua_cpu.flags.apic, "apic");
+  add_flag(L, lua_cpu.flags.sep, "sep");
+  add_flag(L, lua_cpu.flags.mtrr, "mtrr");
+  add_flag(L, lua_cpu.flags.pge, "pge");
+  add_flag(L, lua_cpu.flags.mca, "mca");
+  add_flag(L, lua_cpu.flags.cmov, "cmov");
+  add_flag(L, lua_cpu.flags.pat, "pat");
+  add_flag(L, lua_cpu.flags.pse_36, "pse_36");
+  add_flag(L, lua_cpu.flags.psn, "psn");
+  add_flag(L, lua_cpu.flags.clflsh, "clflsh");
+  add_flag(L, lua_cpu.flags.dts, "dts");
+  add_flag(L, lua_cpu.flags.acpi, "acpi");
+  add_flag(L, lua_cpu.flags.mmx, "mmx");
+  add_flag(L, lua_cpu.flags.sse, "sse");
+  add_flag(L, lua_cpu.flags.sse2, "sse2");
+  add_flag(L, lua_cpu.flags.ss, "ss");
+  add_flag(L, lua_cpu.flags.htt, "ht");
+  add_flag(L, lua_cpu.flags.acc, "acc");
+  add_flag(L, lua_cpu.flags.syscall, "syscall");
+  add_flag(L, lua_cpu.flags.mp, "mp");
+  add_flag(L, lua_cpu.flags.nx, "nx");
+  add_flag(L, lua_cpu.flags.mmxext, "mmxext");
+  add_flag(L, lua_cpu.flags.lm, "lm");
+  add_flag(L, lua_cpu.flags.nowext, "3dnowext");
+  add_flag(L, lua_cpu.flags.now, "3dnow!");
+  add_flag(L, lua_cpu.flags.svm, "svm");
+  add_flag(L, lua_cpu.flags.vmx, "vmx");
+  add_flag(L, lua_cpu.flags.pbe, "pbe");
+  add_flag(L, lua_cpu.flags.fxsr_opt, "fxsr_opt");
+  add_flag(L, lua_cpu.flags.gbpages, "gbpages");
+  add_flag(L, lua_cpu.flags.rdtscp, "rdtscp");
+  add_flag(L, lua_cpu.flags.pni, "pni");
+  add_flag(L, lua_cpu.flags.pclmulqd, "pclmulqd");
+  add_flag(L, lua_cpu.flags.dtes64, "dtes64");
+  add_flag(L, lua_cpu.flags.smx, "smx");
+  add_flag(L, lua_cpu.flags.est, "est");
+  add_flag(L, lua_cpu.flags.tm2, "tm2");
+  add_flag(L, lua_cpu.flags.sse3, "sse3");
+  add_flag(L, lua_cpu.flags.fma, "fma");
+  add_flag(L, lua_cpu.flags.cx16, "cx16");
+  add_flag(L, lua_cpu.flags.xtpr, "xtpr");
+  add_flag(L, lua_cpu.flags.pdcm, "pdcm");
+  add_flag(L, lua_cpu.flags.dca, "dca");
+  add_flag(L, lua_cpu.flags.xmm4_1, "xmm4_1");
+  add_flag(L, lua_cpu.flags.xmm4_2, "xmm4_2");
+  add_flag(L, lua_cpu.flags.x2apic, "x2apic");
+  add_flag(L, lua_cpu.flags.movbe, "movbe");
+  add_flag(L, lua_cpu.flags.popcnt, "popcnt");
+  add_flag(L, lua_cpu.flags.aes, "aes");
+  add_flag(L, lua_cpu.flags.xsave, "xsave");
+  add_flag(L, lua_cpu.flags.osxsave, "osxsave");
+  add_flag(L, lua_cpu.flags.avx, "avx");
+  add_flag(L, lua_cpu.flags.hypervisor, "hypervisor");
+  add_flag(L, lua_cpu.flags.ace2, "ace2");
+  add_flag(L, lua_cpu.flags.ace2_en, "ace2_en");
+  add_flag(L, lua_cpu.flags.phe, "phe");
+  add_flag(L, lua_cpu.flags.phe_en, "phe_en");
+  add_flag(L, lua_cpu.flags.pmm, "pmm");
+  add_flag(L, lua_cpu.flags.pmm_en, "pmm_en");
+  add_flag(L, lua_cpu.flags.extapic, "extapic");
+  add_flag(L, lua_cpu.flags.cr8_legacy, "cr8_legacy");
+  add_flag(L, lua_cpu.flags.abm, "abm");
+  add_flag(L, lua_cpu.flags.sse4a, "sse4a");
+  add_flag(L, lua_cpu.flags.misalignsse, "misalignsse");
+  add_flag(L, lua_cpu.flags.nowprefetch, "3dnowprefetch");
+  add_flag(L, lua_cpu.flags.osvw, "osvw");
+  add_flag(L, lua_cpu.flags.ibs, "ibs");
+  add_flag(L, lua_cpu.flags.sse5, "sse5");
+  add_flag(L, lua_cpu.flags.skinit, "skinit");
+  add_flag(L, lua_cpu.flags.wdt, "wdt");
+  add_flag(L, lua_cpu.flags.ida, "ida");
+  add_flag(L, lua_cpu.flags.arat, "arat");
+  add_flag(L, lua_cpu.flags.tpr_shadow, "tpr_shadow");
+  add_flag(L, lua_cpu.flags.vnmi, "vnmi");
+  add_flag(L, lua_cpu.flags.flexpriority, "flexpriority");
+  add_flag(L, lua_cpu.flags.ept, "ept");
+  add_flag(L, lua_cpu.flags.vpid, "vpid");
+
+  /* return number of return values on stack */
+  return 1;
+}
+
+static const luaL_Reg cpulib[] = {
+  {"flags", cpu_getflags},
+  {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_cpu(lua_State *L) {
+  luaL_newlib(L, cpulib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,358 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2011 Timothy J Gleason <timmgleason_at_gmail.com> - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * dhcp.c
+ *
+ * Adds DHCPINFO functionality to the lua.c32 binary
+ *
+ * gettable() returns a table of the BOOTP message fields returned by
+ * the DHCP server for use in a Lua pxeboot script
+ * See http://tools.ietf.org/html/rfc1542
+ *
+ *	lua key value		RFC key
+ * ----------------------------------------------------------------------- 
+ *	opcode			op	 message opcode 
+ *	hardware.type		htype	 Hardware address type 
+ *	hardware.length		hlen	 Hardware address length 
+ *	hops			hops	 Used by relay agents 
+ *	transaction.id		xid	 transaction id 
+ *	elapsed.seconds		secs	 Secs elapsed since client boot 
+ *	flags			flags	 DHCP Flags field 
+ *	client.ip.addr		ciaddr	 client IP addr 
+ *	your.ip.addr		yiaddr	 'Your' IP addr. (from server) 
+ *	server.ip.addr		siaddr	 Boot server IP addr 
+ *	gateway.ip.addr		giaddr	 Relay agent IP addr 
+ *	client.mac		chaddr	 Client hardware addr 
+ *	server.hostname		sname	 Optl. boot server hostname 
+ * 	boot.file		file	 boot file name (ascii path) 
+ *	magic.cookie		cookie	 Magic cookie 
+ *
+ * getoptions() returns a table of the DHCP Options field of the BOOTP
+ * message returned by the DHCP server for use in a Lua pxeboot script.
+ * Many of the options are reurned formatted in as strings in a standard,
+ * recognizable format, such as IP addresses.
+ *
+ * 1, 2, and 4 byte numerical options are returned as integers. 
+ *
+ * Other Options with non-standard formats are returned as strings of the 
+ * raw binary number that was returned by the DHCP server and must be decoded
+ * in a Lua script 
+ *
+ * The Options table returns the Option code as the key except where there
+ * are multiple values returned. In those cases, an extra key increment number
+ * is added to allow individual access to each Option value.
+ * 
+ *	lua key value		value Name
+ * ----------------------------------------------------------------------- 
+ *	1			Subnet Mask
+ *	6.1			DNS Server [element 1]
+ *	6.2			DNS Server [element 2]
+ *	6.3			DNS Server [element 3]
+ *	209			PXE Configuration File
+ *	21.1			Policy Filter [element 1]
+ *	21.2			Policy Filter [element 2]
+ *	
+ * Options that can have a list of values, but contain only one (like Option 6)
+ * will not return with .sub key values.	
+ *
+ * Usage:
+            t = dhcp.gettable()
+
+            for k,v in pairs(t) do
+              print(k.." : "..v)
+            end
+ */
+
+#include <stdio.h>
+#include "dhcp.h"
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include <syslinux/pxe.h>
+
+#define STR_BUF_SIZE	129 /* Sized to accomdate File field in BOOTP message */
+
+void
+ip_address_list(lua_State *L, uint8_t* value, uint8_t len, uint8_t option )
+{
+  static char	op_name[64];
+  static char	op_value[255];
+  int		loop;
+
+  loop = len/4;
+
+  if ( loop == 1) {
+    sprintf(op_name, "%u", option);
+    lua_pushstring(L, op_name);
+    sprintf(op_value, "%u.%u.%u.%u", value[0], value[1], value[2], value[3]);
+    lua_pushstring(L, op_value);
+    lua_settable(L,-3);
+  } else {
+      for (int done = 0; done < loop; done++){
+	sprintf(op_name, "%u.%d", option, done+1);
+	lua_pushstring(L, op_name);
+	sprintf(op_value, "%u.%u.%u.%u", value[0+(done*4)], value[1+(done*4)], value[2+(done*4)], value[3+(done*4)]);
+	lua_pushstring(L, op_value);
+	lua_settable(L,-3);
+      }
+  }
+
+}
+
+static int dhcp_getoptions(lua_State *L)
+{
+  void*		dhcpdata = 0;
+  dhcp_t*	dhcp = 0;
+  size_t	dhcplen = 0;
+
+  /* Append the DHCP info */
+  if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
+    &dhcpdata, &dhcplen))
+  {
+    return 0;
+  }
+
+  dhcp = (dhcp_t*)dhcpdata;
+
+  lua_newtable(L);
+
+  int		done = 0;
+  uint8_t*	ptr = (uint8_t*)&dhcp->options;
+  uint8_t	len;
+  uint8_t	option;
+  uint8_t*	value;
+  static char	op_name[64];
+
+  do {
+      option = *ptr++;
+      len = *ptr++;
+      value = ptr;
+      ptr += len;
+      switch (option) {
+// IP Address formatted lists, including singles
+	case 1:
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 16:
+	case 21: /* Policy Filters - address/mask */
+	case 28:
+	case 32:
+	case 33: /* Static routes - destination/router */
+	case 41:
+	case 42:
+	case 44:
+	case 45:
+	case 47:
+	case 48:
+	case 49:
+	case 50:
+	case 51:
+	case 54:
+	case 65:
+	case 68:
+	case 69:
+	case 70:
+	case 71:
+	case 72:
+	case 73:
+	case 74:
+	case 75:
+	case 76:
+	  ip_address_list(L, value, len, option);
+          break;
+// 4byte options - numerical
+        case 2:
+        case 24:
+        case 35:
+        case 38:
+        case 58:
+        case 59:
+        case 211:
+	  sprintf(op_name, "%u", option);
+	  lua_pushstring(L, op_name);
+	  lua_pushinteger(L, ntohl(*(long*)value));
+	  lua_settable(L,-3);
+          break;
+// 2byte options -numerical
+        case 13:
+        case 22:
+        case 26:
+        case 57:
+	  sprintf(op_name, "%u", option);
+	  lua_pushstring(L, op_name);
+	  lua_pushinteger(L, ntohs(*(short*)value));
+	  lua_settable(L,-3);
+          break;
+// 1byte options - numerical
+        case 19:
+        case 20:
+        case 23:
+        case 27:
+        case 29:
+        case 30:
+        case 31:
+        case 34:
+        case 36:
+        case 37:
+        case 39:
+        case 46:
+        case 52:
+        case 53:
+	  sprintf(op_name, "%u", option);
+	  lua_pushstring(L, op_name);
+	  lua_pushinteger(L, *value);
+	  lua_settable(L,-3);
+          break;
+        case 255: 
+          done = 1;
+	  break;
+        default:
+	  sprintf(op_name, "%u", option);
+	  lua_pushstring(L, op_name);
+	  lua_pushlstring(L, (const char*)value, len);
+	  lua_settable(L,-3);
+          break;
+      }
+
+    } while (!done);
+
+  return 1;
+}
+
+static int	dhcp_gettable(lua_State *L)
+{
+  void*		dhcpdata = 0;
+  dhcp_t*	dhcp = 0;
+  size_t	dhcplen = 0;
+  static char	dhcp_arg[STR_BUF_SIZE];
+
+  /* Append the DHCP info */
+  if (pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK,
+    &dhcpdata, &dhcplen))
+  {
+    return 0;
+  }
+
+  dhcp = (dhcp_t*)dhcpdata;
+
+
+  lua_newtable(L);
+
+  lua_pushstring(L, "opcode");
+  lua_pushinteger(L, dhcp->op);
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "hardware.type");
+  lua_pushinteger(L, dhcp->htype);
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "hardware.length");
+  lua_pushinteger(L, dhcp->hlen);
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "hops");
+  lua_pushinteger(L, dhcp->hops);
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "transaction.id");
+  lua_pushinteger(L, ntohl(dhcp->xid));
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "elapsed.seconds");
+  lua_pushinteger(L, ntohs(dhcp->secs));
+  lua_settable(L,-3);
+
+  lua_pushstring(L, "flags");
+  lua_pushinteger(L, ntohs(dhcp->flags));
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->ciaddr[0], dhcp->ciaddr[1], dhcp->ciaddr[2], dhcp->ciaddr[3]);
+  lua_pushstring(L, "client.ip.addr");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->yiaddr[0], dhcp->yiaddr[1], dhcp->yiaddr[2], dhcp->yiaddr[3]);
+  lua_pushstring(L, "your.ip.addr");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->siaddr[0], dhcp->siaddr[1], dhcp->siaddr[2], dhcp->siaddr[3]);
+  lua_pushstring(L, "server.ip.addr");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->giaddr[0], dhcp->giaddr[1], dhcp->giaddr[2], dhcp->giaddr[3]);
+  lua_pushstring(L, "gateway.ip.addr");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%02X:%02X:%02X:%02X:%02X:%02X",
+                    dhcp->chaddr[0], dhcp->chaddr[1], dhcp->chaddr[2],
+                    dhcp->chaddr[3], dhcp->chaddr[4], dhcp->chaddr[5]);
+  lua_pushstring(L, "client.mac");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->sname);
+  dhcp_arg[STR_BUF_SIZE-1] = 0; 	/* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
+  lua_pushstring(L, "server.hostname");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  snprintf(dhcp_arg, STR_BUF_SIZE, "%s", dhcp->file);
+  dhcp_arg[STR_BUF_SIZE-1] = 0; 	/* Guarantee for lua_pushstring that dhcp_arg is 0 terminated /*/
+  lua_pushstring(L, "boot.file");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  sprintf(dhcp_arg, "%u.%u.%u.%u", dhcp->cookie[0], dhcp->cookie[1], dhcp->cookie[2], dhcp->cookie[3]);
+  lua_pushstring(L, "magic.cookie");
+  lua_pushstring(L, dhcp_arg);
+  lua_settable(L,-3);
+
+  return 1;
+}
+
+static const luaL_Reg dhcplib[] = {
+  {"gettable", dhcp_gettable},
+  {"getoptions", dhcp_getoptions},
+  {NULL, NULL}
+};
+
+LUALIB_API int luaopen_dhcp (lua_State *L) {
+  luaL_newlib(L, dhcplib);
+  return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/dhcp.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2011 Timothy J Gleason <timmgleason_at_gmail.com> - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdint.h>
+
+typedef struct dhcp {
+  uint8_t	op;			/* message opcode */
+  uint8_t	htype;			/* Hardware address type */
+  uint8_t	hlen;			/* Hardware address length */
+  uint8_t	hops;			/* Used by relay agents */
+  uint32_t	xid;			/* transaction id */
+  uint16_t	secs;			/* Secs elapsed since client boot */
+  uint16_t	flags;			/* DHCP Flags field */
+  uint8_t	ciaddr[4];		/* client IP addr */
+  uint8_t	yiaddr[4];		/* 'Your' IP addr. (from server) */
+  uint8_t	siaddr[4];		/* Boot server IP addr */
+  uint8_t	giaddr[4];		/* Relay agent IP addr */
+  uint8_t	chaddr[16];		/* Client hardware addr */
+  uint8_t	sname[64];		/* Optl. boot server hostname */
+  uint8_t	file[128];		/* boot file name (ascii path) */
+  uint8_t	cookie[4];		/* Magic cookie */
+  uint8_t	options[1020];		/* Options */
+} dhcp_t;
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,535 @@
+#include <stdlib.h>
+#include <string.h>
+
+#define ldmilib_c       /* Define the library */
+
+/* Include the Lua API header files */
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "dmi/dmi.h"
+
+static void add_string_item(lua_State *L, const char *item, const char *value_str) {
+ lua_pushstring(L,item);
+ lua_pushstring(L,value_str);
+ lua_settable(L,-3);
+}
+
+static void add_int_item(lua_State *L, const char *item, int value_int) {
+ lua_pushstring(L,item);
+ lua_pushnumber(L,value_int);
+ lua_settable(L,-3);
+}
+
+typedef int (*table_fn)(lua_State*, s_dmi*);
+
+/* Add a Lua_String entry to the table on stack
+   xxx_P is the poiter version (i.e., pBase is a pointer)
+   xxx_S is the staic version (i.e., Base is the struct)
+*/
+#define LUA_ADD_STR_P(pLua_state, pBase, Field) \
+  add_string_item(pLua_state, #Field, pBase->Field);
+#define LUA_ADD_STR_S(pLua_state, Base, Field) \
+  add_string_item(pLua_state, #Field, Base.Field);
+
+/* Add a Lua_Number entry to the table on stack
+   xxx_P is the poiter version (i.e., pBase is a pointer)
+   xxx_S is the staic version (i.e., Base is the struct)
+*/
+#define LUA_ADD_NUM_P(pLua_state, pBase, Field) \
+  add_int_item(pLua_state, #Field, pBase->Field);
+#define LUA_ADD_NUM_S(pLua_state, Base, Field) \
+  add_int_item(pLua_state, #Field, Base.Field);
+
+/* Add a sub-DMI table to the table on stack
+   All (*table_fn)() have to be named as get_<tabel_name>_table() for this
+   macro to work. For example, for the bios subtable, the table_fn is
+   get_bios_table() and the subtable name is "bios".
+   All (*table_fn)() have to return 1 if a subtable is created on the stack
+   or 0 if the subtable is not created (no corresponding dim subtable found).
+*/
+#define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \
+  add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table);
+
+
+static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name,
+                              table_fn get_table_fn)
+{
+  if (get_table_fn(L, dmi_ptr)) {  /* only adding it when it is there */
+    lua_pushstring(L, table_name);
+    lua_insert(L, -2);
+    lua_settable(L,-3);
+  }
+}
+
+
+void get_bool_table(lua_State *L, const char *str_table[], int n_elem,
+                           bool *bool_table)
+{
+  int i;
+  for (i = 0; i < n_elem; i++) {
+    if (!str_table[i] || !*str_table[i])  /* aviod NULL/empty string */
+      continue;
+
+    lua_pushstring(L, str_table[i]);
+    lua_pushboolean(L, bool_table[i]);
+    lua_settable(L,-3);
+  }
+}
+
+
+/*
+** {======================================================
+** DMI subtables
+** =======================================================
+*/
+static int get_bios_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_bios *bios = &dmi_ptr->bios;
+
+  if (!bios->filled)
+    return 0;
+  /* bios */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, bios, vendor)
+  LUA_ADD_STR_P(L, bios, version)
+  LUA_ADD_STR_P(L, bios, release_date)
+  LUA_ADD_STR_P(L, bios, bios_revision)
+  LUA_ADD_STR_P(L, bios, firmware_revision)
+  LUA_ADD_NUM_P(L, bios, address)
+  LUA_ADD_NUM_P(L, bios, runtime_size)
+  LUA_ADD_STR_P(L, bios, runtime_size_unit)
+  LUA_ADD_NUM_P(L, bios, rom_size)
+  LUA_ADD_STR_P(L, bios, rom_size_unit)
+
+  /* bios characteristics */
+  lua_pushstring(L, "chars");
+  lua_newtable(L);
+  get_bool_table(L, bios_charac_strings,
+                 sizeof(s_characteristics)/sizeof(bool),
+                 (bool *)(&bios->characteristics));
+  get_bool_table(L, bios_charac_x1_strings,
+                 sizeof(s_characteristics_x1)/sizeof(bool),
+                 (bool *)(&bios->characteristics_x1));
+  get_bool_table(L, bios_charac_x2_strings,
+                 sizeof(s_characteristics_x2)/sizeof(bool),
+                 (bool *)(&bios->characteristics_x2));
+  lua_settable(L,-3);
+
+  return 1;
+}
+
+
+static int get_system_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_system *system = &dmi_ptr->system;
+
+  if (!system->filled)
+    return 0;
+  /* system */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, system, manufacturer)
+  LUA_ADD_STR_P(L, system, product_name)
+  LUA_ADD_STR_P(L, system, version)
+  LUA_ADD_STR_P(L, system, serial)
+  LUA_ADD_STR_P(L, system, uuid)
+  LUA_ADD_STR_P(L, system, wakeup_type)
+  LUA_ADD_STR_P(L, system, sku_number)
+  LUA_ADD_STR_P(L, system, family)
+  LUA_ADD_STR_P(L, system, system_boot_status)
+  LUA_ADD_STR_P(L, system, configuration_options)
+
+  /* system reset */
+  if (system->system_reset.filled) {
+    lua_pushstring(L, "reset");
+    lua_newtable(L);
+    LUA_ADD_NUM_S(L, system->system_reset, status)
+    LUA_ADD_NUM_S(L, system->system_reset, watchdog)
+    LUA_ADD_STR_S(L, system->system_reset, boot_option)
+    LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit)
+	  LUA_ADD_STR_S(L, system->system_reset, reset_count)
+	  LUA_ADD_STR_S(L, system->system_reset, reset_limit)
+	  LUA_ADD_STR_S(L, system->system_reset, timer_interval)
+	  LUA_ADD_STR_S(L, system->system_reset, timeout)
+    lua_settable(L,-3);
+  }
+
+  return 1;
+}
+
+
+static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_base_board *base_board = &dmi_ptr->base_board;
+  int n_dev = sizeof(base_board->devices_information) /
+              sizeof(base_board->devices_information[0]);
+  int i, j, has_dev;
+
+  if (!base_board->filled)
+    return 0;
+  /* base_board */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, base_board, manufacturer)
+  LUA_ADD_STR_P(L, base_board, product_name)
+  LUA_ADD_STR_P(L, base_board, version)
+  LUA_ADD_STR_P(L, base_board, serial)
+  LUA_ADD_STR_P(L, base_board, asset_tag)
+  LUA_ADD_STR_P(L, base_board, location)
+  LUA_ADD_STR_P(L, base_board, type)
+
+  /* base board features */
+  lua_pushstring(L, "features");
+  lua_newtable(L);
+  get_bool_table(L, base_board_features_strings,
+                 sizeof(s_base_board_features)/sizeof(bool),
+                 (bool *)(&base_board->features));
+  lua_settable(L,-3);
+
+  /* on-board devices */
+  for (has_dev = 0, i = 0; i < n_dev; i++)
+    if (*base_board->devices_information[i].type)
+      has_dev++;
+
+  if (has_dev) {
+    lua_pushstring(L, "devices");
+    lua_newtable(L);
+    for (i = 0, j = 1; i < n_dev; i++) {
+      if (!*base_board->devices_information[i].type)  /* empty device */
+        continue;
+
+      lua_pushinteger(L, j++);
+      lua_newtable(L);
+      LUA_ADD_STR_S(L, base_board->devices_information[i], type)
+      LUA_ADD_STR_S(L, base_board->devices_information[i], description)
+      LUA_ADD_NUM_S(L, base_board->devices_information[i], status)
+      lua_settable(L,-3);
+    }
+    lua_settable(L,-3);
+  }
+
+  return 1;
+}
+
+
+static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_chassis *chassis = &dmi_ptr->chassis;
+
+  if (!chassis->filled)
+    return 0;
+  /* chassis */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, chassis, manufacturer)
+  LUA_ADD_STR_P(L, chassis, type)
+  LUA_ADD_STR_P(L, chassis, lock)
+  LUA_ADD_STR_P(L, chassis, version)
+  LUA_ADD_STR_P(L, chassis, serial)
+  LUA_ADD_STR_P(L, chassis, asset_tag)
+  LUA_ADD_STR_P(L, chassis, boot_up_state)
+  LUA_ADD_STR_P(L, chassis, power_supply_state)
+  LUA_ADD_STR_P(L, chassis, thermal_state)
+  LUA_ADD_STR_P(L, chassis, security_status)
+  LUA_ADD_STR_P(L, chassis, oem_information)
+  LUA_ADD_NUM_P(L, chassis, height)
+  LUA_ADD_NUM_P(L, chassis, nb_power_cords)
+
+  return 1;
+}
+
+
+static int get_processor_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_processor *processor = &dmi_ptr->processor;
+  s_signature *signature = &processor->signature;
+
+  if (!processor->filled)
+    return 0;
+  /* processor */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, processor, socket_designation)
+  LUA_ADD_STR_P(L, processor, type)
+  LUA_ADD_STR_P(L, processor, family)
+  LUA_ADD_STR_P(L, processor, manufacturer)
+  LUA_ADD_STR_P(L, processor, version)
+  LUA_ADD_NUM_P(L, processor, external_clock)
+  LUA_ADD_NUM_P(L, processor, max_speed)
+  LUA_ADD_NUM_P(L, processor, current_speed)
+  LUA_ADD_NUM_P(L, processor, voltage_mv)
+  LUA_ADD_STR_P(L, processor, status)
+  LUA_ADD_STR_P(L, processor, upgrade)
+  LUA_ADD_STR_P(L, processor, cache1)
+  LUA_ADD_STR_P(L, processor, cache2)
+  LUA_ADD_STR_P(L, processor, cache3)
+  LUA_ADD_STR_P(L, processor, serial)
+  LUA_ADD_STR_P(L, processor, part_number)
+  LUA_ADD_STR_P(L, processor, id)
+  LUA_ADD_NUM_P(L, processor, core_count)
+  LUA_ADD_NUM_P(L, processor, core_enabled)
+  LUA_ADD_NUM_P(L, processor, thread_count)
+
+  /* processor signature */
+  lua_pushstring(L, "signature");
+  lua_newtable(L);
+  LUA_ADD_NUM_P(L, signature, type)
+  LUA_ADD_NUM_P(L, signature, family)
+  LUA_ADD_NUM_P(L, signature, model)
+  LUA_ADD_NUM_P(L, signature, stepping)
+  LUA_ADD_NUM_P(L, signature, minor_stepping)
+  lua_settable(L,-3);
+
+  /* processor flags */
+  lua_pushstring(L, "flags");
+  lua_newtable(L);
+  get_bool_table(L, cpu_flags_strings,
+                 sizeof(s_dmi_cpu_flags)/sizeof(bool),
+                 (bool *)(&processor->cpu_flags));
+  lua_settable(L,-3);
+
+  return 1;
+}
+
+
+static int get_battery_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_battery *battery = &dmi_ptr->battery;
+
+  if (!battery->filled)
+    return 0;
+  /* battery */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, battery, location)
+  LUA_ADD_STR_P(L, battery, manufacturer)
+  LUA_ADD_STR_P(L, battery, manufacture_date)
+  LUA_ADD_STR_P(L, battery, serial)
+  LUA_ADD_STR_P(L, battery, name)
+  LUA_ADD_STR_P(L, battery, chemistry)
+  LUA_ADD_STR_P(L, battery, design_capacity)
+  LUA_ADD_STR_P(L, battery, design_voltage)
+  LUA_ADD_STR_P(L, battery, sbds)
+  LUA_ADD_STR_P(L, battery, sbds_serial)
+  LUA_ADD_STR_P(L, battery, maximum_error)
+  LUA_ADD_STR_P(L, battery, sbds_manufacture_date)
+  LUA_ADD_STR_P(L, battery, sbds_chemistry)
+  LUA_ADD_STR_P(L, battery, oem_info)
+
+  return 1;
+}
+
+
+static int get_memory_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_memory *memory = dmi_ptr->memory;
+  int i, j, n_mem = dmi_ptr->memory_count;
+
+  if (n_mem <= 0)  /*  no memory info */
+    return 0;
+
+  /* memory */
+  lua_newtable(L);
+  for (j = 1, i = 0; i < n_mem; i++) {
+    if (!memory[i].filled)
+      continue;
+
+    lua_pushinteger(L, j++);
+    lua_newtable(L);
+    LUA_ADD_STR_S(L, memory[i], manufacturer)
+    LUA_ADD_STR_S(L, memory[i], error)
+    LUA_ADD_STR_S(L, memory[i], total_width)
+    LUA_ADD_STR_S(L, memory[i], data_width)
+    LUA_ADD_STR_S(L, memory[i], size)
+    LUA_ADD_STR_S(L, memory[i], form_factor)
+    LUA_ADD_STR_S(L, memory[i], device_set)
+    LUA_ADD_STR_S(L, memory[i], device_locator)
+    LUA_ADD_STR_S(L, memory[i], bank_locator)
+    LUA_ADD_STR_S(L, memory[i], type)
+    LUA_ADD_STR_S(L, memory[i], type_detail)
+    LUA_ADD_STR_S(L, memory[i], speed)
+    LUA_ADD_STR_S(L, memory[i], serial)
+    LUA_ADD_STR_S(L, memory[i], asset_tag)
+    LUA_ADD_STR_S(L, memory[i], part_number)
+    lua_settable(L,-3);
+  }
+  return 1;
+}
+
+
+static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_memory_module *memory_module = dmi_ptr->memory_module;
+  int i, j, n_mem = dmi_ptr->memory_module_count;
+
+  if (n_mem <= 0)  /*  no memory module info */
+    return 0;
+
+  /* memory module */
+  lua_newtable(L);
+  for (j = 1, i = 0; i < n_mem; i++) {
+    if (!memory_module[i].filled)
+      continue;
+
+    lua_pushinteger(L, j++);
+    lua_newtable(L);
+    LUA_ADD_STR_S(L, memory_module[i], socket_designation)
+    LUA_ADD_STR_S(L, memory_module[i], bank_connections)
+    LUA_ADD_STR_S(L, memory_module[i], speed)
+    LUA_ADD_STR_S(L, memory_module[i], type)
+    LUA_ADD_STR_S(L, memory_module[i], installed_size)
+    LUA_ADD_STR_S(L, memory_module[i], enabled_size)
+    LUA_ADD_STR_S(L, memory_module[i], error_status)
+    lua_settable(L,-3);
+  }
+  return 1;
+}
+
+
+static int get_cache_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_cache *cache = dmi_ptr->cache;
+  int i, n_cache = dmi_ptr->cache_count;
+
+  if (n_cache <= 0)  /*  no cache info */
+    return 0;
+
+  /* memory */
+  lua_newtable(L);
+  for (i = 0; i < n_cache; i++) {
+    lua_pushinteger(L, i + 1);
+    lua_newtable(L);
+    LUA_ADD_STR_S(L, cache[i], socket_designation)
+    LUA_ADD_STR_S(L, cache[i], configuration)
+    LUA_ADD_STR_S(L, cache[i], mode)
+    LUA_ADD_STR_S(L, cache[i], location)
+    LUA_ADD_NUM_S(L, cache[i], installed_size)
+    LUA_ADD_NUM_S(L, cache[i], max_size)
+    LUA_ADD_STR_S(L, cache[i], supported_sram_types)
+    LUA_ADD_STR_S(L, cache[i], installed_sram_types)
+    LUA_ADD_NUM_S(L, cache[i], speed)
+    LUA_ADD_STR_S(L, cache[i], error_correction_type)
+    LUA_ADD_STR_S(L, cache[i], system_type)
+    LUA_ADD_STR_S(L, cache[i], associativity)
+    lua_settable(L,-3);
+  }
+  return 1;
+}
+
+
+static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  if (!dmi_ptr->hardware_security.filled)
+    return 0;
+  /* hardware_security */
+  lua_newtable(L);
+  LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status)
+	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status)
+	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status)
+	LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status)
+
+  return 1;
+}
+
+
+static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  dmi_table *dmitable = &dmi_ptr->dmitable;
+
+  /* dmi info */
+  lua_newtable(L);
+  LUA_ADD_NUM_P(L, dmitable, num)
+  LUA_ADD_NUM_P(L, dmitable, len)
+  LUA_ADD_NUM_P(L, dmitable, ver)
+  LUA_ADD_NUM_P(L, dmitable, base)
+  LUA_ADD_NUM_P(L, dmitable, major_version)
+  LUA_ADD_NUM_P(L, dmitable, minor_version)
+
+  return 1;
+}
+
+
+static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr)
+{
+  s_ipmi *ipmi = &dmi_ptr->ipmi;
+
+  if (!ipmi->filled)
+    return 0;
+  /* ipmi */
+  lua_newtable(L);
+  LUA_ADD_STR_P(L, ipmi, interface_type)
+  LUA_ADD_NUM_P(L, ipmi, major_specification_version)
+  LUA_ADD_NUM_P(L, ipmi, minor_specification_version)
+  LUA_ADD_NUM_P(L, ipmi, I2C_slave_address)
+  LUA_ADD_NUM_P(L, ipmi, nv_address)
+  LUA_ADD_NUM_P(L, ipmi, base_address)
+  LUA_ADD_NUM_P(L, ipmi, irq)
+
+  return 1;
+}
+/*
+** {======================================================
+** End of DMI subtables
+** =======================================================
+*/
+
+
+static int dmi_gettable(lua_State *L)
+{
+  s_dmi dmi;
+
+  lua_newtable(L);
+
+  if ( ! dmi_iterate(&dmi) ) {
+          printf("No DMI Structure found\n");
+          return -1;
+  }
+
+  parse_dmitable(&dmi);
+
+  LUA_ADD_NUM_S(L, dmi, memory_module_count)
+  LUA_ADD_NUM_S(L, dmi, memory_count)
+  LUA_ADD_NUM_S(L, dmi, cache_count)
+  LUA_ADD_STR_S(L, dmi, oem_strings)
+
+  LUA_ADD_TABLE(L, &dmi, bios)
+  LUA_ADD_TABLE(L, &dmi, system)
+  LUA_ADD_TABLE(L, &dmi, base_board)
+  LUA_ADD_TABLE(L, &dmi, chassis)
+  LUA_ADD_TABLE(L, &dmi, processor)
+  LUA_ADD_TABLE(L, &dmi, battery)
+  LUA_ADD_TABLE(L, &dmi, memory)
+  LUA_ADD_TABLE(L, &dmi, memory_module)
+  LUA_ADD_TABLE(L, &dmi, cache)
+  LUA_ADD_TABLE(L, &dmi, ipmi)
+  LUA_ADD_TABLE(L, &dmi, hardware_security)
+  LUA_ADD_TABLE(L, &dmi, dmi_info)
+
+  /* set global variable: lua_setglobal(L, "dmitable"); */
+
+  /* return number of return values on stack */
+  return 1;
+}
+
+
+static int dmi_supported(lua_State *L)
+{
+  s_dmi dmi;
+
+  if ( dmi_iterate(&dmi) ) {
+    lua_pushboolean(L, 1);
+  } else {
+    lua_pushboolean(L, 0);
+  }
+  return 1;
+}
+
+
+static const luaL_Reg dmilib[] = {
+  {"gettable", dmi_gettable},
+  {"supported", dmi_supported},
+  {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_dmi (lua_State *L) {
+  luaL_newlib(L, dmilib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1284 @@
+/*
+** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdarg.h>
+#include <string.h>
+
+#define lapi_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+
+
+
+const char lua_ident[] =
+  "$LuaVersion: " LUA_COPYRIGHT " $"
+  "$LuaAuthors: " LUA_AUTHORS " $";
+
+
+/* value at a non-valid index */
+#define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
+
+/* corresponding test */
+#define isvalid(o)	((o) != luaO_nilobject)
+
+/* test for pseudo index */
+#define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
+
+/* test for valid but not pseudo index */
+#define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
+
+#define api_checkvalidindex(L, o)  api_check(L, isvalid(o), "invalid index")
+
+#define api_checkstackindex(L, i, o)  \
+	api_check(L, isstackindex(i, o), "index not in the stack")
+
+
+static TValue *index2addr (lua_State *L, int idx) {
+  CallInfo *ci = L->ci;
+  if (idx > 0) {
+    TValue *o = ci->func + idx;
+    api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
+    if (o >= L->top) return NONVALIDVALUE;
+    else return o;
+  }
+  else if (!ispseudo(idx)) {  /* negative index */
+    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+    return L->top + idx;
+  }
+  else if (idx == LUA_REGISTRYINDEX)
+    return &G(L)->l_registry;
+  else {  /* upvalues */
+    idx = LUA_REGISTRYINDEX - idx;
+    api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
+    if (ttislcf(ci->func))  /* light C function? */
+      return NONVALIDVALUE;  /* it has no upvalues */
+    else {
+      CClosure *func = clCvalue(ci->func);
+      return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
+    }
+  }
+}
+
+
+/*
+** to be called by 'lua_checkstack' in protected mode, to grow stack
+** capturing memory errors
+*/
+static void growstack (lua_State *L, void *ud) {
+  int size = *(int *)ud;
+  luaD_growstack(L, size);
+}
+
+
+LUA_API int lua_checkstack (lua_State *L, int size) {
+  int res;
+  CallInfo *ci = L->ci;
+  lua_lock(L);
+  if (L->stack_last - L->top > size)  /* stack large enough? */
+    res = 1;  /* yes; check is OK */
+  else {  /* no; need to grow stack */
+    int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
+    if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
+      res = 0;  /* no */
+    else  /* try to grow stack */
+      res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
+  }
+  if (res && ci->top < L->top + size)
+    ci->top = L->top + size;  /* adjust frame top */
+  lua_unlock(L);
+  return res;
+}
+
+
+LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
+  int i;
+  if (from == to) return;
+  lua_lock(to);
+  api_checknelems(from, n);
+  api_check(from, G(from) == G(to), "moving among independent states");
+  api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
+  from->top -= n;
+  for (i = 0; i < n; i++) {
+    setobj2s(to, to->top++, from->top + i);
+  }
+  lua_unlock(to);
+}
+
+
+LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
+  lua_CFunction old;
+  lua_lock(L);
+  old = G(L)->panic;
+  G(L)->panic = panicf;
+  lua_unlock(L);
+  return old;
+}
+
+
+LUA_API const lua_Number *lua_version (lua_State *L) {
+  static const lua_Number version = LUA_VERSION_NUM;
+  if (L == NULL) return &version;
+  else return G(L)->version;
+}
+
+
+
+/*
+** basic stack manipulation
+*/
+
+
+/*
+** convert an acceptable stack index into an absolute index
+*/
+LUA_API int lua_absindex (lua_State *L, int idx) {
+  return (idx > 0 || ispseudo(idx))
+         ? idx
+         : cast_int(L->top - L->ci->func + idx);
+}
+
+
+LUA_API int lua_gettop (lua_State *L) {
+  return cast_int(L->top - (L->ci->func + 1));
+}
+
+
+LUA_API void lua_settop (lua_State *L, int idx) {
+  StkId func = L->ci->func;
+  lua_lock(L);
+  if (idx >= 0) {
+    api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
+    while (L->top < (func + 1) + idx)
+      setnilvalue(L->top++);
+    L->top = (func + 1) + idx;
+  }
+  else {
+    api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
+    L->top += idx+1;  /* `subtract' index (index is negative) */
+  }
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_remove (lua_State *L, int idx) {
+  StkId p;
+  lua_lock(L);
+  p = index2addr(L, idx);
+  api_checkstackindex(L, idx, p);
+  while (++p < L->top) setobjs2s(L, p-1, p);
+  L->top--;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_insert (lua_State *L, int idx) {
+  StkId p;
+  StkId q;
+  lua_lock(L);
+  p = index2addr(L, idx);
+  api_checkstackindex(L, idx, p);
+  for (q = L->top; q > p; q--)  /* use L->top as a temporary */
+    setobjs2s(L, q, q - 1);
+  setobjs2s(L, p, L->top);
+  lua_unlock(L);
+}
+
+
+static void moveto (lua_State *L, TValue *fr, int idx) {
+  TValue *to = index2addr(L, idx);
+  api_checkvalidindex(L, to);
+  setobj(L, to, fr);
+  if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
+    luaC_barrier(L, clCvalue(L->ci->func), fr);
+  /* LUA_REGISTRYINDEX does not need gc barrier
+     (collector revisits it before finishing collection) */
+}
+
+
+LUA_API void lua_replace (lua_State *L, int idx) {
+  lua_lock(L);
+  api_checknelems(L, 1);
+  moveto(L, L->top - 1, idx);
+  L->top--;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
+  TValue *fr;
+  lua_lock(L);
+  fr = index2addr(L, fromidx);
+  moveto(L, fr, toidx);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushvalue (lua_State *L, int idx) {
+  lua_lock(L);
+  setobj2s(L, L->top, index2addr(L, idx));
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+
+/*
+** access functions (stack -> C)
+*/
+
+
+LUA_API int lua_type (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
+}
+
+
+LUA_API const char *lua_typename (lua_State *L, int t) {
+  UNUSED(L);
+  return ttypename(t);
+}
+
+
+LUA_API int lua_iscfunction (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  return (ttislcf(o) || (ttisCclosure(o)));
+}
+
+
+LUA_API int lua_isnumber (lua_State *L, int idx) {
+  TValue n;
+  const TValue *o = index2addr(L, idx);
+  return tonumber(o, &n);
+}
+
+
+LUA_API int lua_isstring (lua_State *L, int idx) {
+  int t = lua_type(L, idx);
+  return (t == LUA_TSTRING || t == LUA_TNUMBER);
+}
+
+
+LUA_API int lua_isuserdata (lua_State *L, int idx) {
+  const TValue *o = index2addr(L, idx);
+  return (ttisuserdata(o) || ttislightuserdata(o));
+}
+
+
+LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
+  StkId o1 = index2addr(L, index1);
+  StkId o2 = index2addr(L, index2);
+  return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
+}
+
+
+LUA_API void lua_arith (lua_State *L, int op) {
+  StkId o1;  /* 1st operand */
+  StkId o2;  /* 2nd operand */
+  lua_lock(L);
+  if (op != LUA_OPUNM) /* all other operations expect two operands */
+    api_checknelems(L, 2);
+  else {  /* for unary minus, add fake 2nd operand */
+    api_checknelems(L, 1);
+    setobjs2s(L, L->top, L->top - 1);
+    L->top++;
+  }
+  o1 = L->top - 2;
+  o2 = L->top - 1;
+  if (ttisnumber(o1) && ttisnumber(o2)) {
+    setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
+  }
+  else
+    luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
+  L->top--;
+  lua_unlock(L);
+}
+
+
+LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
+  StkId o1, o2;
+  int i = 0;
+  lua_lock(L);  /* may call tag method */
+  o1 = index2addr(L, index1);
+  o2 = index2addr(L, index2);
+  if (isvalid(o1) && isvalid(o2)) {
+    switch (op) {
+      case LUA_OPEQ: i = equalobj(L, o1, o2); break;
+      case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
+      case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
+      default: api_check(L, 0, "invalid option");
+    }
+  }
+  lua_unlock(L);
+  return i;
+}
+
+
+LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
+  TValue n;
+  const TValue *o = index2addr(L, idx);
+  if (tonumber(o, &n)) {
+    if (isnum) *isnum = 1;
+    return nvalue(o);
+  }
+  else {
+    if (isnum) *isnum = 0;
+    return 0;
+  }
+}
+
+
+LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
+  TValue n;
+  const TValue *o = index2addr(L, idx);
+  if (tonumber(o, &n)) {
+    lua_Integer res;
+    lua_Number num = nvalue(o);
+    lua_number2integer(res, num);
+    if (isnum) *isnum = 1;
+    return res;
+  }
+  else {
+    if (isnum) *isnum = 0;
+    return 0;
+  }
+}
+
+
+LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
+  TValue n;
+  const TValue *o = index2addr(L, idx);
+  if (tonumber(o, &n)) {
+    lua_Unsigned res;
+    lua_Number num = nvalue(o);
+    lua_number2unsigned(res, num);
+    if (isnum) *isnum = 1;
+    return res;
+  }
+  else {
+    if (isnum) *isnum = 0;
+    return 0;
+  }
+}
+
+
+LUA_API int lua_toboolean (lua_State *L, int idx) {
+  const TValue *o = index2addr(L, idx);
+  return !l_isfalse(o);
+}
+
+
+LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
+  StkId o = index2addr(L, idx);
+  if (!ttisstring(o)) {
+    lua_lock(L);  /* `luaV_tostring' may create a new string */
+    if (!luaV_tostring(L, o)) {  /* conversion failed? */
+      if (len != NULL) *len = 0;
+      lua_unlock(L);
+      return NULL;
+    }
+    luaC_checkGC(L);
+    o = index2addr(L, idx);  /* previous call may reallocate the stack */
+    lua_unlock(L);
+  }
+  if (len != NULL) *len = tsvalue(o)->len;
+  return svalue(o);
+}
+
+
+LUA_API size_t lua_rawlen (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  switch (ttypenv(o)) {
+    case LUA_TSTRING: return tsvalue(o)->len;
+    case LUA_TUSERDATA: return uvalue(o)->len;
+    case LUA_TTABLE: return luaH_getn(hvalue(o));
+    default: return 0;
+  }
+}
+
+
+LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  if (ttislcf(o)) return fvalue(o);
+  else if (ttisCclosure(o))
+    return clCvalue(o)->f;
+  else return NULL;  /* not a C function */
+}
+
+
+LUA_API void *lua_touserdata (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  switch (ttypenv(o)) {
+    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
+    case LUA_TLIGHTUSERDATA: return pvalue(o);
+    default: return NULL;
+  }
+}
+
+
+LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  return (!ttisthread(o)) ? NULL : thvalue(o);
+}
+
+
+LUA_API const void *lua_topointer (lua_State *L, int idx) {
+  StkId o = index2addr(L, idx);
+  switch (ttype(o)) {
+    case LUA_TTABLE: return hvalue(o);
+    case LUA_TLCL: return clLvalue(o);
+    case LUA_TCCL: return clCvalue(o);
+    case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
+    case LUA_TTHREAD: return thvalue(o);
+    case LUA_TUSERDATA:
+    case LUA_TLIGHTUSERDATA:
+      return lua_touserdata(L, idx);
+    default: return NULL;
+  }
+}
+
+
+
+/*
+** push functions (C -> stack)
+*/
+
+
+LUA_API void lua_pushnil (lua_State *L) {
+  lua_lock(L);
+  setnilvalue(L->top);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+  lua_lock(L);
+  setnvalue(L->top, n);
+  luai_checknum(L, L->top,
+    luaG_runerror(L, "C API - attempt to push a signaling NaN"));
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
+  lua_lock(L);
+  setnvalue(L->top, cast_num(n));
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
+  lua_Number n;
+  lua_lock(L);
+  n = lua_unsigned2number(u);
+  setnvalue(L->top, n);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
+  TString *ts;
+  lua_lock(L);
+  luaC_checkGC(L);
+  ts = luaS_newlstr(L, s, len);
+  setsvalue2s(L, L->top, ts);
+  api_incr_top(L);
+  lua_unlock(L);
+  return getstr(ts);
+}
+
+
+LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
+  if (s == NULL) {
+    lua_pushnil(L);
+    return NULL;
+  }
+  else {
+    TString *ts;
+    lua_lock(L);
+    luaC_checkGC(L);
+    ts = luaS_new(L, s);
+    setsvalue2s(L, L->top, ts);
+    api_incr_top(L);
+    lua_unlock(L);
+    return getstr(ts);
+  }
+}
+
+
+LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
+                                      va_list argp) {
+  const char *ret;
+  lua_lock(L);
+  luaC_checkGC(L);
+  ret = luaO_pushvfstring(L, fmt, argp);
+  lua_unlock(L);
+  return ret;
+}
+
+
+LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
+  const char *ret;
+  va_list argp;
+  lua_lock(L);
+  luaC_checkGC(L);
+  va_start(argp, fmt);
+  ret = luaO_pushvfstring(L, fmt, argp);
+  va_end(argp);
+  lua_unlock(L);
+  return ret;
+}
+
+
+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
+  lua_lock(L);
+  if (n == 0) {
+    setfvalue(L->top, fn);
+  }
+  else {
+    Closure *cl;
+    api_checknelems(L, n);
+    api_check(L, n <= MAXUPVAL, "upvalue index too large");
+    luaC_checkGC(L);
+    cl = luaF_newCclosure(L, n);
+    cl->c.f = fn;
+    L->top -= n;
+    while (n--)
+      setobj2n(L, &cl->c.upvalue[n], L->top + n);
+    setclCvalue(L, L->top, cl);
+  }
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushboolean (lua_State *L, int b) {
+  lua_lock(L);
+  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
+  lua_lock(L);
+  setpvalue(L->top, p);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API int lua_pushthread (lua_State *L) {
+  lua_lock(L);
+  setthvalue(L, L->top, L);
+  api_incr_top(L);
+  lua_unlock(L);
+  return (G(L)->mainthread == L);
+}
+
+
+
+/*
+** get functions (Lua -> stack)
+*/
+
+
+LUA_API void lua_getglobal (lua_State *L, const char *var) {
+  Table *reg = hvalue(&G(L)->l_registry);
+  const TValue *gt;  /* global table */
+  lua_lock(L);
+  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+  setsvalue2s(L, L->top++, luaS_new(L, var));
+  luaV_gettable(L, gt, L->top - 1, L->top - 1);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_gettable (lua_State *L, int idx) {
+  StkId t;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  luaV_gettable(L, t, L->top - 1, L->top - 1);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
+  StkId t;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  setsvalue2s(L, L->top, luaS_new(L, k));
+  api_incr_top(L);
+  luaV_gettable(L, t, L->top - 1, L->top - 1);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawget (lua_State *L, int idx) {
+  StkId t;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
+  StkId t;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  setobj2s(L, L->top, luaH_getint(hvalue(t), n));
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
+  StkId t;
+  TValue k;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  setpvalue(&k, cast(void *, p));
+  setobj2s(L, L->top, luaH_get(hvalue(t), &k));
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
+  Table *t;
+  lua_lock(L);
+  luaC_checkGC(L);
+  t = luaH_new(L);
+  sethvalue(L, L->top, t);
+  api_incr_top(L);
+  if (narray > 0 || nrec > 0)
+    luaH_resize(L, t, narray, nrec);
+  lua_unlock(L);
+}
+
+
+LUA_API int lua_getmetatable (lua_State *L, int objindex) {
+  const TValue *obj;
+  Table *mt = NULL;
+  int res;
+  lua_lock(L);
+  obj = index2addr(L, objindex);
+  switch (ttypenv(obj)) {
+    case LUA_TTABLE:
+      mt = hvalue(obj)->metatable;
+      break;
+    case LUA_TUSERDATA:
+      mt = uvalue(obj)->metatable;
+      break;
+    default:
+      mt = G(L)->mt[ttypenv(obj)];
+      break;
+  }
+  if (mt == NULL)
+    res = 0;
+  else {
+    sethvalue(L, L->top, mt);
+    api_incr_top(L);
+    res = 1;
+  }
+  lua_unlock(L);
+  return res;
+}
+
+
+LUA_API void lua_getuservalue (lua_State *L, int idx) {
+  StkId o;
+  lua_lock(L);
+  o = index2addr(L, idx);
+  api_check(L, ttisuserdata(o), "userdata expected");
+  if (uvalue(o)->env) {
+    sethvalue(L, L->top, uvalue(o)->env);
+  } else
+    setnilvalue(L->top);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+/*
+** set functions (stack -> Lua)
+*/
+
+
+LUA_API void lua_setglobal (lua_State *L, const char *var) {
+  Table *reg = hvalue(&G(L)->l_registry);
+  const TValue *gt;  /* global table */
+  lua_lock(L);
+  api_checknelems(L, 1);
+  gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+  setsvalue2s(L, L->top++, luaS_new(L, var));
+  luaV_settable(L, gt, L->top - 1, L->top - 2);
+  L->top -= 2;  /* pop value and key */
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_settable (lua_State *L, int idx) {
+  StkId t;
+  lua_lock(L);
+  api_checknelems(L, 2);
+  t = index2addr(L, idx);
+  luaV_settable(L, t, L->top - 2, L->top - 1);
+  L->top -= 2;  /* pop index and value */
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
+  StkId t;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  t = index2addr(L, idx);
+  setsvalue2s(L, L->top++, luaS_new(L, k));
+  luaV_settable(L, t, L->top - 1, L->top - 2);
+  L->top -= 2;  /* pop value and key */
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawset (lua_State *L, int idx) {
+  StkId t;
+  lua_lock(L);
+  api_checknelems(L, 2);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
+  invalidateTMcache(hvalue(t));
+  luaC_barrierback(L, gcvalue(t), L->top-1);
+  L->top -= 2;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
+  StkId t;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  luaH_setint(L, hvalue(t), n, L->top - 1);
+  luaC_barrierback(L, gcvalue(t), L->top-1);
+  L->top--;
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
+  StkId t;
+  TValue k;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  setpvalue(&k, cast(void *, p));
+  setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
+  luaC_barrierback(L, gcvalue(t), L->top - 1);
+  L->top--;
+  lua_unlock(L);
+}
+
+
+LUA_API int lua_setmetatable (lua_State *L, int objindex) {
+  TValue *obj;
+  Table *mt;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  obj = index2addr(L, objindex);
+  if (ttisnil(L->top - 1))
+    mt = NULL;
+  else {
+    api_check(L, ttistable(L->top - 1), "table expected");
+    mt = hvalue(L->top - 1);
+  }
+  switch (ttypenv(obj)) {
+    case LUA_TTABLE: {
+      hvalue(obj)->metatable = mt;
+      if (mt) {
+        luaC_objbarrierback(L, gcvalue(obj), mt);
+        luaC_checkfinalizer(L, gcvalue(obj), mt);
+      }
+      break;
+    }
+    case LUA_TUSERDATA: {
+      uvalue(obj)->metatable = mt;
+      if (mt) {
+        luaC_objbarrier(L, rawuvalue(obj), mt);
+        luaC_checkfinalizer(L, gcvalue(obj), mt);
+      }
+      break;
+    }
+    default: {
+      G(L)->mt[ttypenv(obj)] = mt;
+      break;
+    }
+  }
+  L->top--;
+  lua_unlock(L);
+  return 1;
+}
+
+
+LUA_API void lua_setuservalue (lua_State *L, int idx) {
+  StkId o;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  o = index2addr(L, idx);
+  api_check(L, ttisuserdata(o), "userdata expected");
+  if (ttisnil(L->top - 1))
+    uvalue(o)->env = NULL;
+  else {
+    api_check(L, ttistable(L->top - 1), "table expected");
+    uvalue(o)->env = hvalue(L->top - 1);
+    luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
+  }
+  L->top--;
+  lua_unlock(L);
+}
+
+
+/*
+** `load' and `call' functions (run Lua code)
+*/
+
+
+#define checkresults(L,na,nr) \
+     api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
+	"results from function overflow current stack size")
+
+
+LUA_API int lua_getctx (lua_State *L, int *ctx) {
+  if (L->ci->callstatus & CIST_YIELDED) {
+    if (ctx) *ctx = L->ci->u.c.ctx;
+    return L->ci->u.c.status;
+  }
+  else return LUA_OK;
+}
+
+
+LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
+                        lua_CFunction k) {
+  StkId func;
+  lua_lock(L);
+  api_check(L, k == NULL || !isLua(L->ci),
+    "cannot use continuations inside hooks");
+  api_checknelems(L, nargs+1);
+  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+  checkresults(L, nargs, nresults);
+  func = L->top - (nargs+1);
+  if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
+    L->ci->u.c.k = k;  /* save continuation */
+    L->ci->u.c.ctx = ctx;  /* save context */
+    luaD_call(L, func, nresults, 1);  /* do the call */
+  }
+  else  /* no continuation or no yieldable */
+    luaD_call(L, func, nresults, 0);  /* just do the call */
+  adjustresults(L, nresults);
+  lua_unlock(L);
+}
+
+
+
+/*
+** Execute a protected call.
+*/
+struct CallS {  /* data to `f_call' */
+  StkId func;
+  int nresults;
+};
+
+
+static void f_call (lua_State *L, void *ud) {
+  struct CallS *c = cast(struct CallS *, ud);
+  luaD_call(L, c->func, c->nresults, 0);
+}
+
+
+
+LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
+                        int ctx, lua_CFunction k) {
+  struct CallS c;
+  int status;
+  ptrdiff_t func;
+  lua_lock(L);
+  api_check(L, k == NULL || !isLua(L->ci),
+    "cannot use continuations inside hooks");
+  api_checknelems(L, nargs+1);
+  api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
+  checkresults(L, nargs, nresults);
+  if (errfunc == 0)
+    func = 0;
+  else {
+    StkId o = index2addr(L, errfunc);
+    api_checkstackindex(L, errfunc, o);
+    func = savestack(L, o);
+  }
+  c.func = L->top - (nargs+1);  /* function to be called */
+  if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
+    c.nresults = nresults;  /* do a 'conventional' protected call */
+    status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
+  }
+  else {  /* prepare continuation (call is already protected by 'resume') */
+    CallInfo *ci = L->ci;
+    ci->u.c.k = k;  /* save continuation */
+    ci->u.c.ctx = ctx;  /* save context */
+    /* save information for error recovery */
+    ci->extra = savestack(L, c.func);
+    ci->u.c.old_allowhook = L->allowhook;
+    ci->u.c.old_errfunc = L->errfunc;
+    L->errfunc = func;
+    /* mark that function may do error recovery */
+    ci->callstatus |= CIST_YPCALL;
+    luaD_call(L, c.func, nresults, 1);  /* do the call */
+    ci->callstatus &= ~CIST_YPCALL;
+    L->errfunc = ci->u.c.old_errfunc;
+    status = LUA_OK;  /* if it is here, there were no errors */
+  }
+  adjustresults(L, nresults);
+  lua_unlock(L);
+  return status;
+}
+
+
+LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
+                      const char *chunkname, const char *mode) {
+  ZIO z;
+  int status;
+  lua_lock(L);
+  if (!chunkname) chunkname = "?";
+  luaZ_init(L, &z, reader, data);
+  status = luaD_protectedparser(L, &z, chunkname, mode);
+  if (status == LUA_OK) {  /* no errors? */
+    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
+    if (f->nupvalues == 1) {  /* does it have one upvalue? */
+      /* get global table from registry */
+      Table *reg = hvalue(&G(L)->l_registry);
+      const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+      /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
+      setobj(L, f->upvals[0]->v, gt);
+      luaC_barrier(L, f->upvals[0], gt);
+    }
+  }
+  lua_unlock(L);
+  return status;
+}
+
+
+LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
+  int status;
+  TValue *o;
+  lua_lock(L);
+  api_checknelems(L, 1);
+  o = L->top - 1;
+  if (isLfunction(o))
+    status = luaU_dump(L, getproto(o), writer, data, 0);
+  else
+    status = 1;
+  lua_unlock(L);
+  return status;
+}
+
+
+LUA_API int lua_status (lua_State *L) {
+  return L->status;
+}
+
+
+/*
+** Garbage-collection function
+*/
+
+LUA_API int lua_gc (lua_State *L, int what, int data) {
+  int res = 0;
+  global_State *g;
+  lua_lock(L);
+  g = G(L);
+  switch (what) {
+    case LUA_GCSTOP: {
+      g->gcrunning = 0;
+      break;
+    }
+    case LUA_GCRESTART: {
+      luaE_setdebt(g, 0);
+      g->gcrunning = 1;
+      break;
+    }
+    case LUA_GCCOLLECT: {
+      luaC_fullgc(L, 0);
+      break;
+    }
+    case LUA_GCCOUNT: {
+      /* GC values are expressed in Kbytes: #bytes/2^10 */
+      res = cast_int(gettotalbytes(g) >> 10);
+      break;
+    }
+    case LUA_GCCOUNTB: {
+      res = cast_int(gettotalbytes(g) & 0x3ff);
+      break;
+    }
+    case LUA_GCSTEP: {
+      if (g->gckind == KGC_GEN) {  /* generational mode? */
+        res = (g->GCestimate == 0);  /* true if it will do major collection */
+        luaC_forcestep(L);  /* do a single step */
+      }
+      else {
+       lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
+       if (g->gcrunning)
+         debt += g->GCdebt;  /* include current debt */
+       luaE_setdebt(g, debt);
+       luaC_forcestep(L);
+       if (g->gcstate == GCSpause)  /* end of cycle? */
+         res = 1;  /* signal it */
+      }
+      break;
+    }
+    case LUA_GCSETPAUSE: {
+      res = g->gcpause;
+      g->gcpause = data;
+      break;
+    }
+    case LUA_GCSETMAJORINC: {
+      res = g->gcmajorinc;
+      g->gcmajorinc = data;
+      break;
+    }
+    case LUA_GCSETSTEPMUL: {
+      res = g->gcstepmul;
+      g->gcstepmul = data;
+      break;
+    }
+    case LUA_GCISRUNNING: {
+      res = g->gcrunning;
+      break;
+    }
+    case LUA_GCGEN: {  /* change collector to generational mode */
+      luaC_changemode(L, KGC_GEN);
+      break;
+    }
+    case LUA_GCINC: {  /* change collector to incremental mode */
+      luaC_changemode(L, KGC_NORMAL);
+      break;
+    }
+    default: res = -1;  /* invalid option */
+  }
+  lua_unlock(L);
+  return res;
+}
+
+
+
+/*
+** miscellaneous functions
+*/
+
+
+LUA_API int lua_error (lua_State *L) {
+  lua_lock(L);
+  api_checknelems(L, 1);
+  luaG_errormsg(L);
+  /* code unreachable; will unlock when control actually leaves the kernel */
+  return 0;  /* to avoid warnings */
+}
+
+
+LUA_API int lua_next (lua_State *L, int idx) {
+  StkId t;
+  int more;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  api_check(L, ttistable(t), "table expected");
+  more = luaH_next(L, hvalue(t), L->top - 1);
+  if (more) {
+    api_incr_top(L);
+  }
+  else  /* no more elements */
+    L->top -= 1;  /* remove key */
+  lua_unlock(L);
+  return more;
+}
+
+
+LUA_API void lua_concat (lua_State *L, int n) {
+  lua_lock(L);
+  api_checknelems(L, n);
+  if (n >= 2) {
+    luaC_checkGC(L);
+    luaV_concat(L, n);
+  }
+  else if (n == 0) {  /* push empty string */
+    setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
+    api_incr_top(L);
+  }
+  /* else n == 1; nothing to do */
+  lua_unlock(L);
+}
+
+
+LUA_API void lua_len (lua_State *L, int idx) {
+  StkId t;
+  lua_lock(L);
+  t = index2addr(L, idx);
+  luaV_objlen(L, L->top, t);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
+LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
+  lua_Alloc f;
+  lua_lock(L);
+  if (ud) *ud = G(L)->ud;
+  f = G(L)->frealloc;
+  lua_unlock(L);
+  return f;
+}
+
+
+LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
+  lua_lock(L);
+  G(L)->ud = ud;
+  G(L)->frealloc = f;
+  lua_unlock(L);
+}
+
+
+LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
+  Udata *u;
+  lua_lock(L);
+  luaC_checkGC(L);
+  u = luaS_newudata(L, size, NULL);
+  setuvalue(L, L->top, u);
+  api_incr_top(L);
+  lua_unlock(L);
+  return u + 1;
+}
+
+
+
+static const char *aux_upvalue (StkId fi, int n, TValue **val,
+                                GCObject **owner) {
+  switch (ttype(fi)) {
+    case LUA_TCCL: {  /* C closure */
+      CClosure *f = clCvalue(fi);
+      if (!(1 <= n && n <= f->nupvalues)) return NULL;
+      *val = &f->upvalue[n-1];
+      if (owner) *owner = obj2gco(f);
+      return "";
+    }
+    case LUA_TLCL: {  /* Lua closure */
+      LClosure *f = clLvalue(fi);
+      TString *name;
+      Proto *p = f->p;
+      if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+      *val = f->upvals[n-1]->v;
+      if (owner) *owner = obj2gco(f->upvals[n - 1]);
+      name = p->upvalues[n-1].name;
+      return (name == NULL) ? "" : getstr(name);
+    }
+    default: return NULL;  /* not a closure */
+  }
+}
+
+
+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
+  const char *name;
+  TValue *val = NULL;  /* to avoid warnings */
+  lua_lock(L);
+  name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
+  if (name) {
+    setobj2s(L, L->top, val);
+    api_incr_top(L);
+  }
+  lua_unlock(L);
+  return name;
+}
+
+
+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
+  const char *name;
+  TValue *val = NULL;  /* to avoid warnings */
+  GCObject *owner = NULL;  /* to avoid warnings */
+  StkId fi;
+  lua_lock(L);
+  fi = index2addr(L, funcindex);
+  api_checknelems(L, 1);
+  name = aux_upvalue(fi, n, &val, &owner);
+  if (name) {
+    L->top--;
+    setobj(L, val, L->top);
+    luaC_barrier(L, owner, L->top);
+  }
+  lua_unlock(L);
+  return name;
+}
+
+
+static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
+  LClosure *f;
+  StkId fi = index2addr(L, fidx);
+  api_check(L, ttisLclosure(fi), "Lua function expected");
+  f = clLvalue(fi);
+  api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
+  if (pf) *pf = f;
+  return &f->upvals[n - 1];  /* get its upvalue pointer */
+}
+
+
+LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
+  StkId fi = index2addr(L, fidx);
+  switch (ttype(fi)) {
+    case LUA_TLCL: {  /* lua closure */
+      return *getupvalref(L, fidx, n, NULL);
+    }
+    case LUA_TCCL: {  /* C closure */
+      CClosure *f = clCvalue(fi);
+      api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
+      return &f->upvalue[n - 1];
+    }
+    default: {
+      api_check(L, 0, "closure expected");
+      return NULL;
+    }
+  }
+}
+
+
+LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
+                                            int fidx2, int n2) {
+  LClosure *f1;
+  UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
+  UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
+  *up1 = *up2;
+  luaC_objbarrier(L, f1, *up2);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lapi.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,24 @@
+/*
+** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions from Lua API
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lapi_h
+#define lapi_h
+
+
+#include "llimits.h"
+#include "lstate.h"
+
+#define api_incr_top(L)   {L->top++; api_check(L, L->top <= L->ci->top, \
+				"stack overflow");}
+
+#define adjustresults(L,nres) \
+    { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
+
+#define api_checknelems(L,n)	api_check(L, (n) < (L->top - L->ci->func), \
+				  "not enough elements in the stack")
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,961 @@
+/*
+** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* This file uses only the official API of Lua.
+** Any function declared here could be written as an application function.
+*/
+
+#define lauxlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+
+
+/*
+** {======================================================
+** Traceback
+** =======================================================
+*/
+
+
+#define LEVELS1	12	/* size of the first part of the stack */
+#define LEVELS2	10	/* size of the second part of the stack */
+
+
+
+/*
+** search for 'objidx' in table at index -1.
+** return 1 + string at top if find a good name.
+*/
+static int findfield (lua_State *L, int objidx, int level) {
+  if (level == 0 || !lua_istable(L, -1))
+    return 0;  /* not found */
+  lua_pushnil(L);  /* start 'next' loop */
+  while (lua_next(L, -2)) {  /* for each pair in table */
+    if (lua_type(L, -2) == LUA_TSTRING) {  /* ignore non-string keys */
+      if (lua_rawequal(L, objidx, -1)) {  /* found object? */
+        lua_pop(L, 1);  /* remove value (but keep name) */
+        return 1;
+      }
+      else if (findfield(L, objidx, level - 1)) {  /* try recursively */
+        lua_remove(L, -2);  /* remove table (but keep name) */
+        lua_pushliteral(L, ".");
+        lua_insert(L, -2);  /* place '.' between the two names */
+        lua_concat(L, 3);
+        return 1;
+      }
+    }
+    lua_pop(L, 1);  /* remove value */
+  }
+  return 0;  /* not found */
+}
+
+
+static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
+  int top = lua_gettop(L);
+  lua_getinfo(L, "f", ar);  /* push function */
+  lua_pushglobaltable(L);
+  if (findfield(L, top + 1, 2)) {
+    lua_copy(L, -1, top + 1);  /* move name to proper place */
+    lua_pop(L, 2);  /* remove pushed values */
+    return 1;
+  }
+  else {
+    lua_settop(L, top);  /* remove function and global table */
+    return 0;
+  }
+}
+
+
+static void pushfuncname (lua_State *L, lua_Debug *ar) {
+  if (*ar->namewhat != '\0')  /* is there a name? */
+    lua_pushfstring(L, "function " LUA_QS, ar->name);
+  else if (*ar->what == 'm')  /* main? */
+      lua_pushliteral(L, "main chunk");
+  else if (*ar->what == 'C') {
+    if (pushglobalfuncname(L, ar)) {
+      lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
+      lua_remove(L, -2);  /* remove name */
+    }
+    else
+      lua_pushliteral(L, "?");
+  }
+  else
+    lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
+}
+
+
+static int countlevels (lua_State *L) {
+  lua_Debug ar;
+  int li = 1, le = 1;
+  /* find an upper bound */
+  while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
+  /* do a binary search */
+  while (li < le) {
+    int m = (li + le)/2;
+    if (lua_getstack(L, m, &ar)) li = m + 1;
+    else le = m;
+  }
+  return le - 1;
+}
+
+
+LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
+                                const char *msg, int level) {
+  lua_Debug ar;
+  int top = lua_gettop(L);
+  int numlevels = countlevels(L1);
+  int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
+  if (msg) lua_pushfstring(L, "%s\n", msg);
+  lua_pushliteral(L, "stack traceback:");
+  while (lua_getstack(L1, level++, &ar)) {
+    if (level == mark) {  /* too many levels? */
+      lua_pushliteral(L, "\n\t...");  /* add a '...' */
+      level = numlevels - LEVELS2;  /* and skip to last ones */
+    }
+    else {
+      lua_getinfo(L1, "Slnt", &ar);
+      lua_pushfstring(L, "\n\t%s:", ar.short_src);
+      if (ar.currentline > 0)
+        lua_pushfstring(L, "%d:", ar.currentline);
+      lua_pushliteral(L, " in ");
+      pushfuncname(L, &ar);
+      if (ar.istailcall)
+        lua_pushliteral(L, "\n\t(...tail calls...)");
+      lua_concat(L, lua_gettop(L) - top);
+    }
+  }
+  lua_concat(L, lua_gettop(L) - top);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Error-report functions
+** =======================================================
+*/
+
+LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
+  lua_Debug ar;
+  if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
+    return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
+  lua_getinfo(L, "n", &ar);
+  if (strcmp(ar.namewhat, "method") == 0) {
+    narg--;  /* do not count `self' */
+    if (narg == 0)  /* error is in the self argument itself? */
+      return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
+                           ar.name, extramsg);
+  }
+  if (ar.name == NULL)
+    ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
+  return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
+                        narg, ar.name, extramsg);
+}
+
+
+static int typeerror (lua_State *L, int narg, const char *tname) {
+  const char *msg = lua_pushfstring(L, "%s expected, got %s",
+                                    tname, luaL_typename(L, narg));
+  return luaL_argerror(L, narg, msg);
+}
+
+
+static void tag_error (lua_State *L, int narg, int tag) {
+  typeerror(L, narg, lua_typename(L, tag));
+}
+
+
+LUALIB_API void luaL_where (lua_State *L, int level) {
+  lua_Debug ar;
+  if (lua_getstack(L, level, &ar)) {  /* check function at level */
+    lua_getinfo(L, "Sl", &ar);  /* get info about it */
+    if (ar.currentline > 0) {  /* is there info? */
+      lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
+      return;
+    }
+  }
+  lua_pushliteral(L, "");  /* else, no information available... */
+}
+
+
+LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
+  va_list argp;
+  va_start(argp, fmt);
+  luaL_where(L, 1);
+  lua_pushvfstring(L, fmt, argp);
+  va_end(argp);
+  lua_concat(L, 2);
+  return lua_error(L);
+}
+
+
+LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
+  int en = errno;  /* calls to Lua API may change this value */
+  if (stat) {
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  else {
+    lua_pushnil(L);
+    if (fname)
+      lua_pushfstring(L, "%s: %s", fname, strerror(en));
+    else
+      lua_pushstring(L, strerror(en));
+    lua_pushinteger(L, en);
+    return 3;
+  }
+}
+
+
+#if !defined(inspectstat)	/* { */
+
+#if defined(LUA_USE_POSIX)
+
+#include <sys/wait.h>
+
+/*
+** use appropriate macros to interpret 'pclose' return status
+*/
+#define inspectstat(stat,what)  \
+   if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
+   else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
+
+#else
+
+#define inspectstat(stat,what)  /* no op */
+
+#endif
+
+#endif				/* } */
+
+
+LUALIB_API int luaL_execresult (lua_State *L, int stat) {
+  const char *what = "exit";  /* type of termination */
+  if (stat == -1)  /* error? */
+    return luaL_fileresult(L, 0, NULL);
+  else {
+    inspectstat(stat, what);  /* interpret result */
+    if (*what == 'e' && stat == 0)  /* successful termination? */
+      lua_pushboolean(L, 1);
+    else
+      lua_pushnil(L);
+    lua_pushstring(L, what);
+    lua_pushinteger(L, stat);
+    return 3;  /* return true/nil,what,code */
+  }
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Userdata's metatable manipulation
+** =======================================================
+*/
+
+LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
+  luaL_getmetatable(L, tname);  /* try to get metatable */
+  if (!lua_isnil(L, -1))  /* name already in use? */
+    return 0;  /* leave previous value on top, but return 0 */
+  lua_pop(L, 1);
+  lua_newtable(L);  /* create metatable */
+  lua_pushvalue(L, -1);
+  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
+  return 1;
+}
+
+
+LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
+  luaL_getmetatable(L, tname);
+  lua_setmetatable(L, -2);
+}
+
+
+LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
+  void *p = lua_touserdata(L, ud);
+  if (p != NULL) {  /* value is a userdata? */
+    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
+      luaL_getmetatable(L, tname);  /* get correct metatable */
+      if (!lua_rawequal(L, -1, -2))  /* not the same? */
+        p = NULL;  /* value is a userdata with wrong metatable */
+      lua_pop(L, 2);  /* remove both metatables */
+      return p;
+    }
+  }
+  return NULL;  /* value is not a userdata with a metatable */
+}
+
+
+LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
+  void *p = luaL_testudata(L, ud, tname);
+  if (p == NULL) typeerror(L, ud, tname);
+  return p;
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Argument check functions
+** =======================================================
+*/
+
+LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
+                                 const char *const lst[]) {
+  const char *name = (def) ? luaL_optstring(L, narg, def) :
+                             luaL_checkstring(L, narg);
+  int i;
+  for (i=0; lst[i]; i++)
+    if (strcmp(lst[i], name) == 0)
+      return i;
+  return luaL_argerror(L, narg,
+                       lua_pushfstring(L, "invalid option " LUA_QS, name));
+}
+
+
+LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
+  /* keep some extra space to run error routines, if needed */
+  const int extra = LUA_MINSTACK;
+  if (!lua_checkstack(L, space + extra)) {
+    if (msg)
+      luaL_error(L, "stack overflow (%s)", msg);
+    else
+      luaL_error(L, "stack overflow");
+  }
+}
+
+
+LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
+  if (lua_type(L, narg) != t)
+    tag_error(L, narg, t);
+}
+
+
+LUALIB_API void luaL_checkany (lua_State *L, int narg) {
+  if (lua_type(L, narg) == LUA_TNONE)
+    luaL_argerror(L, narg, "value expected");
+}
+
+
+LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
+  const char *s = lua_tolstring(L, narg, len);
+  if (!s) tag_error(L, narg, LUA_TSTRING);
+  return s;
+}
+
+
+LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
+                                        const char *def, size_t *len) {
+  if (lua_isnoneornil(L, narg)) {
+    if (len)
+      *len = (def ? strlen(def) : 0);
+    return def;
+  }
+  else return luaL_checklstring(L, narg, len);
+}
+
+
+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
+  int isnum;
+  lua_Number d = lua_tonumberx(L, narg, &isnum);
+  if (!isnum)
+    tag_error(L, narg, LUA_TNUMBER);
+  return d;
+}
+
+
+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
+  return luaL_opt(L, luaL_checknumber, narg, def);
+}
+
+
+LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
+  int isnum;
+  lua_Integer d = lua_tointegerx(L, narg, &isnum);
+  if (!isnum)
+    tag_error(L, narg, LUA_TNUMBER);
+  return d;
+}
+
+
+LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
+  int isnum;
+  lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
+  if (!isnum)
+    tag_error(L, narg, LUA_TNUMBER);
+  return d;
+}
+
+
+LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
+                                                      lua_Integer def) {
+  return luaL_opt(L, luaL_checkinteger, narg, def);
+}
+
+
+LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
+                                                        lua_Unsigned def) {
+  return luaL_opt(L, luaL_checkunsigned, narg, def);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+/*
+** check whether buffer is using a userdata on the stack as a temporary
+** buffer
+*/
+#define buffonstack(B)	((B)->b != (B)->initb)
+
+
+/*
+** returns a pointer to a free area with at least 'sz' bytes
+*/
+LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
+  lua_State *L = B->L;
+  if (B->size - B->n < sz) {  /* not enough space? */
+    char *newbuff;
+    size_t newsize = B->size * 2;  /* double buffer size */
+    if (newsize - B->n < sz)  /* not big enough? */
+      newsize = B->n + sz;
+    if (newsize < B->n || newsize - B->n < sz)
+      luaL_error(L, "buffer too large");
+    /* create larger buffer */
+    newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
+    /* move content to new buffer */
+    memcpy(newbuff, B->b, B->n * sizeof(char));
+    if (buffonstack(B))
+      lua_remove(L, -2);  /* remove old buffer */
+    B->b = newbuff;
+    B->size = newsize;
+  }
+  return &B->b[B->n];
+}
+
+
+LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
+  char *b = luaL_prepbuffsize(B, l);
+  memcpy(b, s, l * sizeof(char));
+  luaL_addsize(B, l);
+}
+
+
+LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
+  luaL_addlstring(B, s, strlen(s));
+}
+
+
+LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
+  lua_State *L = B->L;
+  lua_pushlstring(L, B->b, B->n);
+  if (buffonstack(B))
+    lua_remove(L, -2);  /* remove old buffer */
+}
+
+
+LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
+  luaL_addsize(B, sz);
+  luaL_pushresult(B);
+}
+
+
+LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
+  lua_State *L = B->L;
+  size_t l;
+  const char *s = lua_tolstring(L, -1, &l);
+  if (buffonstack(B))
+    lua_insert(L, -2);  /* put value below buffer */
+  luaL_addlstring(B, s, l);
+  lua_remove(L, (buffonstack(B)) ? -2 : -1);  /* remove value */
+}
+
+
+LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
+  B->L = L;
+  B->b = B->initb;
+  B->n = 0;
+  B->size = LUAL_BUFFERSIZE;
+}
+
+
+LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
+  luaL_buffinit(L, B);
+  return luaL_prepbuffsize(B, sz);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Reference system
+** =======================================================
+*/
+
+/* index of free-list header */
+#define freelist	0
+
+
+LUALIB_API int luaL_ref (lua_State *L, int t) {
+  int ref;
+  if (lua_isnil(L, -1)) {
+    lua_pop(L, 1);  /* remove from stack */
+    return LUA_REFNIL;  /* `nil' has a unique fixed reference */
+  }
+  t = lua_absindex(L, t);
+  lua_rawgeti(L, t, freelist);  /* get first free element */
+  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
+  lua_pop(L, 1);  /* remove it from stack */
+  if (ref != 0) {  /* any free element? */
+    lua_rawgeti(L, t, ref);  /* remove it from list */
+    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
+  }
+  else  /* no free elements */
+    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */
+  lua_rawseti(L, t, ref);
+  return ref;
+}
+
+
+LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
+  if (ref >= 0) {
+    t = lua_absindex(L, t);
+    lua_rawgeti(L, t, freelist);
+    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
+    lua_pushinteger(L, ref);
+    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
+  }
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Load functions
+** =======================================================
+*/
+
+typedef struct LoadF {
+  int n;  /* number of pre-read characters */
+  FILE *f;  /* file being read */
+  char buff[LUAL_BUFFERSIZE];  /* area for reading file */
+} LoadF;
+
+
+static const char *getF (lua_State *L, void *ud, size_t *size) {
+  LoadF *lf = (LoadF *)ud;
+  (void)L;  /* not used */
+  if (lf->n > 0) {  /* are there pre-read characters to be read? */
+    *size = lf->n;  /* return them (chars already in buffer) */
+    lf->n = 0;  /* no more pre-read characters */
+  }
+  else {  /* read a block from file */
+    /* 'fread' can return > 0 *and* set the EOF flag. If next call to
+       'getF' called 'fread', it might still wait for user input.
+       The next check avoids this problem. */
+    if (feof(lf->f)) return NULL;
+    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
+  }
+  return lf->buff;
+}
+
+
+static int errfile (lua_State *L, const char *what, int fnameindex) {
+  const char *serr = strerror(errno);
+  const char *filename = lua_tostring(L, fnameindex) + 1;
+  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
+  lua_remove(L, fnameindex);
+  return LUA_ERRFILE;
+}
+
+
+static int skipBOM (LoadF *lf) {
+  const char *p = "\xEF\xBB\xBF";  /* Utf8 BOM mark */
+  int c;
+  lf->n = 0;
+  do {
+    c = getc(lf->f);
+    if (c == EOF || c != *(const unsigned char *)p++) return c;
+    lf->buff[lf->n++] = c;  /* to be read by the parser */
+  } while (*p != '\0');
+  lf->n = 0;  /* prefix matched; discard it */
+  return getc(lf->f);  /* return next character */
+}
+
+
+/*
+** reads the first character of file 'f' and skips an optional BOM mark
+** in its beginning plus its first line if it starts with '#'. Returns
+** true if it skipped the first line.  In any case, '*cp' has the
+** first "valid" character of the file (after the optional BOM and
+** a first-line comment).
+*/
+static int skipcomment (LoadF *lf, int *cp) {
+  int c = *cp = skipBOM(lf);
+  if (c == '#') {  /* first line is a comment (Unix exec. file)? */
+    do {  /* skip first line */
+      c = getc(lf->f);
+    } while (c != EOF && c != '\n') ;
+    *cp = getc(lf->f);  /* skip end-of-line, if present */
+    return 1;  /* there was a comment */
+  }
+  else return 0;  /* no comment */
+}
+
+
+LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
+                                             const char *mode) {
+  LoadF lf;
+  int status, readstatus;
+  int c;
+  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
+  if (filename == NULL) {
+    lua_pushliteral(L, "=stdin");
+    lf.f = stdin;
+  }
+  else {
+    lua_pushfstring(L, "@%s", filename);
+    lf.f = fopen(filename, "r");
+    if (lf.f == NULL) return errfile(L, "open", fnameindex);
+  }
+  if (skipcomment(&lf, &c))  /* read initial portion */
+    lf.buff[lf.n++] = '\n';  /* add line to correct line numbers */
+#ifndef SYSLINUX
+  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
+    lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
+    if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
+    skipcomment(&lf, &c);  /* re-read initial portion */
+  }
+#endif
+  if (c != EOF)
+    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
+  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
+  readstatus = ferror(lf.f);
+  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
+  if (readstatus) {
+    lua_settop(L, fnameindex);  /* ignore results from `lua_load' */
+    return errfile(L, "read", fnameindex);
+  }
+  lua_remove(L, fnameindex);
+  return status;
+}
+
+
+typedef struct LoadS {
+  const char *s;
+  size_t size;
+} LoadS;
+
+
+static const char *getS (lua_State *L, void *ud, size_t *size) {
+  LoadS *ls = (LoadS *)ud;
+  (void)L;  /* not used */
+  if (ls->size == 0) return NULL;
+  *size = ls->size;
+  ls->size = 0;
+  return ls->s;
+}
+
+
+LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
+                                 const char *name, const char *mode) {
+  LoadS ls;
+  ls.s = buff;
+  ls.size = size;
+  return lua_load(L, getS, &ls, name, mode);
+}
+
+
+LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
+  return luaL_loadbuffer(L, s, strlen(s), s);
+}
+
+/* }====================================================== */
+
+
+
+LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+  if (!lua_getmetatable(L, obj))  /* no metatable? */
+    return 0;
+  lua_pushstring(L, event);
+  lua_rawget(L, -2);
+  if (lua_isnil(L, -1)) {
+    lua_pop(L, 2);  /* remove metatable and metafield */
+    return 0;
+  }
+  else {
+    lua_remove(L, -2);  /* remove only metatable */
+    return 1;
+  }
+}
+
+
+LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
+  obj = lua_absindex(L, obj);
+  if (!luaL_getmetafield(L, obj, event))  /* no metafield? */
+    return 0;
+  lua_pushvalue(L, obj);
+  lua_call(L, 1, 1);
+  return 1;
+}
+
+
+LUALIB_API int luaL_len (lua_State *L, int idx) {
+  int l;
+  int isnum;
+  lua_len(L, idx);
+  l = (int)lua_tointegerx(L, -1, &isnum);
+  if (!isnum)
+    luaL_error(L, "object length is not a number");
+  lua_pop(L, 1);  /* remove object */
+  return l;
+}
+
+
+LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
+  if (!luaL_callmeta(L, idx, "__tostring")) {  /* no metafield? */
+    switch (lua_type(L, idx)) {
+      case LUA_TNUMBER:
+      case LUA_TSTRING:
+        lua_pushvalue(L, idx);
+        break;
+      case LUA_TBOOLEAN:
+        lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
+        break;
+      case LUA_TNIL:
+        lua_pushliteral(L, "nil");
+        break;
+      default:
+        lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
+                                            lua_topointer(L, idx));
+        break;
+    }
+  }
+  return lua_tolstring(L, -1, len);
+}
+
+
+/*
+** {======================================================
+** Compatibility with 5.1 module functions
+** =======================================================
+*/
+#if defined(LUA_COMPAT_MODULE)
+
+static const char *luaL_findtable (lua_State *L, int idx,
+                                   const char *fname, int szhint) {
+  const char *e;
+  if (idx) lua_pushvalue(L, idx);
+  do {
+    e = strchr(fname, '.');
+    if (e == NULL) e = fname + strlen(fname);
+    lua_pushlstring(L, fname, e - fname);
+    lua_rawget(L, -2);
+    if (lua_isnil(L, -1)) {  /* no such field? */
+      lua_pop(L, 1);  /* remove this nil */
+      lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
+      lua_pushlstring(L, fname, e - fname);
+      lua_pushvalue(L, -2);
+      lua_settable(L, -4);  /* set new table into field */
+    }
+    else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
+      lua_pop(L, 2);  /* remove table and value */
+      return fname;  /* return problematic part of the name */
+    }
+    lua_remove(L, -2);  /* remove previous table */
+    fname = e + 1;
+  } while (*e == '.');
+  return NULL;
+}
+
+
+/*
+** Count number of elements in a luaL_Reg list.
+*/
+static int libsize (const luaL_Reg *l) {
+  int size = 0;
+  for (; l && l->name; l++) size++;
+  return size;
+}
+
+
+/*
+** Find or create a module table with a given name. The function
+** first looks at the _LOADED table and, if that fails, try a
+** global variable with that name. In any case, leaves on the stack
+** the module table.
+*/
+LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
+                                 int sizehint) {
+  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
+  lua_getfield(L, -1, modname);  /* get _LOADED[modname] */
+  if (!lua_istable(L, -1)) {  /* not found? */
+    lua_pop(L, 1);  /* remove previous result */
+    /* try global variable (and create one if it does not exist) */
+    lua_pushglobaltable(L);
+    if (luaL_findtable(L, 0, modname, sizehint) != NULL)
+      luaL_error(L, "name conflict for module " LUA_QS, modname);
+    lua_pushvalue(L, -1);
+    lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
+  }
+  lua_remove(L, -2);  /* remove _LOADED table */
+}
+
+
+LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
+                               const luaL_Reg *l, int nup) {
+  luaL_checkversion(L);
+  if (libname) {
+    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
+    lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
+  }
+  if (l)
+    luaL_setfuncs(L, l, nup);
+  else
+    lua_pop(L, nup);  /* remove upvalues */
+}
+
+#endif
+/* }====================================================== */
+
+/*
+** set functions from list 'l' into table at top - 'nup'; each
+** function gets the 'nup' elements at the top as upvalues.
+** Returns with only the table at the stack.
+*/
+LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
+  luaL_checkversion(L);
+  luaL_checkstack(L, nup, "too many upvalues");
+  for (; l->name != NULL; l++) {  /* fill the table with given functions */
+    int i;
+    for (i = 0; i < nup; i++)  /* copy upvalues to the top */
+      lua_pushvalue(L, -nup);
+    lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
+    lua_setfield(L, -(nup + 2), l->name);
+  }
+  lua_pop(L, nup);  /* remove upvalues */
+}
+
+
+/*
+** ensure that stack[idx][fname] has a table and push that table
+** into the stack
+*/
+LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
+  lua_getfield(L, idx, fname);
+  if (lua_istable(L, -1)) return 1;  /* table already there */
+  else {
+    lua_pop(L, 1);  /* remove previous result */
+    idx = lua_absindex(L, idx);
+    lua_newtable(L);
+    lua_pushvalue(L, -1);  /* copy to be left at top */
+    lua_setfield(L, idx, fname);  /* assign new table to field */
+    return 0;  /* false, because did not find table there */
+  }
+}
+
+
+/*
+** stripped-down 'require'. Calls 'openf' to open a module,
+** registers the result in 'package.loaded' table and, if 'glb'
+** is true, also registers the result in the global table.
+** Leaves resulting module on the top.
+*/
+LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
+                               lua_CFunction openf, int glb) {
+  lua_pushcfunction(L, openf);
+  lua_pushstring(L, modname);  /* argument to open function */
+  lua_call(L, 1, 1);  /* open module */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_pushvalue(L, -2);  /* make copy of module (call result) */
+  lua_setfield(L, -2, modname);  /* _LOADED[modname] = module */
+  lua_pop(L, 1);  /* remove _LOADED table */
+  if (glb) {
+    lua_pushvalue(L, -1);  /* copy of 'mod' */
+    lua_setglobal(L, modname);  /* _G[modname] = module */
+  }
+}
+
+
+LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
+                                                               const char *r) {
+  const char *wild;
+  size_t l = strlen(p);
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  while ((wild = strstr(s, p)) != NULL) {
+    luaL_addlstring(&b, s, wild - s);  /* push prefix */
+    luaL_addstring(&b, r);  /* push replacement in place of pattern */
+    s = wild + l;  /* continue after `p' */
+  }
+  luaL_addstring(&b, s);  /* push last suffix */
+  luaL_pushresult(&b);
+  return lua_tostring(L, -1);
+}
+
+
+static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+  (void)ud; (void)osize;  /* not used */
+  if (nsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+  else
+    return realloc(ptr, nsize);
+}
+
+
+static int panic (lua_State *L) {
+  luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
+                   lua_tostring(L, -1));
+  return 0;  /* return to Lua to abort */
+}
+
+
+LUALIB_API lua_State *luaL_newstate (void) {
+  lua_State *L = lua_newstate(l_alloc, NULL);
+  if (L) lua_atpanic(L, &panic);
+  return L;
+}
+
+
+LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
+  const lua_Number *v = lua_version(L);
+  if (v != lua_version(NULL))
+    luaL_error(L, "multiple Lua VMs detected");
+  else if (*v != ver)
+    luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
+                  ver, *v);
+  /* check conversions number -> integer types */
+  lua_pushnumber(L, -(lua_Number)0x1234);
+  if (lua_tointeger(L, -1) != -0x1234 ||
+      lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
+    luaL_error(L, "bad conversion number->int;"
+                  " must recompile Lua with proper settings");
+  lua_pop(L, 1);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lauxlib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,212 @@
+/*
+** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+
+
+/* extra error code for `luaL_load' */
+#define LUA_ERRFILE     (LUA_ERRERR+1)
+
+
+typedef struct luaL_Reg {
+  const char *name;
+  lua_CFunction func;
+} luaL_Reg;
+
+
+LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
+#define luaL_checkversion(L)	luaL_checkversion_(L, LUA_VERSION_NUM)
+
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
+LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
+                                                          size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
+                                          const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
+
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
+                                          lua_Integer def);
+LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
+LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
+                                            lua_Unsigned def);
+
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
+
+LUALIB_API int   (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void  (luaL_setmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
+                                   const char *const lst[]);
+
+LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
+LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
+
+/* pre-defined references */
+#define LUA_NOREF       (-2)
+#define LUA_REFNIL      (-1)
+
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+                                               const char *mode);
+
+#define luaL_loadfile(L,f)	luaL_loadfilex(L,f,NULL)
+
+LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+                                   const char *name, const char *mode);
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+
+LUALIB_API lua_State *(luaL_newstate) (void);
+
+LUALIB_API int (luaL_len) (lua_State *L, int idx);
+
+LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+                                                  const char *r);
+
+LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
+
+LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
+
+LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
+                                  const char *msg, int level);
+
+LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
+                                 lua_CFunction openf, int glb);
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+
+#define luaL_newlibtable(L,l)	\
+  lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
+
+#define luaL_newlib(L,l)	(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
+#define luaL_argcheck(L, cond,numarg,extramsg)	\
+		((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
+#define luaL_checkstring(L,n)	(luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d)	(luaL_optlstring(L, (n), (d), NULL))
+#define luaL_checkint(L,n)	((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d)	((int)luaL_optinteger(L, (n), (d)))
+#define luaL_checklong(L,n)	((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d)	((long)luaL_optinteger(L, (n), (d)))
+
+#define luaL_typename(L,i)	lua_typename(L, lua_type(L,(i)))
+
+#define luaL_dofile(L, fn) \
+	(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_dostring(L, s) \
+	(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_getmetatable(L,n)	(lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+#define luaL_opt(L,f,n,d)	(lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+#define luaL_loadbuffer(L,s,sz,n)	luaL_loadbufferx(L,s,sz,n,NULL)
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+typedef struct luaL_Buffer {
+  char *b;  /* buffer address */
+  size_t size;  /* buffer size */
+  size_t n;  /* number of characters in buffer */
+  lua_State *L;
+  char initb[LUAL_BUFFERSIZE];  /* initial buffer */
+} luaL_Buffer;
+
+
+#define luaL_addchar(B,c) \
+  ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
+   ((B)->b[(B)->n++] = (c)))
+
+#define luaL_addsize(B,s)	((B)->n += (s))
+
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
+
+#define luaL_prepbuffer(B)	luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE          "FILE*"
+
+
+typedef struct luaL_Stream {
+  FILE *f;  /* stream (NULL for incompletely created streams) */
+  lua_CFunction closef;  /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
+/* compatibility with old module system */
+#if defined(LUA_COMPAT_MODULE)
+
+LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
+                                   int sizehint);
+LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+                                const luaL_Reg *l, int nup);
+
+#define luaL_register(L,n,l)	(luaL_openlib(L,(n),(l),0))
+
+#endif
+
+
+#endif
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lbaselib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lbaselib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lbaselib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,458 @@
+/*
+** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $
+** Basic library
+** See Copyright Notice in lua.h
+*/
+
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lbaselib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+static int luaB_print (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  int i;
+  lua_getglobal(L, "tostring");
+  for (i=1; i<=n; i++) {
+    const char *s;
+    size_t l;
+    lua_pushvalue(L, -1);  /* function to be called */
+    lua_pushvalue(L, i);   /* value to print */
+    lua_call(L, 1, 1);
+    s = lua_tolstring(L, -1, &l);  /* get result */
+    if (s == NULL)
+      return luaL_error(L,
+         LUA_QL("tostring") " must return a string to " LUA_QL("print"));
+    if (i>1) luai_writestring("\t", 1);
+    luai_writestring(s, l);
+    lua_pop(L, 1);  /* pop result */
+  }
+  luai_writeline();
+  return 0;
+}
+
+
+#define SPACECHARS	" \f\n\r\t\v"
+
+static int luaB_tonumber (lua_State *L) {
+  if (lua_isnoneornil(L, 2)) {  /* standard conversion */
+    int isnum;
+    lua_Number n = lua_tonumberx(L, 1, &isnum);
+    if (isnum) {
+      lua_pushnumber(L, n);
+      return 1;
+    }  /* else not a number; must be something */
+    luaL_checkany(L, 1);
+  }
+  else {
+    size_t l;
+    const char *s = luaL_checklstring(L, 1, &l);
+    const char *e = s + l;  /* end point for 's' */
+    int base = luaL_checkint(L, 2);
+    int neg = 0;
+    luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+    s += strspn(s, SPACECHARS);  /* skip initial spaces */
+    if (*s == '-') { s++; neg = 1; }  /* handle signal */
+    else if (*s == '+') s++;
+    if (isalnum((unsigned char)*s)) {
+      lua_Number n = 0;
+      do {
+        int digit = (isdigit((unsigned char)*s)) ? *s - '0'
+                       : toupper((unsigned char)*s) - 'A' + 10;
+        if (digit >= base) break;  /* invalid numeral; force a fail */
+        n = n * (lua_Number)base + (lua_Number)digit;
+        s++;
+      } while (isalnum((unsigned char)*s));
+      s += strspn(s, SPACECHARS);  /* skip trailing spaces */
+      if (s == e) {  /* no invalid trailing characters? */
+        lua_pushnumber(L, (neg) ? -n : n);
+        return 1;
+      }  /* else not a number */
+    }  /* else not a number */
+  }
+  lua_pushnil(L);  /* not a number */
+  return 1;
+}
+
+
+static int luaB_error (lua_State *L) {
+  int level = luaL_optint(L, 2, 1);
+  lua_settop(L, 1);
+  if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
+    luaL_where(L, level);
+    lua_pushvalue(L, 1);
+    lua_concat(L, 2);
+  }
+  return lua_error(L);
+}
+
+
+static int luaB_getmetatable (lua_State *L) {
+  luaL_checkany(L, 1);
+  if (!lua_getmetatable(L, 1)) {
+    lua_pushnil(L);
+    return 1;  /* no metatable */
+  }
+  luaL_getmetafield(L, 1, "__metatable");
+  return 1;  /* returns either __metatable field (if present) or metatable */
+}
+
+
+static int luaB_setmetatable (lua_State *L) {
+  int t = lua_type(L, 2);
+  luaL_checktype(L, 1, LUA_TTABLE);
+  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+                    "nil or table expected");
+  if (luaL_getmetafield(L, 1, "__metatable"))
+    return luaL_error(L, "cannot change a protected metatable");
+  lua_settop(L, 2);
+  lua_setmetatable(L, 1);
+  return 1;
+}
+
+
+static int luaB_rawequal (lua_State *L) {
+  luaL_checkany(L, 1);
+  luaL_checkany(L, 2);
+  lua_pushboolean(L, lua_rawequal(L, 1, 2));
+  return 1;
+}
+
+
+static int luaB_rawlen (lua_State *L) {
+  int t = lua_type(L, 1);
+  luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
+                   "table or string expected");
+  lua_pushinteger(L, lua_rawlen(L, 1));
+  return 1;
+}
+
+
+static int luaB_rawget (lua_State *L) {
+  luaL_checktype(L, 1, LUA_TTABLE);
+  luaL_checkany(L, 2);
+  lua_settop(L, 2);
+  lua_rawget(L, 1);
+  return 1;
+}
+
+static int luaB_rawset (lua_State *L) {
+  luaL_checktype(L, 1, LUA_TTABLE);
+  luaL_checkany(L, 2);
+  luaL_checkany(L, 3);
+  lua_settop(L, 3);
+  lua_rawset(L, 1);
+  return 1;
+}
+
+
+static int luaB_collectgarbage (lua_State *L) {
+  static const char *const opts[] = {"stop", "restart", "collect",
+    "count", "step", "setpause", "setstepmul",
+    "setmajorinc", "isrunning", "generational", "incremental", NULL};
+  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
+    LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
+    LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
+  int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
+  int ex = luaL_optint(L, 2, 0);
+  int res = lua_gc(L, o, ex);
+  switch (o) {
+    case LUA_GCCOUNT: {
+      int b = lua_gc(L, LUA_GCCOUNTB, 0);
+      lua_pushnumber(L, res + ((lua_Number)b/1024));
+      lua_pushinteger(L, b);
+      return 2;
+    }
+    case LUA_GCSTEP: case LUA_GCISRUNNING: {
+      lua_pushboolean(L, res);
+      return 1;
+    }
+    default: {
+      lua_pushinteger(L, res);
+      return 1;
+    }
+  }
+}
+
+
+static int luaB_type (lua_State *L) {
+  luaL_checkany(L, 1);
+  lua_pushstring(L, luaL_typename(L, 1));
+  return 1;
+}
+
+
+static int pairsmeta (lua_State *L, const char *method, int iszero,
+                      lua_CFunction iter) {
+  if (!luaL_getmetafield(L, 1, method)) {  /* no metamethod? */
+    luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
+    lua_pushcfunction(L, iter);  /* will return generator, */
+    lua_pushvalue(L, 1);  /* state, */
+    if (iszero) lua_pushinteger(L, 0);  /* and initial value */
+    else lua_pushnil(L);
+  }
+  else {
+    lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
+    lua_call(L, 1, 3);  /* get 3 values from metamethod */
+  }
+  return 3;
+}
+
+
+static int luaB_next (lua_State *L) {
+  luaL_checktype(L, 1, LUA_TTABLE);
+  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
+  if (lua_next(L, 1))
+    return 2;
+  else {
+    lua_pushnil(L);
+    return 1;
+  }
+}
+
+
+static int luaB_pairs (lua_State *L) {
+  return pairsmeta(L, "__pairs", 0, luaB_next);
+}
+
+
+static int ipairsaux (lua_State *L) {
+  int i = luaL_checkint(L, 2);
+  luaL_checktype(L, 1, LUA_TTABLE);
+  i++;  /* next value */
+  lua_pushinteger(L, i);
+  lua_rawgeti(L, 1, i);
+  return (lua_isnil(L, -1)) ? 1 : 2;
+}
+
+
+static int luaB_ipairs (lua_State *L) {
+  return pairsmeta(L, "__ipairs", 1, ipairsaux);
+}
+
+
+static int load_aux (lua_State *L, int status, int envidx) {
+  if (status == LUA_OK) {
+    if (envidx != 0) {  /* 'env' parameter? */
+      lua_pushvalue(L, envidx);  /* environment for loaded function */
+      if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
+        lua_pop(L, 1);  /* remove 'env' if not used by previous call */
+    }
+    return 1;
+  }
+  else {  /* error (message is on top of the stack) */
+    lua_pushnil(L);
+    lua_insert(L, -2);  /* put before error message */
+    return 2;  /* return nil plus error message */
+  }
+}
+
+
+static int luaB_loadfile (lua_State *L) {
+  const char *fname = luaL_optstring(L, 1, NULL);
+  const char *mode = luaL_optstring(L, 2, NULL);
+  int env = (!lua_isnone(L, 3) ? 3 : 0);  /* 'env' index or 0 if no 'env' */
+  int status = luaL_loadfilex(L, fname, mode);
+  return load_aux(L, status, env);
+}
+
+
+/*
+** {======================================================
+** Generic Read function
+** =======================================================
+*/
+
+
+/*
+** reserved slot, above all arguments, to hold a copy of the returned
+** string to avoid it being collected while parsed. 'load' has four
+** optional arguments (chunk, source name, mode, and environment).
+*/
+#define RESERVEDSLOT	5
+
+
+/*
+** Reader for generic `load' function: `lua_load' uses the
+** stack for internal stuff, so the reader cannot change the
+** stack top. Instead, it keeps its resulting string in a
+** reserved slot inside the stack.
+*/
+static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
+  (void)(ud);  /* not used */
+  luaL_checkstack(L, 2, "too many nested functions");
+  lua_pushvalue(L, 1);  /* get function */
+  lua_call(L, 0, 1);  /* call it */
+  if (lua_isnil(L, -1)) {
+    lua_pop(L, 1);  /* pop result */
+    *size = 0;
+    return NULL;
+  }
+  else if (!lua_isstring(L, -1))
+    luaL_error(L, "reader function must return a string");
+  lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
+  return lua_tolstring(L, RESERVEDSLOT, size);
+}
+
+
+static int luaB_load (lua_State *L) {
+  int status;
+  size_t l;
+  const char *s = lua_tolstring(L, 1, &l);
+  const char *mode = luaL_optstring(L, 3, "bt");
+  int env = (!lua_isnone(L, 4) ? 4 : 0);  /* 'env' index or 0 if no 'env' */
+  if (s != NULL) {  /* loading a string? */
+    const char *chunkname = luaL_optstring(L, 2, s);
+    status = luaL_loadbufferx(L, s, l, chunkname, mode);
+  }
+  else {  /* loading from a reader function */
+    const char *chunkname = luaL_optstring(L, 2, "=(load)");
+    luaL_checktype(L, 1, LUA_TFUNCTION);
+    lua_settop(L, RESERVEDSLOT);  /* create reserved slot */
+    status = lua_load(L, generic_reader, NULL, chunkname, mode);
+  }
+  return load_aux(L, status, env);
+}
+
+/* }====================================================== */
+
+
+static int dofilecont (lua_State *L) {
+  return lua_gettop(L) - 1;
+}
+
+
+static int luaB_dofile (lua_State *L) {
+  const char *fname = luaL_optstring(L, 1, NULL);
+  lua_settop(L, 1);
+  if (luaL_loadfile(L, fname) != LUA_OK)
+    return lua_error(L);
+  lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
+  return dofilecont(L);
+}
+
+
+static int luaB_assert (lua_State *L) {
+  if (!lua_toboolean(L, 1))
+    return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
+  return lua_gettop(L);
+}
+
+
+static int luaB_select (lua_State *L) {
+  int n = lua_gettop(L);
+  if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
+    lua_pushinteger(L, n-1);
+    return 1;
+  }
+  else {
+    int i = luaL_checkint(L, 1);
+    if (i < 0) i = n + i;
+    else if (i > n) i = n;
+    luaL_argcheck(L, 1 <= i, 1, "index out of range");
+    return n - i;
+  }
+}
+
+
+static int finishpcall (lua_State *L, int status) {
+  if (!lua_checkstack(L, 1)) {  /* no space for extra boolean? */
+    lua_settop(L, 0);  /* create space for return values */
+    lua_pushboolean(L, 0);
+    lua_pushstring(L, "stack overflow");
+    return 2;  /* return false, msg */
+  }
+  lua_pushboolean(L, status);  /* first result (status) */
+  lua_replace(L, 1);  /* put first result in first slot */
+  return lua_gettop(L);
+}
+
+
+static int pcallcont (lua_State *L) {
+  int status = lua_getctx(L, NULL);
+  return finishpcall(L, (status == LUA_YIELD));
+}
+
+
+static int luaB_pcall (lua_State *L) {
+  int status;
+  luaL_checkany(L, 1);
+  lua_pushnil(L);
+  lua_insert(L, 1);  /* create space for status result */
+  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
+  return finishpcall(L, (status == LUA_OK));
+}
+
+
+static int luaB_xpcall (lua_State *L) {
+  int status;
+  int n = lua_gettop(L);
+  luaL_argcheck(L, n >= 2, 2, "value expected");
+  lua_pushvalue(L, 1);  /* exchange function... */
+  lua_copy(L, 2, 1);  /* ...and error handler */
+  lua_replace(L, 2);
+  status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
+  return finishpcall(L, (status == LUA_OK));
+}
+
+
+static int luaB_tostring (lua_State *L) {
+  luaL_checkany(L, 1);
+  luaL_tolstring(L, 1, NULL);
+  return 1;
+}
+
+
+static const luaL_Reg base_funcs[] = {
+  {"assert", luaB_assert},
+  {"collectgarbage", luaB_collectgarbage},
+  {"dofile", luaB_dofile},
+  {"error", luaB_error},
+  {"getmetatable", luaB_getmetatable},
+  {"ipairs", luaB_ipairs},
+  {"loadfile", luaB_loadfile},
+  {"load", luaB_load},
+#if defined(LUA_COMPAT_LOADSTRING)
+  {"loadstring", luaB_load},
+#endif
+  {"next", luaB_next},
+  {"pairs", luaB_pairs},
+  {"pcall", luaB_pcall},
+  {"print", luaB_print},
+  {"rawequal", luaB_rawequal},
+  {"rawlen", luaB_rawlen},
+  {"rawget", luaB_rawget},
+  {"rawset", luaB_rawset},
+  {"select", luaB_select},
+  {"setmetatable", luaB_setmetatable},
+  {"tonumber", luaB_tonumber},
+  {"tostring", luaB_tostring},
+  {"type", luaB_type},
+  {"xpcall", luaB_xpcall},
+  {NULL, NULL}
+};
+
+
+LUAMOD_API int luaopen_base (lua_State *L) {
+  /* set global _G */
+  lua_pushglobaltable(L);
+  lua_pushglobaltable(L);
+  lua_setfield(L, -2, "_G");
+  /* open lib into global table */
+  luaL_setfuncs(L, base_funcs, 0);
+  lua_pushliteral(L, LUA_VERSION);
+  lua_setfield(L, -2, "_VERSION");  /* set global _VERSION */
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lbitlib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lbitlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lbitlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,212 @@
+/*
+** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $
+** Standard library for bitwise operations
+** See Copyright Notice in lua.h
+*/
+
+#define lbitlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/* number of bits to consider in a number */
+#if !defined(LUA_NBITS)
+#define LUA_NBITS	32
+#endif
+
+
+#define ALLONES		(~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
+
+/* macro to trim extra bits */
+#define trim(x)		((x) & ALLONES)
+
+
+/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
+#define mask(n)		(~((ALLONES << 1) << ((n) - 1)))
+
+
+typedef lua_Unsigned b_uint;
+
+
+
+static b_uint andaux (lua_State *L) {
+  int i, n = lua_gettop(L);
+  b_uint r = ~(b_uint)0;
+  for (i = 1; i <= n; i++)
+    r &= luaL_checkunsigned(L, i);
+  return trim(r);
+}
+
+
+static int b_and (lua_State *L) {
+  b_uint r = andaux(L);
+  lua_pushunsigned(L, r);
+  return 1;
+}
+
+
+static int b_test (lua_State *L) {
+  b_uint r = andaux(L);
+  lua_pushboolean(L, r != 0);
+  return 1;
+}
+
+
+static int b_or (lua_State *L) {
+  int i, n = lua_gettop(L);
+  b_uint r = 0;
+  for (i = 1; i <= n; i++)
+    r |= luaL_checkunsigned(L, i);
+  lua_pushunsigned(L, trim(r));
+  return 1;
+}
+
+
+static int b_xor (lua_State *L) {
+  int i, n = lua_gettop(L);
+  b_uint r = 0;
+  for (i = 1; i <= n; i++)
+    r ^= luaL_checkunsigned(L, i);
+  lua_pushunsigned(L, trim(r));
+  return 1;
+}
+
+
+static int b_not (lua_State *L) {
+  b_uint r = ~luaL_checkunsigned(L, 1);
+  lua_pushunsigned(L, trim(r));
+  return 1;
+}
+
+
+static int b_shift (lua_State *L, b_uint r, int i) {
+  if (i < 0) {  /* shift right? */
+    i = -i;
+    r = trim(r);
+    if (i >= LUA_NBITS) r = 0;
+    else r >>= i;
+  }
+  else {  /* shift left */
+    if (i >= LUA_NBITS) r = 0;
+    else r <<= i;
+    r = trim(r);
+  }
+  lua_pushunsigned(L, r);
+  return 1;
+}
+
+
+static int b_lshift (lua_State *L) {
+  return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
+}
+
+
+static int b_rshift (lua_State *L) {
+  return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
+}
+
+
+static int b_arshift (lua_State *L) {
+  b_uint r = luaL_checkunsigned(L, 1);
+  int i = luaL_checkint(L, 2);
+  if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
+    return b_shift(L, r, -i);
+  else {  /* arithmetic shift for 'negative' number */
+    if (i >= LUA_NBITS) r = ALLONES;
+    else
+      r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
+    lua_pushunsigned(L, r);
+    return 1;
+  }
+}
+
+
+static int b_rot (lua_State *L, int i) {
+  b_uint r = luaL_checkunsigned(L, 1);
+  i &= (LUA_NBITS - 1);  /* i = i % NBITS */
+  r = trim(r);
+  if (i != 0)  /* avoid undefined shift of LUA_NBITS when i == 0 */
+    r = (r << i) | (r >> (LUA_NBITS - i));
+  lua_pushunsigned(L, trim(r));
+  return 1;
+}
+
+
+static int b_lrot (lua_State *L) {
+  return b_rot(L, luaL_checkint(L, 2));
+}
+
+
+static int b_rrot (lua_State *L) {
+  return b_rot(L, -luaL_checkint(L, 2));
+}
+
+
+/*
+** get field and width arguments for field-manipulation functions,
+** checking whether they are valid.
+** ('luaL_error' called without 'return' to avoid later warnings about
+** 'width' being used uninitialized.)
+*/
+static int fieldargs (lua_State *L, int farg, int *width) {
+  int f = luaL_checkint(L, farg);
+  int w = luaL_optint(L, farg + 1, 1);
+  luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
+  luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
+  if (f + w > LUA_NBITS)
+    luaL_error(L, "trying to access non-existent bits");
+  *width = w;
+  return f;
+}
+
+
+static int b_extract (lua_State *L) {
+  int w;
+  b_uint r = luaL_checkunsigned(L, 1);
+  int f = fieldargs(L, 2, &w);
+  r = (r >> f) & mask(w);
+  lua_pushunsigned(L, r);
+  return 1;
+}
+
+
+static int b_replace (lua_State *L) {
+  int w;
+  b_uint r = luaL_checkunsigned(L, 1);
+  b_uint v = luaL_checkunsigned(L, 2);
+  int f = fieldargs(L, 3, &w);
+  int m = mask(w);
+  v &= m;  /* erase bits outside given width */
+  r = (r & ~(m << f)) | (v << f);
+  lua_pushunsigned(L, r);
+  return 1;
+}
+
+
+static const luaL_Reg bitlib[] = {
+  {"arshift", b_arshift},
+  {"band", b_and},
+  {"bnot", b_not},
+  {"bor", b_or},
+  {"bxor", b_xor},
+  {"btest", b_test},
+  {"extract", b_extract},
+  {"lrotate", b_lrot},
+  {"lshift", b_lshift},
+  {"replace", b_replace},
+  {"rrotate", b_rrot},
+  {"rshift", b_rshift},
+  {NULL, NULL}
+};
+
+
+
+LUAMOD_API int luaopen_bit32 (lua_State *L) {
+  luaL_newlib(L, bitlib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,881 @@
+/*
+** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lcode_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lvm.h"
+
+
+#define hasjumps(e)	((e)->t != (e)->f)
+
+
+static int isnumeral(expdesc *e) {
+  return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
+}
+
+
+void luaK_nil (FuncState *fs, int from, int n) {
+  Instruction *previous;
+  int l = from + n - 1;  /* last register to set nil */
+  if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
+    previous = &fs->f->code[fs->pc-1];
+    if (GET_OPCODE(*previous) == OP_LOADNIL) {
+      int pfrom = GETARG_A(*previous);
+      int pl = pfrom + GETARG_B(*previous);
+      if ((pfrom <= from && from <= pl + 1) ||
+          (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
+        if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
+        if (pl > l) l = pl;  /* l = max(l, pl) */
+        SETARG_A(*previous, from);
+        SETARG_B(*previous, l - from);
+        return;
+      }
+    }  /* else go through */
+  }
+  luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
+}
+
+
+int luaK_jump (FuncState *fs) {
+  int jpc = fs->jpc;  /* save list of jumps to here */
+  int j;
+  fs->jpc = NO_JUMP;
+  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+  luaK_concat(fs, &j, jpc);  /* keep them on hold */
+  return j;
+}
+
+
+void luaK_ret (FuncState *fs, int first, int nret) {
+  luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
+}
+
+
+static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
+  luaK_codeABC(fs, op, A, B, C);
+  return luaK_jump(fs);
+}
+
+
+static void fixjump (FuncState *fs, int pc, int dest) {
+  Instruction *jmp = &fs->f->code[pc];
+  int offset = dest-(pc+1);
+  lua_assert(dest != NO_JUMP);
+  if (abs(offset) > MAXARG_sBx)
+    luaX_syntaxerror(fs->ls, "control structure too long");
+  SETARG_sBx(*jmp, offset);
+}
+
+
+/*
+** returns current `pc' and marks it as a jump target (to avoid wrong
+** optimizations with consecutive instructions not in the same basic block).
+*/
+int luaK_getlabel (FuncState *fs) {
+  fs->lasttarget = fs->pc;
+  return fs->pc;
+}
+
+
+static int getjump (FuncState *fs, int pc) {
+  int offset = GETARG_sBx(fs->f->code[pc]);
+  if (offset == NO_JUMP)  /* point to itself represents end of list */
+    return NO_JUMP;  /* end of list */
+  else
+    return (pc+1)+offset;  /* turn offset into absolute position */
+}
+
+
+static Instruction *getjumpcontrol (FuncState *fs, int pc) {
+  Instruction *pi = &fs->f->code[pc];
+  if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
+    return pi-1;
+  else
+    return pi;
+}
+
+
+/*
+** check whether list has any jump that do not produce a value
+** (or produce an inverted value)
+*/
+static int need_value (FuncState *fs, int list) {
+  for (; list != NO_JUMP; list = getjump(fs, list)) {
+    Instruction i = *getjumpcontrol(fs, list);
+    if (GET_OPCODE(i) != OP_TESTSET) return 1;
+  }
+  return 0;  /* not found */
+}
+
+
+static int patchtestreg (FuncState *fs, int node, int reg) {
+  Instruction *i = getjumpcontrol(fs, node);
+  if (GET_OPCODE(*i) != OP_TESTSET)
+    return 0;  /* cannot patch other instructions */
+  if (reg != NO_REG && reg != GETARG_B(*i))
+    SETARG_A(*i, reg);
+  else  /* no register to put value or register already has the value */
+    *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
+
+  return 1;
+}
+
+
+static void removevalues (FuncState *fs, int list) {
+  for (; list != NO_JUMP; list = getjump(fs, list))
+      patchtestreg(fs, list, NO_REG);
+}
+
+
+static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
+                          int dtarget) {
+  while (list != NO_JUMP) {
+    int next = getjump(fs, list);
+    if (patchtestreg(fs, list, reg))
+      fixjump(fs, list, vtarget);
+    else
+      fixjump(fs, list, dtarget);  /* jump to default target */
+    list = next;
+  }
+}
+
+
+static void dischargejpc (FuncState *fs) {
+  patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
+  fs->jpc = NO_JUMP;
+}
+
+
+void luaK_patchlist (FuncState *fs, int list, int target) {
+  if (target == fs->pc)
+    luaK_patchtohere(fs, list);
+  else {
+    lua_assert(target < fs->pc);
+    patchlistaux(fs, list, target, NO_REG, target);
+  }
+}
+
+
+LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
+  level++;  /* argument is +1 to reserve 0 as non-op */
+  while (list != NO_JUMP) {
+    int next = getjump(fs, list);
+    lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
+                (GETARG_A(fs->f->code[list]) == 0 ||
+                 GETARG_A(fs->f->code[list]) >= level));
+    SETARG_A(fs->f->code[list], level);
+    list = next;
+  }
+}
+
+
+void luaK_patchtohere (FuncState *fs, int list) {
+  luaK_getlabel(fs);
+  luaK_concat(fs, &fs->jpc, list);
+}
+
+
+void luaK_concat (FuncState *fs, int *l1, int l2) {
+  if (l2 == NO_JUMP) return;
+  else if (*l1 == NO_JUMP)
+    *l1 = l2;
+  else {
+    int list = *l1;
+    int next;
+    while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
+      list = next;
+    fixjump(fs, list, l2);
+  }
+}
+
+
+static int luaK_code (FuncState *fs, Instruction i) {
+  Proto *f = fs->f;
+  dischargejpc(fs);  /* `pc' will change */
+  /* put new instruction in code array */
+  luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
+                  MAX_INT, "opcodes");
+  f->code[fs->pc] = i;
+  /* save corresponding line information */
+  luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+                  MAX_INT, "opcodes");
+  f->lineinfo[fs->pc] = fs->ls->lastline;
+  return fs->pc++;
+}
+
+
+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
+  lua_assert(getOpMode(o) == iABC);
+  lua_assert(getBMode(o) != OpArgN || b == 0);
+  lua_assert(getCMode(o) != OpArgN || c == 0);
+  lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
+  return luaK_code(fs, CREATE_ABC(o, a, b, c));
+}
+
+
+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
+  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+  lua_assert(getCMode(o) == OpArgN);
+  lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
+  return luaK_code(fs, CREATE_ABx(o, a, bc));
+}
+
+
+static int codeextraarg (FuncState *fs, int a) {
+  lua_assert(a <= MAXARG_Ax);
+  return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
+}
+
+
+int luaK_codek (FuncState *fs, int reg, int k) {
+  if (k <= MAXARG_Bx)
+    return luaK_codeABx(fs, OP_LOADK, reg, k);
+  else {
+    int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
+    codeextraarg(fs, k);
+    return p;
+  }
+}
+
+
+void luaK_checkstack (FuncState *fs, int n) {
+  int newstack = fs->freereg + n;
+  if (newstack > fs->f->maxstacksize) {
+    if (newstack >= MAXSTACK)
+      luaX_syntaxerror(fs->ls, "function or expression too complex");
+    fs->f->maxstacksize = cast_byte(newstack);
+  }
+}
+
+
+void luaK_reserveregs (FuncState *fs, int n) {
+  luaK_checkstack(fs, n);
+  fs->freereg += n;
+}
+
+
+static void freereg (FuncState *fs, int reg) {
+  if (!ISK(reg) && reg >= fs->nactvar) {
+    fs->freereg--;
+    lua_assert(reg == fs->freereg);
+  }
+}
+
+
+static void freeexp (FuncState *fs, expdesc *e) {
+  if (e->k == VNONRELOC)
+    freereg(fs, e->u.info);
+}
+
+
+static int addk (FuncState *fs, TValue *key, TValue *v) {
+  lua_State *L = fs->ls->L;
+  TValue *idx = luaH_set(L, fs->h, key);
+  Proto *f = fs->f;
+  int k, oldsize;
+  if (ttisnumber(idx)) {
+    lua_Number n = nvalue(idx);
+    lua_number2int(k, n);
+    if (luaV_rawequalobj(&f->k[k], v))
+      return k;
+    /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
+       go through and create a new entry for this value */
+  }
+  /* constant not found; create a new entry */
+  oldsize = f->sizek;
+  k = fs->nk;
+  /* numerical value does not need GC barrier;
+     table has no metatable, so it does not need to invalidate cache */
+  setnvalue(idx, cast_num(k));
+  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
+  while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
+  setobj(L, &f->k[k], v);
+  fs->nk++;
+  luaC_barrier(L, f, v);
+  return k;
+}
+
+
+int luaK_stringK (FuncState *fs, TString *s) {
+  TValue o;
+  setsvalue(fs->ls->L, &o, s);
+  return addk(fs, &o, &o);
+}
+
+
+int luaK_numberK (FuncState *fs, lua_Number r) {
+  int n;
+  lua_State *L = fs->ls->L;
+  TValue o;
+  setnvalue(&o, r);
+  if (r == 0 || luai_numisnan(NULL, r)) {  /* handle -0 and NaN */
+    /* use raw representation as key to avoid numeric problems */
+    setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
+    n = addk(fs, L->top - 1, &o);
+    L->top--;
+  }
+  else
+    n = addk(fs, &o, &o);  /* regular case */
+  return n;
+}
+
+
+static int boolK (FuncState *fs, int b) {
+  TValue o;
+  setbvalue(&o, b);
+  return addk(fs, &o, &o);
+}
+
+
+static int nilK (FuncState *fs) {
+  TValue k, v;
+  setnilvalue(&v);
+  /* cannot use nil as key; instead use table itself to represent nil */
+  sethvalue(fs->ls->L, &k, fs->h);
+  return addk(fs, &k, &v);
+}
+
+
+void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
+  if (e->k == VCALL) {  /* expression is an open function call? */
+    SETARG_C(getcode(fs, e), nresults+1);
+  }
+  else if (e->k == VVARARG) {
+    SETARG_B(getcode(fs, e), nresults+1);
+    SETARG_A(getcode(fs, e), fs->freereg);
+    luaK_reserveregs(fs, 1);
+  }
+}
+
+
+void luaK_setoneret (FuncState *fs, expdesc *e) {
+  if (e->k == VCALL) {  /* expression is an open function call? */
+    e->k = VNONRELOC;
+    e->u.info = GETARG_A(getcode(fs, e));
+  }
+  else if (e->k == VVARARG) {
+    SETARG_B(getcode(fs, e), 2);
+    e->k = VRELOCABLE;  /* can relocate its simple result */
+  }
+}
+
+
+void luaK_dischargevars (FuncState *fs, expdesc *e) {
+  switch (e->k) {
+    case VLOCAL: {
+      e->k = VNONRELOC;
+      break;
+    }
+    case VUPVAL: {
+      e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
+      e->k = VRELOCABLE;
+      break;
+    }
+    case VINDEXED: {
+      OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
+      freereg(fs, e->u.ind.idx);
+      if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
+        freereg(fs, e->u.ind.t);
+        op = OP_GETTABLE;
+      }
+      e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
+      e->k = VRELOCABLE;
+      break;
+    }
+    case VVARARG:
+    case VCALL: {
+      luaK_setoneret(fs, e);
+      break;
+    }
+    default: break;  /* there is one value available (somewhere) */
+  }
+}
+
+
+static int code_label (FuncState *fs, int A, int b, int jump) {
+  luaK_getlabel(fs);  /* those instructions may be jump targets */
+  return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
+}
+
+
+static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
+  luaK_dischargevars(fs, e);
+  switch (e->k) {
+    case VNIL: {
+      luaK_nil(fs, reg, 1);
+      break;
+    }
+    case VFALSE: case VTRUE: {
+      luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+      break;
+    }
+    case VK: {
+      luaK_codek(fs, reg, e->u.info);
+      break;
+    }
+    case VKNUM: {
+      luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
+      break;
+    }
+    case VRELOCABLE: {
+      Instruction *pc = &getcode(fs, e);
+      SETARG_A(*pc, reg);
+      break;
+    }
+    case VNONRELOC: {
+      if (reg != e->u.info)
+        luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
+      break;
+    }
+    default: {
+      lua_assert(e->k == VVOID || e->k == VJMP);
+      return;  /* nothing to do... */
+    }
+  }
+  e->u.info = reg;
+  e->k = VNONRELOC;
+}
+
+
+static void discharge2anyreg (FuncState *fs, expdesc *e) {
+  if (e->k != VNONRELOC) {
+    luaK_reserveregs(fs, 1);
+    discharge2reg(fs, e, fs->freereg-1);
+  }
+}
+
+
+static void exp2reg (FuncState *fs, expdesc *e, int reg) {
+  discharge2reg(fs, e, reg);
+  if (e->k == VJMP)
+    luaK_concat(fs, &e->t, e->u.info);  /* put this jump in `t' list */
+  if (hasjumps(e)) {
+    int final;  /* position after whole expression */
+    int p_f = NO_JUMP;  /* position of an eventual LOAD false */
+    int p_t = NO_JUMP;  /* position of an eventual LOAD true */
+    if (need_value(fs, e->t) || need_value(fs, e->f)) {
+      int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
+      p_f = code_label(fs, reg, 0, 1);
+      p_t = code_label(fs, reg, 1, 0);
+      luaK_patchtohere(fs, fj);
+    }
+    final = luaK_getlabel(fs);
+    patchlistaux(fs, e->f, final, reg, p_f);
+    patchlistaux(fs, e->t, final, reg, p_t);
+  }
+  e->f = e->t = NO_JUMP;
+  e->u.info = reg;
+  e->k = VNONRELOC;
+}
+
+
+void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
+  luaK_dischargevars(fs, e);
+  freeexp(fs, e);
+  luaK_reserveregs(fs, 1);
+  exp2reg(fs, e, fs->freereg - 1);
+}
+
+
+int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
+  luaK_dischargevars(fs, e);
+  if (e->k == VNONRELOC) {
+    if (!hasjumps(e)) return e->u.info;  /* exp is already in a register */
+    if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
+      exp2reg(fs, e, e->u.info);  /* put value on it */
+      return e->u.info;
+    }
+  }
+  luaK_exp2nextreg(fs, e);  /* default */
+  return e->u.info;
+}
+
+
+void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
+  if (e->k != VUPVAL || hasjumps(e))
+    luaK_exp2anyreg(fs, e);
+}
+
+
+void luaK_exp2val (FuncState *fs, expdesc *e) {
+  if (hasjumps(e))
+    luaK_exp2anyreg(fs, e);
+  else
+    luaK_dischargevars(fs, e);
+}
+
+
+int luaK_exp2RK (FuncState *fs, expdesc *e) {
+  luaK_exp2val(fs, e);
+  switch (e->k) {
+    case VTRUE:
+    case VFALSE:
+    case VNIL: {
+      if (fs->nk <= MAXINDEXRK) {  /* constant fits in RK operand? */
+        e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
+        e->k = VK;
+        return RKASK(e->u.info);
+      }
+      else break;
+    }
+    case VKNUM: {
+      e->u.info = luaK_numberK(fs, e->u.nval);
+      e->k = VK;
+      /* go through */
+    }
+    case VK: {
+      if (e->u.info <= MAXINDEXRK)  /* constant fits in argC? */
+        return RKASK(e->u.info);
+      else break;
+    }
+    default: break;
+  }
+  /* not a constant in the right range: put it in a register */
+  return luaK_exp2anyreg(fs, e);
+}
+
+
+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
+  switch (var->k) {
+    case VLOCAL: {
+      freeexp(fs, ex);
+      exp2reg(fs, ex, var->u.info);
+      return;
+    }
+    case VUPVAL: {
+      int e = luaK_exp2anyreg(fs, ex);
+      luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
+      break;
+    }
+    case VINDEXED: {
+      OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
+      int e = luaK_exp2RK(fs, ex);
+      luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
+      break;
+    }
+    default: {
+      lua_assert(0);  /* invalid var kind to store */
+      break;
+    }
+  }
+  freeexp(fs, ex);
+}
+
+
+void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
+  int ereg;
+  luaK_exp2anyreg(fs, e);
+  ereg = e->u.info;  /* register where 'e' was placed */
+  freeexp(fs, e);
+  e->u.info = fs->freereg;  /* base register for op_self */
+  e->k = VNONRELOC;
+  luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
+  luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
+  freeexp(fs, key);
+}
+
+
+static void invertjump (FuncState *fs, expdesc *e) {
+  Instruction *pc = getjumpcontrol(fs, e->u.info);
+  lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
+                                           GET_OPCODE(*pc) != OP_TEST);
+  SETARG_A(*pc, !(GETARG_A(*pc)));
+}
+
+
+static int jumponcond (FuncState *fs, expdesc *e, int cond) {
+  if (e->k == VRELOCABLE) {
+    Instruction ie = getcode(fs, e);
+    if (GET_OPCODE(ie) == OP_NOT) {
+      fs->pc--;  /* remove previous OP_NOT */
+      return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
+    }
+    /* else go through */
+  }
+  discharge2anyreg(fs, e);
+  freeexp(fs, e);
+  return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
+}
+
+
+void luaK_goiftrue (FuncState *fs, expdesc *e) {
+  int pc;  /* pc of last jump */
+  luaK_dischargevars(fs, e);
+  switch (e->k) {
+    case VJMP: {
+      invertjump(fs, e);
+      pc = e->u.info;
+      break;
+    }
+    case VK: case VKNUM: case VTRUE: {
+      pc = NO_JUMP;  /* always true; do nothing */
+      break;
+    }
+    default: {
+      pc = jumponcond(fs, e, 0);
+      break;
+    }
+  }
+  luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
+  luaK_patchtohere(fs, e->t);
+  e->t = NO_JUMP;
+}
+
+
+void luaK_goiffalse (FuncState *fs, expdesc *e) {
+  int pc;  /* pc of last jump */
+  luaK_dischargevars(fs, e);
+  switch (e->k) {
+    case VJMP: {
+      pc = e->u.info;
+      break;
+    }
+    case VNIL: case VFALSE: {
+      pc = NO_JUMP;  /* always false; do nothing */
+      break;
+    }
+    default: {
+      pc = jumponcond(fs, e, 1);
+      break;
+    }
+  }
+  luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
+  luaK_patchtohere(fs, e->f);
+  e->f = NO_JUMP;
+}
+
+
+static void codenot (FuncState *fs, expdesc *e) {
+  luaK_dischargevars(fs, e);
+  switch (e->k) {
+    case VNIL: case VFALSE: {
+      e->k = VTRUE;
+      break;
+    }
+    case VK: case VKNUM: case VTRUE: {
+      e->k = VFALSE;
+      break;
+    }
+    case VJMP: {
+      invertjump(fs, e);
+      break;
+    }
+    case VRELOCABLE:
+    case VNONRELOC: {
+      discharge2anyreg(fs, e);
+      freeexp(fs, e);
+      e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
+      e->k = VRELOCABLE;
+      break;
+    }
+    default: {
+      lua_assert(0);  /* cannot happen */
+      break;
+    }
+  }
+  /* interchange true and false lists */
+  { int temp = e->f; e->f = e->t; e->t = temp; }
+  removevalues(fs, e->f);
+  removevalues(fs, e->t);
+}
+
+
+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
+  lua_assert(!hasjumps(t));
+  t->u.ind.t = t->u.info;
+  t->u.ind.idx = luaK_exp2RK(fs, k);
+  t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
+                                 : check_exp(vkisinreg(t->k), VLOCAL);
+  t->k = VINDEXED;
+}
+
+
+static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
+  lua_Number r;
+  if (!isnumeral(e1) || !isnumeral(e2)) return 0;
+  if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
+    return 0;  /* do not attempt to divide by 0 */
+  r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
+  e1->u.nval = r;
+  return 1;
+}
+
+
+static void codearith (FuncState *fs, OpCode op,
+                       expdesc *e1, expdesc *e2, int line) {
+  if (constfolding(op, e1, e2))
+    return;
+  else {
+    int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
+    int o1 = luaK_exp2RK(fs, e1);
+    if (o1 > o2) {
+      freeexp(fs, e1);
+      freeexp(fs, e2);
+    }
+    else {
+      freeexp(fs, e2);
+      freeexp(fs, e1);
+    }
+    e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
+    e1->k = VRELOCABLE;
+    luaK_fixline(fs, line);
+  }
+}
+
+
+static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
+                                                          expdesc *e2) {
+  int o1 = luaK_exp2RK(fs, e1);
+  int o2 = luaK_exp2RK(fs, e2);
+  freeexp(fs, e2);
+  freeexp(fs, e1);
+  if (cond == 0 && op != OP_EQ) {
+    int temp;  /* exchange args to replace by `<' or `<=' */
+    temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
+    cond = 1;
+  }
+  e1->u.info = condjump(fs, op, cond, o1, o2);
+  e1->k = VJMP;
+}
+
+
+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
+  expdesc e2;
+  e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
+  switch (op) {
+    case OPR_MINUS: {
+      if (isnumeral(e))  /* minus constant? */
+        e->u.nval = luai_numunm(NULL, e->u.nval);  /* fold it */
+      else {
+        luaK_exp2anyreg(fs, e);
+        codearith(fs, OP_UNM, e, &e2, line);
+      }
+      break;
+    }
+    case OPR_NOT: codenot(fs, e); break;
+    case OPR_LEN: {
+      luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
+      codearith(fs, OP_LEN, e, &e2, line);
+      break;
+    }
+    default: lua_assert(0);
+  }
+}
+
+
+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
+  switch (op) {
+    case OPR_AND: {
+      luaK_goiftrue(fs, v);
+      break;
+    }
+    case OPR_OR: {
+      luaK_goiffalse(fs, v);
+      break;
+    }
+    case OPR_CONCAT: {
+      luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
+      break;
+    }
+    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+    case OPR_MOD: case OPR_POW: {
+      if (!isnumeral(v)) luaK_exp2RK(fs, v);
+      break;
+    }
+    default: {
+      luaK_exp2RK(fs, v);
+      break;
+    }
+  }
+}
+
+
+void luaK_posfix (FuncState *fs, BinOpr op,
+                  expdesc *e1, expdesc *e2, int line) {
+  switch (op) {
+    case OPR_AND: {
+      lua_assert(e1->t == NO_JUMP);  /* list must be closed */
+      luaK_dischargevars(fs, e2);
+      luaK_concat(fs, &e2->f, e1->f);
+      *e1 = *e2;
+      break;
+    }
+    case OPR_OR: {
+      lua_assert(e1->f == NO_JUMP);  /* list must be closed */
+      luaK_dischargevars(fs, e2);
+      luaK_concat(fs, &e2->t, e1->t);
+      *e1 = *e2;
+      break;
+    }
+    case OPR_CONCAT: {
+      luaK_exp2val(fs, e2);
+      if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
+        lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
+        freeexp(fs, e1);
+        SETARG_B(getcode(fs, e2), e1->u.info);
+        e1->k = VRELOCABLE; e1->u.info = e2->u.info;
+      }
+      else {
+        luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
+        codearith(fs, OP_CONCAT, e1, e2, line);
+      }
+      break;
+    }
+    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+    case OPR_MOD: case OPR_POW: {
+      codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
+      break;
+    }
+    case OPR_EQ: case OPR_LT: case OPR_LE: {
+      codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
+      break;
+    }
+    case OPR_NE: case OPR_GT: case OPR_GE: {
+      codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
+      break;
+    }
+    default: lua_assert(0);
+  }
+}
+
+
+void luaK_fixline (FuncState *fs, int line) {
+  fs->f->lineinfo[fs->pc - 1] = line;
+}
+
+
+void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
+  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+  int b = (tostore == LUA_MULTRET) ? 0 : tostore;
+  lua_assert(tostore != 0);
+  if (c <= MAXARG_C)
+    luaK_codeABC(fs, OP_SETLIST, base, b, c);
+  else if (c <= MAXARG_Ax) {
+    luaK_codeABC(fs, OP_SETLIST, base, b, 0);
+    codeextraarg(fs, c);
+  }
+  else
+    luaX_syntaxerror(fs->ls, "constructor too long");
+  fs->freereg = base + 1;  /* free registers with list values */
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lcode.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/*
+** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lcode_h
+#define lcode_h
+
+#include "llex.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+
+
+/*
+** Marks the end of a patch list. It is an invalid value both as an absolute
+** address, and as a list link (would link an element to itself).
+*/
+#define NO_JUMP (-1)
+
+
+/*
+** grep "ORDER OPR" if you change these enums  (ORDER OP)
+*/
+typedef enum BinOpr {
+  OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
+  OPR_CONCAT,
+  OPR_EQ, OPR_LT, OPR_LE,
+  OPR_NE, OPR_GT, OPR_GE,
+  OPR_AND, OPR_OR,
+  OPR_NOBINOPR
+} BinOpr;
+
+
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
+
+
+#define getcode(fs,e)	((fs)->f->code[(e)->u.info])
+
+#define luaK_codeAsBx(fs,o,A,sBx)	luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
+
+#define luaK_setmultret(fs,e)	luaK_setreturns(fs, e, LUA_MULTRET)
+
+#define luaK_jumpto(fs,t)	luaK_patchlist(fs, luaK_jump(fs), t)
+
+LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
+LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
+LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
+LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
+LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
+LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
+LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
+LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
+LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
+LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
+LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
+LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
+LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
+LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_jump (FuncState *fs);
+LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
+LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
+LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
+LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
+LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
+LUAI_FUNC int luaK_getlabel (FuncState *fs);
+LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
+LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
+                            expdesc *v2, int line);
+LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lcorolib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lcorolib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lcorolib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,155 @@
+/*
+** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $
+** Coroutine Library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+
+#define lcorolib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+static int auxresume (lua_State *L, lua_State *co, int narg) {
+  int status;
+  if (!lua_checkstack(co, narg)) {
+    lua_pushliteral(L, "too many arguments to resume");
+    return -1;  /* error flag */
+  }
+  if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
+    lua_pushliteral(L, "cannot resume dead coroutine");
+    return -1;  /* error flag */
+  }
+  lua_xmove(L, co, narg);
+  status = lua_resume(co, L, narg);
+  if (status == LUA_OK || status == LUA_YIELD) {
+    int nres = lua_gettop(co);
+    if (!lua_checkstack(L, nres + 1)) {
+      lua_pop(co, nres);  /* remove results anyway */
+      lua_pushliteral(L, "too many results to resume");
+      return -1;  /* error flag */
+    }
+    lua_xmove(co, L, nres);  /* move yielded values */
+    return nres;
+  }
+  else {
+    lua_xmove(co, L, 1);  /* move error message */
+    return -1;  /* error flag */
+  }
+}
+
+
+static int luaB_coresume (lua_State *L) {
+  lua_State *co = lua_tothread(L, 1);
+  int r;
+  luaL_argcheck(L, co, 1, "coroutine expected");
+  r = auxresume(L, co, lua_gettop(L) - 1);
+  if (r < 0) {
+    lua_pushboolean(L, 0);
+    lua_insert(L, -2);
+    return 2;  /* return false + error message */
+  }
+  else {
+    lua_pushboolean(L, 1);
+    lua_insert(L, -(r + 1));
+    return r + 1;  /* return true + `resume' returns */
+  }
+}
+
+
+static int luaB_auxwrap (lua_State *L) {
+  lua_State *co = lua_tothread(L, lua_upvalueindex(1));
+  int r = auxresume(L, co, lua_gettop(L));
+  if (r < 0) {
+    if (lua_isstring(L, -1)) {  /* error object is a string? */
+      luaL_where(L, 1);  /* add extra info */
+      lua_insert(L, -2);
+      lua_concat(L, 2);
+    }
+    return lua_error(L);  /* propagate error */
+  }
+  return r;
+}
+
+
+static int luaB_cocreate (lua_State *L) {
+  lua_State *NL;
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+  NL = lua_newthread(L);
+  lua_pushvalue(L, 1);  /* move function to top */
+  lua_xmove(L, NL, 1);  /* move function from L to NL */
+  return 1;
+}
+
+
+static int luaB_cowrap (lua_State *L) {
+  luaB_cocreate(L);
+  lua_pushcclosure(L, luaB_auxwrap, 1);
+  return 1;
+}
+
+
+static int luaB_yield (lua_State *L) {
+  return lua_yield(L, lua_gettop(L));
+}
+
+
+static int luaB_costatus (lua_State *L) {
+  lua_State *co = lua_tothread(L, 1);
+  luaL_argcheck(L, co, 1, "coroutine expected");
+  if (L == co) lua_pushliteral(L, "running");
+  else {
+    switch (lua_status(co)) {
+      case LUA_YIELD:
+        lua_pushliteral(L, "suspended");
+        break;
+      case LUA_OK: {
+        lua_Debug ar;
+        if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
+          lua_pushliteral(L, "normal");  /* it is running */
+        else if (lua_gettop(co) == 0)
+            lua_pushliteral(L, "dead");
+        else
+          lua_pushliteral(L, "suspended");  /* initial state */
+        break;
+      }
+      default:  /* some error occurred */
+        lua_pushliteral(L, "dead");
+        break;
+    }
+  }
+  return 1;
+}
+
+
+static int luaB_corunning (lua_State *L) {
+  int ismain = lua_pushthread(L);
+  lua_pushboolean(L, ismain);
+  return 2;
+}
+
+
+static const luaL_Reg co_funcs[] = {
+  {"create", luaB_cocreate},
+  {"resume", luaB_coresume},
+  {"running", luaB_corunning},
+  {"status", luaB_costatus},
+  {"wrap", luaB_cowrap},
+  {"yield", luaB_yield},
+  {NULL, NULL}
+};
+
+
+
+LUAMOD_API int luaopen_coroutine (lua_State *L) {
+  luaL_newlib(L, co_funcs);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/*
+** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $
+** 'ctype' functions for Lua
+** See Copyright Notice in lua.h
+*/
+
+#define lctype_c
+#define LUA_CORE
+
+#include "lctype.h"
+
+#if !LUA_USE_CTYPE	/* { */
+
+#include <limits.h>
+
+LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
+  0x00,  /* EOZ */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 0. */
+  0x00,  0x08,  0x08,  0x08,  0x08,  0x08,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 1. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x0c,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,	/* 2. */
+  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
+  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,  0x16,	/* 3. */
+  0x16,  0x16,  0x04,  0x04,  0x04,  0x04,  0x04,  0x04,
+  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,	/* 4. */
+  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
+  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,	/* 5. */
+  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x05,
+  0x04,  0x15,  0x15,  0x15,  0x15,  0x15,  0x15,  0x05,	/* 6. */
+  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,
+  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,  0x05,	/* 7. */
+  0x05,  0x05,  0x05,  0x04,  0x04,  0x04,  0x04,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 8. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* 9. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* a. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* b. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* c. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* d. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* e. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,	/* f. */
+  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+};
+
+#endif			/* } */
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lctype.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,95 @@
+/*
+** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
+** 'ctype' functions for Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lctype_h
+#define lctype_h
+
+#include "lua.h"
+
+
+/*
+** WARNING: the functions defined here do not necessarily correspond
+** to the similar functions in the standard C ctype.h. They are
+** optimized for the specific needs of Lua
+*/
+
+#if !defined(LUA_USE_CTYPE)
+
+#if 'A' == 65 && '0' == 48
+/* ASCII case: can use its own tables; faster and fixed */
+#define LUA_USE_CTYPE	0
+#else
+/* must use standard C ctype */
+#define LUA_USE_CTYPE	1
+#endif
+
+#endif
+
+
+#if !LUA_USE_CTYPE	/* { */
+
+#include <limits.h>
+
+#include "llimits.h"
+
+
+#define ALPHABIT	0
+#define DIGITBIT	1
+#define PRINTBIT	2
+#define SPACEBIT	3
+#define XDIGITBIT	4
+
+
+#define MASK(B)		(1 << (B))
+
+
+/*
+** add 1 to char to allow index -1 (EOZ)
+*/
+#define testprop(c,p)	(luai_ctype_[(c)+1] & (p))
+
+/*
+** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
+*/
+#define lislalpha(c)	testprop(c, MASK(ALPHABIT))
+#define lislalnum(c)	testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
+#define lisdigit(c)	testprop(c, MASK(DIGITBIT))
+#define lisspace(c)	testprop(c, MASK(SPACEBIT))
+#define lisprint(c)	testprop(c, MASK(PRINTBIT))
+#define lisxdigit(c)	testprop(c, MASK(XDIGITBIT))
+
+/*
+** this 'ltolower' only works for alphabetic characters
+*/
+#define ltolower(c)	((c) | ('A' ^ 'a'))
+
+
+/* two more entries for 0 and -1 (EOZ) */
+LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
+
+
+#else			/* }{ */
+
+/*
+** use standard C ctypes
+*/
+
+#include <ctype.h>
+
+
+#define lislalpha(c)	(isalpha(c) || (c) == '_')
+#define lislalnum(c)	(isalnum(c) || (c) == '_')
+#define lisdigit(c)	(isdigit(c))
+#define lisspace(c)	(isspace(c))
+#define lisprint(c)	(isprint(c))
+#define lisxdigit(c)	(isxdigit(c))
+
+#define ltolower(c)	(tolower(c))
+
+#endif			/* } */
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldblib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldblib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldblib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,398 @@
+/*
+** $Id: ldblib.c,v 1.132.1.1 2013/04/12 18:48:47 roberto Exp $
+** Interface from Lua to its debug API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldblib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#define HOOKKEY		"_HKEY"
+
+
+
+static int db_getregistry (lua_State *L) {
+  lua_pushvalue(L, LUA_REGISTRYINDEX);
+  return 1;
+}
+
+
+static int db_getmetatable (lua_State *L) {
+  luaL_checkany(L, 1);
+  if (!lua_getmetatable(L, 1)) {
+    lua_pushnil(L);  /* no metatable */
+  }
+  return 1;
+}
+
+
+static int db_setmetatable (lua_State *L) {
+  int t = lua_type(L, 2);
+  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+                    "nil or table expected");
+  lua_settop(L, 2);
+  lua_setmetatable(L, 1);
+  return 1;  /* return 1st argument */
+}
+
+
+static int db_getuservalue (lua_State *L) {
+  if (lua_type(L, 1) != LUA_TUSERDATA)
+    lua_pushnil(L);
+  else
+    lua_getuservalue(L, 1);
+  return 1;
+}
+
+
+static int db_setuservalue (lua_State *L) {
+  if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
+    luaL_argerror(L, 1, "full userdata expected, got light userdata");
+  luaL_checktype(L, 1, LUA_TUSERDATA);
+  if (!lua_isnoneornil(L, 2))
+    luaL_checktype(L, 2, LUA_TTABLE);
+  lua_settop(L, 2);
+  lua_setuservalue(L, 1);
+  return 1;
+}
+
+
+static void settabss (lua_State *L, const char *i, const char *v) {
+  lua_pushstring(L, v);
+  lua_setfield(L, -2, i);
+}
+
+
+static void settabsi (lua_State *L, const char *i, int v) {
+  lua_pushinteger(L, v);
+  lua_setfield(L, -2, i);
+}
+
+
+static void settabsb (lua_State *L, const char *i, int v) {
+  lua_pushboolean(L, v);
+  lua_setfield(L, -2, i);
+}
+
+
+static lua_State *getthread (lua_State *L, int *arg) {
+  if (lua_isthread(L, 1)) {
+    *arg = 1;
+    return lua_tothread(L, 1);
+  }
+  else {
+    *arg = 0;
+    return L;
+  }
+}
+
+
+static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
+  if (L == L1) {
+    lua_pushvalue(L, -2);
+    lua_remove(L, -3);
+  }
+  else
+    lua_xmove(L1, L, 1);
+  lua_setfield(L, -2, fname);
+}
+
+
+static int db_getinfo (lua_State *L) {
+  lua_Debug ar;
+  int arg;
+  lua_State *L1 = getthread(L, &arg);
+  const char *options = luaL_optstring(L, arg+2, "flnStu");
+  if (lua_isnumber(L, arg+1)) {
+    if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
+      lua_pushnil(L);  /* level out of range */
+      return 1;
+    }
+  }
+  else if (lua_isfunction(L, arg+1)) {
+    lua_pushfstring(L, ">%s", options);
+    options = lua_tostring(L, -1);
+    lua_pushvalue(L, arg+1);
+    lua_xmove(L, L1, 1);
+  }
+  else
+    return luaL_argerror(L, arg+1, "function or level expected");
+  if (!lua_getinfo(L1, options, &ar))
+    return luaL_argerror(L, arg+2, "invalid option");
+  lua_createtable(L, 0, 2);
+  if (strchr(options, 'S')) {
+    settabss(L, "source", ar.source);
+    settabss(L, "short_src", ar.short_src);
+    settabsi(L, "linedefined", ar.linedefined);
+    settabsi(L, "lastlinedefined", ar.lastlinedefined);
+    settabss(L, "what", ar.what);
+  }
+  if (strchr(options, 'l'))
+    settabsi(L, "currentline", ar.currentline);
+  if (strchr(options, 'u')) {
+    settabsi(L, "nups", ar.nups);
+    settabsi(L, "nparams", ar.nparams);
+    settabsb(L, "isvararg", ar.isvararg);
+  }
+  if (strchr(options, 'n')) {
+    settabss(L, "name", ar.name);
+    settabss(L, "namewhat", ar.namewhat);
+  }
+  if (strchr(options, 't'))
+    settabsb(L, "istailcall", ar.istailcall);
+  if (strchr(options, 'L'))
+    treatstackoption(L, L1, "activelines");
+  if (strchr(options, 'f'))
+    treatstackoption(L, L1, "func");
+  return 1;  /* return table */
+}
+
+
+static int db_getlocal (lua_State *L) {
+  int arg;
+  lua_State *L1 = getthread(L, &arg);
+  lua_Debug ar;
+  const char *name;
+  int nvar = luaL_checkint(L, arg+2);  /* local-variable index */
+  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
+    lua_pushvalue(L, arg + 1);  /* push function */
+    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
+    return 1;
+  }
+  else {  /* stack-level argument */
+    if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
+      return luaL_argerror(L, arg+1, "level out of range");
+    name = lua_getlocal(L1, &ar, nvar);
+    if (name) {
+      lua_xmove(L1, L, 1);  /* push local value */
+      lua_pushstring(L, name);  /* push name */
+      lua_pushvalue(L, -2);  /* re-order */
+      return 2;
+    }
+    else {
+      lua_pushnil(L);  /* no name (nor value) */
+      return 1;
+    }
+  }
+}
+
+
+static int db_setlocal (lua_State *L) {
+  int arg;
+  lua_State *L1 = getthread(L, &arg);
+  lua_Debug ar;
+  if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
+    return luaL_argerror(L, arg+1, "level out of range");
+  luaL_checkany(L, arg+3);
+  lua_settop(L, arg+3);
+  lua_xmove(L, L1, 1);
+  lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
+  return 1;
+}
+
+
+static int auxupvalue (lua_State *L, int get) {
+  const char *name;
+  int n = luaL_checkint(L, 2);
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
+  if (name == NULL) return 0;
+  lua_pushstring(L, name);
+  lua_insert(L, -(get+1));
+  return get + 1;
+}
+
+
+static int db_getupvalue (lua_State *L) {
+  return auxupvalue(L, 1);
+}
+
+
+static int db_setupvalue (lua_State *L) {
+  luaL_checkany(L, 3);
+  return auxupvalue(L, 0);
+}
+
+
+static int checkupval (lua_State *L, int argf, int argnup) {
+  lua_Debug ar;
+  int nup = luaL_checkint(L, argnup);
+  luaL_checktype(L, argf, LUA_TFUNCTION);
+  lua_pushvalue(L, argf);
+  lua_getinfo(L, ">u", &ar);
+  luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
+  return nup;
+}
+
+
+static int db_upvalueid (lua_State *L) {
+  int n = checkupval(L, 1, 2);
+  lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
+  return 1;
+}
+
+
+static int db_upvaluejoin (lua_State *L) {
+  int n1 = checkupval(L, 1, 2);
+  int n2 = checkupval(L, 3, 4);
+  luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
+  luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
+  lua_upvaluejoin(L, 1, n1, 3, n2);
+  return 0;
+}
+
+
+#define gethooktable(L)	luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)
+
+
+static void hookf (lua_State *L, lua_Debug *ar) {
+  static const char *const hooknames[] =
+    {"call", "return", "line", "count", "tail call"};
+  gethooktable(L);
+  lua_pushthread(L);
+  lua_rawget(L, -2);
+  if (lua_isfunction(L, -1)) {
+    lua_pushstring(L, hooknames[(int)ar->event]);
+    if (ar->currentline >= 0)
+      lua_pushinteger(L, ar->currentline);
+    else lua_pushnil(L);
+    lua_assert(lua_getinfo(L, "lS", ar));
+    lua_call(L, 2, 0);
+  }
+}
+
+
+static int makemask (const char *smask, int count) {
+  int mask = 0;
+  if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
+  if (strchr(smask, 'r')) mask |= LUA_MASKRET;
+  if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+  if (count > 0) mask |= LUA_MASKCOUNT;
+  return mask;
+}
+
+
+static char *unmakemask (int mask, char *smask) {
+  int i = 0;
+  if (mask & LUA_MASKCALL) smask[i++] = 'c';
+  if (mask & LUA_MASKRET) smask[i++] = 'r';
+  if (mask & LUA_MASKLINE) smask[i++] = 'l';
+  smask[i] = '\0';
+  return smask;
+}
+
+
+static int db_sethook (lua_State *L) {
+  int arg, mask, count;
+  lua_Hook func;
+  lua_State *L1 = getthread(L, &arg);
+  if (lua_isnoneornil(L, arg+1)) {
+    lua_settop(L, arg+1);
+    func = NULL; mask = 0; count = 0;  /* turn off hooks */
+  }
+  else {
+    const char *smask = luaL_checkstring(L, arg+2);
+    luaL_checktype(L, arg+1, LUA_TFUNCTION);
+    count = luaL_optint(L, arg+3, 0);
+    func = hookf; mask = makemask(smask, count);
+  }
+  if (gethooktable(L) == 0) {  /* creating hook table? */
+    lua_pushstring(L, "k");
+    lua_setfield(L, -2, "__mode");  /** hooktable.__mode = "k" */
+    lua_pushvalue(L, -1);
+    lua_setmetatable(L, -2);  /* setmetatable(hooktable) = hooktable */
+  }
+  lua_pushthread(L1); lua_xmove(L1, L, 1);
+  lua_pushvalue(L, arg+1);
+  lua_rawset(L, -3);  /* set new hook */
+  lua_sethook(L1, func, mask, count);  /* set hooks */
+  return 0;
+}
+
+
+static int db_gethook (lua_State *L) {
+  int arg;
+  lua_State *L1 = getthread(L, &arg);
+  char buff[5];
+  int mask = lua_gethookmask(L1);
+  lua_Hook hook = lua_gethook(L1);
+  if (hook != NULL && hook != hookf)  /* external hook? */
+    lua_pushliteral(L, "external hook");
+  else {
+    gethooktable(L);
+    lua_pushthread(L1); lua_xmove(L1, L, 1);
+    lua_rawget(L, -2);   /* get hook */
+    lua_remove(L, -2);  /* remove hook table */
+  }
+  lua_pushstring(L, unmakemask(mask, buff));
+  lua_pushinteger(L, lua_gethookcount(L1));
+  return 3;
+}
+
+
+static int db_debug (lua_State *L) {
+  for (;;) {
+    char buffer[250];
+    luai_writestringerror("%s", "lua_debug> ");
+    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
+        strcmp(buffer, "cont\n") == 0)
+      return 0;
+    if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
+        lua_pcall(L, 0, 0, 0))
+      luai_writestringerror("%s\n", lua_tostring(L, -1));
+    lua_settop(L, 0);  /* remove eventual returns */
+  }
+}
+
+
+static int db_traceback (lua_State *L) {
+  int arg;
+  lua_State *L1 = getthread(L, &arg);
+  const char *msg = lua_tostring(L, arg + 1);
+  if (msg == NULL && !lua_isnoneornil(L, arg + 1))  /* non-string 'msg'? */
+    lua_pushvalue(L, arg + 1);  /* return it untouched */
+  else {
+    int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
+    luaL_traceback(L, L1, msg, level);
+  }
+  return 1;
+}
+
+
+static const luaL_Reg dblib[] = {
+  {"debug", db_debug},
+  {"getuservalue", db_getuservalue},
+  {"gethook", db_gethook},
+  {"getinfo", db_getinfo},
+  {"getlocal", db_getlocal},
+  {"getregistry", db_getregistry},
+  {"getmetatable", db_getmetatable},
+  {"getupvalue", db_getupvalue},
+  {"upvaluejoin", db_upvaluejoin},
+  {"upvalueid", db_upvalueid},
+  {"setuservalue", db_setuservalue},
+  {"sethook", db_sethook},
+  {"setlocal", db_setlocal},
+  {"setmetatable", db_setmetatable},
+  {"setupvalue", db_setupvalue},
+  {"traceback", db_traceback},
+  {NULL, NULL}
+};
+
+
+LUAMOD_API int luaopen_debug (lua_State *L) {
+  luaL_newlib(L, dblib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,593 @@
+/*
+** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp $
+** Debug Interface
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+
+#define ldebug_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+
+#define noLuaClosure(f)		((f) == NULL || (f)->c.tt == LUA_TCCL)
+
+
+static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
+
+
+static int currentpc (CallInfo *ci) {
+  lua_assert(isLua(ci));
+  return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
+}
+
+
+static int currentline (CallInfo *ci) {
+  return getfuncline(ci_func(ci)->p, currentpc(ci));
+}
+
+
+/*
+** this function can be called asynchronous (e.g. during a signal)
+*/
+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
+  if (func == NULL || mask == 0) {  /* turn off hooks? */
+    mask = 0;
+    func = NULL;
+  }
+  if (isLua(L->ci))
+    L->oldpc = L->ci->u.l.savedpc;
+  L->hook = func;
+  L->basehookcount = count;
+  resethookcount(L);
+  L->hookmask = cast_byte(mask);
+  return 1;
+}
+
+
+LUA_API lua_Hook lua_gethook (lua_State *L) {
+  return L->hook;
+}
+
+
+LUA_API int lua_gethookmask (lua_State *L) {
+  return L->hookmask;
+}
+
+
+LUA_API int lua_gethookcount (lua_State *L) {
+  return L->basehookcount;
+}
+
+
+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
+  int status;
+  CallInfo *ci;
+  if (level < 0) return 0;  /* invalid (negative) level */
+  lua_lock(L);
+  for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
+    level--;
+  if (level == 0 && ci != &L->base_ci) {  /* level found? */
+    status = 1;
+    ar->i_ci = ci;
+  }
+  else status = 0;  /* no such level */
+  lua_unlock(L);
+  return status;
+}
+
+
+static const char *upvalname (Proto *p, int uv) {
+  TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
+  if (s == NULL) return "?";
+  else return getstr(s);
+}
+
+
+static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
+  int nparams = clLvalue(ci->func)->p->numparams;
+  if (n >= ci->u.l.base - ci->func - nparams)
+    return NULL;  /* no such vararg */
+  else {
+    *pos = ci->func + nparams + n;
+    return "(*vararg)";  /* generic name for any vararg */
+  }
+}
+
+
+static const char *findlocal (lua_State *L, CallInfo *ci, int n,
+                              StkId *pos) {
+  const char *name = NULL;
+  StkId base;
+  if (isLua(ci)) {
+    if (n < 0)  /* access to vararg values? */
+      return findvararg(ci, -n, pos);
+    else {
+      base = ci->u.l.base;
+      name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
+    }
+  }
+  else
+    base = ci->func + 1;
+  if (name == NULL) {  /* no 'standard' name? */
+    StkId limit = (ci == L->ci) ? L->top : ci->next->func;
+    if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
+      name = "(*temporary)";  /* generic name for any valid slot */
+    else
+      return NULL;  /* no name */
+  }
+  *pos = base + (n - 1);
+  return name;
+}
+
+
+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
+  const char *name;
+  lua_lock(L);
+  if (ar == NULL) {  /* information about non-active function? */
+    if (!isLfunction(L->top - 1))  /* not a Lua function? */
+      name = NULL;
+    else  /* consider live variables at function start (parameters) */
+      name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
+  }
+  else {  /* active function; get information through 'ar' */
+    StkId pos = 0;  /* to avoid warnings */
+    name = findlocal(L, ar->i_ci, n, &pos);
+    if (name) {
+      setobj2s(L, L->top, pos);
+      api_incr_top(L);
+    }
+  }
+  lua_unlock(L);
+  return name;
+}
+
+
+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
+  StkId pos = 0;  /* to avoid warnings */
+  const char *name = findlocal(L, ar->i_ci, n, &pos);
+  lua_lock(L);
+  if (name)
+    setobjs2s(L, pos, L->top - 1);
+  L->top--;  /* pop value */
+  lua_unlock(L);
+  return name;
+}
+
+
+static void funcinfo (lua_Debug *ar, Closure *cl) {
+  if (noLuaClosure(cl)) {
+    ar->source = "=[C]";
+    ar->linedefined = -1;
+    ar->lastlinedefined = -1;
+    ar->what = "C";
+  }
+  else {
+    Proto *p = cl->l.p;
+    ar->source = p->source ? getstr(p->source) : "=?";
+    ar->linedefined = p->linedefined;
+    ar->lastlinedefined = p->lastlinedefined;
+    ar->what = (ar->linedefined == 0) ? "main" : "Lua";
+  }
+  luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+}
+
+
+static void collectvalidlines (lua_State *L, Closure *f) {
+  if (noLuaClosure(f)) {
+    setnilvalue(L->top);
+    api_incr_top(L);
+  }
+  else {
+    int i;
+    TValue v;
+    int *lineinfo = f->l.p->lineinfo;
+    Table *t = luaH_new(L);  /* new table to store active lines */
+    sethvalue(L, L->top, t);  /* push it on stack */
+    api_incr_top(L);
+    setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
+    for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
+      luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
+  }
+}
+
+
+static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
+                       Closure *f, CallInfo *ci) {
+  int status = 1;
+  for (; *what; what++) {
+    switch (*what) {
+      case 'S': {
+        funcinfo(ar, f);
+        break;
+      }
+      case 'l': {
+        ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
+        break;
+      }
+      case 'u': {
+        ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
+        if (noLuaClosure(f)) {
+          ar->isvararg = 1;
+          ar->nparams = 0;
+        }
+        else {
+          ar->isvararg = f->l.p->is_vararg;
+          ar->nparams = f->l.p->numparams;
+        }
+        break;
+      }
+      case 't': {
+        ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
+        break;
+      }
+      case 'n': {
+        /* calling function is a known Lua function? */
+        if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
+          ar->namewhat = getfuncname(L, ci->previous, &ar->name);
+        else
+          ar->namewhat = NULL;
+        if (ar->namewhat == NULL) {
+          ar->namewhat = "";  /* not found */
+          ar->name = NULL;
+        }
+        break;
+      }
+      case 'L':
+      case 'f':  /* handled by lua_getinfo */
+        break;
+      default: status = 0;  /* invalid option */
+    }
+  }
+  return status;
+}
+
+
+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
+  int status;
+  Closure *cl;
+  CallInfo *ci;
+  StkId func;
+  lua_lock(L);
+  if (*what == '>') {
+    ci = NULL;
+    func = L->top - 1;
+    api_check(L, ttisfunction(func), "function expected");
+    what++;  /* skip the '>' */
+    L->top--;  /* pop function */
+  }
+  else {
+    ci = ar->i_ci;
+    func = ci->func;
+    lua_assert(ttisfunction(ci->func));
+  }
+  cl = ttisclosure(func) ? clvalue(func) : NULL;
+  status = auxgetinfo(L, what, ar, cl, ci);
+  if (strchr(what, 'f')) {
+    setobjs2s(L, L->top, func);
+    api_incr_top(L);
+  }
+  if (strchr(what, 'L'))
+    collectvalidlines(L, cl);
+  lua_unlock(L);
+  return status;
+}
+
+
+/*
+** {======================================================
+** Symbolic Execution
+** =======================================================
+*/
+
+static const char *getobjname (Proto *p, int lastpc, int reg,
+                               const char **name);
+
+
+/*
+** find a "name" for the RK value 'c'
+*/
+static void kname (Proto *p, int pc, int c, const char **name) {
+  if (ISK(c)) {  /* is 'c' a constant? */
+    TValue *kvalue = &p->k[INDEXK(c)];
+    if (ttisstring(kvalue)) {  /* literal constant? */
+      *name = svalue(kvalue);  /* it is its own name */
+      return;
+    }
+    /* else no reasonable name found */
+  }
+  else {  /* 'c' is a register */
+    const char *what = getobjname(p, pc, c, name); /* search for 'c' */
+    if (what && *what == 'c') {  /* found a constant name? */
+      return;  /* 'name' already filled */
+    }
+    /* else no reasonable name found */
+  }
+  *name = "?";  /* no reasonable name found */
+}
+
+
+static int filterpc (int pc, int jmptarget) {
+  if (pc < jmptarget)  /* is code conditional (inside a jump)? */
+    return -1;  /* cannot know who sets that register */
+  else return pc;  /* current position sets that register */
+}
+
+
+/*
+** try to find last instruction before 'lastpc' that modified register 'reg'
+*/
+static int findsetreg (Proto *p, int lastpc, int reg) {
+  int pc;
+  int setreg = -1;  /* keep last instruction that changed 'reg' */
+  int jmptarget = 0;  /* any code before this address is conditional */
+  for (pc = 0; pc < lastpc; pc++) {
+    Instruction i = p->code[pc];
+    OpCode op = GET_OPCODE(i);
+    int a = GETARG_A(i);
+    switch (op) {
+      case OP_LOADNIL: {
+        int b = GETARG_B(i);
+        if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
+          setreg = filterpc(pc, jmptarget);
+        break;
+      }
+      case OP_TFORCALL: {
+        if (reg >= a + 2)  /* affect all regs above its base */
+          setreg = filterpc(pc, jmptarget);
+        break;
+      }
+      case OP_CALL:
+      case OP_TAILCALL: {
+        if (reg >= a)  /* affect all registers above base */
+          setreg = filterpc(pc, jmptarget);
+        break;
+      }
+      case OP_JMP: {
+        int b = GETARG_sBx(i);
+        int dest = pc + 1 + b;
+        /* jump is forward and do not skip `lastpc'? */
+        if (pc < dest && dest <= lastpc) {
+          if (dest > jmptarget)
+            jmptarget = dest;  /* update 'jmptarget' */
+        }
+        break;
+      }
+      case OP_TEST: {
+        if (reg == a)  /* jumped code can change 'a' */
+          setreg = filterpc(pc, jmptarget);
+        break;
+      }
+      default:
+        if (testAMode(op) && reg == a)  /* any instruction that set A */
+          setreg = filterpc(pc, jmptarget);
+        break;
+    }
+  }
+  return setreg;
+}
+
+
+static const char *getobjname (Proto *p, int lastpc, int reg,
+                               const char **name) {
+  int pc;
+  *name = luaF_getlocalname(p, reg + 1, lastpc);
+  if (*name)  /* is a local? */
+    return "local";
+  /* else try symbolic execution */
+  pc = findsetreg(p, lastpc, reg);
+  if (pc != -1) {  /* could find instruction? */
+    Instruction i = p->code[pc];
+    OpCode op = GET_OPCODE(i);
+    switch (op) {
+      case OP_MOVE: {
+        int b = GETARG_B(i);  /* move from 'b' to 'a' */
+        if (b < GETARG_A(i))
+          return getobjname(p, pc, b, name);  /* get name for 'b' */
+        break;
+      }
+      case OP_GETTABUP:
+      case OP_GETTABLE: {
+        int k = GETARG_C(i);  /* key index */
+        int t = GETARG_B(i);  /* table index */
+        const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
+                         ? luaF_getlocalname(p, t + 1, pc)
+                         : upvalname(p, t);
+        kname(p, pc, k, name);
+        return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
+      }
+      case OP_GETUPVAL: {
+        *name = upvalname(p, GETARG_B(i));
+        return "upvalue";
+      }
+      case OP_LOADK:
+      case OP_LOADKX: {
+        int b = (op == OP_LOADK) ? GETARG_Bx(i)
+                                 : GETARG_Ax(p->code[pc + 1]);
+        if (ttisstring(&p->k[b])) {
+          *name = svalue(&p->k[b]);
+          return "constant";
+        }
+        break;
+      }
+      case OP_SELF: {
+        int k = GETARG_C(i);  /* key index */
+        kname(p, pc, k, name);
+        return "method";
+      }
+      default: break;  /* go through to return NULL */
+    }
+  }
+  return NULL;  /* could not find reasonable name */
+}
+
+
+static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
+  TMS tm;
+  Proto *p = ci_func(ci)->p;  /* calling function */
+  int pc = currentpc(ci);  /* calling instruction index */
+  Instruction i = p->code[pc];  /* calling instruction */
+  switch (GET_OPCODE(i)) {
+    case OP_CALL:
+    case OP_TAILCALL:  /* get function name */
+      return getobjname(p, pc, GETARG_A(i), name);
+    case OP_TFORCALL: {  /* for iterator */
+      *name = "for iterator";
+       return "for iterator";
+    }
+    /* all other instructions can call only through metamethods */
+    case OP_SELF:
+    case OP_GETTABUP:
+    case OP_GETTABLE: tm = TM_INDEX; break;
+    case OP_SETTABUP:
+    case OP_SETTABLE: tm = TM_NEWINDEX; break;
+    case OP_EQ: tm = TM_EQ; break;
+    case OP_ADD: tm = TM_ADD; break;
+    case OP_SUB: tm = TM_SUB; break;
+    case OP_MUL: tm = TM_MUL; break;
+    case OP_DIV: tm = TM_DIV; break;
+    case OP_MOD: tm = TM_MOD; break;
+    case OP_POW: tm = TM_POW; break;
+    case OP_UNM: tm = TM_UNM; break;
+    case OP_LEN: tm = TM_LEN; break;
+    case OP_LT: tm = TM_LT; break;
+    case OP_LE: tm = TM_LE; break;
+    case OP_CONCAT: tm = TM_CONCAT; break;
+    default:
+      return NULL;  /* else no useful name can be found */
+  }
+  *name = getstr(G(L)->tmname[tm]);
+  return "metamethod";
+}
+
+/* }====================================================== */
+
+
+
+/*
+** only ANSI way to check whether a pointer points to an array
+** (used only for error messages, so efficiency is not a big concern)
+*/
+static int isinstack (CallInfo *ci, const TValue *o) {
+  StkId p;
+  for (p = ci->u.l.base; p < ci->top; p++)
+    if (o == p) return 1;
+  return 0;
+}
+
+
+static const char *getupvalname (CallInfo *ci, const TValue *o,
+                                 const char **name) {
+  LClosure *c = ci_func(ci);
+  int i;
+  for (i = 0; i < c->nupvalues; i++) {
+    if (c->upvals[i]->v == o) {
+      *name = upvalname(c->p, i);
+      return "upvalue";
+    }
+  }
+  return NULL;
+}
+
+
+l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+  CallInfo *ci = L->ci;
+  const char *name = NULL;
+  const char *t = objtypename(o);
+  const char *kind = NULL;
+  if (isLua(ci)) {
+    kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
+    if (!kind && isinstack(ci, o))  /* no? try a register */
+      kind = getobjname(ci_func(ci)->p, currentpc(ci),
+                        cast_int(o - ci->u.l.base), &name);
+  }
+  if (kind)
+    luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
+                op, kind, name, t);
+  else
+    luaG_runerror(L, "attempt to %s a %s value", op, t);
+}
+
+
+l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+  if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
+  lua_assert(!ttisstring(p1) && !ttisnumber(p1));
+  luaG_typeerror(L, p1, "concatenate");
+}
+
+
+l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
+  TValue temp;
+  if (luaV_tonumber(p1, &temp) == NULL)
+    p2 = p1;  /* first operand is wrong */
+  luaG_typeerror(L, p2, "perform arithmetic on");
+}
+
+
+l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+  const char *t1 = objtypename(p1);
+  const char *t2 = objtypename(p2);
+  if (t1 == t2)
+    luaG_runerror(L, "attempt to compare two %s values", t1);
+  else
+    luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
+}
+
+
+static void addinfo (lua_State *L, const char *msg) {
+  CallInfo *ci = L->ci;
+  if (isLua(ci)) {  /* is Lua code? */
+    char buff[LUA_IDSIZE];  /* add file:line information */
+    int line = currentline(ci);
+    TString *src = ci_func(ci)->p->source;
+    if (src)
+      luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
+    else {  /* no source available; use "?" instead */
+      buff[0] = '?'; buff[1] = '\0';
+    }
+    luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+  }
+}
+
+
+l_noret luaG_errormsg (lua_State *L) {
+  if (L->errfunc != 0) {  /* is there an error handling function? */
+    StkId errfunc = restorestack(L, L->errfunc);
+    if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
+    setobjs2s(L, L->top, L->top - 1);  /* move argument */
+    setobjs2s(L, L->top - 1, errfunc);  /* push function */
+    L->top++;
+    luaD_call(L, L->top - 2, 1, 0);  /* call it */
+  }
+  luaD_throw(L, LUA_ERRRUN);
+}
+
+
+l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
+  va_list argp;
+  va_start(argp, fmt);
+  addinfo(L, luaO_pushvfstring(L, fmt, argp));
+  va_end(argp);
+  luaG_errormsg(L);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldebug.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,34 @@
+/*
+** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions from Debug Interface module
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldebug_h
+#define ldebug_h
+
+
+#include "lstate.h"
+
+
+#define pcRel(pc, p)	(cast(int, (pc) - (p)->code) - 1)
+
+#define getfuncline(f,pc)	(((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
+
+#define resethookcount(L)	(L->hookcount = L->basehookcount)
+
+/* Active Lua function (given call info) */
+#define ci_func(ci)		(clLvalue((ci)->func))
+
+
+LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
+                                                const char *opname);
+LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
+                                                 const TValue *p2);
+LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
+                                                 const TValue *p2);
+LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,681 @@
+/*
+** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldo_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+#include "lzio.h"
+
+
+
+
+/*
+** {======================================================
+** Error-recovery functions
+** =======================================================
+*/
+
+/*
+** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
+** default, Lua handles errors with exceptions when compiling as
+** C++ code, with _longjmp/_setjmp when asked to use them, and with
+** longjmp/setjmp otherwise.
+*/
+#if !defined(LUAI_THROW)
+
+#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
+/* C++ exceptions */
+#define LUAI_THROW(L,c)		throw(c)
+#define LUAI_TRY(L,c,a) \
+	try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
+#define luai_jmpbuf		int  /* dummy variable */
+
+#elif defined(LUA_USE_ULONGJMP)
+/* in Unix, try _longjmp/_setjmp (more efficient) */
+#define LUAI_THROW(L,c)		_longjmp((c)->b, 1)
+#define LUAI_TRY(L,c,a)		if (_setjmp((c)->b) == 0) { a }
+#define luai_jmpbuf		jmp_buf
+
+#else
+/* default handling with long jumps */
+#define LUAI_THROW(L,c)		longjmp((c)->b, 1)
+#define LUAI_TRY(L,c,a)		if (setjmp((c)->b) == 0) { a }
+#define luai_jmpbuf		jmp_buf
+
+#endif
+
+#endif
+
+
+
+/* chain list of long jump buffers */
+struct lua_longjmp {
+  struct lua_longjmp *previous;
+  luai_jmpbuf b;
+  volatile int status;  /* error code */
+};
+
+
+static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
+  switch (errcode) {
+    case LUA_ERRMEM: {  /* memory error? */
+      setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
+      break;
+    }
+    case LUA_ERRERR: {
+      setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
+      break;
+    }
+    default: {
+      setobjs2s(L, oldtop, L->top - 1);  /* error message on current top */
+      break;
+    }
+  }
+  L->top = oldtop + 1;
+}
+
+
+l_noret luaD_throw (lua_State *L, int errcode) {
+  if (L->errorJmp) {  /* thread has an error handler? */
+    L->errorJmp->status = errcode;  /* set status */
+    LUAI_THROW(L, L->errorJmp);  /* jump to it */
+  }
+  else {  /* thread has no error handler */
+    L->status = cast_byte(errcode);  /* mark it as dead */
+    if (G(L)->mainthread->errorJmp) {  /* main thread has a handler? */
+      setobjs2s(L, G(L)->mainthread->top++, L->top - 1);  /* copy error obj. */
+      luaD_throw(G(L)->mainthread, errcode);  /* re-throw in main thread */
+    }
+    else {  /* no handler at all; abort */
+      if (G(L)->panic) {  /* panic function? */
+        lua_unlock(L);
+        G(L)->panic(L);  /* call it (last chance to jump out) */
+      }
+      abort();
+    }
+  }
+}
+
+
+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
+  unsigned short oldnCcalls = L->nCcalls;
+  struct lua_longjmp lj;
+  lj.status = LUA_OK;
+  lj.previous = L->errorJmp;  /* chain new error handler */
+  L->errorJmp = &lj;
+  LUAI_TRY(L, &lj,
+    (*f)(L, ud);
+  );
+  L->errorJmp = lj.previous;  /* restore old error handler */
+  L->nCcalls = oldnCcalls;
+  return lj.status;
+}
+
+/* }====================================================== */
+
+
+static void correctstack (lua_State *L, TValue *oldstack) {
+  CallInfo *ci;
+  GCObject *up;
+  L->top = (L->top - oldstack) + L->stack;
+  for (up = L->openupval; up != NULL; up = up->gch.next)
+    gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+  for (ci = L->ci; ci != NULL; ci = ci->previous) {
+    ci->top = (ci->top - oldstack) + L->stack;
+    ci->func = (ci->func - oldstack) + L->stack;
+    if (isLua(ci))
+      ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
+  }
+}
+
+
+/* some space for error handling */
+#define ERRORSTACKSIZE	(LUAI_MAXSTACK + 200)
+
+
+void luaD_reallocstack (lua_State *L, int newsize) {
+  TValue *oldstack = L->stack;
+  int lim = L->stacksize;
+  lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
+  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
+  luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
+  for (; lim < newsize; lim++)
+    setnilvalue(L->stack + lim); /* erase new segment */
+  L->stacksize = newsize;
+  L->stack_last = L->stack + newsize - EXTRA_STACK;
+  correctstack(L, oldstack);
+}
+
+
+void luaD_growstack (lua_State *L, int n) {
+  int size = L->stacksize;
+  if (size > LUAI_MAXSTACK)  /* error after extra size? */
+    luaD_throw(L, LUA_ERRERR);
+  else {
+    int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
+    int newsize = 2 * size;
+    if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
+    if (newsize < needed) newsize = needed;
+    if (newsize > LUAI_MAXSTACK) {  /* stack overflow? */
+      luaD_reallocstack(L, ERRORSTACKSIZE);
+      luaG_runerror(L, "stack overflow");
+    }
+    else
+      luaD_reallocstack(L, newsize);
+  }
+}
+
+
+static int stackinuse (lua_State *L) {
+  CallInfo *ci;
+  StkId lim = L->top;
+  for (ci = L->ci; ci != NULL; ci = ci->previous) {
+    lua_assert(ci->top <= L->stack_last);
+    if (lim < ci->top) lim = ci->top;
+  }
+  return cast_int(lim - L->stack) + 1;  /* part of stack in use */
+}
+
+
+void luaD_shrinkstack (lua_State *L) {
+  int inuse = stackinuse(L);
+  int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
+  if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
+  if (inuse > LUAI_MAXSTACK ||  /* handling stack overflow? */
+      goodsize >= L->stacksize)  /* would grow instead of shrink? */
+    condmovestack(L);  /* don't change stack (change only for debugging) */
+  else
+    luaD_reallocstack(L, goodsize);  /* shrink it */
+}
+
+
+void luaD_hook (lua_State *L, int event, int line) {
+  lua_Hook hook = L->hook;
+  if (hook && L->allowhook) {
+    CallInfo *ci = L->ci;
+    ptrdiff_t top = savestack(L, L->top);
+    ptrdiff_t ci_top = savestack(L, ci->top);
+    lua_Debug ar;
+    ar.event = event;
+    ar.currentline = line;
+    ar.i_ci = ci;
+    luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
+    ci->top = L->top + LUA_MINSTACK;
+    lua_assert(ci->top <= L->stack_last);
+    L->allowhook = 0;  /* cannot call hooks inside a hook */
+    ci->callstatus |= CIST_HOOKED;
+    lua_unlock(L);
+    (*hook)(L, &ar);
+    lua_lock(L);
+    lua_assert(!L->allowhook);
+    L->allowhook = 1;
+    ci->top = restorestack(L, ci_top);
+    L->top = restorestack(L, top);
+    ci->callstatus &= ~CIST_HOOKED;
+  }
+}
+
+
+static void callhook (lua_State *L, CallInfo *ci) {
+  int hook = LUA_HOOKCALL;
+  ci->u.l.savedpc++;  /* hooks assume 'pc' is already incremented */
+  if (isLua(ci->previous) &&
+      GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
+    ci->callstatus |= CIST_TAIL;
+    hook = LUA_HOOKTAILCALL;
+  }
+  luaD_hook(L, hook, -1);
+  ci->u.l.savedpc--;  /* correct 'pc' */
+}
+
+
+static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
+  int i;
+  int nfixargs = p->numparams;
+  StkId base, fixed;
+  lua_assert(actual >= nfixargs);
+  /* move fixed parameters to final position */
+  luaD_checkstack(L, p->maxstacksize);  /* check again for new 'base' */
+  fixed = L->top - actual;  /* first fixed argument */
+  base = L->top;  /* final position of first argument */
+  for (i=0; i<nfixargs; i++) {
+    setobjs2s(L, L->top++, fixed + i);
+    setnilvalue(fixed + i);
+  }
+  return base;
+}
+
+
+static StkId tryfuncTM (lua_State *L, StkId func) {
+  const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
+  StkId p;
+  ptrdiff_t funcr = savestack(L, func);
+  if (!ttisfunction(tm))
+    luaG_typeerror(L, func, "call");
+  /* Open a hole inside the stack at `func' */
+  for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
+  incr_top(L);
+  func = restorestack(L, funcr);  /* previous call may change stack */
+  setobj2s(L, func, tm);  /* tag method is the new function to be called */
+  return func;
+}
+
+
+
+#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
+
+
+/*
+** returns true if function has been executed (C function)
+*/
+int luaD_precall (lua_State *L, StkId func, int nresults) {
+  lua_CFunction f;
+  CallInfo *ci;
+  int n;  /* number of arguments (Lua) or returns (C) */
+  ptrdiff_t funcr = savestack(L, func);
+  switch (ttype(func)) {
+    case LUA_TLCF:  /* light C function */
+      f = fvalue(func);
+      goto Cfunc;
+    case LUA_TCCL: {  /* C closure */
+      f = clCvalue(func)->f;
+     Cfunc:
+      luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = restorestack(L, funcr);
+      ci->top = L->top + LUA_MINSTACK;
+      lua_assert(ci->top <= L->stack_last);
+      ci->callstatus = 0;
+      luaC_checkGC(L);  /* stack grow uses memory */
+      if (L->hookmask & LUA_MASKCALL)
+        luaD_hook(L, LUA_HOOKCALL, -1);
+      lua_unlock(L);
+      n = (*f)(L);  /* do the actual call */
+      lua_lock(L);
+      api_checknelems(L, n);
+      luaD_poscall(L, L->top - n);
+      return 1;
+    }
+    case LUA_TLCL: {  /* Lua function: prepare its call */
+      StkId base;
+      Proto *p = clLvalue(func)->p;
+      n = cast_int(L->top - func) - 1;  /* number of real arguments */
+      luaD_checkstack(L, p->maxstacksize);
+      for (; n < p->numparams; n++)
+        setnilvalue(L->top++);  /* complete missing arguments */
+      if (!p->is_vararg) {
+        func = restorestack(L, funcr);
+        base = func + 1;
+      }
+      else {
+        base = adjust_varargs(L, p, n);
+        func = restorestack(L, funcr);  /* previous call can change stack */
+      }
+      ci = next_ci(L);  /* now 'enter' new function */
+      ci->nresults = nresults;
+      ci->func = func;
+      ci->u.l.base = base;
+      ci->top = base + p->maxstacksize;
+      lua_assert(ci->top <= L->stack_last);
+      ci->u.l.savedpc = p->code;  /* starting point */
+      ci->callstatus = CIST_LUA;
+      L->top = ci->top;
+      luaC_checkGC(L);  /* stack grow uses memory */
+      if (L->hookmask & LUA_MASKCALL)
+        callhook(L, ci);
+      return 0;
+    }
+    default: {  /* not a function */
+      func = tryfuncTM(L, func);  /* retry with 'function' tag method */
+      return luaD_precall(L, func, nresults);  /* now it must be a function */
+    }
+  }
+}
+
+
+int luaD_poscall (lua_State *L, StkId firstResult) {
+  StkId res;
+  int wanted, i;
+  CallInfo *ci = L->ci;
+  if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
+    if (L->hookmask & LUA_MASKRET) {
+      ptrdiff_t fr = savestack(L, firstResult);  /* hook may change stack */
+      luaD_hook(L, LUA_HOOKRET, -1);
+      firstResult = restorestack(L, fr);
+    }
+    L->oldpc = ci->previous->u.l.savedpc;  /* 'oldpc' for caller function */
+  }
+  res = ci->func;  /* res == final position of 1st result */
+  wanted = ci->nresults;
+  L->ci = ci = ci->previous;  /* back to caller */
+  /* move results to correct place */
+  for (i = wanted; i != 0 && firstResult < L->top; i--)
+    setobjs2s(L, res++, firstResult++);
+  while (i-- > 0)
+    setnilvalue(res++);
+  L->top = res;
+  return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
+}
+
+
+/*
+** Call a function (C or Lua). The function to be called is at *func.
+** The arguments are on the stack, right after the function.
+** When returns, all the results are on the stack, starting at the original
+** function position.
+*/
+void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
+  if (++L->nCcalls >= LUAI_MAXCCALLS) {
+    if (L->nCcalls == LUAI_MAXCCALLS)
+      luaG_runerror(L, "C stack overflow");
+    else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
+      luaD_throw(L, LUA_ERRERR);  /* error while handing stack error */
+  }
+  if (!allowyield) L->nny++;
+  if (!luaD_precall(L, func, nResults))  /* is a Lua function? */
+    luaV_execute(L);  /* call it */
+  if (!allowyield) L->nny--;
+  L->nCcalls--;
+}
+
+
+static void finishCcall (lua_State *L) {
+  CallInfo *ci = L->ci;
+  int n;
+  lua_assert(ci->u.c.k != NULL);  /* must have a continuation */
+  lua_assert(L->nny == 0);
+  if (ci->callstatus & CIST_YPCALL) {  /* was inside a pcall? */
+    ci->callstatus &= ~CIST_YPCALL;  /* finish 'lua_pcall' */
+    L->errfunc = ci->u.c.old_errfunc;
+  }
+  /* finish 'lua_callk'/'lua_pcall' */
+  adjustresults(L, ci->nresults);
+  /* call continuation function */
+  if (!(ci->callstatus & CIST_STAT))  /* no call status? */
+    ci->u.c.status = LUA_YIELD;  /* 'default' status */
+  lua_assert(ci->u.c.status != LUA_OK);
+  ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
+  lua_unlock(L);
+  n = (*ci->u.c.k)(L);
+  lua_lock(L);
+  api_checknelems(L, n);
+  /* finish 'luaD_precall' */
+  luaD_poscall(L, L->top - n);
+}
+
+
+static void unroll (lua_State *L, void *ud) {
+  UNUSED(ud);
+  for (;;) {
+    if (L->ci == &L->base_ci)  /* stack is empty? */
+      return;  /* coroutine finished normally */
+    if (!isLua(L->ci))  /* C function? */
+      finishCcall(L);
+    else {  /* Lua function */
+      luaV_finishOp(L);  /* finish interrupted instruction */
+      luaV_execute(L);  /* execute down to higher C 'boundary' */
+    }
+  }
+}
+
+
+/*
+** check whether thread has a suspended protected call
+*/
+static CallInfo *findpcall (lua_State *L) {
+  CallInfo *ci;
+  for (ci = L->ci; ci != NULL; ci = ci->previous) {  /* search for a pcall */
+    if (ci->callstatus & CIST_YPCALL)
+      return ci;
+  }
+  return NULL;  /* no pending pcall */
+}
+
+
+static int recover (lua_State *L, int status) {
+  StkId oldtop;
+  CallInfo *ci = findpcall(L);
+  if (ci == NULL) return 0;  /* no recovery point */
+  /* "finish" luaD_pcall */
+  oldtop = restorestack(L, ci->extra);
+  luaF_close(L, oldtop);
+  seterrorobj(L, status, oldtop);
+  L->ci = ci;
+  L->allowhook = ci->u.c.old_allowhook;
+  L->nny = 0;  /* should be zero to be yieldable */
+  luaD_shrinkstack(L);
+  L->errfunc = ci->u.c.old_errfunc;
+  ci->callstatus |= CIST_STAT;  /* call has error status */
+  ci->u.c.status = status;  /* (here it is) */
+  return 1;  /* continue running the coroutine */
+}
+
+
+/*
+** signal an error in the call to 'resume', not in the execution of the
+** coroutine itself. (Such errors should not be handled by any coroutine
+** error handler and should not kill the coroutine.)
+*/
+static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
+  L->top = firstArg;  /* remove args from the stack */
+  setsvalue2s(L, L->top, luaS_new(L, msg));  /* push error message */
+  api_incr_top(L);
+  luaD_throw(L, -1);  /* jump back to 'lua_resume' */
+}
+
+
+/*
+** do the work for 'lua_resume' in protected mode
+*/
+static void resume (lua_State *L, void *ud) {
+  int nCcalls = L->nCcalls;
+  StkId firstArg = cast(StkId, ud);
+  CallInfo *ci = L->ci;
+  if (nCcalls >= LUAI_MAXCCALLS)
+    resume_error(L, "C stack overflow", firstArg);
+  if (L->status == LUA_OK) {  /* may be starting a coroutine */
+    if (ci != &L->base_ci)  /* not in base level? */
+      resume_error(L, "cannot resume non-suspended coroutine", firstArg);
+    /* coroutine is in base level; start running it */
+    if (!luaD_precall(L, firstArg - 1, LUA_MULTRET))  /* Lua function? */
+      luaV_execute(L);  /* call it */
+  }
+  else if (L->status != LUA_YIELD)
+    resume_error(L, "cannot resume dead coroutine", firstArg);
+  else {  /* resuming from previous yield */
+    L->status = LUA_OK;
+    ci->func = restorestack(L, ci->extra);
+    if (isLua(ci))  /* yielded inside a hook? */
+      luaV_execute(L);  /* just continue running Lua code */
+    else {  /* 'common' yield */
+      if (ci->u.c.k != NULL) {  /* does it have a continuation? */
+        int n;
+        ci->u.c.status = LUA_YIELD;  /* 'default' status */
+        ci->callstatus |= CIST_YIELDED;
+        lua_unlock(L);
+        n = (*ci->u.c.k)(L);  /* call continuation */
+        lua_lock(L);
+        api_checknelems(L, n);
+        firstArg = L->top - n;  /* yield results come from continuation */
+      }
+      luaD_poscall(L, firstArg);  /* finish 'luaD_precall' */
+    }
+    unroll(L, NULL);
+  }
+  lua_assert(nCcalls == L->nCcalls);
+}
+
+
+LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
+  int status;
+  int oldnny = L->nny;  /* save 'nny' */
+  lua_lock(L);
+  luai_userstateresume(L, nargs);
+  L->nCcalls = (from) ? from->nCcalls + 1 : 1;
+  L->nny = 0;  /* allow yields */
+  api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
+  status = luaD_rawrunprotected(L, resume, L->top - nargs);
+  if (status == -1)  /* error calling 'lua_resume'? */
+    status = LUA_ERRRUN;
+  else {  /* yield or regular error */
+    while (status != LUA_OK && status != LUA_YIELD) {  /* error? */
+      if (recover(L, status))  /* recover point? */
+        status = luaD_rawrunprotected(L, unroll, NULL);  /* run continuation */
+      else {  /* unrecoverable error */
+        L->status = cast_byte(status);  /* mark thread as `dead' */
+        seterrorobj(L, status, L->top);
+        L->ci->top = L->top;
+        break;
+      }
+    }
+    lua_assert(status == L->status);
+  }
+  L->nny = oldnny;  /* restore 'nny' */
+  L->nCcalls--;
+  lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
+  lua_unlock(L);
+  return status;
+}
+
+
+LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
+  CallInfo *ci = L->ci;
+  luai_userstateyield(L, nresults);
+  lua_lock(L);
+  api_checknelems(L, nresults);
+  if (L->nny > 0) {
+    if (L != G(L)->mainthread)
+      luaG_runerror(L, "attempt to yield across a C-call boundary");
+    else
+      luaG_runerror(L, "attempt to yield from outside a coroutine");
+  }
+  L->status = LUA_YIELD;
+  ci->extra = savestack(L, ci->func);  /* save current 'func' */
+  if (isLua(ci)) {  /* inside a hook? */
+    api_check(L, k == NULL, "hooks cannot continue after yielding");
+  }
+  else {
+    if ((ci->u.c.k = k) != NULL)  /* is there a continuation? */
+      ci->u.c.ctx = ctx;  /* save context */
+    ci->func = L->top - nresults - 1;  /* protect stack below results */
+    luaD_throw(L, LUA_YIELD);
+  }
+  lua_assert(ci->callstatus & CIST_HOOKED);  /* must be inside a hook */
+  lua_unlock(L);
+  return 0;  /* return to 'luaD_hook' */
+}
+
+
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+                ptrdiff_t old_top, ptrdiff_t ef) {
+  int status;
+  CallInfo *old_ci = L->ci;
+  lu_byte old_allowhooks = L->allowhook;
+  unsigned short old_nny = L->nny;
+  ptrdiff_t old_errfunc = L->errfunc;
+  L->errfunc = ef;
+  status = luaD_rawrunprotected(L, func, u);
+  if (status != LUA_OK) {  /* an error occurred? */
+    StkId oldtop = restorestack(L, old_top);
+    luaF_close(L, oldtop);  /* close possible pending closures */
+    seterrorobj(L, status, oldtop);
+    L->ci = old_ci;
+    L->allowhook = old_allowhooks;
+    L->nny = old_nny;
+    luaD_shrinkstack(L);
+  }
+  L->errfunc = old_errfunc;
+  return status;
+}
+
+
+
+/*
+** Execute a protected parser.
+*/
+struct SParser {  /* data to `f_parser' */
+  ZIO *z;
+  Mbuffer buff;  /* dynamic structure used by the scanner */
+  Dyndata dyd;  /* dynamic structures used by the parser */
+  const char *mode;
+  const char *name;
+};
+
+
+static void checkmode (lua_State *L, const char *mode, const char *x) {
+  if (mode && strchr(mode, x[0]) == NULL) {
+    luaO_pushfstring(L,
+       "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
+    luaD_throw(L, LUA_ERRSYNTAX);
+  }
+}
+
+
+static void f_parser (lua_State *L, void *ud) {
+  int i;
+  Closure *cl;
+  struct SParser *p = cast(struct SParser *, ud);
+  int c = zgetc(p->z);  /* read first character */
+  if (c == LUA_SIGNATURE[0]) {
+    checkmode(L, p->mode, "binary");
+    cl = luaU_undump(L, p->z, &p->buff, p->name);
+  }
+  else {
+    checkmode(L, p->mode, "text");
+    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+  }
+  lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
+  for (i = 0; i < cl->l.nupvalues; i++) {  /* initialize upvalues */
+    UpVal *up = luaF_newupval(L);
+    cl->l.upvals[i] = up;
+    luaC_objbarrier(L, cl, up);
+  }
+}
+
+
+int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+                                        const char *mode) {
+  struct SParser p;
+  int status;
+  L->nny++;  /* cannot yield during parsing */
+  p.z = z; p.name = name; p.mode = mode;
+  p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
+  p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
+  p.dyd.label.arr = NULL; p.dyd.label.size = 0;
+  luaZ_initbuffer(L, &p.buff);
+  status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
+  luaZ_freebuffer(L, &p.buff);
+  luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
+  luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
+  luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
+  L->nny--;
+  return status;
+}
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldo.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/*
+** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldo_h
+#define ldo_h
+
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lzio.h"
+
+
+#define luaD_checkstack(L,n)	if (L->stack_last - L->top <= (n)) \
+				    luaD_growstack(L, n); else condmovestack(L);
+
+
+#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
+
+#define savestack(L,p)		((char *)(p) - (char *)L->stack)
+#define restorestack(L,n)	((TValue *)((char *)L->stack + (n)))
+
+
+/* type of protected functions, to be ran by `runprotected' */
+typedef void (*Pfunc) (lua_State *L, void *ud);
+
+LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
+                                                  const char *mode);
+LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
+LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
+LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
+                                        int allowyield);
+LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
+                                        ptrdiff_t oldtop, ptrdiff_t ef);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
+LUAI_FUNC void luaD_growstack (lua_State *L, int n);
+LUAI_FUNC void luaD_shrinkstack (lua_State *L);
+
+LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
+LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ldump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ldump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ldump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,173 @@
+/*
+** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $
+** save precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#include <stddef.h>
+
+#define ldump_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lundump.h"
+
+typedef struct {
+ lua_State* L;
+ lua_Writer writer;
+ void* data;
+ int strip;
+ int status;
+} DumpState;
+
+#define DumpMem(b,n,size,D)	DumpBlock(b,(n)*(size),D)
+#define DumpVar(x,D)		DumpMem(&x,1,sizeof(x),D)
+
+static void DumpBlock(const void* b, size_t size, DumpState* D)
+{
+ if (D->status==0)
+ {
+  lua_unlock(D->L);
+  D->status=(*D->writer)(D->L,b,size,D->data);
+  lua_lock(D->L);
+ }
+}
+
+static void DumpChar(int y, DumpState* D)
+{
+ char x=(char)y;
+ DumpVar(x,D);
+}
+
+static void DumpInt(int x, DumpState* D)
+{
+ DumpVar(x,D);
+}
+
+static void DumpNumber(lua_Number x, DumpState* D)
+{
+ DumpVar(x,D);
+}
+
+static void DumpVector(const void* b, int n, size_t size, DumpState* D)
+{
+ DumpInt(n,D);
+ DumpMem(b,n,size,D);
+}
+
+static void DumpString(const TString* s, DumpState* D)
+{
+ if (s==NULL)
+ {
+  size_t size=0;
+  DumpVar(size,D);
+ }
+ else
+ {
+  size_t size=s->tsv.len+1;		/* include trailing '\0' */
+  DumpVar(size,D);
+  DumpBlock(getstr(s),size*sizeof(char),D);
+ }
+}
+
+#define DumpCode(f,D)	 DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
+
+static void DumpFunction(const Proto* f, DumpState* D);
+
+static void DumpConstants(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizek;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+  const TValue* o=&f->k[i];
+  DumpChar(ttypenv(o),D);
+  switch (ttypenv(o))
+  {
+   case LUA_TNIL:
+	break;
+   case LUA_TBOOLEAN:
+	DumpChar(bvalue(o),D);
+	break;
+   case LUA_TNUMBER:
+	DumpNumber(nvalue(o),D);
+	break;
+   case LUA_TSTRING:
+	DumpString(rawtsvalue(o),D);
+	break;
+    default: lua_assert(0);
+  }
+ }
+ n=f->sizep;
+ DumpInt(n,D);
+ for (i=0; i<n; i++) DumpFunction(f->p[i],D);
+}
+
+static void DumpUpvalues(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizeupvalues;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+  DumpChar(f->upvalues[i].instack,D);
+  DumpChar(f->upvalues[i].idx,D);
+ }
+}
+
+static void DumpDebug(const Proto* f, DumpState* D)
+{
+ int i,n;
+ DumpString((D->strip) ? NULL : f->source,D);
+ n= (D->strip) ? 0 : f->sizelineinfo;
+ DumpVector(f->lineinfo,n,sizeof(int),D);
+ n= (D->strip) ? 0 : f->sizelocvars;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+  DumpString(f->locvars[i].varname,D);
+  DumpInt(f->locvars[i].startpc,D);
+  DumpInt(f->locvars[i].endpc,D);
+ }
+ n= (D->strip) ? 0 : f->sizeupvalues;
+ DumpInt(n,D);
+ for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
+}
+
+static void DumpFunction(const Proto* f, DumpState* D)
+{
+ DumpInt(f->linedefined,D);
+ DumpInt(f->lastlinedefined,D);
+ DumpChar(f->numparams,D);
+ DumpChar(f->is_vararg,D);
+ DumpChar(f->maxstacksize,D);
+ DumpCode(f,D);
+ DumpConstants(f,D);
+ DumpUpvalues(f,D);
+ DumpDebug(f,D);
+}
+
+static void DumpHeader(DumpState* D)
+{
+ lu_byte h[LUAC_HEADERSIZE];
+ luaU_header(h);
+ DumpBlock(h,LUAC_HEADERSIZE,D);
+}
+
+/*
+** dump Lua function as precompiled chunk
+*/
+int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
+{
+ DumpState D;
+ D.L=L;
+ D.writer=w;
+ D.data=data;
+ D.strip=strip;
+ D.status=0;
+ DumpHeader(&D);
+ DumpFunction(f,&D);
+ return D.status;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lfs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lfs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lfs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,296 @@
+/*
+** Code implementing read only functionality copied from
+** src/lfs.c at commit 2fd989cd6c777583be1c93616018c55b2cbb1bcf:
+**
+** LuaFileSystem 1.6.2
+** Copyright 2003-2014 Kepler Project
+** http://www.keplerproject.org/luafilesystem
+**
+** File system manipulation library.
+** This library offers these functions:
+** lfs.attributes (filepath [, attributename])
+** lfs.chdir (path)
+** lfs.currentdir ()
+** lfs.dir (path)
+**
+** $Id: lfs.c,v 1.61 2009/07/04 02:10:16 mascarenhas Exp $
+*/
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+
+#define chdir_error	strerror(errno)
+
+/* Size of path buffer string, stolen from pwd.c */
+#ifndef PATH_MAX
+#  ifdef NAME_MAX
+#    define PATH_MAX   NAME_MAX
+#  elif FILENAME_MAX
+#    define PATH_MAX   FILENAME_MAX
+#  else
+#    define PATH_MAX   256
+#  endif       /* NAME_MAX */
+#endif /* PATH_MAX */
+
+
+#define DIR_METATABLE "directory metatable"
+typedef struct dir_data {
+        int  closed;
+        DIR *dir;
+} dir_data;
+
+
+#define STAT_STRUCT struct stat
+#define STAT_FUNC stat_via_fstat
+
+/* Emulate stat via fstat */
+int stat_via_fstat (const char *path, struct stat *buf)
+{
+  int fd = open (path, O_RDONLY);
+  if (fd == -1) {
+    DIR *dir = opendir (path);
+    if (!dir) return -1;
+    closedir (dir);
+    buf->st_mode=S_IFDIR;
+    buf->st_size=0;
+    return 0;
+  }
+  if (fstat (fd, buf) == -1) {
+    int err = errno;
+    close (fd);
+    errno = err;
+    return -1;
+  }
+  close (fd);
+  return 0;
+}
+
+/*
+** This function changes the working (current) directory
+*/
+static int change_dir (lua_State *L) {
+        const char *path = luaL_checkstring(L, 1);
+        if (chdir(path)) {
+                lua_pushnil (L);
+                lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n",
+                                path, chdir_error);
+                return 2;
+        } else {
+                lua_pushboolean (L, 1);
+                return 1;
+        }
+}
+
+
+/*
+** This function returns the current directory
+** If unable to get the current directory, it returns nil
+** and a string describing the error
+*/
+static int get_dir (lua_State *L) {
+  char *path;
+  /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
+  char buf[PATH_MAX];
+  if ((path = getcwd(buf, PATH_MAX)) == NULL) {
+    lua_pushnil(L);
+    lua_pushstring(L, strerror(errno));
+    return 2;
+  }
+  else {
+    lua_pushstring(L, path);
+    return 1;
+  }
+}
+
+
+/*
+** Directory iterator
+*/
+static int dir_iter (lua_State *L) {
+        struct dirent *entry;
+        dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE);
+        luaL_argcheck (L, d->closed == 0, 1, "closed directory");
+        if ((entry = readdir (d->dir)) != NULL) {
+                lua_pushstring (L, entry->d_name);
+                return 1;
+        } else {
+                /* no more entries => close directory */
+                closedir (d->dir);
+                d->closed = 1;
+                return 0;
+        }
+}
+
+
+/*
+** Closes directory iterators
+*/
+static int dir_close (lua_State *L) {
+        dir_data *d = (dir_data *)lua_touserdata (L, 1);
+        if (!d->closed && d->dir) {
+                closedir (d->dir);
+        }
+        d->closed = 1;
+        return 0;
+}
+
+
+/*
+** Factory of directory iterators
+*/
+static int dir_iter_factory (lua_State *L) {
+        const char *path = luaL_checkstring (L, 1);
+        dir_data *d;
+        lua_pushcfunction (L, dir_iter);
+        d = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
+        luaL_getmetatable (L, DIR_METATABLE);
+        lua_setmetatable (L, -2);
+        d->closed = 0;
+        d->dir = opendir (path);
+        if (d->dir == NULL)
+          luaL_error (L, "cannot open %s: %s", path, strerror (errno));
+        return 2;
+}
+
+
+/*
+** Creates directory metatable.
+*/
+static int dir_create_meta (lua_State *L) {
+        luaL_newmetatable (L, DIR_METATABLE);
+
+        /* Method table */
+        lua_newtable(L);
+        lua_pushcfunction (L, dir_iter);
+        lua_setfield(L, -2, "next");
+        lua_pushcfunction (L, dir_close);
+        lua_setfield(L, -2, "close");
+
+        /* Metamethods */
+        lua_setfield(L, -2, "__index");
+        lua_pushcfunction (L, dir_close);
+        lua_setfield (L, -2, "__gc");
+        return 1;
+}
+
+
+/*
+** Convert the inode protection mode to a string.
+*/
+static const char *mode2string (mode_t mode) {
+  if ( S_ISREG(mode) )
+    return "file";
+  else if ( S_ISDIR(mode) )
+    return "directory";
+  else if ( S_ISLNK(mode) )
+        return "link";
+  else if ( S_ISSOCK(mode) )
+    return "socket";
+  else if ( S_ISFIFO(mode) )
+        return "named pipe";
+  else if ( S_ISCHR(mode) )
+        return "char device";
+  else if ( S_ISBLK(mode) )
+        return "block device";
+  else
+        return "other";
+}
+
+
+/* inode protection mode */
+static void push_st_mode (lua_State *L, STAT_STRUCT *info) {
+        lua_pushstring (L, mode2string (info->st_mode));
+}
+/* file size, in bytes */
+static void push_st_size (lua_State *L, STAT_STRUCT *info) {
+        lua_pushnumber (L, (lua_Number)info->st_size);
+}
+static void push_invalid (lua_State *L, STAT_STRUCT *info) {
+  luaL_error(L, "invalid attribute name");
+  info->st_size = 0; /* never reached */
+}
+
+typedef void (*_push_function) (lua_State *L, STAT_STRUCT *info);
+
+struct _stat_members {
+        const char *name;
+        _push_function push;
+};
+
+struct _stat_members members[] = {
+        { "mode",         push_st_mode },
+        { "size",         push_st_size },
+        { NULL, push_invalid }
+};
+
+/*
+** Get file or symbolic link information
+*/
+static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
+        int i;
+        STAT_STRUCT info;
+        const char *file = luaL_checkstring (L, 1);
+
+        if (st(file, &info)) {
+                lua_pushnil (L);
+                lua_pushfstring (L, "cannot obtain information from file `%s'", file);
+                return 2;
+        }
+        if (lua_isstring (L, 2)) {
+                int v;
+                const char *member = lua_tostring (L, 2);
+                if (strcmp (member, "mode") == 0) v = 0;
+#ifndef _WIN32
+                else if (strcmp (member, "blocks")  == 0) v = 11;
+                else if (strcmp (member, "blksize") == 0) v = 12;
+#endif
+                else /* look for member */
+                        for (v = 1; members[v].name; v++)
+                                if (*members[v].name == *member)
+                                        break;
+                /* push member value and return */
+                members[v].push (L, &info);
+                return 1;
+        } else if (!lua_istable (L, 2))
+                /* creates a table if none is given */
+                lua_newtable (L);
+        /* stores all members in table on top of the stack */
+        for (i = 0; members[i].name; i++) {
+                lua_pushstring (L, members[i].name);
+                members[i].push (L, &info);
+                lua_rawset (L, -3);
+        }
+        return 1;
+}
+
+
+/*
+** Get file information using stat.
+*/
+static int file_info (lua_State *L) {
+        return _file_info_ (L, STAT_FUNC);
+}
+
+
+static const struct luaL_Reg fslib[] = {
+        {"attributes", file_info},
+        {"chdir", change_dir},
+        {"currentdir", get_dir},
+        {"dir", dir_iter_factory},
+        {NULL, NULL},
+};
+
+LUALIB_API int luaopen_lfs (lua_State *L) {
+  dir_create_meta (L);
+  luaL_newlib (L, fslib);
+  return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,161 @@
+/*
+** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define lfunc_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+Closure *luaF_newCclosure (lua_State *L, int n) {
+  Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
+  c->c.nupvalues = cast_byte(n);
+  return c;
+}
+
+
+Closure *luaF_newLclosure (lua_State *L, int n) {
+  Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
+  c->l.p = NULL;
+  c->l.nupvalues = cast_byte(n);
+  while (n--) c->l.upvals[n] = NULL;
+  return c;
+}
+
+
+UpVal *luaF_newupval (lua_State *L) {
+  UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
+  uv->v = &uv->u.value;
+  setnilvalue(uv->v);
+  return uv;
+}
+
+
+UpVal *luaF_findupval (lua_State *L, StkId level) {
+  global_State *g = G(L);
+  GCObject **pp = &L->openupval;
+  UpVal *p;
+  UpVal *uv;
+  while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
+    GCObject *o = obj2gco(p);
+    lua_assert(p->v != &p->u.value);
+    lua_assert(!isold(o) || isold(obj2gco(L)));
+    if (p->v == level) {  /* found a corresponding upvalue? */
+      if (isdead(g, o))  /* is it dead? */
+        changewhite(o);  /* resurrect it */
+      return p;
+    }
+    pp = &p->next;
+  }
+  /* not found: create a new one */
+  uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
+  uv->v = level;  /* current value lives in the stack */
+  uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
+  uv->u.l.next = g->uvhead.u.l.next;
+  uv->u.l.next->u.l.prev = uv;
+  g->uvhead.u.l.next = uv;
+  lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+  return uv;
+}
+
+
+static void unlinkupval (UpVal *uv) {
+  lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+  uv->u.l.next->u.l.prev = uv->u.l.prev;  /* remove from `uvhead' list */
+  uv->u.l.prev->u.l.next = uv->u.l.next;
+}
+
+
+void luaF_freeupval (lua_State *L, UpVal *uv) {
+  if (uv->v != &uv->u.value)  /* is it open? */
+    unlinkupval(uv);  /* remove from open list */
+  luaM_free(L, uv);  /* free upvalue */
+}
+
+
+void luaF_close (lua_State *L, StkId level) {
+  UpVal *uv;
+  global_State *g = G(L);
+  while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
+    GCObject *o = obj2gco(uv);
+    lua_assert(!isblack(o) && uv->v != &uv->u.value);
+    L->openupval = uv->next;  /* remove from `open' list */
+    if (isdead(g, o))
+      luaF_freeupval(L, uv);  /* free upvalue */
+    else {
+      unlinkupval(uv);  /* remove upvalue from 'uvhead' list */
+      setobj(L, &uv->u.value, uv->v);  /* move value to upvalue slot */
+      uv->v = &uv->u.value;  /* now current value lives here */
+      gch(o)->next = g->allgc;  /* link upvalue into 'allgc' list */
+      g->allgc = o;
+      luaC_checkupvalcolor(g, uv);
+    }
+  }
+}
+
+
+Proto *luaF_newproto (lua_State *L) {
+  Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
+  f->k = NULL;
+  f->sizek = 0;
+  f->p = NULL;
+  f->sizep = 0;
+  f->code = NULL;
+  f->cache = NULL;
+  f->sizecode = 0;
+  f->lineinfo = NULL;
+  f->sizelineinfo = 0;
+  f->upvalues = NULL;
+  f->sizeupvalues = 0;
+  f->numparams = 0;
+  f->is_vararg = 0;
+  f->maxstacksize = 0;
+  f->locvars = NULL;
+  f->sizelocvars = 0;
+  f->linedefined = 0;
+  f->lastlinedefined = 0;
+  f->source = NULL;
+  return f;
+}
+
+
+void luaF_freeproto (lua_State *L, Proto *f) {
+  luaM_freearray(L, f->code, f->sizecode);
+  luaM_freearray(L, f->p, f->sizep);
+  luaM_freearray(L, f->k, f->sizek);
+  luaM_freearray(L, f->lineinfo, f->sizelineinfo);
+  luaM_freearray(L, f->locvars, f->sizelocvars);
+  luaM_freearray(L, f->upvalues, f->sizeupvalues);
+  luaM_free(L, f);
+}
+
+
+/*
+** Look for n-th local variable at line `line' in function `func'.
+** Returns NULL if not found.
+*/
+const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
+  int i;
+  for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
+    if (pc < f->locvars[i].endpc) {  /* is variable active? */
+      local_number--;
+      if (local_number == 0)
+        return getstr(f->locvars[i].varname);
+    }
+  }
+  return NULL;  /* not found */
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lfunc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+/*
+** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lfunc_h
+#define lfunc_h
+
+
+#include "lobject.h"
+
+
+#define sizeCclosure(n)	(cast(int, sizeof(CClosure)) + \
+                         cast(int, sizeof(TValue)*((n)-1)))
+
+#define sizeLclosure(n)	(cast(int, sizeof(LClosure)) + \
+                         cast(int, sizeof(TValue *)*((n)-1)))
+
+
+LUAI_FUNC Proto *luaF_newproto (lua_State *L);
+LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
+LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
+LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
+LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
+LUAI_FUNC void luaF_close (lua_State *L, StkId level);
+LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
+LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
+LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
+                                         int pc);
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1220 @@
+/*
+** $Id: lgc.c,v 2.140.1.2 2013/04/26 18:22:05 roberto Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#include <string.h>
+
+#define lgc_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+
+/*
+** cost of sweeping one element (the size of a small object divided
+** by some adjust for the sweep speed)
+*/
+#define GCSWEEPCOST	((sizeof(TString) + 4) / 4)
+
+/* maximum number of elements to sweep in each single step */
+#define GCSWEEPMAX	(cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
+
+/* maximum number of finalizers to call in each GC step */
+#define GCFINALIZENUM	4
+
+
+/*
+** macro to adjust 'stepmul': 'stepmul' is actually used like
+** 'stepmul / STEPMULADJ' (value chosen by tests)
+*/
+#define STEPMULADJ		200
+
+
+/*
+** macro to adjust 'pause': 'pause' is actually used like
+** 'pause / PAUSEADJ' (value chosen by tests)
+*/
+#define PAUSEADJ		100
+
+
+/*
+** 'makewhite' erases all color bits plus the old bit and then
+** sets only the current white bit
+*/
+#define maskcolors	(~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))
+#define makewhite(g,x)	\
+ (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
+
+#define white2gray(x)	resetbits(gch(x)->marked, WHITEBITS)
+#define black2gray(x)	resetbit(gch(x)->marked, BLACKBIT)
+
+
+#define isfinalized(x)		testbit(gch(x)->marked, FINALIZEDBIT)
+
+#define checkdeadkey(n)	lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
+
+
+#define checkconsistency(obj)  \
+  lua_longassert(!iscollectable(obj) || righttt(obj))
+
+
+#define markvalue(g,o) { checkconsistency(o); \
+  if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
+
+#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
+		reallymarkobject(g, obj2gco(t)); }
+
+static void reallymarkobject (global_State *g, GCObject *o);
+
+
+/*
+** {======================================================
+** Generic functions
+** =======================================================
+*/
+
+
+/*
+** one after last element in a hash array
+*/
+#define gnodelast(h)	gnode(h, cast(size_t, sizenode(h)))
+
+
+/*
+** link table 'h' into list pointed by 'p'
+*/
+#define linktable(h,p)	((h)->gclist = *(p), *(p) = obj2gco(h))
+
+
+/*
+** if key is not marked, mark its entry as dead (therefore removing it
+** from the table)
+*/
+static void removeentry (Node *n) {
+  lua_assert(ttisnil(gval(n)));
+  if (valiswhite(gkey(n)))
+    setdeadvalue(gkey(n));  /* unused and unmarked key; remove it */
+}
+
+
+/*
+** tells whether a key or value can be cleared from a weak
+** table. Non-collectable objects are never removed from weak
+** tables. Strings behave as `values', so are never removed too. for
+** other objects: if really collected, cannot keep them; for objects
+** being finalized, keep them in keys, but not in values
+*/
+static int iscleared (global_State *g, const TValue *o) {
+  if (!iscollectable(o)) return 0;
+  else if (ttisstring(o)) {
+    markobject(g, rawtsvalue(o));  /* strings are `values', so are never weak */
+    return 0;
+  }
+  else return iswhite(gcvalue(o));
+}
+
+
+/*
+** barrier that moves collector forward, that is, mark the white object
+** being pointed by a black object.
+*/
+void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
+  global_State *g = G(L);
+  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+  lua_assert(g->gcstate != GCSpause);
+  lua_assert(gch(o)->tt != LUA_TTABLE);
+  if (keepinvariantout(g))  /* must keep invariant? */
+    reallymarkobject(g, v);  /* restore invariant */
+  else {  /* sweep phase */
+    lua_assert(issweepphase(g));
+    makewhite(g, o);  /* mark main obj. as white to avoid other barriers */
+  }
+}
+
+
+/*
+** barrier that moves collector backward, that is, mark the black object
+** pointing to a white object as gray again. (Current implementation
+** only works for tables; access to 'gclist' is not uniform across
+** different types.)
+*/
+void luaC_barrierback_ (lua_State *L, GCObject *o) {
+  global_State *g = G(L);
+  lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
+  black2gray(o);  /* make object gray (again) */
+  gco2t(o)->gclist = g->grayagain;
+  g->grayagain = o;
+}
+
+
+/*
+** barrier for prototypes. When creating first closure (cache is
+** NULL), use a forward barrier; this may be the only closure of the
+** prototype (if it is a "regular" function, with a single instance)
+** and the prototype may be big, so it is better to avoid traversing
+** it again. Otherwise, use a backward barrier, to avoid marking all
+** possible instances.
+*/
+LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {
+  global_State *g = G(L);
+  lua_assert(isblack(obj2gco(p)));
+  if (p->cache == NULL) {  /* first time? */
+    luaC_objbarrier(L, p, c);
+  }
+  else {  /* use a backward barrier */
+    black2gray(obj2gco(p));  /* make prototype gray (again) */
+    p->gclist = g->grayagain;
+    g->grayagain = obj2gco(p);
+  }
+}
+
+
+/*
+** check color (and invariants) for an upvalue that was closed,
+** i.e., moved into the 'allgc' list
+*/
+void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
+  GCObject *o = obj2gco(uv);
+  lua_assert(!isblack(o));  /* open upvalues are never black */
+  if (isgray(o)) {
+    if (keepinvariant(g)) {
+      resetoldbit(o);  /* see MOVE OLD rule */
+      gray2black(o);  /* it is being visited now */
+      markvalue(g, uv->v);
+    }
+    else {
+      lua_assert(issweepphase(g));
+      makewhite(g, o);
+    }
+  }
+}
+
+
+/*
+** create a new collectable object (with given type and size) and link
+** it to '*list'. 'offset' tells how many bytes to allocate before the
+** object itself (used only by states).
+*/
+GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,
+                       int offset) {
+  global_State *g = G(L);
+  char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz));
+  GCObject *o = obj2gco(raw + offset);
+  if (list == NULL)
+    list = &g->allgc;  /* standard list for collectable objects */
+  gch(o)->marked = luaC_white(g);
+  gch(o)->tt = tt;
+  gch(o)->next = *list;
+  *list = o;
+  return o;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** Mark functions
+** =======================================================
+*/
+
+
+/*
+** mark an object. Userdata, strings, and closed upvalues are visited
+** and turned black here. Other objects are marked gray and added
+** to appropriate list to be visited (and turned black) later. (Open
+** upvalues are already linked in 'headuv' list.)
+*/
+static void reallymarkobject (global_State *g, GCObject *o) {
+  lu_mem size;
+  white2gray(o);
+  switch (gch(o)->tt) {
+    case LUA_TSHRSTR:
+    case LUA_TLNGSTR: {
+      size = sizestring(gco2ts(o));
+      break;  /* nothing else to mark; make it black */
+    }
+    case LUA_TUSERDATA: {
+      Table *mt = gco2u(o)->metatable;
+      markobject(g, mt);
+      markobject(g, gco2u(o)->env);
+      size = sizeudata(gco2u(o));
+      break;
+    }
+    case LUA_TUPVAL: {
+      UpVal *uv = gco2uv(o);
+      markvalue(g, uv->v);
+      if (uv->v != &uv->u.value)  /* open? */
+        return;  /* open upvalues remain gray */
+      size = sizeof(UpVal);
+      break;
+    }
+    case LUA_TLCL: {
+      gco2lcl(o)->gclist = g->gray;
+      g->gray = o;
+      return;
+    }
+    case LUA_TCCL: {
+      gco2ccl(o)->gclist = g->gray;
+      g->gray = o;
+      return;
+    }
+    case LUA_TTABLE: {
+      linktable(gco2t(o), &g->gray);
+      return;
+    }
+    case LUA_TTHREAD: {
+      gco2th(o)->gclist = g->gray;
+      g->gray = o;
+      return;
+    }
+    case LUA_TPROTO: {
+      gco2p(o)->gclist = g->gray;
+      g->gray = o;
+      return;
+    }
+    default: lua_assert(0); return;
+  }
+  gray2black(o);
+  g->GCmemtrav += size;
+}
+
+
+/*
+** mark metamethods for basic types
+*/
+static void markmt (global_State *g) {
+  int i;
+  for (i=0; i < LUA_NUMTAGS; i++)
+    markobject(g, g->mt[i]);
+}
+
+
+/*
+** mark all objects in list of being-finalized
+*/
+static void markbeingfnz (global_State *g) {
+  GCObject *o;
+  for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
+    makewhite(g, o);
+    reallymarkobject(g, o);
+  }
+}
+
+
+/*
+** mark all values stored in marked open upvalues. (See comment in
+** 'lstate.h'.)
+*/
+static void remarkupvals (global_State *g) {
+  UpVal *uv;
+  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
+    if (isgray(obj2gco(uv)))
+      markvalue(g, uv->v);
+  }
+}
+
+
+/*
+** mark root set and reset all gray lists, to start a new
+** incremental (or full) collection
+*/
+static void restartcollection (global_State *g) {
+  g->gray = g->grayagain = NULL;
+  g->weak = g->allweak = g->ephemeron = NULL;
+  markobject(g, g->mainthread);
+  markvalue(g, &g->l_registry);
+  markmt(g);
+  markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Traverse functions
+** =======================================================
+*/
+
+static void traverseweakvalue (global_State *g, Table *h) {
+  Node *n, *limit = gnodelast(h);
+  /* if there is array part, assume it may have white values (do not
+     traverse it just to check) */
+  int hasclears = (h->sizearray > 0);
+  for (n = gnode(h, 0); n < limit; n++) {
+    checkdeadkey(n);
+    if (ttisnil(gval(n)))  /* entry is empty? */
+      removeentry(n);  /* remove it */
+    else {
+      lua_assert(!ttisnil(gkey(n)));
+      markvalue(g, gkey(n));  /* mark key */
+      if (!hasclears && iscleared(g, gval(n)))  /* is there a white value? */
+        hasclears = 1;  /* table will have to be cleared */
+    }
+  }
+  if (hasclears)
+    linktable(h, &g->weak);  /* has to be cleared later */
+  else  /* no white values */
+    linktable(h, &g->grayagain);  /* no need to clean */
+}
+
+
+static int traverseephemeron (global_State *g, Table *h) {
+  int marked = 0;  /* true if an object is marked in this traversal */
+  int hasclears = 0;  /* true if table has white keys */
+  int prop = 0;  /* true if table has entry "white-key -> white-value" */
+  Node *n, *limit = gnodelast(h);
+  int i;
+  /* traverse array part (numeric keys are 'strong') */
+  for (i = 0; i < h->sizearray; i++) {
+    if (valiswhite(&h->array[i])) {
+      marked = 1;
+      reallymarkobject(g, gcvalue(&h->array[i]));
+    }
+  }
+  /* traverse hash part */
+  for (n = gnode(h, 0); n < limit; n++) {
+    checkdeadkey(n);
+    if (ttisnil(gval(n)))  /* entry is empty? */
+      removeentry(n);  /* remove it */
+    else if (iscleared(g, gkey(n))) {  /* key is not marked (yet)? */
+      hasclears = 1;  /* table must be cleared */
+      if (valiswhite(gval(n)))  /* value not marked yet? */
+        prop = 1;  /* must propagate again */
+    }
+    else if (valiswhite(gval(n))) {  /* value not marked yet? */
+      marked = 1;
+      reallymarkobject(g, gcvalue(gval(n)));  /* mark it now */
+    }
+  }
+  if (prop)
+    linktable(h, &g->ephemeron);  /* have to propagate again */
+  else if (hasclears)  /* does table have white keys? */
+    linktable(h, &g->allweak);  /* may have to clean white keys */
+  else  /* no white keys */
+    linktable(h, &g->grayagain);  /* no need to clean */
+  return marked;
+}
+
+
+static void traversestrongtable (global_State *g, Table *h) {
+  Node *n, *limit = gnodelast(h);
+  int i;
+  for (i = 0; i < h->sizearray; i++)  /* traverse array part */
+    markvalue(g, &h->array[i]);
+  for (n = gnode(h, 0); n < limit; n++) {  /* traverse hash part */
+    checkdeadkey(n);
+    if (ttisnil(gval(n)))  /* entry is empty? */
+      removeentry(n);  /* remove it */
+    else {
+      lua_assert(!ttisnil(gkey(n)));
+      markvalue(g, gkey(n));  /* mark key */
+      markvalue(g, gval(n));  /* mark value */
+    }
+  }
+}
+
+
+static lu_mem traversetable (global_State *g, Table *h) {
+  const char *weakkey, *weakvalue;
+  const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
+  markobject(g, h->metatable);
+  if (mode && ttisstring(mode) &&  /* is there a weak mode? */
+      ((weakkey = strchr(svalue(mode), 'k')),
+       (weakvalue = strchr(svalue(mode), 'v')),
+       (weakkey || weakvalue))) {  /* is really weak? */
+    black2gray(obj2gco(h));  /* keep table gray */
+    if (!weakkey)  /* strong keys? */
+      traverseweakvalue(g, h);
+    else if (!weakvalue)  /* strong values? */
+      traverseephemeron(g, h);
+    else  /* all weak */
+      linktable(h, &g->allweak);  /* nothing to traverse now */
+  }
+  else  /* not weak */
+    traversestrongtable(g, h);
+  return sizeof(Table) + sizeof(TValue) * h->sizearray +
+                         sizeof(Node) * cast(size_t, sizenode(h));
+}
+
+
+static int traverseproto (global_State *g, Proto *f) {
+  int i;
+  if (f->cache && iswhite(obj2gco(f->cache)))
+    f->cache = NULL;  /* allow cache to be collected */
+  markobject(g, f->source);
+  for (i = 0; i < f->sizek; i++)  /* mark literals */
+    markvalue(g, &f->k[i]);
+  for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
+    markobject(g, f->upvalues[i].name);
+  for (i = 0; i < f->sizep; i++)  /* mark nested protos */
+    markobject(g, f->p[i]);
+  for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
+    markobject(g, f->locvars[i].varname);
+  return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
+                         sizeof(Proto *) * f->sizep +
+                         sizeof(TValue) * f->sizek +
+                         sizeof(int) * f->sizelineinfo +
+                         sizeof(LocVar) * f->sizelocvars +
+                         sizeof(Upvaldesc) * f->sizeupvalues;
+}
+
+
+static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
+  int i;
+  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
+    markvalue(g, &cl->upvalue[i]);
+  return sizeCclosure(cl->nupvalues);
+}
+
+static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
+  int i;
+  markobject(g, cl->p);  /* mark its prototype */
+  for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
+    markobject(g, cl->upvals[i]);
+  return sizeLclosure(cl->nupvalues);
+}
+
+
+static lu_mem traversestack (global_State *g, lua_State *th) {
+  int n = 0;
+  StkId o = th->stack;
+  if (o == NULL)
+    return 1;  /* stack not completely built yet */
+  for (; o < th->top; o++)  /* mark live elements in the stack */
+    markvalue(g, o);
+  if (g->gcstate == GCSatomic) {  /* final traversal? */
+    StkId lim = th->stack + th->stacksize;  /* real end of stack */
+    for (; o < lim; o++)  /* clear not-marked stack slice */
+      setnilvalue(o);
+  }
+  else {  /* count call infos to compute size */
+    CallInfo *ci;
+    for (ci = &th->base_ci; ci != th->ci; ci = ci->next)
+      n++;
+  }
+  return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
+         sizeof(CallInfo) * n;
+}
+
+
+/*
+** traverse one gray object, turning it to black (except for threads,
+** which are always gray).
+*/
+static void propagatemark (global_State *g) {
+  lu_mem size;
+  GCObject *o = g->gray;
+  lua_assert(isgray(o));
+  gray2black(o);
+  switch (gch(o)->tt) {
+    case LUA_TTABLE: {
+      Table *h = gco2t(o);
+      g->gray = h->gclist;  /* remove from 'gray' list */
+      size = traversetable(g, h);
+      break;
+    }
+    case LUA_TLCL: {
+      LClosure *cl = gco2lcl(o);
+      g->gray = cl->gclist;  /* remove from 'gray' list */
+      size = traverseLclosure(g, cl);
+      break;
+    }
+    case LUA_TCCL: {
+      CClosure *cl = gco2ccl(o);
+      g->gray = cl->gclist;  /* remove from 'gray' list */
+      size = traverseCclosure(g, cl);
+      break;
+    }
+    case LUA_TTHREAD: {
+      lua_State *th = gco2th(o);
+      g->gray = th->gclist;  /* remove from 'gray' list */
+      th->gclist = g->grayagain;
+      g->grayagain = o;  /* insert into 'grayagain' list */
+      black2gray(o);
+      size = traversestack(g, th);
+      break;
+    }
+    case LUA_TPROTO: {
+      Proto *p = gco2p(o);
+      g->gray = p->gclist;  /* remove from 'gray' list */
+      size = traverseproto(g, p);
+      break;
+    }
+    default: lua_assert(0); return;
+  }
+  g->GCmemtrav += size;
+}
+
+
+static void propagateall (global_State *g) {
+  while (g->gray) propagatemark(g);
+}
+
+
+static void propagatelist (global_State *g, GCObject *l) {
+  lua_assert(g->gray == NULL);  /* no grays left */
+  g->gray = l;
+  propagateall(g);  /* traverse all elements from 'l' */
+}
+
+/*
+** retraverse all gray lists. Because tables may be reinserted in other
+** lists when traversed, traverse the original lists to avoid traversing
+** twice the same table (which is not wrong, but inefficient)
+*/
+static void retraversegrays (global_State *g) {
+  GCObject *weak = g->weak;  /* save original lists */
+  GCObject *grayagain = g->grayagain;
+  GCObject *ephemeron = g->ephemeron;
+  g->weak = g->grayagain = g->ephemeron = NULL;
+  propagateall(g);  /* traverse main gray list */
+  propagatelist(g, grayagain);
+  propagatelist(g, weak);
+  propagatelist(g, ephemeron);
+}
+
+
+static void convergeephemerons (global_State *g) {
+  int changed;
+  do {
+    GCObject *w;
+    GCObject *next = g->ephemeron;  /* get ephemeron list */
+    g->ephemeron = NULL;  /* tables will return to this list when traversed */
+    changed = 0;
+    while ((w = next) != NULL) {
+      next = gco2t(w)->gclist;
+      if (traverseephemeron(g, gco2t(w))) {  /* traverse marked some value? */
+        propagateall(g);  /* propagate changes */
+        changed = 1;  /* will have to revisit all ephemeron tables */
+      }
+    }
+  } while (changed);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Sweep Functions
+** =======================================================
+*/
+
+
+/*
+** clear entries with unmarked keys from all weaktables in list 'l' up
+** to element 'f'
+*/
+static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
+  for (; l != f; l = gco2t(l)->gclist) {
+    Table *h = gco2t(l);
+    Node *n, *limit = gnodelast(h);
+    for (n = gnode(h, 0); n < limit; n++) {
+      if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
+        setnilvalue(gval(n));  /* remove value ... */
+        removeentry(n);  /* and remove entry from table */
+      }
+    }
+  }
+}
+
+
+/*
+** clear entries with unmarked values from all weaktables in list 'l' up
+** to element 'f'
+*/
+static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
+  for (; l != f; l = gco2t(l)->gclist) {
+    Table *h = gco2t(l);
+    Node *n, *limit = gnodelast(h);
+    int i;
+    for (i = 0; i < h->sizearray; i++) {
+      TValue *o = &h->array[i];
+      if (iscleared(g, o))  /* value was collected? */
+        setnilvalue(o);  /* remove value */
+    }
+    for (n = gnode(h, 0); n < limit; n++) {
+      if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
+        setnilvalue(gval(n));  /* remove value ... */
+        removeentry(n);  /* and remove entry from table */
+      }
+    }
+  }
+}
+
+
+static void freeobj (lua_State *L, GCObject *o) {
+  switch (gch(o)->tt) {
+    case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
+    case LUA_TLCL: {
+      luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
+      break;
+    }
+    case LUA_TCCL: {
+      luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
+      break;
+    }
+    case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
+    case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
+    case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
+    case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
+    case LUA_TSHRSTR:
+      G(L)->strt.nuse--;
+      /* go through */
+    case LUA_TLNGSTR: {
+      luaM_freemem(L, o, sizestring(gco2ts(o)));
+      break;
+    }
+    default: lua_assert(0);
+  }
+}
+
+
+#define sweepwholelist(L,p)	sweeplist(L,p,MAX_LUMEM)
+static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
+
+
+/*
+** sweep the (open) upvalues of a thread and resize its stack and
+** list of call-info structures.
+*/
+static void sweepthread (lua_State *L, lua_State *L1) {
+  if (L1->stack == NULL) return;  /* stack not completely built yet */
+  sweepwholelist(L, &L1->openupval);  /* sweep open upvalues */
+  luaE_freeCI(L1);  /* free extra CallInfo slots */
+  /* should not change the stack during an emergency gc cycle */
+  if (G(L)->gckind != KGC_EMERGENCY)
+    luaD_shrinkstack(L1);
+}
+
+
+/*
+** sweep at most 'count' elements from a list of GCObjects erasing dead
+** objects, where a dead (not alive) object is one marked with the "old"
+** (non current) white and not fixed.
+** In non-generational mode, change all non-dead objects back to white,
+** preparing for next collection cycle.
+** In generational mode, keep black objects black, and also mark them as
+** old; stop when hitting an old object, as all objects after that
+** one will be old too.
+** When object is a thread, sweep its list of open upvalues too.
+*/
+static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
+  global_State *g = G(L);
+  int ow = otherwhite(g);
+  int toclear, toset;  /* bits to clear and to set in all live objects */
+  int tostop;  /* stop sweep when this is true */
+  if (isgenerational(g)) {  /* generational mode? */
+    toclear = ~0;  /* clear nothing */
+    toset = bitmask(OLDBIT);  /* set the old bit of all surviving objects */
+    tostop = bitmask(OLDBIT);  /* do not sweep old generation */
+  }
+  else {  /* normal mode */
+    toclear = maskcolors;  /* clear all color bits + old bit */
+    toset = luaC_white(g);  /* make object white */
+    tostop = 0;  /* do not stop */
+  }
+  while (*p != NULL && count-- > 0) {
+    GCObject *curr = *p;
+    int marked = gch(curr)->marked;
+    if (isdeadm(ow, marked)) {  /* is 'curr' dead? */
+      *p = gch(curr)->next;  /* remove 'curr' from list */
+      freeobj(L, curr);  /* erase 'curr' */
+    }
+    else {
+      if (testbits(marked, tostop))
+        return NULL;  /* stop sweeping this list */
+      if (gch(curr)->tt == LUA_TTHREAD)
+        sweepthread(L, gco2th(curr));  /* sweep thread's upvalues */
+      /* update marks */
+      gch(curr)->marked = cast_byte((marked & toclear) | toset);
+      p = &gch(curr)->next;  /* go to next element */
+    }
+  }
+  return (*p == NULL) ? NULL : p;
+}
+
+
+/*
+** sweep a list until a live object (or end of list)
+*/
+static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
+  GCObject ** old = p;
+  int i = 0;
+  do {
+    i++;
+    p = sweeplist(L, p, 1);
+  } while (p == old);
+  if (n) *n += i;
+  return p;
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Finalization
+** =======================================================
+*/
+
+static void checkSizes (lua_State *L) {
+  global_State *g = G(L);
+  if (g->gckind != KGC_EMERGENCY) {  /* do not change sizes in emergency */
+    int hs = g->strt.size / 2;  /* half the size of the string table */
+    if (g->strt.nuse < cast(lu_int32, hs))  /* using less than that half? */
+      luaS_resize(L, hs);  /* halve its size */
+    luaZ_freebuffer(L, &g->buff);  /* free concatenation buffer */
+  }
+}
+
+
+static GCObject *udata2finalize (global_State *g) {
+  GCObject *o = g->tobefnz;  /* get first element */
+  lua_assert(isfinalized(o));
+  g->tobefnz = gch(o)->next;  /* remove it from 'tobefnz' list */
+  gch(o)->next = g->allgc;  /* return it to 'allgc' list */
+  g->allgc = o;
+  resetbit(gch(o)->marked, SEPARATED);  /* mark that it is not in 'tobefnz' */
+  lua_assert(!isold(o));  /* see MOVE OLD rule */
+  if (!keepinvariantout(g))  /* not keeping invariant? */
+    makewhite(g, o);  /* "sweep" object */
+  return o;
+}
+
+
+static void dothecall (lua_State *L, void *ud) {
+  UNUSED(ud);
+  luaD_call(L, L->top - 2, 0, 0);
+}
+
+
+static void GCTM (lua_State *L, int propagateerrors) {
+  global_State *g = G(L);
+  const TValue *tm;
+  TValue v;
+  setgcovalue(L, &v, udata2finalize(g));
+  tm = luaT_gettmbyobj(L, &v, TM_GC);
+  if (tm != NULL && ttisfunction(tm)) {  /* is there a finalizer? */
+    int status;
+    lu_byte oldah = L->allowhook;
+    int running  = g->gcrunning;
+    L->allowhook = 0;  /* stop debug hooks during GC metamethod */
+    g->gcrunning = 0;  /* avoid GC steps */
+    setobj2s(L, L->top, tm);  /* push finalizer... */
+    setobj2s(L, L->top + 1, &v);  /* ... and its argument */
+    L->top += 2;  /* and (next line) call the finalizer */
+    status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
+    L->allowhook = oldah;  /* restore hooks */
+    g->gcrunning = running;  /* restore state */
+    if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
+      if (status == LUA_ERRRUN) {  /* is there an error object? */
+        const char *msg = (ttisstring(L->top - 1))
+                            ? svalue(L->top - 1)
+                            : "no message";
+        luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
+        status = LUA_ERRGCMM;  /* error in __gc metamethod */
+      }
+      luaD_throw(L, status);  /* re-throw error */
+    }
+  }
+}
+
+
+/*
+** move all unreachable objects (or 'all' objects) that need
+** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
+*/
+static void separatetobefnz (lua_State *L, int all) {
+  global_State *g = G(L);
+  GCObject **p = &g->finobj;
+  GCObject *curr;
+  GCObject **lastnext = &g->tobefnz;
+  /* find last 'next' field in 'tobefnz' list (to add elements in its end) */
+  while (*lastnext != NULL)
+    lastnext = &gch(*lastnext)->next;
+  while ((curr = *p) != NULL) {  /* traverse all finalizable objects */
+    lua_assert(!isfinalized(curr));
+    lua_assert(testbit(gch(curr)->marked, SEPARATED));
+    if (!(iswhite(curr) || all))  /* not being collected? */
+      p = &gch(curr)->next;  /* don't bother with it */
+    else {
+      l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
+      *p = gch(curr)->next;  /* remove 'curr' from 'finobj' list */
+      gch(curr)->next = *lastnext;  /* link at the end of 'tobefnz' list */
+      *lastnext = curr;
+      lastnext = &gch(curr)->next;
+    }
+  }
+}
+
+
+/*
+** if object 'o' has a finalizer, remove it from 'allgc' list (must
+** search the list to find it) and link it in 'finobj' list.
+*/
+void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
+  global_State *g = G(L);
+  if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
+      isfinalized(o) ||                           /* ... or is finalized... */
+      gfasttm(g, mt, TM_GC) == NULL)                /* or has no finalizer? */
+    return;  /* nothing to be done */
+  else {  /* move 'o' to 'finobj' list */
+    GCObject **p;
+    GCheader *ho = gch(o);
+    if (g->sweepgc == &ho->next) {  /* avoid removing current sweep object */
+      lua_assert(issweepphase(g));
+      g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
+    }
+    /* search for pointer pointing to 'o' */
+    for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
+    *p = ho->next;  /* remove 'o' from root list */
+    ho->next = g->finobj;  /* link it in list 'finobj' */
+    g->finobj = o;
+    l_setbit(ho->marked, SEPARATED);  /* mark it as such */
+    if (!keepinvariantout(g))  /* not keeping invariant? */
+      makewhite(g, o);  /* "sweep" object */
+    else
+      resetoldbit(o);  /* see MOVE OLD rule */
+  }
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** GC control
+** =======================================================
+*/
+
+
+/*
+** set a reasonable "time" to wait before starting a new GC cycle;
+** cycle will start when memory use hits threshold
+*/
+static void setpause (global_State *g, l_mem estimate) {
+  l_mem debt, threshold;
+  estimate = estimate / PAUSEADJ;  /* adjust 'estimate' */
+  threshold = (g->gcpause < MAX_LMEM / estimate)  /* overflow? */
+            ? estimate * g->gcpause  /* no overflow */
+            : MAX_LMEM;  /* overflow; truncate to maximum */
+  debt = -cast(l_mem, threshold - gettotalbytes(g));
+  luaE_setdebt(g, debt);
+}
+
+
+#define sweepphases  \
+	(bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
+
+
+/*
+** enter first sweep phase (strings) and prepare pointers for other
+** sweep phases.  The calls to 'sweeptolive' make pointers point to an
+** object inside the list (instead of to the header), so that the real
+** sweep do not need to skip objects created between "now" and the start
+** of the real sweep.
+** Returns how many objects it swept.
+*/
+static int entersweep (lua_State *L) {
+  global_State *g = G(L);
+  int n = 0;
+  g->gcstate = GCSsweepstring;
+  lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
+  /* prepare to sweep strings, finalizable objects, and regular objects */
+  g->sweepstrgc = 0;
+  g->sweepfin = sweeptolive(L, &g->finobj, &n);
+  g->sweepgc = sweeptolive(L, &g->allgc, &n);
+  return n;
+}
+
+
+/*
+** change GC mode
+*/
+void luaC_changemode (lua_State *L, int mode) {
+  global_State *g = G(L);
+  if (mode == g->gckind) return;  /* nothing to change */
+  if (mode == KGC_GEN) {  /* change to generational mode */
+    /* make sure gray lists are consistent */
+    luaC_runtilstate(L, bitmask(GCSpropagate));
+    g->GCestimate = gettotalbytes(g);
+    g->gckind = KGC_GEN;
+  }
+  else {  /* change to incremental mode */
+    /* sweep all objects to turn them back to white
+       (as white has not changed, nothing extra will be collected) */
+    g->gckind = KGC_NORMAL;
+    entersweep(L);
+    luaC_runtilstate(L, ~sweepphases);
+  }
+}
+
+
+/*
+** call all pending finalizers
+*/
+static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
+  global_State *g = G(L);
+  while (g->tobefnz) {
+    resetoldbit(g->tobefnz);
+    GCTM(L, propagateerrors);
+  }
+}
+
+
+void luaC_freeallobjects (lua_State *L) {
+  global_State *g = G(L);
+  int i;
+  separatetobefnz(L, 1);  /* separate all objects with finalizers */
+  lua_assert(g->finobj == NULL);
+  callallpendingfinalizers(L, 0);
+  g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
+  g->gckind = KGC_NORMAL;
+  sweepwholelist(L, &g->finobj);  /* finalizers can create objs. in 'finobj' */
+  sweepwholelist(L, &g->allgc);
+  for (i = 0; i < g->strt.size; i++)  /* free all string lists */
+    sweepwholelist(L, &g->strt.hash[i]);
+  lua_assert(g->strt.nuse == 0);
+}
+
+
+static l_mem atomic (lua_State *L) {
+  global_State *g = G(L);
+  l_mem work = -cast(l_mem, g->GCmemtrav);  /* start counting work */
+  GCObject *origweak, *origall;
+  lua_assert(!iswhite(obj2gco(g->mainthread)));
+  markobject(g, L);  /* mark running thread */
+  /* registry and global metatables may be changed by API */
+  markvalue(g, &g->l_registry);
+  markmt(g);  /* mark basic metatables */
+  /* remark occasional upvalues of (maybe) dead threads */
+  remarkupvals(g);
+  propagateall(g);  /* propagate changes */
+  work += g->GCmemtrav;  /* stop counting (do not (re)count grays) */
+  /* traverse objects caught by write barrier and by 'remarkupvals' */
+  retraversegrays(g);
+  work -= g->GCmemtrav;  /* restart counting */
+  convergeephemerons(g);
+  /* at this point, all strongly accessible objects are marked. */
+  /* clear values from weak tables, before checking finalizers */
+  clearvalues(g, g->weak, NULL);
+  clearvalues(g, g->allweak, NULL);
+  origweak = g->weak; origall = g->allweak;
+  work += g->GCmemtrav;  /* stop counting (objects being finalized) */
+  separatetobefnz(L, 0);  /* separate objects to be finalized */
+  markbeingfnz(g);  /* mark objects that will be finalized */
+  propagateall(g);  /* remark, to propagate `preserveness' */
+  work -= g->GCmemtrav;  /* restart counting */
+  convergeephemerons(g);
+  /* at this point, all resurrected objects are marked. */
+  /* remove dead objects from weak tables */
+  clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
+  clearkeys(g, g->allweak, NULL);  /* clear keys from all allweak tables */
+  /* clear values from resurrected weak tables */
+  clearvalues(g, g->weak, origweak);
+  clearvalues(g, g->allweak, origall);
+  g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
+  work += g->GCmemtrav;  /* complete counting */
+  return work;  /* estimate of memory marked by 'atomic' */
+}
+
+
+static lu_mem singlestep (lua_State *L) {
+  global_State *g = G(L);
+  switch (g->gcstate) {
+    case GCSpause: {
+      /* start to count memory traversed */
+      g->GCmemtrav = g->strt.size * sizeof(GCObject*);
+      lua_assert(!isgenerational(g));
+      restartcollection(g);
+      g->gcstate = GCSpropagate;
+      return g->GCmemtrav;
+    }
+    case GCSpropagate: {
+      if (g->gray) {
+        lu_mem oldtrav = g->GCmemtrav;
+        propagatemark(g);
+        return g->GCmemtrav - oldtrav;  /* memory traversed in this step */
+      }
+      else {  /* no more `gray' objects */
+        lu_mem work;
+        int sw;
+        g->gcstate = GCSatomic;  /* finish mark phase */
+        g->GCestimate = g->GCmemtrav;  /* save what was counted */;
+        work = atomic(L);  /* add what was traversed by 'atomic' */
+        g->GCestimate += work;  /* estimate of total memory traversed */ 
+        sw = entersweep(L);
+        return work + sw * GCSWEEPCOST;
+      }
+    }
+    case GCSsweepstring: {
+      int i;
+      for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
+        sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
+      g->sweepstrgc += i;
+      if (g->sweepstrgc >= g->strt.size)  /* no more strings to sweep? */
+        g->gcstate = GCSsweepudata;
+      return i * GCSWEEPCOST;
+    }
+    case GCSsweepudata: {
+      if (g->sweepfin) {
+        g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
+        return GCSWEEPMAX*GCSWEEPCOST;
+      }
+      else {
+        g->gcstate = GCSsweep;
+        return 0;
+      }
+    }
+    case GCSsweep: {
+      if (g->sweepgc) {
+        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
+        return GCSWEEPMAX*GCSWEEPCOST;
+      }
+      else {
+        /* sweep main thread */
+        GCObject *mt = obj2gco(g->mainthread);
+        sweeplist(L, &mt, 1);
+        checkSizes(L);
+        g->gcstate = GCSpause;  /* finish collection */
+        return GCSWEEPCOST;
+      }
+    }
+    default: lua_assert(0); return 0;
+  }
+}
+
+
+/*
+** advances the garbage collector until it reaches a state allowed
+** by 'statemask'
+*/
+void luaC_runtilstate (lua_State *L, int statesmask) {
+  global_State *g = G(L);
+  while (!testbit(statesmask, g->gcstate))
+    singlestep(L);
+}
+
+
+static void generationalcollection (lua_State *L) {
+  global_State *g = G(L);
+  lua_assert(g->gcstate == GCSpropagate);
+  if (g->GCestimate == 0) {  /* signal for another major collection? */
+    luaC_fullgc(L, 0);  /* perform a full regular collection */
+    g->GCestimate = gettotalbytes(g);  /* update control */
+  }
+  else {
+    lu_mem estimate = g->GCestimate;
+    luaC_runtilstate(L, bitmask(GCSpause));  /* run complete (minor) cycle */
+    g->gcstate = GCSpropagate;  /* skip restart */
+    if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
+      g->GCestimate = 0;  /* signal for a major collection */
+    else
+      g->GCestimate = estimate;  /* keep estimate from last major coll. */
+
+  }
+  setpause(g, gettotalbytes(g));
+  lua_assert(g->gcstate == GCSpropagate);
+}
+
+
+static void incstep (lua_State *L) {
+  global_State *g = G(L);
+  l_mem debt = g->GCdebt;
+  int stepmul = g->gcstepmul;
+  if (stepmul < 40) stepmul = 40;  /* avoid ridiculous low values (and 0) */
+  /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
+  debt = (debt / STEPMULADJ) + 1;
+  debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
+  do {  /* always perform at least one single step */
+    lu_mem work = singlestep(L);  /* do some work */
+    debt -= work;
+  } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
+  if (g->gcstate == GCSpause)
+    setpause(g, g->GCestimate);  /* pause until next cycle */
+  else {
+    debt = (debt / stepmul) * STEPMULADJ;  /* convert 'work units' to Kb */
+    luaE_setdebt(g, debt);
+  }
+}
+
+
+/*
+** performs a basic GC step
+*/
+void luaC_forcestep (lua_State *L) {
+  global_State *g = G(L);
+  int i;
+  if (isgenerational(g)) generationalcollection(L);
+  else incstep(L);
+  /* run a few finalizers (or all of them at the end of a collect cycle) */
+  for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
+    GCTM(L, 1);  /* call one finalizer */
+}
+
+
+/*
+** performs a basic GC step only if collector is running
+*/
+void luaC_step (lua_State *L) {
+  global_State *g = G(L);
+  if (g->gcrunning) luaC_forcestep(L);
+  else luaE_setdebt(g, -GCSTEPSIZE);  /* avoid being called too often */
+}
+
+
+
+/*
+** performs a full GC cycle; if "isemergency", does not call
+** finalizers (which could change stack positions)
+*/
+void luaC_fullgc (lua_State *L, int isemergency) {
+  global_State *g = G(L);
+  int origkind = g->gckind;
+  lua_assert(origkind != KGC_EMERGENCY);
+  if (isemergency)  /* do not run finalizers during emergency GC */
+    g->gckind = KGC_EMERGENCY;
+  else {
+    g->gckind = KGC_NORMAL;
+    callallpendingfinalizers(L, 1);
+  }
+  if (keepinvariant(g)) {  /* may there be some black objects? */
+    /* must sweep all objects to turn them back to white
+       (as white has not changed, nothing will be collected) */
+    entersweep(L);
+  }
+  /* finish any pending sweep phase to start a new cycle */
+  luaC_runtilstate(L, bitmask(GCSpause));
+  luaC_runtilstate(L, ~bitmask(GCSpause));  /* start new collection */
+  luaC_runtilstate(L, bitmask(GCSpause));  /* run entire collection */
+  if (origkind == KGC_GEN) {  /* generational mode? */
+    /* generational mode must be kept in propagate phase */
+    luaC_runtilstate(L, bitmask(GCSpropagate));
+  }
+  g->gckind = origkind;
+  setpause(g, gettotalbytes(g));
+  if (!isemergency)   /* do not run finalizers during emergency GC */
+    callallpendingfinalizers(L, 1);
+}
+
+/* }====================================================== */
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lgc.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,157 @@
+/*
+** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lgc_h
+#define lgc_h
+
+
+#include "lobject.h"
+#include "lstate.h"
+
+/*
+** Collectable objects may have one of three colors: white, which
+** means the object is not marked; gray, which means the
+** object is marked, but its references may be not marked; and
+** black, which means that the object and all its references are marked.
+** The main invariant of the garbage collector, while marking objects,
+** is that a black object can never point to a white one. Moreover,
+** any gray object must be in a "gray list" (gray, grayagain, weak,
+** allweak, ephemeron) so that it can be visited again before finishing
+** the collection cycle. These lists have no meaning when the invariant
+** is not being enforced (e.g., sweep phase).
+*/
+
+
+
+/* how much to allocate before next GC step */
+#if !defined(GCSTEPSIZE)
+/* ~100 small strings */
+#define GCSTEPSIZE	(cast_int(100 * sizeof(TString)))
+#endif
+
+
+/*
+** Possible states of the Garbage Collector
+*/
+#define GCSpropagate	0
+#define GCSatomic	1
+#define GCSsweepstring	2
+#define GCSsweepudata	3
+#define GCSsweep	4
+#define GCSpause	5
+
+
+#define issweepphase(g)  \
+	(GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)
+
+#define isgenerational(g)	((g)->gckind == KGC_GEN)
+
+/*
+** macros to tell when main invariant (white objects cannot point to black
+** ones) must be kept. During a non-generational collection, the sweep
+** phase may break the invariant, as objects turned white may point to
+** still-black objects. The invariant is restored when sweep ends and
+** all objects are white again. During a generational collection, the
+** invariant must be kept all times.
+*/
+
+#define keepinvariant(g)	(isgenerational(g) || g->gcstate <= GCSatomic)
+
+
+/*
+** Outside the collector, the state in generational mode is kept in
+** 'propagate', so 'keepinvariant' is always true.
+*/
+#define keepinvariantout(g)  \
+  check_exp(g->gcstate == GCSpropagate || !isgenerational(g),  \
+            g->gcstate <= GCSatomic)
+
+
+/*
+** some useful bit tricks
+*/
+#define resetbits(x,m)		((x) &= cast(lu_byte, ~(m)))
+#define setbits(x,m)		((x) |= (m))
+#define testbits(x,m)		((x) & (m))
+#define bitmask(b)		(1<<(b))
+#define bit2mask(b1,b2)		(bitmask(b1) | bitmask(b2))
+#define l_setbit(x,b)		setbits(x, bitmask(b))
+#define resetbit(x,b)		resetbits(x, bitmask(b))
+#define testbit(x,b)		testbits(x, bitmask(b))
+
+
+/* Layout for bit use in `marked' field: */
+#define WHITE0BIT	0  /* object is white (type 0) */
+#define WHITE1BIT	1  /* object is white (type 1) */
+#define BLACKBIT	2  /* object is black */
+#define FINALIZEDBIT	3  /* object has been separated for finalization */
+#define SEPARATED	4  /* object is in 'finobj' list or in 'tobefnz' */
+#define FIXEDBIT	5  /* object is fixed (should not be collected) */
+#define OLDBIT		6  /* object is old (only in generational mode) */
+/* bit 7 is currently used by tests (luaL_checkmemory) */
+
+#define WHITEBITS	bit2mask(WHITE0BIT, WHITE1BIT)
+
+
+#define iswhite(x)      testbits((x)->gch.marked, WHITEBITS)
+#define isblack(x)      testbit((x)->gch.marked, BLACKBIT)
+#define isgray(x)  /* neither white nor black */  \
+	(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
+
+#define isold(x)	testbit((x)->gch.marked, OLDBIT)
+
+/* MOVE OLD rule: whenever an object is moved to the beginning of
+   a GC list, its old bit must be cleared */
+#define resetoldbit(o)	resetbit((o)->gch.marked, OLDBIT)
+
+#define otherwhite(g)	(g->currentwhite ^ WHITEBITS)
+#define isdeadm(ow,m)	(!(((m) ^ WHITEBITS) & (ow)))
+#define isdead(g,v)	isdeadm(otherwhite(g), (v)->gch.marked)
+
+#define changewhite(x)	((x)->gch.marked ^= WHITEBITS)
+#define gray2black(x)	l_setbit((x)->gch.marked, BLACKBIT)
+
+#define valiswhite(x)	(iscollectable(x) && iswhite(gcvalue(x)))
+
+#define luaC_white(g)	cast(lu_byte, (g)->currentwhite & WHITEBITS)
+
+
+#define luaC_condGC(L,c) \
+	{if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
+#define luaC_checkGC(L)		luaC_condGC(L, luaC_step(L);)
+
+
+#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
+	luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
+
+#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p)))  \
+	luaC_barrierback_(L,p); }
+
+#define luaC_objbarrier(L,p,o)  \
+	{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
+		luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
+
+#define luaC_objbarrierback(L,p,o)  \
+   { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
+
+#define luaC_barrierproto(L,p,c) \
+   { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
+
+LUAI_FUNC void luaC_freeallobjects (lua_State *L);
+LUAI_FUNC void luaC_step (lua_State *L);
+LUAI_FUNC void luaC_forcestep (lua_State *L);
+LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
+LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
+LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,
+                                 GCObject **list, int offset);
+LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
+LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
+LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);
+LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
+LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);
+LUAI_FUNC void luaC_changemode (lua_State *L, int mode);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/linit.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/linit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/linit.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,69 @@
+/*
+** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $
+** Initialization of libraries for lua.c and other clients
+** See Copyright Notice in lua.h
+*/
+
+
+/*
+** If you embed Lua in your program and need to open the standard
+** libraries, call luaL_openlibs in your program. If you need a
+** different set of libraries, copy this file to your project and edit
+** it to suit your needs.
+*/
+
+
+#define linit_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lualib.h"
+#include "lauxlib.h"
+
+
+/*
+** these libs are loaded by lua.c and are readily available to any Lua
+** program
+*/
+static const luaL_Reg loadedlibs[] = {
+  {"_G", luaopen_base},
+  {LUA_LOADLIBNAME, luaopen_package},
+  {LUA_COLIBNAME, luaopen_coroutine},
+  {LUA_TABLIBNAME, luaopen_table},
+  {LUA_IOLIBNAME, luaopen_io},
+  {LUA_OSLIBNAME, luaopen_os},
+  {LUA_STRLIBNAME, luaopen_string},
+  {LUA_BITLIBNAME, luaopen_bit32},
+#ifndef LUA_NUMBER_INTEGRAL
+  {LUA_MATHLIBNAME, luaopen_math},
+#endif
+  {LUA_DBLIBNAME, luaopen_debug},
+  {NULL, NULL}
+};
+
+
+/*
+** these libs are preloaded and must be required before used
+*/
+static const luaL_Reg preloadedlibs[] = {
+  {NULL, NULL}
+};
+
+
+LUALIB_API void luaL_openlibs (lua_State *L) {
+  const luaL_Reg *lib;
+  /* call open functions from 'loadedlibs' and set results to global table */
+  for (lib = loadedlibs; lib->func; lib++) {
+    luaL_requiref(L, lib->name, lib->func, 1);
+    lua_pop(L, 1);  /* remove lib */
+  }
+  /* add open functions from 'preloadedlibs' into 'package.preload' table */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
+  for (lib = preloadedlibs; lib->func; lib++) {
+    lua_pushcfunction(L, lib->func);
+    lua_setfield(L, -2, lib->name);
+  }
+  lua_pop(L, 1);  /* remove _PRELOAD table */
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/liolib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/liolib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/liolib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,686 @@
+/*
+** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $
+** Standard I/O (and system) library
+** See Copyright Notice in lua.h
+*/
+
+
+/*
+** This definition must come before the inclusion of 'stdio.h'; it
+** should not affect non-POSIX systems
+*/
+#if !defined(_FILE_OFFSET_BITS)
+#define	_LARGEFILE_SOURCE	1
+#define _FILE_OFFSET_BITS	64
+#endif
+
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define liolib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#if !defined(lua_checkmode)
+
+/*
+** Check whether 'mode' matches '[rwa]%+?b?'.
+** Change this macro to accept other modes for 'fopen' besides
+** the standard ones.
+*/
+#define lua_checkmode(mode) \
+	(*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&	\
+	(*mode != '+' || ++mode) &&  /* skip if char is '+' */	\
+	(*mode != 'b' || ++mode) &&  /* skip if char is 'b' */	\
+	(*mode == '\0'))
+
+#endif
+
+/*
+** {======================================================
+** lua_popen spawns a new process connected to the current
+** one through the file streams.
+** =======================================================
+*/
+
+#if !defined(lua_popen)	/* { */
+
+#if defined(LUA_USE_POPEN)	/* { */
+
+#define lua_popen(L,c,m)	((void)L, fflush(NULL), popen(c,m))
+#define lua_pclose(L,file)	((void)L, pclose(file))
+
+#elif defined(LUA_WIN)		/* }{ */
+
+#define lua_popen(L,c,m)		((void)L, _popen(c,m))
+#define lua_pclose(L,file)		((void)L, _pclose(file))
+
+
+#else				/* }{ */
+
+#define lua_popen(L,c,m)		((void)((void)c, m),  \
+		luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
+#define lua_pclose(L,file)		((void)((void)L, file), -1)
+
+
+#endif				/* } */
+
+#endif			/* } */
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** lua_fseek: configuration for longer offsets
+** =======================================================
+*/
+
+#if !defined(lua_fseek)	&& !defined(LUA_ANSI)	/* { */
+
+#if defined(LUA_USE_POSIX)	/* { */
+
+#define l_fseek(f,o,w)		fseeko(f,o,w)
+#define l_ftell(f)		ftello(f)
+#define l_seeknum		off_t
+
+#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
+   && defined(_MSC_VER) && (_MSC_VER >= 1400)	/* }{ */
+/* Windows (but not DDK) and Visual C++ 2005 or higher */
+
+#define l_fseek(f,o,w)		_fseeki64(f,o,w)
+#define l_ftell(f)		_ftelli64(f)
+#define l_seeknum		__int64
+
+#endif	/* } */
+
+#endif			/* } */
+
+
+#if !defined(l_fseek)		/* default definitions */
+#define l_fseek(f,o,w)		fseek(f,o,w)
+#define l_ftell(f)		ftell(f)
+#define l_seeknum		long
+#endif
+
+/* }====================================================== */
+
+
+#define IO_PREFIX	"_IO_"
+#define IO_INPUT	(IO_PREFIX "input")
+#define IO_OUTPUT	(IO_PREFIX "output")
+
+
+typedef luaL_Stream LStream;
+
+
+#define tolstream(L)	((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+
+#define isclosed(p)	((p)->closef == NULL)
+
+
+static int io_type (lua_State *L) {
+  LStream *p;
+  luaL_checkany(L, 1);
+  p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
+  if (p == NULL)
+    lua_pushnil(L);  /* not a file */
+  else if (isclosed(p))
+    lua_pushliteral(L, "closed file");
+  else
+    lua_pushliteral(L, "file");
+  return 1;
+}
+
+
+static int f_tostring (lua_State *L) {
+  LStream *p = tolstream(L);
+  if (isclosed(p))
+    lua_pushliteral(L, "file (closed)");
+  else
+    lua_pushfstring(L, "file (%p)", p->f);
+  return 1;
+}
+
+
+static FILE *tofile (lua_State *L) {
+  LStream *p = tolstream(L);
+  if (isclosed(p))
+    luaL_error(L, "attempt to use a closed file");
+  lua_assert(p->f);
+  return p->f;
+}
+
+
+/*
+** When creating file handles, always creates a `closed' file handle
+** before opening the actual file; so, if there is a memory error, the
+** file is not left opened.
+*/
+static LStream *newprefile (lua_State *L) {
+  LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
+  p->closef = NULL;  /* mark file handle as 'closed' */
+  luaL_setmetatable(L, LUA_FILEHANDLE);
+  return p;
+}
+
+
+static int aux_close (lua_State *L) {
+  LStream *p = tolstream(L);
+  lua_CFunction cf = p->closef;
+  p->closef = NULL;  /* mark stream as closed */
+  return (*cf)(L);  /* close it */
+}
+
+
+static int io_close (lua_State *L) {
+  if (lua_isnone(L, 1))  /* no argument? */
+    lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT);  /* use standard output */
+  tofile(L);  /* make sure argument is an open stream */
+  return aux_close(L);
+}
+
+
+static int f_gc (lua_State *L) {
+  LStream *p = tolstream(L);
+  if (!isclosed(p) && p->f != NULL)
+    aux_close(L);  /* ignore closed and incompletely open files */
+  return 0;
+}
+
+
+/*
+** function to close regular files
+*/
+static int io_fclose (lua_State *L) {
+  LStream *p = tolstream(L);
+  int res = fclose(p->f);
+  return luaL_fileresult(L, (res == 0), NULL);
+}
+
+
+static LStream *newfile (lua_State *L) {
+  LStream *p = newprefile(L);
+  p->f = NULL;
+  p->closef = &io_fclose;
+  return p;
+}
+
+
+static void opencheck (lua_State *L, const char *fname, const char *mode) {
+  LStream *p = newfile(L);
+  p->f = fopen(fname, mode);
+  if (p->f == NULL)
+    luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
+}
+
+
+static int io_open (lua_State *L) {
+  const char *filename = luaL_checkstring(L, 1);
+  const char *mode = luaL_optstring(L, 2, "r");
+  LStream *p = newfile(L);
+  const char *md = mode;  /* to traverse/check mode */
+  luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
+  p->f = fopen(filename, mode);
+  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+}
+
+
+/*
+** function to close 'popen' files
+*/
+static int io_pclose (lua_State *L) {
+  LStream *p = tolstream(L);
+  return luaL_execresult(L, lua_pclose(L, p->f));
+}
+
+
+static int io_popen (lua_State *L) {
+  const char *filename = luaL_checkstring(L, 1);
+  const char *mode = luaL_optstring(L, 2, "r");
+  LStream *p = newprefile(L);
+  p->f = lua_popen(L, filename, mode);
+  p->closef = &io_pclose;
+  return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
+}
+
+
+#ifndef SYSLINUX
+static int io_tmpfile (lua_State *L) {
+  LStream *p = newfile(L);
+  p->f = tmpfile();
+  return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
+}
+#endif
+
+
+static FILE *getiofile (lua_State *L, const char *findex) {
+  LStream *p;
+  lua_getfield(L, LUA_REGISTRYINDEX, findex);
+  p = (LStream *)lua_touserdata(L, -1);
+  if (isclosed(p))
+    luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
+  return p->f;
+}
+
+
+static int g_iofile (lua_State *L, const char *f, const char *mode) {
+  if (!lua_isnoneornil(L, 1)) {
+    const char *filename = lua_tostring(L, 1);
+    if (filename)
+      opencheck(L, filename, mode);
+    else {
+      tofile(L);  /* check that it's a valid file handle */
+      lua_pushvalue(L, 1);
+    }
+    lua_setfield(L, LUA_REGISTRYINDEX, f);
+  }
+  /* return current value */
+  lua_getfield(L, LUA_REGISTRYINDEX, f);
+  return 1;
+}
+
+
+static int io_input (lua_State *L) {
+  return g_iofile(L, IO_INPUT, "r");
+}
+
+
+static int io_output (lua_State *L) {
+  return g_iofile(L, IO_OUTPUT, "w");
+}
+
+
+static int io_readline (lua_State *L);
+
+
+static void aux_lines (lua_State *L, int toclose) {
+  int i;
+  int n = lua_gettop(L) - 1;  /* number of arguments to read */
+  /* ensure that arguments will fit here and into 'io_readline' stack */
+  luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options");
+  lua_pushvalue(L, 1);  /* file handle */
+  lua_pushinteger(L, n);  /* number of arguments to read */
+  lua_pushboolean(L, toclose);  /* close/not close file when finished */
+  for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1);  /* copy arguments */
+  lua_pushcclosure(L, io_readline, 3 + n);
+}
+
+
+static int f_lines (lua_State *L) {
+  tofile(L);  /* check that it's a valid file handle */
+  aux_lines(L, 0);
+  return 1;
+}
+
+
+static int io_lines (lua_State *L) {
+  int toclose;
+  if (lua_isnone(L, 1)) lua_pushnil(L);  /* at least one argument */
+  if (lua_isnil(L, 1)) {  /* no file name? */
+    lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT);  /* get default input */
+    lua_replace(L, 1);  /* put it at index 1 */
+    tofile(L);  /* check that it's a valid file handle */
+    toclose = 0;  /* do not close it after iteration */
+  }
+  else {  /* open a new file */
+    const char *filename = luaL_checkstring(L, 1);
+    opencheck(L, filename, "r");
+    lua_replace(L, 1);  /* put file at index 1 */
+    toclose = 1;  /* close it after iteration */
+  }
+  aux_lines(L, toclose);
+  return 1;
+}
+
+
+/*
+** {======================================================
+** READ
+** =======================================================
+*/
+
+
+#ifndef SYSLINUX
+static int read_number (lua_State *L, FILE *f) {
+  lua_Number d;
+  if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
+    lua_pushnumber(L, d);
+    return 1;
+  }
+  else {
+   lua_pushnil(L);  /* "result" to be removed */
+   return 0;  /* read fails */
+  }
+}
+
+
+static int test_eof (lua_State *L, FILE *f) {
+  int c = getc(f);
+  ungetc(c, f);
+  lua_pushlstring(L, NULL, 0);
+  return (c != EOF);
+}
+#else
+static int test_eof (lua_State *L, FILE *f) {
+  (void)f;
+  lua_pushlstring(L, NULL, 0);
+  return 1;
+}
+#endif
+
+
+static int read_line (lua_State *L, FILE *f, int chop) {
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  for (;;) {
+    size_t l;
+    char *p = luaL_prepbuffer(&b);
+    if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) {  /* eof? */
+      luaL_pushresult(&b);  /* close buffer */
+      return (lua_rawlen(L, -1) > 0);  /* check whether read something */
+    }
+    l = strlen(p);
+    if (l == 0 || p[l-1] != '\n')
+      luaL_addsize(&b, l);
+    else {
+      luaL_addsize(&b, l - chop);  /* chop 'eol' if needed */
+      luaL_pushresult(&b);  /* close buffer */
+      return 1;  /* read at least an `eol' */
+    }
+  }
+}
+
+
+#define MAX_SIZE_T	(~(size_t)0)
+
+static void read_all (lua_State *L, FILE *f) {
+  size_t rlen = LUAL_BUFFERSIZE;  /* how much to read in each cycle */
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  for (;;) {
+    char *p = luaL_prepbuffsize(&b, rlen);
+    size_t nr = fread(p, sizeof(char), rlen, f);
+    luaL_addsize(&b, nr);
+    if (nr < rlen) break;  /* eof? */
+    else if (rlen <= (MAX_SIZE_T / 4))  /* avoid buffers too large */
+      rlen *= 2;  /* double buffer size at each iteration */
+  }
+  luaL_pushresult(&b);  /* close buffer */
+}
+
+
+static int read_chars (lua_State *L, FILE *f, size_t n) {
+  size_t nr;  /* number of chars actually read */
+  char *p;
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  p = luaL_prepbuffsize(&b, n);  /* prepare buffer to read whole block */
+  nr = fread(p, sizeof(char), n, f);  /* try to read 'n' chars */
+  luaL_addsize(&b, nr);
+  luaL_pushresult(&b);  /* close buffer */
+  return (nr > 0);  /* true iff read something */
+}
+
+
+static int g_read (lua_State *L, FILE *f, int first) {
+  int nargs = lua_gettop(L) - 1;
+  int success;
+  int n;
+  clearerr(f);
+  if (nargs == 0) {  /* no arguments? */
+    success = read_line(L, f, 1);
+    n = first+1;  /* to return 1 result */
+  }
+  else {  /* ensure stack space for all results and for auxlib's buffer */
+    luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
+    success = 1;
+    for (n = first; nargs-- && success; n++) {
+      if (lua_type(L, n) == LUA_TNUMBER) {
+        size_t l = (size_t)lua_tointeger(L, n);
+        success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
+      }
+      else {
+        const char *p = lua_tostring(L, n);
+        luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
+        switch (p[1]) {
+          case 'n':  /* number */
+#ifndef SYSLINUX
+            success = read_number(L, f);
+#else
+            return luaL_argerror(L, n, "\"*number\" not supported");
+#endif
+            break;
+          case 'l':  /* line */
+            success = read_line(L, f, 1);
+            break;
+          case 'L':  /* line with end-of-line */
+            success = read_line(L, f, 0);
+            break;
+          case 'a':  /* file */
+            read_all(L, f);  /* read entire file */
+            success = 1; /* always success */
+            break;
+          default:
+            return luaL_argerror(L, n, "invalid format");
+        }
+      }
+    }
+  }
+  if (ferror(f))
+    return luaL_fileresult(L, 0, NULL);
+  if (!success) {
+    lua_pop(L, 1);  /* remove last result */
+    lua_pushnil(L);  /* push nil instead */
+  }
+  return n - first;
+}
+
+
+static int io_read (lua_State *L) {
+  return g_read(L, getiofile(L, IO_INPUT), 1);
+}
+
+
+static int f_read (lua_State *L) {
+  return g_read(L, tofile(L), 2);
+}
+
+
+static int io_readline (lua_State *L) {
+  LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
+  int i;
+  int n = (int)lua_tointeger(L, lua_upvalueindex(2));
+  if (isclosed(p))  /* file is already closed? */
+    return luaL_error(L, "file is already closed");
+  lua_settop(L , 1);
+  for (i = 1; i <= n; i++)  /* push arguments to 'g_read' */
+    lua_pushvalue(L, lua_upvalueindex(3 + i));
+  n = g_read(L, p->f, 2);  /* 'n' is number of results */
+  lua_assert(n > 0);  /* should return at least a nil */
+  if (!lua_isnil(L, -n))  /* read at least one value? */
+    return n;  /* return them */
+  else {  /* first result is nil: EOF or error */
+    if (n > 1) {  /* is there error information? */
+      /* 2nd result is error message */
+      return luaL_error(L, "%s", lua_tostring(L, -n + 1));
+    }
+    if (lua_toboolean(L, lua_upvalueindex(3))) {  /* generator created file? */
+      lua_settop(L, 0);
+      lua_pushvalue(L, lua_upvalueindex(1));
+      aux_close(L);  /* close it */
+    }
+    return 0;
+  }
+}
+
+/* }====================================================== */
+
+
+static int g_write (lua_State *L, FILE *f, int arg) {
+  int nargs = lua_gettop(L) - arg;
+  int status = 1;
+  for (; nargs--; arg++) {
+    if (lua_type(L, arg) == LUA_TNUMBER) {
+      /* optimization: could be done exactly as for strings */
+      status = status &&
+          fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+    }
+    else {
+      size_t l;
+      const char *s = luaL_checklstring(L, arg, &l);
+      status = status && (fwrite(s, sizeof(char), l, f) == l);
+    }
+  }
+  if (status) return 1;  /* file handle already on stack top */
+  else return luaL_fileresult(L, status, NULL);
+}
+
+
+static int io_write (lua_State *L) {
+  return g_write(L, getiofile(L, IO_OUTPUT), 1);
+}
+
+
+static int f_write (lua_State *L) {
+  FILE *f = tofile(L);
+  lua_pushvalue(L, 1);  /* push file at the stack top (to be returned) */
+  return g_write(L, f, 2);
+}
+
+
+#ifndef SYSLINUX
+static int f_seek (lua_State *L) {
+  static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+  static const char *const modenames[] = {"set", "cur", "end", NULL};
+  FILE *f = tofile(L);
+  int op = luaL_checkoption(L, 2, "cur", modenames);
+  lua_Number p3 = luaL_optnumber(L, 3, 0);
+  l_seeknum offset = (l_seeknum)p3;
+  luaL_argcheck(L, (lua_Number)offset == p3, 3,
+                  "not an integer in proper range");
+  op = l_fseek(f, offset, mode[op]);
+  if (op)
+    return luaL_fileresult(L, 0, NULL);  /* error */
+  else {
+    lua_pushnumber(L, (lua_Number)l_ftell(f));
+    return 1;
+  }
+}
+
+
+static int f_setvbuf (lua_State *L) {
+  static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
+  static const char *const modenames[] = {"no", "full", "line", NULL};
+  FILE *f = tofile(L);
+  int op = luaL_checkoption(L, 2, NULL, modenames);
+  lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
+  int res = setvbuf(f, NULL, mode[op], sz);
+  return luaL_fileresult(L, res == 0, NULL);
+}
+#endif
+
+
+
+static int io_flush (lua_State *L) {
+  return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+}
+
+
+static int f_flush (lua_State *L) {
+  return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
+}
+
+
+/*
+** functions for 'io' library
+*/
+static const luaL_Reg iolib[] = {
+  {"close", io_close},
+  {"flush", io_flush},
+  {"input", io_input},
+  {"lines", io_lines},
+  {"open", io_open},
+  {"output", io_output},
+  {"popen", io_popen},
+  {"read", io_read},
+#ifndef SYSLINUX
+  {"tmpfile", io_tmpfile},
+#endif
+  {"type", io_type},
+  {"write", io_write},
+  {NULL, NULL}
+};
+
+
+/*
+** methods for file handles
+*/
+static const luaL_Reg flib[] = {
+  {"close", io_close},
+  {"flush", f_flush},
+  {"lines", f_lines},
+  {"read", f_read},
+#ifndef SYSLINUX
+  {"seek", f_seek},
+  {"setvbuf", f_setvbuf},
+#endif
+  {"write", f_write},
+  {"__gc", f_gc},
+  {"__tostring", f_tostring},
+  {NULL, NULL}
+};
+
+
+static void createmeta (lua_State *L) {
+  luaL_newmetatable(L, LUA_FILEHANDLE);  /* create metatable for file handles */
+  lua_pushvalue(L, -1);  /* push metatable */
+  lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
+  luaL_setfuncs(L, flib, 0);  /* add file methods to new metatable */
+  lua_pop(L, 1);  /* pop new metatable */
+}
+
+
+/*
+** function to (not) close the standard files stdin, stdout, and stderr
+*/
+static int io_noclose (lua_State *L) {
+  LStream *p = tolstream(L);
+  p->closef = &io_noclose;  /* keep file opened */
+  lua_pushnil(L);
+  lua_pushliteral(L, "cannot close standard file");
+  return 2;
+}
+
+
+static void createstdfile (lua_State *L, FILE *f, const char *k,
+                           const char *fname) {
+  LStream *p = newprefile(L);
+  p->f = f;
+  p->closef = &io_noclose;
+  if (k != NULL) {
+    lua_pushvalue(L, -1);
+    lua_setfield(L, LUA_REGISTRYINDEX, k);  /* add file to registry */
+  }
+  lua_setfield(L, -2, fname);  /* add file to module */
+}
+
+
+LUAMOD_API int luaopen_io (lua_State *L) {
+  luaL_newlib(L, iolib);  /* new module */
+  createmeta(L);
+  /* create (and set) default files */
+  createstdfile(L, stdin, IO_INPUT, "stdin");
+  createstdfile(L, stdout, IO_OUTPUT, "stdout");
+  createstdfile(L, stderr, NULL, "stderr");
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,534 @@
+/*
+** $Id: llex.c,v 2.63.1.2 2013/08/30 15:49:41 roberto Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef SYSLINUX
+#include <locale.h>
+#else
+#define getlocaledecpoint() '.'
+#endif
+#include <string.h>
+
+#define llex_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lctype.h"
+#include "ldo.h"
+#include "llex.h"
+#include "lobject.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lzio.h"
+
+
+
+#define next(ls) (ls->current = zgetc(ls->z))
+
+
+
+#define currIsNewline(ls)	(ls->current == '\n' || ls->current == '\r')
+
+
+/* ORDER RESERVED */
+static const char *const luaX_tokens [] = {
+    "and", "break", "do", "else", "elseif",
+    "end", "false", "for", "function", "goto", "if",
+    "in", "local", "nil", "not", "or", "repeat",
+    "return", "then", "true", "until", "while",
+    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
+    "<number>", "<name>", "<string>"
+};
+
+
+#define save_and_next(ls) (save(ls, ls->current), next(ls))
+
+
+static l_noret lexerror (LexState *ls, const char *msg, int token);
+
+
+static void save (LexState *ls, int c) {
+  Mbuffer *b = ls->buff;
+  if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
+    size_t newsize;
+    if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
+      lexerror(ls, "lexical element too long", 0);
+    newsize = luaZ_sizebuffer(b) * 2;
+    luaZ_resizebuffer(ls->L, b, newsize);
+  }
+  b->buffer[luaZ_bufflen(b)++] = cast(char, c);
+}
+
+
+void luaX_init (lua_State *L) {
+  int i;
+  for (i=0; i<NUM_RESERVED; i++) {
+    TString *ts = luaS_new(L, luaX_tokens[i]);
+    luaS_fix(ts);  /* reserved words are never collected */
+    ts->tsv.extra = cast_byte(i+1);  /* reserved word */
+  }
+}
+
+
+const char *luaX_token2str (LexState *ls, int token) {
+  if (token < FIRST_RESERVED) {  /* single-byte symbols? */
+    lua_assert(token == cast(unsigned char, token));
+    return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
+                              luaO_pushfstring(ls->L, "char(%d)", token);
+  }
+  else {
+    const char *s = luaX_tokens[token - FIRST_RESERVED];
+    if (token < TK_EOS)  /* fixed format (symbols and reserved words)? */
+      return luaO_pushfstring(ls->L, LUA_QS, s);
+    else  /* names, strings, and numerals */
+      return s;
+  }
+}
+
+
+static const char *txtToken (LexState *ls, int token) {
+  switch (token) {
+    case TK_NAME:
+    case TK_STRING:
+    case TK_NUMBER:
+      save(ls, '\0');
+      return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
+    default:
+      return luaX_token2str(ls, token);
+  }
+}
+
+
+static l_noret lexerror (LexState *ls, const char *msg, int token) {
+  char buff[LUA_IDSIZE];
+  luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
+  msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
+  if (token)
+    luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
+  luaD_throw(ls->L, LUA_ERRSYNTAX);
+}
+
+
+l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
+  lexerror(ls, msg, ls->t.token);
+}
+
+
+/*
+** creates a new string and anchors it in function's table so that
+** it will not be collected until the end of the function's compilation
+** (by that time it should be anchored in function's prototype)
+*/
+TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
+  lua_State *L = ls->L;
+  TValue *o;  /* entry for `str' */
+  TString *ts = luaS_newlstr(L, str, l);  /* create new string */
+  setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
+  o = luaH_set(L, ls->fs->h, L->top - 1);
+  if (ttisnil(o)) {  /* not in use yet? (see 'addK') */
+    /* boolean value does not need GC barrier;
+       table has no metatable, so it does not need to invalidate cache */
+    setbvalue(o, 1);  /* t[string] = true */
+    luaC_checkGC(L);
+  }
+  else {  /* string already present */
+    ts = rawtsvalue(keyfromval(o));  /* re-use value previously stored */
+  }
+  L->top--;  /* remove string from stack */
+  return ts;
+}
+
+
+/*
+** increment line number and skips newline sequence (any of
+** \n, \r, \n\r, or \r\n)
+*/
+static void inclinenumber (LexState *ls) {
+  int old = ls->current;
+  lua_assert(currIsNewline(ls));
+  next(ls);  /* skip `\n' or `\r' */
+  if (currIsNewline(ls) && ls->current != old)
+    next(ls);  /* skip `\n\r' or `\r\n' */
+  if (++ls->linenumber >= MAX_INT)
+    luaX_syntaxerror(ls, "chunk has too many lines");
+}
+
+
+void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
+                    int firstchar) {
+  ls->decpoint = '.';
+  ls->L = L;
+  ls->current = firstchar;
+  ls->lookahead.token = TK_EOS;  /* no look-ahead token */
+  ls->z = z;
+  ls->fs = NULL;
+  ls->linenumber = 1;
+  ls->lastline = 1;
+  ls->source = source;
+  ls->envn = luaS_new(L, LUA_ENV);  /* create env name */
+  luaS_fix(ls->envn);  /* never collect this name */
+  luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
+}
+
+
+
+/*
+** =======================================================
+** LEXICAL ANALYZER
+** =======================================================
+*/
+
+
+
+static int check_next (LexState *ls, const char *set) {
+  if (ls->current == '\0' || !strchr(set, ls->current))
+    return 0;
+  save_and_next(ls);
+  return 1;
+}
+
+
+/*
+** change all characters 'from' in buffer to 'to'
+*/
+static void buffreplace (LexState *ls, char from, char to) {
+  size_t n = luaZ_bufflen(ls->buff);
+  char *p = luaZ_buffer(ls->buff);
+  while (n--)
+    if (p[n] == from) p[n] = to;
+}
+
+
+#if !defined(getlocaledecpoint)
+#define getlocaledecpoint()	(localeconv()->decimal_point[0])
+#endif
+
+
+#define buff2d(b,e)	luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
+
+/*
+** in case of format error, try to change decimal point separator to
+** the one defined in the current locale and check again
+*/
+static void trydecpoint (LexState *ls, SemInfo *seminfo) {
+  char old = ls->decpoint;
+  ls->decpoint = getlocaledecpoint();
+  buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
+  if (!buff2d(ls->buff, &seminfo->r)) {
+    /* format error with correct decimal point: no more options */
+    buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
+    lexerror(ls, "malformed number", TK_NUMBER);
+  }
+}
+
+
+/* LUA_NUMBER */
+/*
+** this function is quite liberal in what it accepts, as 'luaO_str2d'
+** will reject ill-formed numerals.
+*/
+static void read_numeral (LexState *ls, SemInfo *seminfo) {
+  const char *expo = "Ee";
+  int first = ls->current;
+  lua_assert(lisdigit(ls->current));
+  save_and_next(ls);
+  if (first == '0' && check_next(ls, "Xx"))  /* hexadecimal? */
+    expo = "Pp";
+  for (;;) {
+    if (check_next(ls, expo))  /* exponent part? */
+      check_next(ls, "+-");  /* optional exponent sign */
+    if (lisxdigit(ls->current) || ls->current == '.')
+      save_and_next(ls);
+    else  break;
+  }
+  save(ls, '\0');
+  buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
+  if (!buff2d(ls->buff, &seminfo->r))  /* format error? */
+    trydecpoint(ls, seminfo); /* try to update decimal point separator */
+}
+
+
+/*
+** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
+** -1 if sequence is malformed
+*/
+static int skip_sep (LexState *ls) {
+  int count = 0;
+  int s = ls->current;
+  lua_assert(s == '[' || s == ']');
+  save_and_next(ls);
+  while (ls->current == '=') {
+    save_and_next(ls);
+    count++;
+  }
+  return (ls->current == s) ? count : (-count) - 1;
+}
+
+
+static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
+  save_and_next(ls);  /* skip 2nd `[' */
+  if (currIsNewline(ls))  /* string starts with a newline? */
+    inclinenumber(ls);  /* skip it */
+  for (;;) {
+    switch (ls->current) {
+      case EOZ:
+        lexerror(ls, (seminfo) ? "unfinished long string" :
+                                 "unfinished long comment", TK_EOS);
+        break;  /* to avoid warnings */
+      case ']': {
+        if (skip_sep(ls) == sep) {
+          save_and_next(ls);  /* skip 2nd `]' */
+          goto endloop;
+        }
+        break;
+      }
+      case '\n': case '\r': {
+        save(ls, '\n');
+        inclinenumber(ls);
+        if (!seminfo) luaZ_resetbuffer(ls->buff);  /* avoid wasting space */
+        break;
+      }
+      default: {
+        if (seminfo) save_and_next(ls);
+        else next(ls);
+      }
+    }
+  } endloop:
+  if (seminfo)
+    seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
+                                     luaZ_bufflen(ls->buff) - 2*(2 + sep));
+}
+
+
+static void escerror (LexState *ls, int *c, int n, const char *msg) {
+  int i;
+  luaZ_resetbuffer(ls->buff);  /* prepare error message */
+  save(ls, '\\');
+  for (i = 0; i < n && c[i] != EOZ; i++)
+    save(ls, c[i]);
+  lexerror(ls, msg, TK_STRING);
+}
+
+
+static int readhexaesc (LexState *ls) {
+  int c[3], i;  /* keep input for error message */
+  int r = 0;  /* result accumulator */
+  c[0] = 'x';  /* for error message */
+  for (i = 1; i < 3; i++) {  /* read two hexadecimal digits */
+    c[i] = next(ls);
+    if (!lisxdigit(c[i]))
+      escerror(ls, c, i + 1, "hexadecimal digit expected");
+    r = (r << 4) + luaO_hexavalue(c[i]);
+  }
+  return r;
+}
+
+
+static int readdecesc (LexState *ls) {
+  int c[3], i;
+  int r = 0;  /* result accumulator */
+  for (i = 0; i < 3 && lisdigit(ls->current); i++) {  /* read up to 3 digits */
+    c[i] = ls->current;
+    r = 10*r + c[i] - '0';
+    next(ls);
+  }
+  if (r > UCHAR_MAX)
+    escerror(ls, c, i, "decimal escape too large");
+  return r;
+}
+
+
+static void read_string (LexState *ls, int del, SemInfo *seminfo) {
+  save_and_next(ls);  /* keep delimiter (for error messages) */
+  while (ls->current != del) {
+    switch (ls->current) {
+      case EOZ:
+        lexerror(ls, "unfinished string", TK_EOS);
+        break;  /* to avoid warnings */
+      case '\n':
+      case '\r':
+        lexerror(ls, "unfinished string", TK_STRING);
+        break;  /* to avoid warnings */
+      case '\\': {  /* escape sequences */
+        int c;  /* final character to be saved */
+        next(ls);  /* do not save the `\' */
+        switch (ls->current) {
+          case 'a': c = '\a'; goto read_save;
+          case 'b': c = '\b'; goto read_save;
+          case 'f': c = '\f'; goto read_save;
+          case 'n': c = '\n'; goto read_save;
+          case 'r': c = '\r'; goto read_save;
+          case 't': c = '\t'; goto read_save;
+          case 'v': c = '\v'; goto read_save;
+          case 'x': c = readhexaesc(ls); goto read_save;
+          case '\n': case '\r':
+            inclinenumber(ls); c = '\n'; goto only_save;
+          case '\\': case '\"': case '\'':
+            c = ls->current; goto read_save;
+          case EOZ: goto no_save;  /* will raise an error next loop */
+          case 'z': {  /* zap following span of spaces */
+            next(ls);  /* skip the 'z' */
+            while (lisspace(ls->current)) {
+              if (currIsNewline(ls)) inclinenumber(ls);
+              else next(ls);
+            }
+            goto no_save;
+          }
+          default: {
+            if (!lisdigit(ls->current))
+              escerror(ls, &ls->current, 1, "invalid escape sequence");
+            /* digital escape \ddd */
+            c = readdecesc(ls);
+            goto only_save;
+          }
+        }
+       read_save: next(ls);  /* read next character */
+       only_save: save(ls, c);  /* save 'c' */
+       no_save: break;
+      }
+      default:
+        save_and_next(ls);
+    }
+  }
+  save_and_next(ls);  /* skip delimiter */
+  seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
+                                   luaZ_bufflen(ls->buff) - 2);
+}
+
+
+static int llex (LexState *ls, SemInfo *seminfo) {
+  luaZ_resetbuffer(ls->buff);
+  for (;;) {
+    switch (ls->current) {
+      case '\n': case '\r': {  /* line breaks */
+        inclinenumber(ls);
+        break;
+      }
+      case ' ': case '\f': case '\t': case '\v': {  /* spaces */
+        next(ls);
+        break;
+      }
+      case '-': {  /* '-' or '--' (comment) */
+        next(ls);
+        if (ls->current != '-') return '-';
+        /* else is a comment */
+        next(ls);
+        if (ls->current == '[') {  /* long comment? */
+          int sep = skip_sep(ls);
+          luaZ_resetbuffer(ls->buff);  /* `skip_sep' may dirty the buffer */
+          if (sep >= 0) {
+            read_long_string(ls, NULL, sep);  /* skip long comment */
+            luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
+            break;
+          }
+        }
+        /* else short comment */
+        while (!currIsNewline(ls) && ls->current != EOZ)
+          next(ls);  /* skip until end of line (or end of file) */
+        break;
+      }
+      case '[': {  /* long string or simply '[' */
+        int sep = skip_sep(ls);
+        if (sep >= 0) {
+          read_long_string(ls, seminfo, sep);
+          return TK_STRING;
+        }
+        else if (sep == -1) return '[';
+        else lexerror(ls, "invalid long string delimiter", TK_STRING);
+      }
+      case '=': {
+        next(ls);
+        if (ls->current != '=') return '=';
+        else { next(ls); return TK_EQ; }
+      }
+      case '<': {
+        next(ls);
+        if (ls->current != '=') return '<';
+        else { next(ls); return TK_LE; }
+      }
+      case '>': {
+        next(ls);
+        if (ls->current != '=') return '>';
+        else { next(ls); return TK_GE; }
+      }
+      case '~': {
+        next(ls);
+        if (ls->current != '=') return '~';
+        else { next(ls); return TK_NE; }
+      }
+      case ':': {
+        next(ls);
+        if (ls->current != ':') return ':';
+        else { next(ls); return TK_DBCOLON; }
+      }
+      case '"': case '\'': {  /* short literal strings */
+        read_string(ls, ls->current, seminfo);
+        return TK_STRING;
+      }
+      case '.': {  /* '.', '..', '...', or number */
+        save_and_next(ls);
+        if (check_next(ls, ".")) {
+          if (check_next(ls, "."))
+            return TK_DOTS;   /* '...' */
+          else return TK_CONCAT;   /* '..' */
+        }
+        else if (!lisdigit(ls->current)) return '.';
+        /* else go through */
+      }
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9': {
+        read_numeral(ls, seminfo);
+        return TK_NUMBER;
+      }
+      case EOZ: {
+        return TK_EOS;
+      }
+      default: {
+        if (lislalpha(ls->current)) {  /* identifier or reserved word? */
+          TString *ts;
+          do {
+            save_and_next(ls);
+          } while (lislalnum(ls->current));
+          ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
+                                  luaZ_bufflen(ls->buff));
+          seminfo->ts = ts;
+          if (isreserved(ts))  /* reserved word? */
+            return ts->tsv.extra - 1 + FIRST_RESERVED;
+          else {
+            return TK_NAME;
+          }
+        }
+        else {  /* single-char tokens (+ - / ...) */
+          int c = ls->current;
+          next(ls);
+          return c;
+        }
+      }
+    }
+  }
+}
+
+
+void luaX_next (LexState *ls) {
+  ls->lastline = ls->linenumber;
+  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
+    ls->t = ls->lookahead;  /* use this one */
+    ls->lookahead.token = TK_EOS;  /* and discharge it */
+  }
+  else
+    ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
+}
+
+
+int luaX_lookahead (LexState *ls) {
+  lua_assert(ls->lookahead.token == TK_EOS);
+  ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
+  return ls->lookahead.token;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/llex.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,78 @@
+/*
+** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llex_h
+#define llex_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+
+#define FIRST_RESERVED	257
+
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER RESERVED"
+*/
+enum RESERVED {
+  /* terminal symbols denoted by reserved words */
+  TK_AND = FIRST_RESERVED, TK_BREAK,
+  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+  TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+  TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+  /* other terminal symbols */
+  TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
+  TK_NUMBER, TK_NAME, TK_STRING
+};
+
+/* number of reserved words */
+#define NUM_RESERVED	(cast(int, TK_WHILE-FIRST_RESERVED+1))
+
+
+typedef union {
+  lua_Number r;
+  TString *ts;
+} SemInfo;  /* semantics information */
+
+
+typedef struct Token {
+  int token;
+  SemInfo seminfo;
+} Token;
+
+
+/* state of the lexer plus state of the parser when shared by all
+   functions */
+typedef struct LexState {
+  int current;  /* current character (charint) */
+  int linenumber;  /* input line counter */
+  int lastline;  /* line of last token `consumed' */
+  Token t;  /* current token */
+  Token lookahead;  /* look ahead token */
+  struct FuncState *fs;  /* current function (parser) */
+  struct lua_State *L;
+  ZIO *z;  /* input stream */
+  Mbuffer *buff;  /* buffer for tokens */
+  struct Dyndata *dyd;  /* dynamic structures used by the parser */
+  TString *source;  /* current source name */
+  TString *envn;  /* environment variable name */
+  char decpoint;  /* locale decimal point */
+} LexState;
+
+
+LUAI_FUNC void luaX_init (lua_State *L);
+LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
+                              TString *source, int firstchar);
+LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
+LUAI_FUNC void luaX_next (LexState *ls);
+LUAI_FUNC int luaX_lookahead (LexState *ls);
+LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
+LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/llimits.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/llimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/llimits.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,309 @@
+/*
+** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $
+** Limits, basic types, and some other `installation-dependent' definitions
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llimits_h
+#define llimits_h
+
+
+#include <limits.h>
+#include <stddef.h>
+
+
+#include "lua.h"
+
+
+typedef unsigned LUA_INT32 lu_int32;
+
+typedef LUAI_UMEM lu_mem;
+
+typedef LUAI_MEM l_mem;
+
+
+
+/* chars used as small naturals (so that `char' is reserved for characters) */
+typedef unsigned char lu_byte;
+
+
+#define MAX_SIZET	((size_t)(~(size_t)0)-2)
+
+#define MAX_LUMEM	((lu_mem)(~(lu_mem)0)-2)
+
+#define MAX_LMEM	((l_mem) ((MAX_LUMEM >> 1) - 2))
+
+
+#define MAX_INT (INT_MAX-2)  /* maximum value of an int (-2 for safety) */
+
+/*
+** conversion of pointer to integer
+** this is for hashing only; there is no problem if the integer
+** cannot hold the whole pointer value
+*/
+#define IntPoint(p)  ((unsigned int)(lu_mem)(p))
+
+
+
+/* type to ensure maximum alignment */
+#if !defined(LUAI_USER_ALIGNMENT_T)
+#define LUAI_USER_ALIGNMENT_T	union { double u; void *s; long l; }
+#endif
+
+typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
+
+
+/* result of a `usual argument conversion' over lua_Number */
+typedef LUAI_UACNUMBER l_uacNumber;
+
+
+/* internal assertions for in-house debugging */
+#if defined(lua_assert)
+#define check_exp(c,e)		(lua_assert(c), (e))
+/* to avoid problems with conditions too long */
+#define lua_longassert(c)	{ if (!(c)) lua_assert(0); }
+#else
+#define lua_assert(c)		((void)0)
+#define check_exp(c,e)		(e)
+#define lua_longassert(c)	((void)0)
+#endif
+
+/*
+** assertion for checking API calls
+*/
+#if !defined(luai_apicheck)
+
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(L,e)	assert(e)
+#else
+#define luai_apicheck(L,e)	lua_assert(e)
+#endif
+
+#endif
+
+#define api_check(l,e,msg)	luai_apicheck(l,(e) && msg)
+
+
+#if !defined(UNUSED)
+#define UNUSED(x)	((void)(x))	/* to avoid warnings */
+#endif
+
+
+#define cast(t, exp)	((t)(exp))
+
+#define cast_byte(i)	cast(lu_byte, (i))
+#define cast_num(i)	cast(lua_Number, (i))
+#define cast_int(i)	cast(int, (i))
+#define cast_uchar(i)	cast(unsigned char, (i))
+
+
+/*
+** non-return type
+*/
+#if defined(__GNUC__)
+#define l_noret		void __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define l_noret		void __declspec(noreturn)
+#else
+#define l_noret		void
+#endif
+
+
+
+/*
+** maximum depth for nested C calls and syntactical nested non-terminals
+** in a program. (Value must fit in an unsigned short int.)
+*/
+#if !defined(LUAI_MAXCCALLS)
+#define LUAI_MAXCCALLS		200
+#endif
+
+/*
+** maximum number of upvalues in a closure (both C and Lua). (Value
+** must fit in an unsigned char.)
+*/
+#define MAXUPVAL	UCHAR_MAX
+
+
+/*
+** type for virtual-machine instructions
+** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+*/
+typedef lu_int32 Instruction;
+
+
+
+/* maximum stack for a Lua function */
+#define MAXSTACK	250
+
+
+
+/* minimum size for the string table (must be power of 2) */
+#if !defined(MINSTRTABSIZE)
+#define MINSTRTABSIZE	32
+#endif
+
+
+/* minimum size for string buffer */
+#if !defined(LUA_MINBUFFER)
+#define LUA_MINBUFFER	32
+#endif
+
+
+#if !defined(lua_lock)
+#define lua_lock(L)     ((void) 0)
+#define lua_unlock(L)   ((void) 0)
+#endif
+
+#if !defined(luai_threadyield)
+#define luai_threadyield(L)     {lua_unlock(L); lua_lock(L);}
+#endif
+
+
+/*
+** these macros allow user-specific actions on threads when you defined
+** LUAI_EXTRASPACE and need to do something extra when a thread is
+** created/deleted/resumed/yielded.
+*/
+#if !defined(luai_userstateopen)
+#define luai_userstateopen(L)		((void)L)
+#endif
+
+#if !defined(luai_userstateclose)
+#define luai_userstateclose(L)		((void)L)
+#endif
+
+#if !defined(luai_userstatethread)
+#define luai_userstatethread(L,L1)	((void)L)
+#endif
+
+#if !defined(luai_userstatefree)
+#define luai_userstatefree(L,L1)	((void)L)
+#endif
+
+#if !defined(luai_userstateresume)
+#define luai_userstateresume(L,n)       ((void)L)
+#endif
+
+#if !defined(luai_userstateyield)
+#define luai_userstateyield(L,n)        ((void)L)
+#endif
+
+/*
+** lua_number2int is a macro to convert lua_Number to int.
+** lua_number2integer is a macro to convert lua_Number to lua_Integer.
+** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
+** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
+** luai_hashnum is a macro to hash a lua_Number value into an integer.
+** The hash must be deterministic and give reasonable values for
+** both small and large values (outside the range of integers).
+*/
+
+#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK)	/* { */
+/* trick with Microsoft assembler for X86 */
+
+#define lua_number2int(i,n)  __asm {__asm fld n   __asm fistp i}
+#define lua_number2integer(i,n)		lua_number2int(i, n)
+#define lua_number2unsigned(i,n)  \
+  {__int64 l; __asm {__asm fld n   __asm fistp l} i = (unsigned int)l;}
+
+
+#elif defined(LUA_IEEE754TRICK)		/* }{ */
+/* the next trick should work on any machine using IEEE754 with
+   a 32-bit int type */
+
+union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
+
+#if !defined(LUA_IEEEENDIAN)	/* { */
+#define LUAI_EXTRAIEEE	\
+  static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
+#define LUA_IEEEENDIANLOC	(ieeeendian.l_p[1] == 33)
+#else
+#define LUA_IEEEENDIANLOC	LUA_IEEEENDIAN
+#define LUAI_EXTRAIEEE		/* empty */
+#endif				/* } */
+
+#define lua_number2int32(i,n,t) \
+  { LUAI_EXTRAIEEE \
+    volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
+    (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
+
+#define luai_hashnum(i,n)  \
+  { volatile union luai_Cast u; u.l_d = (n) + 1.0;  /* avoid -0 */ \
+    (i) = u.l_p[0]; (i) += u.l_p[1]; }  /* add double bits for his hash */
+
+#define lua_number2int(i,n)		lua_number2int32(i, n, int)
+#define lua_number2unsigned(i,n)	lua_number2int32(i, n, lua_Unsigned)
+
+/* the trick can be expanded to lua_Integer when it is a 32-bit value */
+#if defined(LUA_IEEELL)
+#define lua_number2integer(i,n)		lua_number2int32(i, n, lua_Integer)
+#endif
+
+#endif				/* } */
+
+
+/* the following definitions always work, but may be slow */
+
+#if !defined(lua_number2int)
+#define lua_number2int(i,n)	((i)=(int)(n))
+#endif
+
+#if !defined(lua_number2integer)
+#define lua_number2integer(i,n)	((i)=(lua_Integer)(n))
+#endif
+
+#if !defined(lua_number2unsigned)	/* { */
+/* the following definition assures proper modulo behavior */
+#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
+#include <math.h>
+#define SUPUNSIGNED	((lua_Number)(~(lua_Unsigned)0) + 1)
+#define lua_number2unsigned(i,n)  \
+	((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
+#else
+#define lua_number2unsigned(i,n)	((i)=(lua_Unsigned)(n))
+#endif
+#endif				/* } */
+
+
+#if !defined(lua_unsigned2number)
+/* on several machines, coercion from unsigned to double is slow,
+   so it may be worth to avoid */
+#define lua_unsigned2number(u)  \
+    (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
+#endif
+
+
+
+#if defined(ltable_c) && !defined(luai_hashnum)
+
+#include <float.h>
+#include <math.h>
+
+#define luai_hashnum(i,n) { int e;  \
+  n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP);  \
+  lua_number2int(i, n); i += e; }
+
+#endif
+
+
+
+/*
+** macro to control inclusion of some hard tests on stack reallocation
+*/
+#if !defined(HARDSTACKTESTS)
+#define condmovestack(L)	((void)0)
+#else
+/* realloc stack keeping its size */
+#define condmovestack(L)	luaD_reallocstack((L), (L)->stacksize)
+#endif
+
+#if !defined(HARDMEMTESTS)
+#define condchangemem(L)	condmovestack(L)
+#else
+#define condchangemem(L)  \
+	((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1)))
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lmathlib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lmathlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lmathlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,281 @@
+/*
+** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 roberto Exp $
+** Standard mathematical library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+#include <math.h>
+
+#define lmathlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#undef PI
+#define PI	((lua_Number)(3.1415926535897932384626433832795))
+#define RADIANS_PER_DEGREE	((lua_Number)(PI/180.0))
+
+
+
+static int math_abs (lua_State *L) {
+  lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_sin (lua_State *L) {
+  lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_sinh (lua_State *L) {
+  lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_cos (lua_State *L) {
+  lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_cosh (lua_State *L) {
+  lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_tan (lua_State *L) {
+  lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_tanh (lua_State *L) {
+  lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_asin (lua_State *L) {
+  lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_acos (lua_State *L) {
+  lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_atan (lua_State *L) {
+  lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_atan2 (lua_State *L) {
+  lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1),
+                                luaL_checknumber(L, 2)));
+  return 1;
+}
+
+static int math_ceil (lua_State *L) {
+  lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_floor (lua_State *L) {
+  lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_fmod (lua_State *L) {
+  lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
+                               luaL_checknumber(L, 2)));
+  return 1;
+}
+
+static int math_modf (lua_State *L) {
+  lua_Number ip;
+  lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
+  lua_pushnumber(L, ip);
+  lua_pushnumber(L, fp);
+  return 2;
+}
+
+static int math_sqrt (lua_State *L) {
+  lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_pow (lua_State *L) {
+  lua_Number x = luaL_checknumber(L, 1);
+  lua_Number y = luaL_checknumber(L, 2);
+  lua_pushnumber(L, l_mathop(pow)(x, y));
+  return 1;
+}
+
+static int math_log (lua_State *L) {
+  lua_Number x = luaL_checknumber(L, 1);
+  lua_Number res;
+  if (lua_isnoneornil(L, 2))
+    res = l_mathop(log)(x);
+  else {
+    lua_Number base = luaL_checknumber(L, 2);
+    if (base == (lua_Number)10.0) res = l_mathop(log10)(x);
+    else res = l_mathop(log)(x)/l_mathop(log)(base);
+  }
+  lua_pushnumber(L, res);
+  return 1;
+}
+
+#if defined(LUA_COMPAT_LOG10)
+static int math_log10 (lua_State *L) {
+  lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
+  return 1;
+}
+#endif
+
+static int math_exp (lua_State *L) {
+  lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
+  return 1;
+}
+
+static int math_deg (lua_State *L) {
+  lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
+  return 1;
+}
+
+static int math_rad (lua_State *L) {
+  lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
+  return 1;
+}
+
+static int math_frexp (lua_State *L) {
+  int e;
+  lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
+  lua_pushinteger(L, e);
+  return 2;
+}
+
+static int math_ldexp (lua_State *L) {
+  lua_Number x = luaL_checknumber(L, 1);
+  int ep = luaL_checkint(L, 2);
+  lua_pushnumber(L, l_mathop(ldexp)(x, ep));
+  return 1;
+}
+
+
+
+static int math_min (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  lua_Number dmin = luaL_checknumber(L, 1);
+  int i;
+  for (i=2; i<=n; i++) {
+    lua_Number d = luaL_checknumber(L, i);
+    if (d < dmin)
+      dmin = d;
+  }
+  lua_pushnumber(L, dmin);
+  return 1;
+}
+
+
+static int math_max (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  lua_Number dmax = luaL_checknumber(L, 1);
+  int i;
+  for (i=2; i<=n; i++) {
+    lua_Number d = luaL_checknumber(L, i);
+    if (d > dmax)
+      dmax = d;
+  }
+  lua_pushnumber(L, dmax);
+  return 1;
+}
+
+
+static int math_random (lua_State *L) {
+  /* the `%' avoids the (rare) case of r==1, and is needed also because on
+     some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
+  lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+  switch (lua_gettop(L)) {  /* check number of arguments */
+    case 0: {  /* no arguments */
+      lua_pushnumber(L, r);  /* Number between 0 and 1 */
+      break;
+    }
+    case 1: {  /* only upper limit */
+      lua_Number u = luaL_checknumber(L, 1);
+      luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
+      lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0));  /* [1, u] */
+      break;
+    }
+    case 2: {  /* lower and upper limits */
+      lua_Number l = luaL_checknumber(L, 1);
+      lua_Number u = luaL_checknumber(L, 2);
+      luaL_argcheck(L, l <= u, 2, "interval is empty");
+      lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l);  /* [l, u] */
+      break;
+    }
+    default: return luaL_error(L, "wrong number of arguments");
+  }
+  return 1;
+}
+
+
+static int math_randomseed (lua_State *L) {
+  srand(luaL_checkunsigned(L, 1));
+  (void)rand(); /* discard first value to avoid undesirable correlations */
+  return 0;
+}
+
+
+static const luaL_Reg mathlib[] = {
+  {"abs",   math_abs},
+  {"acos",  math_acos},
+  {"asin",  math_asin},
+  {"atan2", math_atan2},
+  {"atan",  math_atan},
+  {"ceil",  math_ceil},
+  {"cosh",   math_cosh},
+  {"cos",   math_cos},
+  {"deg",   math_deg},
+  {"exp",   math_exp},
+  {"floor", math_floor},
+  {"fmod",   math_fmod},
+  {"frexp", math_frexp},
+  {"ldexp", math_ldexp},
+#if defined(LUA_COMPAT_LOG10)
+  {"log10", math_log10},
+#endif
+  {"log",   math_log},
+  {"max",   math_max},
+  {"min",   math_min},
+  {"modf",   math_modf},
+  {"pow",   math_pow},
+  {"rad",   math_rad},
+  {"random",     math_random},
+  {"randomseed", math_randomseed},
+  {"sinh",   math_sinh},
+  {"sin",   math_sin},
+  {"sqrt",  math_sqrt},
+  {"tanh",   math_tanh},
+  {"tan",   math_tan},
+  {NULL, NULL}
+};
+
+
+/*
+** Open math library
+*/
+LUAMOD_API int luaopen_math (lua_State *L) {
+  luaL_newlib(L, mathlib);
+  lua_pushnumber(L, PI);
+  lua_setfield(L, -2, "pi");
+#ifndef LUA_NUMBER_INTEGRAL
+  lua_pushnumber(L, HUGE_VAL);
+  lua_setfield(L, -2, "huge");
+#endif
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,99 @@
+/*
+** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define lmem_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+/*
+** About the realloc function:
+** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
+** (`osize' is the old size, `nsize' is the new size)
+**
+** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
+** matter 'x').
+**
+** * frealloc(ud, p, x, 0) frees the block `p'
+** (in this specific case, frealloc must return NULL);
+** particularly, frealloc(ud, NULL, 0, 0) does nothing
+** (which is equivalent to free(NULL) in ANSI C)
+**
+** frealloc returns NULL if it cannot create or reallocate the area
+** (any reallocation to an equal or smaller size cannot fail!)
+*/
+
+
+
+#define MINSIZEARRAY	4
+
+
+void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
+                     int limit, const char *what) {
+  void *newblock;
+  int newsize;
+  if (*size >= limit/2) {  /* cannot double it? */
+    if (*size >= limit)  /* cannot grow even a little? */
+      luaG_runerror(L, "too many %s (limit is %d)", what, limit);
+    newsize = limit;  /* still have at least one free place */
+  }
+  else {
+    newsize = (*size)*2;
+    if (newsize < MINSIZEARRAY)
+      newsize = MINSIZEARRAY;  /* minimum size */
+  }
+  newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
+  *size = newsize;  /* update only when everything else is OK */
+  return newblock;
+}
+
+
+l_noret luaM_toobig (lua_State *L) {
+  luaG_runerror(L, "memory allocation error: block too big");
+}
+
+
+
+/*
+** generic allocation routine.
+*/
+void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
+  void *newblock;
+  global_State *g = G(L);
+  size_t realosize = (block) ? osize : 0;
+  lua_assert((realosize == 0) == (block == NULL));
+#if defined(HARDMEMTESTS)
+  if (nsize > realosize && g->gcrunning)
+    luaC_fullgc(L, 1);  /* force a GC whenever possible */
+#endif
+  newblock = (*g->frealloc)(g->ud, block, osize, nsize);
+  if (newblock == NULL && nsize > 0) {
+    api_check(L, nsize > realosize,
+                 "realloc cannot fail when shrinking a block");
+    if (g->gcrunning) {
+      luaC_fullgc(L, 1);  /* try to free some memory... */
+      newblock = (*g->frealloc)(g->ud, block, osize, nsize);  /* try again */
+    }
+    if (newblock == NULL)
+      luaD_throw(L, LUA_ERRMEM);
+  }
+  lua_assert((nsize == 0) == (newblock == NULL));
+  g->GCdebt = (g->GCdebt + nsize) - realosize;
+  return newblock;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lmem.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/*
+** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lmem_h
+#define lmem_h
+
+
+#include <stddef.h>
+
+#include "llimits.h"
+#include "lua.h"
+
+
+/*
+** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
+** always constant.
+** The macro is somewhat complex to avoid warnings:
+** +1 avoids warnings of "comparison has constant result";
+** cast to 'void' avoids warnings of "value unused".
+*/
+#define luaM_reallocv(L,b,on,n,e) \
+  (cast(void, \
+     (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
+   luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
+
+#define luaM_freemem(L, b, s)	luaM_realloc_(L, (b), (s), 0)
+#define luaM_free(L, b)		luaM_realloc_(L, (b), sizeof(*(b)), 0)
+#define luaM_freearray(L, b, n)   luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
+
+#define luaM_malloc(L,s)	luaM_realloc_(L, NULL, 0, (s))
+#define luaM_new(L,t)		cast(t *, luaM_malloc(L, sizeof(t)))
+#define luaM_newvector(L,n,t) \
+		cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
+
+#define luaM_newobject(L,tag,s)	luaM_realloc_(L, NULL, tag, (s))
+
+#define luaM_growvector(L,v,nelems,size,t,limit,e) \
+          if ((nelems)+1 > (size)) \
+            ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
+
+#define luaM_reallocvector(L, v,oldn,n,t) \
+   ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
+
+LUAI_FUNC l_noret luaM_toobig (lua_State *L);
+
+/* not to be called directly */
+LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
+                                                          size_t size);
+LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
+                               size_t size_elem, int limit,
+                               const char *what);
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/loadlib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/loadlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/loadlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,802 @@
+/*
+** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $
+** Dynamic library loader for Lua
+** See Copyright Notice in lua.h
+**
+** This module contains an implementation of loadlib for Unix systems
+** that have dlfcn, an implementation for Windows, and a stub for other
+** systems.
+*/
+
+
+/*
+** if needed, includes windows header before everything else
+*/
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+/* Base the Lua paths on the Syslinux path */
+#ifdef SYSLINUX
+#include <fs.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define loadlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/*
+** LUA_PATH and LUA_CPATH are the names of the environment
+** variables that Lua check to set its paths.
+*/
+#if !defined(LUA_PATH)
+#define LUA_PATH	"LUA_PATH"
+#endif
+
+#if !defined(LUA_CPATH)
+#define LUA_CPATH	"LUA_CPATH"
+#endif
+
+#define LUA_PATHSUFFIX		"_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
+
+#define LUA_PATHVERSION		LUA_PATH LUA_PATHSUFFIX
+#define LUA_CPATHVERSION	LUA_CPATH LUA_PATHSUFFIX
+
+/*
+** LUA_PATH_SEP is the character that separates templates in a path.
+** LUA_PATH_MARK is the string that marks the substitution points in a
+** template.
+** LUA_EXEC_DIR in a Windows path is replaced by the executable's
+** directory.
+** LUA_IGMARK is a mark to ignore all before it when building the
+** luaopen_ function name.
+*/
+#if !defined (LUA_PATH_SEP)
+#define LUA_PATH_SEP		";"
+#endif
+#if !defined (LUA_PATH_MARK)
+#define LUA_PATH_MARK		"?"
+#endif
+#if !defined (LUA_EXEC_DIR)
+#define LUA_EXEC_DIR		"!"
+#endif
+#if !defined (LUA_IGMARK)
+#define LUA_IGMARK		"-"
+#endif
+
+
+/*
+** LUA_CSUBSEP is the character that replaces dots in submodule names
+** when searching for a C loader.
+** LUA_LSUBSEP is the character that replaces dots in submodule names
+** when searching for a Lua loader.
+*/
+#if !defined(LUA_CSUBSEP)
+#define LUA_CSUBSEP		LUA_DIRSEP
+#endif
+
+#if !defined(LUA_LSUBSEP)
+#define LUA_LSUBSEP		LUA_DIRSEP
+#endif
+
+
+/* prefix for open functions in C libraries */
+#define LUA_POF		"luaopen_"
+
+/* separator for open functions in C libraries */
+#define LUA_OFSEP	"_"
+
+
+/* table (in the registry) that keeps handles for all loaded C libraries */
+#define CLIBS		"_CLIBS"
+
+#define LIB_FAIL	"open"
+
+
+/* error codes for ll_loadfunc */
+#define ERRLIB		1
+#define ERRFUNC		2
+
+#define setprogdir(L)		((void)0)
+
+
+/*
+** system-dependent functions
+*/
+static void ll_unloadlib (void *lib);
+static void *ll_load (lua_State *L, const char *path, int seeglb);
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
+
+
+
+#if defined(LUA_USE_DLOPEN)
+/*
+** {========================================================================
+** This is an implementation of loadlib based on the dlfcn interface.
+** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+** NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
+** as an emulation layer on top of native functions.
+** =========================================================================
+*/
+
+#include <dlfcn.h>
+
+static void ll_unloadlib (void *lib) {
+  dlclose(lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path, int seeglb) {
+  void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
+  if (lib == NULL) lua_pushstring(L, dlerror());
+  return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
+  if (f == NULL) lua_pushstring(L, dlerror());
+  return f;
+}
+
+/* }====================================================== */
+
+
+
+#elif defined(LUA_DL_DLL)
+/*
+** {======================================================================
+** This is an implementation of loadlib for Windows using native functions.
+** =======================================================================
+*/
+
+#undef setprogdir
+
+/*
+** optional flags for LoadLibraryEx
+*/
+#if !defined(LUA_LLE_FLAGS)
+#define LUA_LLE_FLAGS	0
+#endif
+
+
+static void setprogdir (lua_State *L) {
+  char buff[MAX_PATH + 1];
+  char *lb;
+  DWORD nsize = sizeof(buff)/sizeof(char);
+  DWORD n = GetModuleFileNameA(NULL, buff, nsize);
+  if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
+    luaL_error(L, "unable to get ModuleFileName");
+  else {
+    *lb = '\0';
+    luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
+    lua_remove(L, -2);  /* remove original string */
+  }
+}
+
+
+static void pusherror (lua_State *L) {
+  int error = GetLastError();
+  char buffer[128];
+  if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
+      NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
+    lua_pushstring(L, buffer);
+  else
+    lua_pushfstring(L, "system error %d\n", error);
+}
+
+static void ll_unloadlib (void *lib) {
+  FreeLibrary((HMODULE)lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path, int seeglb) {
+  HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
+  (void)(seeglb);  /* not used: symbols are 'global' by default */
+  if (lib == NULL) pusherror(L);
+  return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
+  if (f == NULL) pusherror(L);
+  return f;
+}
+
+/* }====================================================== */
+
+
+#elif defined(SYSLINUX)
+/*
+** {=========================================================================
+** This is an implementation of loadlib for the Syslinux COM32 module system.
+** ==========================================================================
+*/
+
+#include <sys/module.h>
+
+static void ll_unloadlib (void *lib) {
+  module_unload ((struct elf_module *)lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path, int seeglb) {
+  int err;
+  struct elf_module *lib = module_alloc (path);
+  if (lib == NULL) {
+    lua_pushstring (L, "module not found");
+    return NULL;
+  }
+  (void)seeglb; /* gcc, ignore it */
+  err = module_load (lib);
+  if (err) {
+    printf ("module load error: %d\n", err);
+    lua_pushstring (L, "failed to load module");
+    return NULL;
+  }
+  return (void *)lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  Elf_Sym *p = module_find_symbol (sym, (struct elf_module *)lib);
+  if (p == NULL) {
+    lua_pushstring (L, "symbol not found in module");
+    return NULL;
+  }
+  return (lua_CFunction)module_get_absolute(p->st_value, (struct elf_module *)lib);
+}
+
+/* }====================================================== */
+
+
+
+#else
+/*
+** {======================================================
+** Fallback for other systems
+** =======================================================
+*/
+
+#undef LIB_FAIL
+#define LIB_FAIL	"absent"
+
+
+#define DLMSG	"dynamic libraries not enabled; check your Lua installation"
+
+
+static void ll_unloadlib (void *lib) {
+  (void)(lib);  /* not used */
+}
+
+
+static void *ll_load (lua_State *L, const char *path, int seeglb) {
+  (void)(path); (void)(seeglb);  /* not used */
+  lua_pushliteral(L, DLMSG);
+  return NULL;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  (void)(lib); (void)(sym);  /* not used */
+  lua_pushliteral(L, DLMSG);
+  return NULL;
+}
+
+/* }====================================================== */
+#endif
+
+
+static void *ll_checkclib (lua_State *L, const char *path) {
+  void *plib;
+  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
+  lua_getfield(L, -1, path);
+  plib = lua_touserdata(L, -1);  /* plib = CLIBS[path] */
+  lua_pop(L, 2);  /* pop CLIBS table and 'plib' */
+  return plib;
+}
+
+
+static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
+  lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
+  lua_pushlightuserdata(L, plib);
+  lua_pushvalue(L, -1);
+  lua_setfield(L, -3, path);  /* CLIBS[path] = plib */
+  lua_rawseti(L, -2, luaL_len(L, -2) + 1);  /* CLIBS[#CLIBS + 1] = plib */
+  lua_pop(L, 1);  /* pop CLIBS table */
+}
+
+
+/*
+** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
+** handles in list CLIBS
+*/
+static int gctm (lua_State *L) {
+  int n = luaL_len(L, 1);
+  for (; n >= 1; n--) {  /* for each handle, in reverse order */
+    lua_rawgeti(L, 1, n);  /* get handle CLIBS[n] */
+    ll_unloadlib(lua_touserdata(L, -1));
+    lua_pop(L, 1);  /* pop handle */
+  }
+  return 0;
+}
+
+
+static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
+  void *reg = ll_checkclib(L, path);  /* check loaded C libraries */
+  if (reg == NULL) {  /* must load library? */
+    reg = ll_load(L, path, *sym == '*');
+    if (reg == NULL) return ERRLIB;  /* unable to load library */
+    ll_addtoclib(L, path, reg);
+  }
+  if (*sym == '*') {  /* loading only library (no function)? */
+    lua_pushboolean(L, 1);  /* return 'true' */
+    return 0;  /* no errors */
+  }
+  else {
+    lua_CFunction f = ll_sym(L, reg, sym);
+    if (f == NULL)
+      return ERRFUNC;  /* unable to find function */
+    lua_pushcfunction(L, f);  /* else create new function */
+    return 0;  /* no errors */
+  }
+}
+
+
+static int ll_loadlib (lua_State *L) {
+  const char *path = luaL_checkstring(L, 1);
+  const char *init = luaL_checkstring(L, 2);
+  int stat = ll_loadfunc(L, path, init);
+  if (stat == 0)  /* no errors? */
+    return 1;  /* return the loaded function */
+  else {  /* error; error message is on stack top */
+    lua_pushnil(L);
+    lua_insert(L, -2);
+    lua_pushstring(L, (stat == ERRLIB) ?  LIB_FAIL : "init");
+    return 3;  /* return nil, error message, and where */
+  }
+}
+
+
+
+/*
+** {======================================================
+** 'require' function
+** =======================================================
+*/
+
+
+static int readable (const char *filename) {
+  FILE *f = fopen(filename, "r");  /* try to open file */
+  if (f == NULL) return 0;  /* open failed */
+  fclose(f);
+  return 1;
+}
+
+
+static const char *pushnexttemplate (lua_State *L, const char *path) {
+  const char *l;
+  while (*path == *LUA_PATH_SEP) path++;  /* skip separators */
+  if (*path == '\0') return NULL;  /* no more templates */
+  l = strchr(path, *LUA_PATH_SEP);  /* find next separator */
+  if (l == NULL) l = path + strlen(path);
+  lua_pushlstring(L, path, l - path);  /* template */
+  return l;
+}
+
+
+static const char *searchpath (lua_State *L, const char *name,
+                                             const char *path,
+                                             const char *sep,
+                                             const char *dirsep) {
+  luaL_Buffer msg;  /* to build error message */
+  luaL_buffinit(L, &msg);
+  if (*sep != '\0')  /* non-empty separator? */
+    name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
+  while ((path = pushnexttemplate(L, path)) != NULL) {
+    const char *filename = luaL_gsub(L, lua_tostring(L, -1),
+                                     LUA_PATH_MARK, name);
+    lua_remove(L, -2);  /* remove path template */
+    if (readable(filename))  /* does file exist and is readable? */
+      return filename;  /* return that file name */
+    lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
+    lua_remove(L, -2);  /* remove file name */
+    luaL_addvalue(&msg);  /* concatenate error msg. entry */
+  }
+  luaL_pushresult(&msg);  /* create error message */
+  return NULL;  /* not found */
+}
+
+
+static int ll_searchpath (lua_State *L) {
+  const char *f = searchpath(L, luaL_checkstring(L, 1),
+                                luaL_checkstring(L, 2),
+                                luaL_optstring(L, 3, "."),
+                                luaL_optstring(L, 4, LUA_DIRSEP));
+  if (f != NULL) return 1;
+  else {  /* error message is on top of the stack */
+    lua_pushnil(L);
+    lua_insert(L, -2);
+    return 2;  /* return nil + error message */
+  }
+}
+
+
+static const char *findfile (lua_State *L, const char *name,
+                                           const char *pname,
+                                           const char *dirsep) {
+  const char *path;
+  lua_getfield(L, lua_upvalueindex(1), pname);
+  path = lua_tostring(L, -1);
+  if (path == NULL)
+    luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+  return searchpath(L, name, path, ".", dirsep);
+}
+
+
+static int checkload (lua_State *L, int stat, const char *filename) {
+  if (stat) {  /* module loaded successfully? */
+    lua_pushstring(L, filename);  /* will be 2nd argument to module */
+    return 2;  /* return open function and file name */
+  }
+  else
+    return luaL_error(L, "error loading module " LUA_QS
+                         " from file " LUA_QS ":\n\t%s",
+                          lua_tostring(L, 1), filename, lua_tostring(L, -1));
+}
+
+
+static int searcher_Lua (lua_State *L) {
+  const char *filename;
+  const char *name = luaL_checkstring(L, 1);
+  filename = findfile(L, name, "path", LUA_LSUBSEP);
+  if (filename == NULL) return 1;  /* module not found in this path */
+  return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
+}
+
+
+static int loadfunc (lua_State *L, const char *filename, const char *modname) {
+  const char *funcname;
+  const char *mark;
+  modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
+  mark = strchr(modname, *LUA_IGMARK);
+  if (mark) {
+    int stat;
+    funcname = lua_pushlstring(L, modname, mark - modname);
+    funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
+    stat = ll_loadfunc(L, filename, funcname);
+    if (stat != ERRFUNC) return stat;
+    modname = mark + 1;  /* else go ahead and try old-style name */
+  }
+  funcname = lua_pushfstring(L, LUA_POF"%s", modname);
+  return ll_loadfunc(L, filename, funcname);
+}
+
+
+static int searcher_C (lua_State *L) {
+  const char *name = luaL_checkstring(L, 1);
+  const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
+  if (filename == NULL) return 1;  /* module not found in this path */
+  return checkload(L, (loadfunc(L, filename, name) == 0), filename);
+}
+
+
+static int searcher_Croot (lua_State *L) {
+  const char *filename;
+  const char *name = luaL_checkstring(L, 1);
+  const char *p = strchr(name, '.');
+  int stat;
+  if (p == NULL) return 0;  /* is root */
+  lua_pushlstring(L, name, p - name);
+  filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
+  if (filename == NULL) return 1;  /* root not found */
+  if ((stat = loadfunc(L, filename, name)) != 0) {
+    if (stat != ERRFUNC)
+      return checkload(L, 0, filename);  /* real error */
+    else {  /* open function not found */
+      lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
+                         name, filename);
+      return 1;
+    }
+  }
+  lua_pushstring(L, filename);  /* will be 2nd argument to module */
+  return 2;
+}
+
+
+static int searcher_preload (lua_State *L) {
+  const char *name = luaL_checkstring(L, 1);
+  lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
+  lua_getfield(L, -1, name);
+  if (lua_isnil(L, -1))  /* not found? */
+    lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
+  return 1;
+}
+
+
+static void findloader (lua_State *L, const char *name) {
+  int i;
+  luaL_Buffer msg;  /* to build error message */
+  luaL_buffinit(L, &msg);
+  lua_getfield(L, lua_upvalueindex(1), "searchers");  /* will be at index 3 */
+  if (!lua_istable(L, 3))
+    luaL_error(L, LUA_QL("package.searchers") " must be a table");
+  /*  iterate over available searchers to find a loader */
+  for (i = 1; ; i++) {
+    lua_rawgeti(L, 3, i);  /* get a searcher */
+    if (lua_isnil(L, -1)) {  /* no more searchers? */
+      lua_pop(L, 1);  /* remove nil */
+      luaL_pushresult(&msg);  /* create error message */
+      luaL_error(L, "module " LUA_QS " not found:%s",
+                    name, lua_tostring(L, -1));
+    }
+    lua_pushstring(L, name);
+    lua_call(L, 1, 2);  /* call it */
+    if (lua_isfunction(L, -2))  /* did it find a loader? */
+      return;  /* module loader found */
+    else if (lua_isstring(L, -2)) {  /* searcher returned error message? */
+      lua_pop(L, 1);  /* remove extra return */
+      luaL_addvalue(&msg);  /* concatenate error message */
+    }
+    else
+      lua_pop(L, 2);  /* remove both returns */
+  }
+}
+
+
+static int ll_require (lua_State *L) {
+  const char *name = luaL_checkstring(L, 1);
+  lua_settop(L, 1);  /* _LOADED table will be at index 2 */
+  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_getfield(L, 2, name);  /* _LOADED[name] */
+  if (lua_toboolean(L, -1))  /* is it there? */
+    return 1;  /* package is already loaded */
+  /* else must load package */
+  lua_pop(L, 1);  /* remove 'getfield' result */
+  findloader(L, name);
+  lua_pushstring(L, name);  /* pass name as argument to module loader */
+  lua_insert(L, -2);  /* name is 1st argument (before search data) */
+  lua_call(L, 2, 1);  /* run loader to load module */
+  if (!lua_isnil(L, -1))  /* non-nil return? */
+    lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
+  lua_getfield(L, 2, name);
+  if (lua_isnil(L, -1)) {   /* module did not set a value? */
+    lua_pushboolean(L, 1);  /* use true as result */
+    lua_pushvalue(L, -1);  /* extra copy to be returned */
+    lua_setfield(L, 2, name);  /* _LOADED[name] = true */
+  }
+  return 1;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** 'module' function
+** =======================================================
+*/
+#if defined(LUA_COMPAT_MODULE)
+
+/*
+** changes the environment variable of calling function
+*/
+static void set_env (lua_State *L) {
+  lua_Debug ar;
+  if (lua_getstack(L, 1, &ar) == 0 ||
+      lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
+      lua_iscfunction(L, -1))
+    luaL_error(L, LUA_QL("module") " not called from a Lua function");
+  lua_pushvalue(L, -2);  /* copy new environment table to top */
+  lua_setupvalue(L, -2, 1);
+  lua_pop(L, 1);  /* remove function */
+}
+
+
+static void dooptions (lua_State *L, int n) {
+  int i;
+  for (i = 2; i <= n; i++) {
+    if (lua_isfunction(L, i)) {  /* avoid 'calling' extra info. */
+      lua_pushvalue(L, i);  /* get option (a function) */
+      lua_pushvalue(L, -2);  /* module */
+      lua_call(L, 1, 0);
+    }
+  }
+}
+
+
+static void modinit (lua_State *L, const char *modname) {
+  const char *dot;
+  lua_pushvalue(L, -1);
+  lua_setfield(L, -2, "_M");  /* module._M = module */
+  lua_pushstring(L, modname);
+  lua_setfield(L, -2, "_NAME");
+  dot = strrchr(modname, '.');  /* look for last dot in module name */
+  if (dot == NULL) dot = modname;
+  else dot++;
+  /* set _PACKAGE as package name (full module name minus last part) */
+  lua_pushlstring(L, modname, dot - modname);
+  lua_setfield(L, -2, "_PACKAGE");
+}
+
+
+static int ll_module (lua_State *L) {
+  const char *modname = luaL_checkstring(L, 1);
+  int lastarg = lua_gettop(L);  /* last parameter */
+  luaL_pushmodule(L, modname, 1);  /* get/create module table */
+  /* check whether table already has a _NAME field */
+  lua_getfield(L, -1, "_NAME");
+  if (!lua_isnil(L, -1))  /* is table an initialized module? */
+    lua_pop(L, 1);
+  else {  /* no; initialize it */
+    lua_pop(L, 1);
+    modinit(L, modname);
+  }
+  lua_pushvalue(L, -1);
+  set_env(L);
+  dooptions(L, lastarg);
+  return 1;
+}
+
+
+static int ll_seeall (lua_State *L) {
+  luaL_checktype(L, 1, LUA_TTABLE);
+  if (!lua_getmetatable(L, 1)) {
+    lua_createtable(L, 0, 1); /* create new metatable */
+    lua_pushvalue(L, -1);
+    lua_setmetatable(L, 1);
+  }
+  lua_pushglobaltable(L);
+  lua_setfield(L, -2, "__index");  /* mt.__index = _G */
+  return 0;
+}
+
+#endif
+/* }====================================================== */
+
+
+
+/* auxiliary mark (for internal use) */
+#define AUXMARK		"\1"
+
+
+#ifdef SYSLINUX
+static void setpath (lua_State *L, const char *fieldname, const char *envname1,
+                                   const char *envname2, const char *def) {
+  struct path_entry *entry;
+  luaL_Buffer b;
+  luaL_buffinit (L, &b);
+  (void)envname1;
+  (void)envname2;
+  list_for_each_entry(entry, &PATH, list) {
+    const char *e = entry->str;
+    int need_slash = e[strlen(e)-1] != '/';
+    void add (const char *stem) {
+      luaL_addstring (&b, e);
+      if (need_slash) luaL_addchar (&b, '/');
+      luaL_addstring (&b, stem);
+      luaL_addstring (&b, def);
+      luaL_addchar (&b, ';');
+    }
+    add ("?");
+    add ("?/init");
+  }
+  luaL_addstring (&b, "./?");
+  luaL_addstring (&b, def);
+  luaL_pushresult (&b);
+  lua_setfield(L, -2, fieldname);
+}
+#else
+/*
+** return registry.LUA_NOENV as a boolean
+*/
+static int noenv (lua_State *L) {
+  int b;
+  lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+  b = lua_toboolean(L, -1);
+  lua_pop(L, 1);  /* remove value */
+  return b;
+}
+
+
+static void setpath (lua_State *L, const char *fieldname, const char *envname1,
+                                   const char *envname2, const char *def) {
+  const char *path = getenv(envname1);
+  if (path == NULL)  /* no environment variable? */
+    path = getenv(envname2);  /* try alternative name */
+  if (path == NULL || noenv(L))  /* no environment variable? */
+    lua_pushstring(L, def);  /* use default */
+  else {
+    /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
+    path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
+                              LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
+    luaL_gsub(L, path, AUXMARK, def);
+    lua_remove(L, -2);
+  }
+  setprogdir(L);
+  lua_setfield(L, -2, fieldname);
+}
+#endif
+
+
+static const luaL_Reg pk_funcs[] = {
+  {"loadlib", ll_loadlib},
+  {"searchpath", ll_searchpath},
+#if defined(LUA_COMPAT_MODULE)
+  {"seeall", ll_seeall},
+#endif
+  {NULL, NULL}
+};
+
+
+static const luaL_Reg ll_funcs[] = {
+#if defined(LUA_COMPAT_MODULE)
+  {"module", ll_module},
+#endif
+  {"require", ll_require},
+  {NULL, NULL}
+};
+
+
+static void createsearcherstable (lua_State *L) {
+  static const lua_CFunction searchers[] =
+    {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
+  int i;
+  /* create 'searchers' table */
+  lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
+  /* fill it with pre-defined searchers */
+  for (i=0; searchers[i] != NULL; i++) {
+    lua_pushvalue(L, -2);  /* set 'package' as upvalue for all searchers */
+    lua_pushcclosure(L, searchers[i], 1);
+    lua_rawseti(L, -2, i+1);
+  }
+}
+
+
+LUAMOD_API int luaopen_package (lua_State *L) {
+  /* create table CLIBS to keep track of loaded C libraries */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
+  lua_createtable(L, 0, 1);  /* metatable for CLIBS */
+  lua_pushcfunction(L, gctm);
+  lua_setfield(L, -2, "__gc");  /* set finalizer for CLIBS table */
+  lua_setmetatable(L, -2);
+  /* create `package' table */
+  luaL_newlib(L, pk_funcs);
+  createsearcherstable(L);
+#if defined(LUA_COMPAT_LOADERS)
+  lua_pushvalue(L, -1);  /* make a copy of 'searchers' table */
+  lua_setfield(L, -3, "loaders");  /* put it in field `loaders' */
+#endif
+  lua_setfield(L, -2, "searchers");  /* put it in field 'searchers' */
+  /* set field 'path' */
+  setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
+  /* set field 'cpath' */
+  setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
+  /* store config information */
+  lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
+                     LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
+  lua_setfield(L, -2, "config");
+  /* set field `loaded' */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_setfield(L, -2, "loaded");
+  /* set field `preload' */
+  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
+  lua_setfield(L, -2, "preload");
+  lua_pushglobaltable(L);
+  lua_pushvalue(L, -2);  /* set 'package' as upvalue for next lib */
+  luaL_setfuncs(L, ll_funcs, 1);  /* open lib into global table */
+  lua_pop(L, 1);  /* pop global table */
+  return 1;  /* return 'package' table */
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,287 @@
+/*
+** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
+** Some generic functions over Lua objects
+** See Copyright Notice in lua.h
+*/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lobject_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lctype.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "lvm.h"
+
+
+
+LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
+
+
+/*
+** converts an integer to a "floating point byte", represented as
+** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+** eeeee != 0 and (xxx) otherwise.
+*/
+int luaO_int2fb (unsigned int x) {
+  int e = 0;  /* exponent */
+  if (x < 8) return x;
+  while (x >= 0x10) {
+    x = (x+1) >> 1;
+    e++;
+  }
+  return ((e+1) << 3) | (cast_int(x) - 8);
+}
+
+
+/* converts back */
+int luaO_fb2int (int x) {
+  int e = (x >> 3) & 0x1f;
+  if (e == 0) return x;
+  else return ((x & 7) + 8) << (e - 1);
+}
+
+
+int luaO_ceillog2 (unsigned int x) {
+  static const lu_byte log_2[256] = {
+    0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+  };
+  int l = 0;
+  x--;
+  while (x >= 256) { l += 8; x >>= 8; }
+  return l + log_2[x];
+}
+
+
+lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
+  switch (op) {
+    case LUA_OPADD: return luai_numadd(NULL, v1, v2);
+    case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
+    case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
+    case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
+    case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
+    case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
+    case LUA_OPUNM: return luai_numunm(NULL, v1);
+    default: lua_assert(0); return 0;
+  }
+}
+
+
+int luaO_hexavalue (int c) {
+  if (lisdigit(c)) return c - '0';
+  else return ltolower(c) - 'a' + 10;
+}
+
+
+#if !defined(lua_strx2number)
+
+#include <math.h>
+
+
+static int isneg (const char **s) {
+  if (**s == '-') { (*s)++; return 1; }
+  else if (**s == '+') (*s)++;
+  return 0;
+}
+
+
+static lua_Number readhexa (const char **s, lua_Number r, int *count) {
+  for (; lisxdigit(cast_uchar(**s)); (*s)++) {  /* read integer part */
+    r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
+    (*count)++;
+  }
+  return r;
+}
+
+
+/*
+** convert an hexadecimal numeric string to a number, following
+** C99 specification for 'strtod'
+*/
+static lua_Number lua_strx2number (const char *s, char **endptr) {
+  lua_Number r = 0.0;
+  int e = 0, i = 0;
+  int neg = 0;  /* 1 if number is negative */
+  *endptr = cast(char *, s);  /* nothing is valid yet */
+  while (lisspace(cast_uchar(*s))) s++;  /* skip initial spaces */
+  neg = isneg(&s);  /* check signal */
+  if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
+    return 0.0;  /* invalid format (no '0x') */
+  s += 2;  /* skip '0x' */
+  r = readhexa(&s, r, &i);  /* read integer part */
+  if (*s == '.') {
+    s++;  /* skip dot */
+    r = readhexa(&s, r, &e);  /* read fractional part */
+  }
+  if (i == 0 && e == 0)
+    return 0.0;  /* invalid format (no digit) */
+  e *= -4;  /* each fractional digit divides value by 2^-4 */
+  *endptr = cast(char *, s);  /* valid up to here */
+  if (*s == 'p' || *s == 'P') {  /* exponent part? */
+    int exp1 = 0;
+    int neg1;
+    s++;  /* skip 'p' */
+    neg1 = isneg(&s);  /* signal */
+    if (!lisdigit(cast_uchar(*s)))
+      goto ret;  /* must have at least one digit */
+    while (lisdigit(cast_uchar(*s)))  /* read exponent */
+      exp1 = exp1 * 10 + *(s++) - '0';
+    if (neg1) exp1 = -exp1;
+    e += exp1;
+  }
+  *endptr = cast(char *, s);  /* valid up to here */
+ ret:
+  if (neg) r = -r;
+  return l_mathop(ldexp)(r, e);
+}
+
+#endif
+
+
+int luaO_str2d (const char *s, size_t len, lua_Number *result) {
+  char *endptr;
+  if (strpbrk(s, "nN"))  /* reject 'inf' and 'nan' */
+    return 0;
+  else if (strpbrk(s, "xX"))  /* hexa? */
+    *result = lua_strx2number(s, &endptr);
+  else
+    *result = lua_str2number(s, &endptr);
+  if (endptr == s) return 0;  /* nothing recognized */
+  while (lisspace(cast_uchar(*endptr))) endptr++;
+  return (endptr == s + len);  /* OK if no trailing characters */
+}
+
+
+
+static void pushstr (lua_State *L, const char *str, size_t l) {
+  setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
+}
+
+
+/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+  int n = 0;
+  for (;;) {
+    const char *e = strchr(fmt, '%');
+    if (e == NULL) break;
+    luaD_checkstack(L, 2);  /* fmt + item */
+    pushstr(L, fmt, e - fmt);
+    switch (*(e+1)) {
+      case 's': {
+        const char *s = va_arg(argp, char *);
+        if (s == NULL) s = "(null)";
+        pushstr(L, s, strlen(s));
+        break;
+      }
+      case 'c': {
+        char buff;
+        buff = cast(char, va_arg(argp, int));
+        pushstr(L, &buff, 1);
+        break;
+      }
+      case 'd': {
+        setnvalue(L->top++, cast_num(va_arg(argp, int)));
+        break;
+      }
+      case 'f': {
+        setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
+        break;
+      }
+      case 'p': {
+        char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
+        int l = sprintf(buff, "%p", va_arg(argp, void *));
+        pushstr(L, buff, l);
+        break;
+      }
+      case '%': {
+        pushstr(L, "%", 1);
+        break;
+      }
+      default: {
+        luaG_runerror(L,
+            "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
+            *(e + 1));
+      }
+    }
+    n += 2;
+    fmt = e+2;
+  }
+  luaD_checkstack(L, 1);
+  pushstr(L, fmt, strlen(fmt));
+  if (n > 0) luaV_concat(L, n + 1);
+  return svalue(L->top - 1);
+}
+
+
+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+  const char *msg;
+  va_list argp;
+  va_start(argp, fmt);
+  msg = luaO_pushvfstring(L, fmt, argp);
+  va_end(argp);
+  return msg;
+}
+
+
+/* number of chars of a literal string without the ending \0 */
+#define LL(x)	(sizeof(x)/sizeof(char) - 1)
+
+#define RETS	"..."
+#define PRE	"[string \""
+#define POS	"\"]"
+
+#define addstr(a,b,l)	( memcpy(a,b,(l) * sizeof(char)), a += (l) )
+
+void luaO_chunkid (char *out, const char *source, size_t bufflen) {
+  size_t l = strlen(source);
+  if (*source == '=') {  /* 'literal' source */
+    if (l <= bufflen)  /* small enough? */
+      memcpy(out, source + 1, l * sizeof(char));
+    else {  /* truncate it */
+      addstr(out, source + 1, bufflen - 1);
+      *out = '\0';
+    }
+  }
+  else if (*source == '@') {  /* file name */
+    if (l <= bufflen)  /* small enough? */
+      memcpy(out, source + 1, l * sizeof(char));
+    else {  /* add '...' before rest of name */
+      addstr(out, RETS, LL(RETS));
+      bufflen -= LL(RETS);
+      memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
+    }
+  }
+  else {  /* string; format as [string "source"] */
+    const char *nl = strchr(source, '\n');  /* find first new line (if any) */
+    addstr(out, PRE, LL(PRE));  /* add prefix */
+    bufflen -= LL(PRE RETS POS) + 1;  /* save space for prefix+suffix+'\0' */
+    if (l < bufflen && nl == NULL) {  /* small one-line source? */
+      addstr(out, source, l);  /* keep it */
+    }
+    else {
+      if (nl != NULL) l = nl - source;  /* stop at first newline */
+      if (l > bufflen) l = bufflen;
+      addstr(out, source, l);
+      addstr(out, RETS, LL(RETS));
+    }
+    memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
+  }
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lobject.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,607 @@
+/*
+** $Id: lobject.h,v 2.71.1.1 2013/04/12 18:48:47 roberto Exp $
+** Type definitions for Lua objects
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lobject_h
+#define lobject_h
+
+
+#include <stdarg.h>
+
+
+#include "llimits.h"
+#include "lua.h"
+
+
+/*
+** Extra tags for non-values
+*/
+#define LUA_TPROTO	LUA_NUMTAGS
+#define LUA_TUPVAL	(LUA_NUMTAGS+1)
+#define LUA_TDEADKEY	(LUA_NUMTAGS+2)
+
+/*
+** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
+*/
+#define LUA_TOTALTAGS	(LUA_TUPVAL+2)
+
+
+/*
+** tags for Tagged Values have the following use of bits:
+** bits 0-3: actual tag (a LUA_T* value)
+** bits 4-5: variant bits
+** bit 6: whether value is collectable
+*/
+
+#define VARBITS		(3 << 4)
+
+
+/*
+** LUA_TFUNCTION variants:
+** 0 - Lua function
+** 1 - light C function
+** 2 - regular C function (closure)
+*/
+
+/* Variant tags for functions */
+#define LUA_TLCL	(LUA_TFUNCTION | (0 << 4))  /* Lua closure */
+#define LUA_TLCF	(LUA_TFUNCTION | (1 << 4))  /* light C function */
+#define LUA_TCCL	(LUA_TFUNCTION | (2 << 4))  /* C closure */
+
+
+/* Variant tags for strings */
+#define LUA_TSHRSTR	(LUA_TSTRING | (0 << 4))  /* short strings */
+#define LUA_TLNGSTR	(LUA_TSTRING | (1 << 4))  /* long strings */
+
+
+/* Bit mark for collectable types */
+#define BIT_ISCOLLECTABLE	(1 << 6)
+
+/* mark a tag as collectable */
+#define ctb(t)			((t) | BIT_ISCOLLECTABLE)
+
+
+/*
+** Union of all collectable objects
+*/
+typedef union GCObject GCObject;
+
+
+/*
+** Common Header for all collectable objects (in macro form, to be
+** included in other objects)
+*/
+#define CommonHeader	GCObject *next; lu_byte tt; lu_byte marked
+
+
+/*
+** Common header in struct form
+*/
+typedef struct GCheader {
+  CommonHeader;
+} GCheader;
+
+
+
+/*
+** Union of all Lua values
+*/
+typedef union Value Value;
+
+
+#define numfield	lua_Number n;    /* numbers */
+
+
+
+/*
+** Tagged Values. This is the basic representation of values in Lua,
+** an actual value plus a tag with its type.
+*/
+
+#define TValuefields	Value value_; int tt_
+
+typedef struct lua_TValue TValue;
+
+
+/* macro defining a nil value */
+#define NILCONSTANT	{NULL}, LUA_TNIL
+
+
+#define val_(o)		((o)->value_)
+#define num_(o)		(val_(o).n)
+
+
+/* raw type tag of a TValue */
+#define rttype(o)	((o)->tt_)
+
+/* tag with no variants (bits 0-3) */
+#define novariant(x)	((x) & 0x0F)
+
+/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
+#define ttype(o)	(rttype(o) & 0x3F)
+
+/* type tag of a TValue with no variants (bits 0-3) */
+#define ttypenv(o)	(novariant(rttype(o)))
+
+
+/* Macros to test type */
+#define checktag(o,t)		(rttype(o) == (t))
+#define checktype(o,t)		(ttypenv(o) == (t))
+#define ttisnumber(o)		checktag((o), LUA_TNUMBER)
+#define ttisnil(o)		checktag((o), LUA_TNIL)
+#define ttisboolean(o)		checktag((o), LUA_TBOOLEAN)
+#define ttislightuserdata(o)	checktag((o), LUA_TLIGHTUSERDATA)
+#define ttisstring(o)		checktype((o), LUA_TSTRING)
+#define ttisshrstring(o)	checktag((o), ctb(LUA_TSHRSTR))
+#define ttislngstring(o)	checktag((o), ctb(LUA_TLNGSTR))
+#define ttistable(o)		checktag((o), ctb(LUA_TTABLE))
+#define ttisfunction(o)		checktype(o, LUA_TFUNCTION)
+#define ttisclosure(o)		((rttype(o) & 0x1F) == LUA_TFUNCTION)
+#define ttisCclosure(o)		checktag((o), ctb(LUA_TCCL))
+#define ttisLclosure(o)		checktag((o), ctb(LUA_TLCL))
+#define ttislcf(o)		checktag((o), LUA_TLCF)
+#define ttisuserdata(o)		checktag((o), ctb(LUA_TUSERDATA))
+#define ttisthread(o)		checktag((o), ctb(LUA_TTHREAD))
+#define ttisdeadkey(o)		checktag((o), LUA_TDEADKEY)
+
+#define ttisequal(o1,o2)	(rttype(o1) == rttype(o2))
+
+/* Macros to access values */
+#define nvalue(o)	check_exp(ttisnumber(o), num_(o))
+#define gcvalue(o)	check_exp(iscollectable(o), val_(o).gc)
+#define pvalue(o)	check_exp(ttislightuserdata(o), val_(o).p)
+#define rawtsvalue(o)	check_exp(ttisstring(o), &val_(o).gc->ts)
+#define tsvalue(o)	(&rawtsvalue(o)->tsv)
+#define rawuvalue(o)	check_exp(ttisuserdata(o), &val_(o).gc->u)
+#define uvalue(o)	(&rawuvalue(o)->uv)
+#define clvalue(o)	check_exp(ttisclosure(o), &val_(o).gc->cl)
+#define clLvalue(o)	check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
+#define clCvalue(o)	check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
+#define fvalue(o)	check_exp(ttislcf(o), val_(o).f)
+#define hvalue(o)	check_exp(ttistable(o), &val_(o).gc->h)
+#define bvalue(o)	check_exp(ttisboolean(o), val_(o).b)
+#define thvalue(o)	check_exp(ttisthread(o), &val_(o).gc->th)
+/* a dead value may get the 'gc' field, but cannot access its contents */
+#define deadvalue(o)	check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
+
+#define l_isfalse(o)	(ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
+
+
+#define iscollectable(o)	(rttype(o) & BIT_ISCOLLECTABLE)
+
+
+/* Macros for internal tests */
+#define righttt(obj)		(ttype(obj) == gcvalue(obj)->gch.tt)
+
+#define checkliveness(g,obj) \
+	lua_longassert(!iscollectable(obj) || \
+			(righttt(obj) && !isdead(g,gcvalue(obj))))
+
+
+/* Macros to set values */
+#define settt_(o,t)	((o)->tt_=(t))
+
+#define setnvalue(obj,x) \
+  { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
+
+#define setnilvalue(obj) settt_(obj, LUA_TNIL)
+
+#define setfvalue(obj,x) \
+  { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
+
+#define setpvalue(obj,x) \
+  { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
+
+#define setbvalue(obj,x) \
+  { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
+
+#define setgcovalue(L,obj,x) \
+  { TValue *io=(obj); GCObject *i_g=(x); \
+    val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); }
+
+#define setsvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    TString *x_ = (x); \
+    val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \
+    checkliveness(G(L),io); }
+
+#define setuvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \
+    checkliveness(G(L),io); }
+
+#define setthvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
+    checkliveness(G(L),io); }
+
+#define setclLvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
+    checkliveness(G(L),io); }
+
+#define setclCvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
+    checkliveness(G(L),io); }
+
+#define sethvalue(L,obj,x) \
+  { TValue *io=(obj); \
+    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
+    checkliveness(G(L),io); }
+
+#define setdeadvalue(obj)	settt_(obj, LUA_TDEADKEY)
+
+
+
+#define setobj(L,obj1,obj2) \
+	{ const TValue *io2=(obj2); TValue *io1=(obj1); \
+	  io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
+	  checkliveness(G(L),io1); }
+
+
+/*
+** different types of assignments, according to destination
+*/
+
+/* from stack to (same) stack */
+#define setobjs2s	setobj
+/* to stack (not from same stack) */
+#define setobj2s	setobj
+#define setsvalue2s	setsvalue
+#define sethvalue2s	sethvalue
+#define setptvalue2s	setptvalue
+/* from table to same table */
+#define setobjt2t	setobj
+/* to table */
+#define setobj2t	setobj
+/* to new object */
+#define setobj2n	setobj
+#define setsvalue2n	setsvalue
+
+
+/* check whether a number is valid (useful only for NaN trick) */
+#define luai_checknum(L,o,c)	{ /* empty */ }
+
+
+/*
+** {======================================================
+** NaN Trick
+** =======================================================
+*/
+#if defined(LUA_NANTRICK)
+
+/*
+** numbers are represented in the 'd_' field. All other values have the
+** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
+** a "signaled NaN", which is never generated by regular operations by
+** the CPU (nor by 'strtod')
+*/
+
+/* allows for external implementation for part of the trick */
+#if !defined(NNMARK)	/* { */
+
+
+#if !defined(LUA_IEEEENDIAN)
+#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN'
+#endif
+
+
+#define NNMARK		0x7FF7A500
+#define NNMASK		0x7FFFFF00
+
+#undef TValuefields
+#undef NILCONSTANT
+
+#if (LUA_IEEEENDIAN == 0)	/* { */
+
+/* little endian */
+#define TValuefields  \
+	union { struct { Value v__; int tt__; } i; double d__; } u
+#define NILCONSTANT	{{{NULL}, tag2tt(LUA_TNIL)}}
+/* field-access macros */
+#define v_(o)		((o)->u.i.v__)
+#define d_(o)		((o)->u.d__)
+#define tt_(o)		((o)->u.i.tt__)
+
+#else				/* }{ */
+
+/* big endian */
+#define TValuefields  \
+	union { struct { int tt__; Value v__; } i; double d__; } u
+#define NILCONSTANT	{{tag2tt(LUA_TNIL), {NULL}}}
+/* field-access macros */
+#define v_(o)		((o)->u.i.v__)
+#define d_(o)		((o)->u.d__)
+#define tt_(o)		((o)->u.i.tt__)
+
+#endif				/* } */
+
+#endif			/* } */
+
+
+/* correspondence with standard representation */
+#undef val_
+#define val_(o)		v_(o)
+#undef num_
+#define num_(o)		d_(o)
+
+
+#undef numfield
+#define numfield	/* no such field; numbers are the entire struct */
+
+/* basic check to distinguish numbers from non-numbers */
+#undef ttisnumber
+#define ttisnumber(o)	((tt_(o) & NNMASK) != NNMARK)
+
+#define tag2tt(t)	(NNMARK | (t))
+
+#undef rttype
+#define rttype(o)	(ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
+
+#undef settt_
+#define settt_(o,t)	(tt_(o) = tag2tt(t))
+
+#undef setnvalue
+#define setnvalue(obj,x) \
+	{ TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); }
+
+#undef setobj
+#define setobj(L,obj1,obj2) \
+	{ const TValue *o2_=(obj2); TValue *o1_=(obj1); \
+	  o1_->u = o2_->u; \
+	  checkliveness(G(L),o1_); }
+
+
+/*
+** these redefinitions are not mandatory, but these forms are more efficient
+*/
+
+#undef checktag
+#undef checktype
+#define checktag(o,t)	(tt_(o) == tag2tt(t))
+#define checktype(o,t)	(ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS))
+
+#undef ttisequal
+#define ttisequal(o1,o2)  \
+	(ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
+
+
+#undef luai_checknum
+#define luai_checknum(L,o,c)	{ if (!ttisnumber(o)) c; }
+
+#endif
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** types and prototypes
+** =======================================================
+*/
+
+
+union Value {
+  GCObject *gc;    /* collectable objects */
+  void *p;         /* light userdata */
+  int b;           /* booleans */
+  lua_CFunction f; /* light C functions */
+  numfield         /* numbers */
+};
+
+
+struct lua_TValue {
+  TValuefields;
+};
+
+
+typedef TValue *StkId;  /* index to stack elements */
+
+
+
+
+/*
+** Header for string value; string bytes follow the end of this structure
+*/
+typedef union TString {
+  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
+  struct {
+    CommonHeader;
+    lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
+    unsigned int hash;
+    size_t len;  /* number of characters in string */
+  } tsv;
+} TString;
+
+
+/* get the actual string (array of bytes) from a TString */
+#define getstr(ts)	cast(const char *, (ts) + 1)
+
+/* get the actual string (array of bytes) from a Lua value */
+#define svalue(o)       getstr(rawtsvalue(o))
+
+
+/*
+** Header for userdata; memory area follows the end of this structure
+*/
+typedef union Udata {
+  L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
+  struct {
+    CommonHeader;
+    struct Table *metatable;
+    struct Table *env;
+    size_t len;  /* number of bytes */
+  } uv;
+} Udata;
+
+
+
+/*
+** Description of an upvalue for function prototypes
+*/
+typedef struct Upvaldesc {
+  TString *name;  /* upvalue name (for debug information) */
+  lu_byte instack;  /* whether it is in stack */
+  lu_byte idx;  /* index of upvalue (in stack or in outer function's list) */
+} Upvaldesc;
+
+
+/*
+** Description of a local variable for function prototypes
+** (used for debug information)
+*/
+typedef struct LocVar {
+  TString *varname;
+  int startpc;  /* first point where variable is active */
+  int endpc;    /* first point where variable is dead */
+} LocVar;
+
+
+/*
+** Function Prototypes
+*/
+typedef struct Proto {
+  CommonHeader;
+  TValue *k;  /* constants used by the function */
+  Instruction *code;
+  struct Proto **p;  /* functions defined inside the function */
+  int *lineinfo;  /* map from opcodes to source lines (debug information) */
+  LocVar *locvars;  /* information about local variables (debug information) */
+  Upvaldesc *upvalues;  /* upvalue information */
+  union Closure *cache;  /* last created closure with this prototype */
+  TString  *source;  /* used for debug information */
+  int sizeupvalues;  /* size of 'upvalues' */
+  int sizek;  /* size of `k' */
+  int sizecode;
+  int sizelineinfo;
+  int sizep;  /* size of `p' */
+  int sizelocvars;
+  int linedefined;
+  int lastlinedefined;
+  GCObject *gclist;
+  lu_byte numparams;  /* number of fixed parameters */
+  lu_byte is_vararg;
+  lu_byte maxstacksize;  /* maximum stack used by this function */
+} Proto;
+
+
+
+/*
+** Lua Upvalues
+*/
+typedef struct UpVal {
+  CommonHeader;
+  TValue *v;  /* points to stack or to its own value */
+  union {
+    TValue value;  /* the value (when closed) */
+    struct {  /* double linked list (when open) */
+      struct UpVal *prev;
+      struct UpVal *next;
+    } l;
+  } u;
+} UpVal;
+
+
+/*
+** Closures
+*/
+
+#define ClosureHeader \
+	CommonHeader; lu_byte nupvalues; GCObject *gclist
+
+typedef struct CClosure {
+  ClosureHeader;
+  lua_CFunction f;
+  TValue upvalue[1];  /* list of upvalues */
+} CClosure;
+
+
+typedef struct LClosure {
+  ClosureHeader;
+  struct Proto *p;
+  UpVal *upvals[1];  /* list of upvalues */
+} LClosure;
+
+
+typedef union Closure {
+  CClosure c;
+  LClosure l;
+} Closure;
+
+
+#define isLfunction(o)	ttisLclosure(o)
+
+#define getproto(o)	(clLvalue(o)->p)
+
+
+/*
+** Tables
+*/
+
+typedef union TKey {
+  struct {
+    TValuefields;
+    struct Node *next;  /* for chaining */
+  } nk;
+  TValue tvk;
+} TKey;
+
+
+typedef struct Node {
+  TValue i_val;
+  TKey i_key;
+} Node;
+
+
+typedef struct Table {
+  CommonHeader;
+  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */
+  lu_byte lsizenode;  /* log2 of size of `node' array */
+  struct Table *metatable;
+  TValue *array;  /* array part */
+  Node *node;
+  Node *lastfree;  /* any free position is before this position */
+  GCObject *gclist;
+  int sizearray;  /* size of `array' array */
+} Table;
+
+
+
+/*
+** `module' operation for hashing (size is always a power of 2)
+*/
+#define lmod(s,size) \
+	(check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
+
+
+#define twoto(x)	(1<<(x))
+#define sizenode(t)	(twoto((t)->lsizenode))
+
+
+/*
+** (address of) a fixed nil value
+*/
+#define luaO_nilobject		(&luaO_nilobject_)
+
+
+LUAI_DDEC const TValue luaO_nilobject_;
+
+
+LUAI_FUNC int luaO_int2fb (unsigned int x);
+LUAI_FUNC int luaO_fb2int (int x);
+LUAI_FUNC int luaO_ceillog2 (unsigned int x);
+LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
+LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
+LUAI_FUNC int luaO_hexavalue (int c);
+LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+                                                       va_list argp);
+LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,107 @@
+/*
+** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $
+** Opcodes for Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+
+#define lopcodes_c
+#define LUA_CORE
+
+
+#include "lopcodes.h"
+
+
+/* ORDER OP */
+
+LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
+  "MOVE",
+  "LOADK",
+  "LOADKX",
+  "LOADBOOL",
+  "LOADNIL",
+  "GETUPVAL",
+  "GETTABUP",
+  "GETTABLE",
+  "SETTABUP",
+  "SETUPVAL",
+  "SETTABLE",
+  "NEWTABLE",
+  "SELF",
+  "ADD",
+  "SUB",
+  "MUL",
+  "DIV",
+  "MOD",
+  "POW",
+  "UNM",
+  "NOT",
+  "LEN",
+  "CONCAT",
+  "JMP",
+  "EQ",
+  "LT",
+  "LE",
+  "TEST",
+  "TESTSET",
+  "CALL",
+  "TAILCALL",
+  "RETURN",
+  "FORLOOP",
+  "FORPREP",
+  "TFORCALL",
+  "TFORLOOP",
+  "SETLIST",
+  "CLOSURE",
+  "VARARG",
+  "EXTRAARG",
+  NULL
+};
+
+
+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
+
+LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
+/*       T  A    B       C     mode		   opcode	*/
+  opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_MOVE */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx)		/* OP_LOADK */
+ ,opmode(0, 1, OpArgN, OpArgN, iABx)		/* OP_LOADKX */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_LOADBOOL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_GETUPVAL */
+ ,opmode(0, 1, OpArgU, OpArgK, iABC)		/* OP_GETTABUP */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_GETTABLE */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABUP */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_SETUPVAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABLE */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_NEWTABLE */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_SELF */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_ADD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_SUB */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MUL */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MOD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_POW */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_UNM */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_LEN */
+ ,opmode(0, 1, OpArgR, OpArgR, iABC)		/* OP_CONCAT */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_JMP */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_EQ */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LT */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LE */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC)		/* OP_TEST */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC)		/* OP_TESTSET */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_CALL */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_TAILCALL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_RETURN */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORLOOP */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORPREP */
+ ,opmode(0, 0, OpArgN, OpArgU, iABC)		/* OP_TFORCALL */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgU, OpArgU, iABC)		/* OP_SETLIST */
+ ,opmode(0, 1, OpArgU, OpArgN, iABx)		/* OP_CLOSURE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_VARARG */
+ ,opmode(0, 0, OpArgU, OpArgU, iAx)		/* OP_EXTRAARG */
+};
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lopcodes.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,288 @@
+/*
+** $Id: lopcodes.h,v 1.142.1.1 2013/04/12 18:48:47 roberto Exp $
+** Opcodes for Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lopcodes_h
+#define lopcodes_h
+
+#include "llimits.h"
+
+
+/*===========================================================================
+  We assume that instructions are unsigned numbers.
+  All instructions have an opcode in the first 6 bits.
+  Instructions can have the following fields:
+	`A' : 8 bits
+	`B' : 9 bits
+	`C' : 9 bits
+	'Ax' : 26 bits ('A', 'B', and 'C' together)
+	`Bx' : 18 bits (`B' and `C' together)
+	`sBx' : signed Bx
+
+  A signed argument is represented in excess K; that is, the number
+  value is the unsigned value minus K. K is exactly the maximum value
+  for that argument (so that -max is represented by 0, and +max is
+  represented by 2*max), which is half the maximum for the corresponding
+  unsigned argument.
+===========================================================================*/
+
+
+enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
+
+
+/*
+** size and position of opcode arguments.
+*/
+#define SIZE_C		9
+#define SIZE_B		9
+#define SIZE_Bx		(SIZE_C + SIZE_B)
+#define SIZE_A		8
+#define SIZE_Ax		(SIZE_C + SIZE_B + SIZE_A)
+
+#define SIZE_OP		6
+
+#define POS_OP		0
+#define POS_A		(POS_OP + SIZE_OP)
+#define POS_C		(POS_A + SIZE_A)
+#define POS_B		(POS_C + SIZE_C)
+#define POS_Bx		POS_C
+#define POS_Ax		POS_A
+
+
+/*
+** limits for opcode arguments.
+** we use (signed) int to manipulate most arguments,
+** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
+*/
+#if SIZE_Bx < LUAI_BITSINT-1
+#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
+#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
+#else
+#define MAXARG_Bx        MAX_INT
+#define MAXARG_sBx        MAX_INT
+#endif
+
+#if SIZE_Ax < LUAI_BITSINT-1
+#define MAXARG_Ax	((1<<SIZE_Ax)-1)
+#else
+#define MAXARG_Ax	MAX_INT
+#endif
+
+
+#define MAXARG_A        ((1<<SIZE_A)-1)
+#define MAXARG_B        ((1<<SIZE_B)-1)
+#define MAXARG_C        ((1<<SIZE_C)-1)
+
+
+/* creates a mask with `n' 1 bits at position `p' */
+#define MASK1(n,p)	((~((~(Instruction)0)<<(n)))<<(p))
+
+/* creates a mask with `n' 0 bits at position `p' */
+#define MASK0(n,p)	(~MASK1(n,p))
+
+/*
+** the following macros help to manipulate instructions
+*/
+
+#define GET_OPCODE(i)	(cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
+#define SET_OPCODE(i,o)	((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
+		((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
+
+#define getarg(i,pos,size)	(cast(int, ((i)>>pos) & MASK1(size,0)))
+#define setarg(i,v,pos,size)	((i) = (((i)&MASK0(size,pos)) | \
+                ((cast(Instruction, v)<<pos)&MASK1(size,pos))))
+
+#define GETARG_A(i)	getarg(i, POS_A, SIZE_A)
+#define SETARG_A(i,v)	setarg(i, v, POS_A, SIZE_A)
+
+#define GETARG_B(i)	getarg(i, POS_B, SIZE_B)
+#define SETARG_B(i,v)	setarg(i, v, POS_B, SIZE_B)
+
+#define GETARG_C(i)	getarg(i, POS_C, SIZE_C)
+#define SETARG_C(i,v)	setarg(i, v, POS_C, SIZE_C)
+
+#define GETARG_Bx(i)	getarg(i, POS_Bx, SIZE_Bx)
+#define SETARG_Bx(i,v)	setarg(i, v, POS_Bx, SIZE_Bx)
+
+#define GETARG_Ax(i)	getarg(i, POS_Ax, SIZE_Ax)
+#define SETARG_Ax(i,v)	setarg(i, v, POS_Ax, SIZE_Ax)
+
+#define GETARG_sBx(i)	(GETARG_Bx(i)-MAXARG_sBx)
+#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+
+
+#define CREATE_ABC(o,a,b,c)	((cast(Instruction, o)<<POS_OP) \
+			| (cast(Instruction, a)<<POS_A) \
+			| (cast(Instruction, b)<<POS_B) \
+			| (cast(Instruction, c)<<POS_C))
+
+#define CREATE_ABx(o,a,bc)	((cast(Instruction, o)<<POS_OP) \
+			| (cast(Instruction, a)<<POS_A) \
+			| (cast(Instruction, bc)<<POS_Bx))
+
+#define CREATE_Ax(o,a)		((cast(Instruction, o)<<POS_OP) \
+			| (cast(Instruction, a)<<POS_Ax))
+
+
+/*
+** Macros to operate RK indices
+*/
+
+/* this bit 1 means constant (0 means register) */
+#define BITRK		(1 << (SIZE_B - 1))
+
+/* test whether value is a constant */
+#define ISK(x)		((x) & BITRK)
+
+/* gets the index of the constant */
+#define INDEXK(r)	((int)(r) & ~BITRK)
+
+#define MAXINDEXRK	(BITRK - 1)
+
+/* code a constant index as a RK value */
+#define RKASK(x)	((x) | BITRK)
+
+
+/*
+** invalid register that fits in 8 bits
+*/
+#define NO_REG		MAXARG_A
+
+
+/*
+** R(x) - register
+** Kst(x) - constant (in constant table)
+** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
+*/
+
+
+/*
+** grep "ORDER OP" if you change these enums
+*/
+
+typedef enum {
+/*----------------------------------------------------------------------
+name		args	description
+------------------------------------------------------------------------*/
+OP_MOVE,/*	A B	R(A) := R(B)					*/
+OP_LOADK,/*	A Bx	R(A) := Kst(Bx)					*/
+OP_LOADKX,/*	A 	R(A) := Kst(extra arg)				*/
+OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
+OP_LOADNIL,/*	A B	R(A), R(A+1), ..., R(A+B) := nil		*/
+OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
+
+OP_GETTABUP,/*	A B C	R(A) := UpValue[B][RK(C)]			*/
+OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
+
+OP_SETTABUP,/*	A B C	UpValue[A][RK(B)] := RK(C)			*/
+OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
+OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
+
+OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
+
+OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
+
+OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
+OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
+OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/
+OP_DIV,/*	A B C	R(A) := RK(B) / RK(C)				*/
+OP_MOD,/*	A B C	R(A) := RK(B) % RK(C)				*/
+OP_POW,/*	A B C	R(A) := RK(B) ^ RK(C)				*/
+OP_UNM,/*	A B	R(A) := -R(B)					*/
+OP_NOT,/*	A B	R(A) := not R(B)				*/
+OP_LEN,/*	A B	R(A) := length of R(B)				*/
+
+OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
+
+OP_JMP,/*	A sBx	pc+=sBx; if (A) close all upvalues >= R(A) + 1	*/
+OP_EQ,/*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
+OP_LT,/*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++		*/
+OP_LE,/*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++		*/
+
+OP_TEST,/*	A C	if not (R(A) <=> C) then pc++			*/
+OP_TESTSET,/*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/
+
+OP_CALL,/*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_TAILCALL,/*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
+OP_RETURN,/*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
+
+OP_FORLOOP,/*	A sBx	R(A)+=R(A+2);
+			if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
+OP_FORPREP,/*	A sBx	R(A)-=R(A+2); pc+=sBx				*/
+
+OP_TFORCALL,/*	A C	R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));	*/
+OP_TFORLOOP,/*	A sBx	if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
+
+OP_SETLIST,/*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
+
+OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx])			*/
+
+OP_VARARG,/*	A B	R(A), R(A+1), ..., R(A+B-2) = vararg		*/
+
+OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
+} OpCode;
+
+
+#define NUM_OPCODES	(cast(int, OP_EXTRAARG) + 1)
+
+
+
+/*===========================================================================
+  Notes:
+  (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
+  set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
+  OP_SETLIST) may use `top'.
+
+  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
+  set top (like in OP_CALL with C == 0).
+
+  (*) In OP_RETURN, if (B == 0) then return up to `top'.
+
+  (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
+  'instruction' is EXTRAARG(real C).
+
+  (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
+
+  (*) For comparisons, A specifies what condition the test should accept
+  (true or false).
+
+  (*) All `skips' (pc++) assume that next instruction is a jump.
+
+===========================================================================*/
+
+
+/*
+** masks for instruction properties. The format is:
+** bits 0-1: op mode
+** bits 2-3: C arg mode
+** bits 4-5: B arg mode
+** bit 6: instruction set register A
+** bit 7: operator is a test (next instruction must be a jump)
+*/
+
+enum OpArgMask {
+  OpArgN,  /* argument is not used */
+  OpArgU,  /* argument is used */
+  OpArgR,  /* argument is a register or a jump offset */
+  OpArgK   /* argument is a constant or register/constant */
+};
+
+LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
+
+#define getOpMode(m)	(cast(enum OpMode, luaP_opmodes[m] & 3))
+#define getBMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
+#define getCMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
+#define testAMode(m)	(luaP_opmodes[m] & (1 << 6))
+#define testTMode(m)	(luaP_opmodes[m] & (1 << 7))
+
+
+LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
+
+
+/* number of list items to accumulate before a SETLIST instruction */
+#define LFIELDS_PER_FLUSH	50
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/loslib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/loslib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/loslib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,337 @@
+/*
+** $Id: loslib.c,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
+** Standard Operating System library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#ifndef SYSLINUX
+#include <locale.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define loslib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#ifndef SYSLINUX
+/*
+** list of valid conversion specifiers for the 'strftime' function
+*/
+#if !defined(LUA_STRFTIMEOPTIONS)
+
+#if !defined(LUA_USE_POSIX)
+#define LUA_STRFTIMEOPTIONS	{ "aAbBcdHIjmMpSUwWxXyYz%", "" }
+#else
+#define LUA_STRFTIMEOPTIONS \
+	{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \
+	  "", "E", "cCxXyY",  \
+	  "O", "deHImMSuUVwWy" }
+#endif
+
+#endif
+
+
+
+/*
+** By default, Lua uses tmpnam except when POSIX is available, where it
+** uses mkstemp.
+*/
+#if defined(LUA_USE_MKSTEMP)
+#include <unistd.h>
+#define LUA_TMPNAMBUFSIZE	32
+#define lua_tmpnam(b,e) { \
+        strcpy(b, "/tmp/lua_XXXXXX"); \
+        e = mkstemp(b); \
+        if (e != -1) close(e); \
+        e = (e == -1); }
+
+#elif !defined(lua_tmpnam)
+
+#define LUA_TMPNAMBUFSIZE	L_tmpnam
+#define lua_tmpnam(b,e)		{ e = (tmpnam(b) == NULL); }
+
+#endif
+
+
+/*
+** By default, Lua uses gmtime/localtime, except when POSIX is available,
+** where it uses gmtime_r/localtime_r
+*/
+#if defined(LUA_USE_GMTIME_R)
+
+#define l_gmtime(t,r)		gmtime_r(t,r)
+#define l_localtime(t,r)	localtime_r(t,r)
+
+#elif !defined(l_gmtime)
+
+#define l_gmtime(t,r)		((void)r, gmtime(t))
+#define l_localtime(t,r)  	((void)r, localtime(t))
+
+#endif
+
+
+
+static int os_execute (lua_State *L) {
+  const char *cmd = luaL_optstring(L, 1, NULL);
+  int stat = system(cmd);
+  if (cmd != NULL)
+    return luaL_execresult(L, stat);
+  else {
+    lua_pushboolean(L, stat);  /* true if there is a shell */
+    return 1;
+  }
+}
+
+
+static int os_remove (lua_State *L) {
+  const char *filename = luaL_checkstring(L, 1);
+  return luaL_fileresult(L, remove(filename) == 0, filename);
+}
+
+
+static int os_rename (lua_State *L) {
+  const char *fromname = luaL_checkstring(L, 1);
+  const char *toname = luaL_checkstring(L, 2);
+  return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
+}
+
+
+static int os_tmpname (lua_State *L) {
+  char buff[LUA_TMPNAMBUFSIZE];
+  int err;
+  lua_tmpnam(buff, err);
+  if (err)
+    return luaL_error(L, "unable to generate a unique filename");
+  lua_pushstring(L, buff);
+  return 1;
+}
+#endif /* SYSLINUX */
+
+
+static int os_getenv (lua_State *L) {
+  lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
+  return 1;
+}
+
+
+#ifndef SYSLINUX
+static int os_clock (lua_State *L) {
+  lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+  return 1;
+}
+
+
+/*
+** {======================================================
+** Time/Date operations
+** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
+**   wday=%w+1, yday=%j, isdst=? }
+** =======================================================
+*/
+
+static void setfield (lua_State *L, const char *key, int value) {
+  lua_pushinteger(L, value);
+  lua_setfield(L, -2, key);
+}
+
+static void setboolfield (lua_State *L, const char *key, int value) {
+  if (value < 0)  /* undefined? */
+    return;  /* does not set field */
+  lua_pushboolean(L, value);
+  lua_setfield(L, -2, key);
+}
+
+static int getboolfield (lua_State *L, const char *key) {
+  int res;
+  lua_getfield(L, -1, key);
+  res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
+  lua_pop(L, 1);
+  return res;
+}
+
+
+static int getfield (lua_State *L, const char *key, int d) {
+  int res, isnum;
+  lua_getfield(L, -1, key);
+  res = (int)lua_tointegerx(L, -1, &isnum);
+  if (!isnum) {
+    if (d < 0)
+      return luaL_error(L, "field " LUA_QS " missing in date table", key);
+    res = d;
+  }
+  lua_pop(L, 1);
+  return res;
+}
+
+
+static const char *checkoption (lua_State *L, const char *conv, char *buff) {
+  static const char *const options[] = LUA_STRFTIMEOPTIONS;
+  unsigned int i;
+  for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
+    if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
+      buff[1] = *conv;
+      if (*options[i + 1] == '\0') {  /* one-char conversion specifier? */
+        buff[2] = '\0';  /* end buffer */
+        return conv + 1;
+      }
+      else if (*(conv + 1) != '\0' &&
+               strchr(options[i + 1], *(conv + 1)) != NULL) {
+        buff[2] = *(conv + 1);  /* valid two-char conversion specifier */
+        buff[3] = '\0';  /* end buffer */
+        return conv + 2;
+      }
+    }
+  }
+  luaL_argerror(L, 1,
+    lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
+  return conv;  /* to avoid warnings */
+}
+
+
+static int os_date (lua_State *L) {
+  const char *s = luaL_optstring(L, 1, "%c");
+  time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
+  struct tm tmr, *stm;
+  if (*s == '!') {  /* UTC? */
+    stm = l_gmtime(&t, &tmr);
+    s++;  /* skip `!' */
+  }
+  else
+    stm = l_localtime(&t, &tmr);
+  if (stm == NULL)  /* invalid date? */
+    lua_pushnil(L);
+  else if (strcmp(s, "*t") == 0) {
+    lua_createtable(L, 0, 9);  /* 9 = number of fields */
+    setfield(L, "sec", stm->tm_sec);
+    setfield(L, "min", stm->tm_min);
+    setfield(L, "hour", stm->tm_hour);
+    setfield(L, "day", stm->tm_mday);
+    setfield(L, "month", stm->tm_mon+1);
+    setfield(L, "year", stm->tm_year+1900);
+    setfield(L, "wday", stm->tm_wday+1);
+    setfield(L, "yday", stm->tm_yday+1);
+    setboolfield(L, "isdst", stm->tm_isdst);
+  }
+  else {
+    char cc[4];
+    luaL_Buffer b;
+    cc[0] = '%';
+    luaL_buffinit(L, &b);
+    while (*s) {
+      if (*s != '%')  /* no conversion specifier? */
+        luaL_addchar(&b, *s++);
+      else {
+        size_t reslen;
+        char buff[200];  /* should be big enough for any conversion result */
+        s = checkoption(L, s + 1, cc);
+        reslen = strftime(buff, sizeof(buff), cc, stm);
+        luaL_addlstring(&b, buff, reslen);
+      }
+    }
+    luaL_pushresult(&b);
+  }
+  return 1;
+}
+
+
+static int os_time (lua_State *L) {
+  time_t t;
+  if (lua_isnoneornil(L, 1))  /* called without args? */
+    t = time(NULL);  /* get current time */
+  else {
+    struct tm ts;
+    luaL_checktype(L, 1, LUA_TTABLE);
+    lua_settop(L, 1);  /* make sure table is at the top */
+    ts.tm_sec = getfield(L, "sec", 0);
+    ts.tm_min = getfield(L, "min", 0);
+    ts.tm_hour = getfield(L, "hour", 12);
+    ts.tm_mday = getfield(L, "day", -1);
+    ts.tm_mon = getfield(L, "month", -1) - 1;
+    ts.tm_year = getfield(L, "year", -1) - 1900;
+    ts.tm_isdst = getboolfield(L, "isdst");
+    t = mktime(&ts);
+  }
+  if (t == (time_t)(-1))
+    lua_pushnil(L);
+  else
+    lua_pushnumber(L, (lua_Number)t);
+  return 1;
+}
+
+
+#ifndef LUA_NUMBER_INTEGRAL
+static int os_difftime (lua_State *L) {
+  lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+                             (time_t)(luaL_optnumber(L, 2, 0))));
+  return 1;
+}
+#endif
+
+/* }====================================================== */
+
+
+static int os_setlocale (lua_State *L) {
+  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+                      LC_NUMERIC, LC_TIME};
+  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+     "numeric", "time", NULL};
+  const char *l = luaL_optstring(L, 1, NULL);
+  int op = luaL_checkoption(L, 2, "all", catnames);
+  lua_pushstring(L, setlocale(cat[op], l));
+  return 1;
+}
+#endif /* SYSLINUX */
+
+
+static int os_exit (lua_State *L) {
+  int status;
+  if (lua_isboolean(L, 1))
+    status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
+  else
+    status = luaL_optint(L, 1, EXIT_SUCCESS);
+  if (lua_toboolean(L, 2))
+    lua_close(L);
+  if (L) exit(status);  /* 'if' to avoid warnings for unreachable 'return' */
+  return 0;
+}
+
+
+static const luaL_Reg syslib[] = {
+#ifndef SYSLINUX
+  {"clock",     os_clock},
+  {"date",      os_date},
+#ifndef LUA_NUMBER_INTEGRAL
+  {"difftime",  os_difftime},
+#endif
+  {"execute",   os_execute},
+#endif
+  {"exit",      os_exit},
+  {"getenv",    os_getenv},
+#ifndef SYSLINUX
+  {"remove",    os_remove},
+  {"rename",    os_rename},
+  {"setlocale", os_setlocale},
+  {"time",      os_time},
+  {"tmpname",   os_tmpname},
+#endif
+  {NULL, NULL}
+};
+
+/* }====================================================== */
+
+
+
+LUAMOD_API int luaopen_os (lua_State *L) {
+  luaL_newlib(L, syslib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1638 @@
+/*
+** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lparser_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+
+
+
+/* maximum number of local variables per function (must be smaller
+   than 250, due to the bytecode format) */
+#define MAXVARS		200
+
+
+#define hasmultret(k)		((k) == VCALL || (k) == VVARARG)
+
+
+
+/*
+** nodes for block list (list of active blocks)
+*/
+typedef struct BlockCnt {
+  struct BlockCnt *previous;  /* chain */
+  short firstlabel;  /* index of first label in this block */
+  short firstgoto;  /* index of first pending goto in this block */
+  lu_byte nactvar;  /* # active locals outside the block */
+  lu_byte upval;  /* true if some variable in the block is an upvalue */
+  lu_byte isloop;  /* true if `block' is a loop */
+} BlockCnt;
+
+
+
+/*
+** prototypes for recursive non-terminal functions
+*/
+static void statement (LexState *ls);
+static void expr (LexState *ls, expdesc *v);
+
+
+static void anchor_token (LexState *ls) {
+  /* last token from outer function must be EOS */
+  lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
+  if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
+    TString *ts = ls->t.seminfo.ts;
+    luaX_newstring(ls, getstr(ts), ts->tsv.len);
+  }
+}
+
+
+/* semantic error */
+static l_noret semerror (LexState *ls, const char *msg) {
+  ls->t.token = 0;  /* remove 'near to' from final message */
+  luaX_syntaxerror(ls, msg);
+}
+
+
+static l_noret error_expected (LexState *ls, int token) {
+  luaX_syntaxerror(ls,
+      luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
+}
+
+
+static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
+  lua_State *L = fs->ls->L;
+  const char *msg;
+  int line = fs->f->linedefined;
+  const char *where = (line == 0)
+                      ? "main function"
+                      : luaO_pushfstring(L, "function at line %d", line);
+  msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
+                             what, limit, where);
+  luaX_syntaxerror(fs->ls, msg);
+}
+
+
+static void checklimit (FuncState *fs, int v, int l, const char *what) {
+  if (v > l) errorlimit(fs, l, what);
+}
+
+
+static int testnext (LexState *ls, int c) {
+  if (ls->t.token == c) {
+    luaX_next(ls);
+    return 1;
+  }
+  else return 0;
+}
+
+
+static void check (LexState *ls, int c) {
+  if (ls->t.token != c)
+    error_expected(ls, c);
+}
+
+
+static void checknext (LexState *ls, int c) {
+  check(ls, c);
+  luaX_next(ls);
+}
+
+
+#define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
+
+
+
+static void check_match (LexState *ls, int what, int who, int where) {
+  if (!testnext(ls, what)) {
+    if (where == ls->linenumber)
+      error_expected(ls, what);
+    else {
+      luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
+             "%s expected (to close %s at line %d)",
+              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
+    }
+  }
+}
+
+
+static TString *str_checkname (LexState *ls) {
+  TString *ts;
+  check(ls, TK_NAME);
+  ts = ls->t.seminfo.ts;
+  luaX_next(ls);
+  return ts;
+}
+
+
+static void init_exp (expdesc *e, expkind k, int i) {
+  e->f = e->t = NO_JUMP;
+  e->k = k;
+  e->u.info = i;
+}
+
+
+static void codestring (LexState *ls, expdesc *e, TString *s) {
+  init_exp(e, VK, luaK_stringK(ls->fs, s));
+}
+
+
+static void checkname (LexState *ls, expdesc *e) {
+  codestring(ls, e, str_checkname(ls));
+}
+
+
+static int registerlocalvar (LexState *ls, TString *varname) {
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;
+  int oldsize = f->sizelocvars;
+  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
+                  LocVar, SHRT_MAX, "local variables");
+  while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
+  f->locvars[fs->nlocvars].varname = varname;
+  luaC_objbarrier(ls->L, f, varname);
+  return fs->nlocvars++;
+}
+
+
+static void new_localvar (LexState *ls, TString *name) {
+  FuncState *fs = ls->fs;
+  Dyndata *dyd = ls->dyd;
+  int reg = registerlocalvar(ls, name);
+  checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
+                  MAXVARS, "local variables");
+  luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
+                  dyd->actvar.size, Vardesc, MAX_INT, "local variables");
+  dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
+}
+
+
+static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
+  new_localvar(ls, luaX_newstring(ls, name, sz));
+}
+
+#define new_localvarliteral(ls,v) \
+	new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
+
+
+static LocVar *getlocvar (FuncState *fs, int i) {
+  int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
+  lua_assert(idx < fs->nlocvars);
+  return &fs->f->locvars[idx];
+}
+
+
+static void adjustlocalvars (LexState *ls, int nvars) {
+  FuncState *fs = ls->fs;
+  fs->nactvar = cast_byte(fs->nactvar + nvars);
+  for (; nvars; nvars--) {
+    getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
+  }
+}
+
+
+static void removevars (FuncState *fs, int tolevel) {
+  fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
+  while (fs->nactvar > tolevel)
+    getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
+}
+
+
+static int searchupvalue (FuncState *fs, TString *name) {
+  int i;
+  Upvaldesc *up = fs->f->upvalues;
+  for (i = 0; i < fs->nups; i++) {
+    if (luaS_eqstr(up[i].name, name)) return i;
+  }
+  return -1;  /* not found */
+}
+
+
+static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
+  Proto *f = fs->f;
+  int oldsize = f->sizeupvalues;
+  checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
+  luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
+                  Upvaldesc, MAXUPVAL, "upvalues");
+  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
+  f->upvalues[fs->nups].instack = (v->k == VLOCAL);
+  f->upvalues[fs->nups].idx = cast_byte(v->u.info);
+  f->upvalues[fs->nups].name = name;
+  luaC_objbarrier(fs->ls->L, f, name);
+  return fs->nups++;
+}
+
+
+static int searchvar (FuncState *fs, TString *n) {
+  int i;
+  for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
+    if (luaS_eqstr(n, getlocvar(fs, i)->varname))
+      return i;
+  }
+  return -1;  /* not found */
+}
+
+
+/*
+  Mark block where variable at given level was defined
+  (to emit close instructions later).
+*/
+static void markupval (FuncState *fs, int level) {
+  BlockCnt *bl = fs->bl;
+  while (bl->nactvar > level) bl = bl->previous;
+  bl->upval = 1;
+}
+
+
+/*
+  Find variable with given name 'n'. If it is an upvalue, add this
+  upvalue into all intermediate functions.
+*/
+static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+  if (fs == NULL)  /* no more levels? */
+    return VVOID;  /* default is global */
+  else {
+    int v = searchvar(fs, n);  /* look up locals at current level */
+    if (v >= 0) {  /* found? */
+      init_exp(var, VLOCAL, v);  /* variable is local */
+      if (!base)
+        markupval(fs, v);  /* local will be used as an upval */
+      return VLOCAL;
+    }
+    else {  /* not found as local at current level; try upvalues */
+      int idx = searchupvalue(fs, n);  /* try existing upvalues */
+      if (idx < 0) {  /* not found? */
+        if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
+          return VVOID;  /* not found; is a global */
+        /* else was LOCAL or UPVAL */
+        idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
+      }
+      init_exp(var, VUPVAL, idx);
+      return VUPVAL;
+    }
+  }
+}
+
+
+static void singlevar (LexState *ls, expdesc *var) {
+  TString *varname = str_checkname(ls);
+  FuncState *fs = ls->fs;
+  if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
+    expdesc key;
+    singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
+    lua_assert(var->k == VLOCAL || var->k == VUPVAL);
+    codestring(ls, &key, varname);  /* key is variable name */
+    luaK_indexed(fs, var, &key);  /* env[varname] */
+  }
+}
+
+
+static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
+  FuncState *fs = ls->fs;
+  int extra = nvars - nexps;
+  if (hasmultret(e->k)) {
+    extra++;  /* includes call itself */
+    if (extra < 0) extra = 0;
+    luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
+    if (extra > 1) luaK_reserveregs(fs, extra-1);
+  }
+  else {
+    if (e->k != VVOID) luaK_exp2nextreg(fs, e);  /* close last expression */
+    if (extra > 0) {
+      int reg = fs->freereg;
+      luaK_reserveregs(fs, extra);
+      luaK_nil(fs, reg, extra);
+    }
+  }
+}
+
+
+static void enterlevel (LexState *ls) {
+  lua_State *L = ls->L;
+  ++L->nCcalls;
+  checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
+}
+
+
+#define leavelevel(ls)	((ls)->L->nCcalls--)
+
+
+static void closegoto (LexState *ls, int g, Labeldesc *label) {
+  int i;
+  FuncState *fs = ls->fs;
+  Labellist *gl = &ls->dyd->gt;
+  Labeldesc *gt = &gl->arr[g];
+  lua_assert(luaS_eqstr(gt->name, label->name));
+  if (gt->nactvar < label->nactvar) {
+    TString *vname = getlocvar(fs, gt->nactvar)->varname;
+    const char *msg = luaO_pushfstring(ls->L,
+      "<goto %s> at line %d jumps into the scope of local " LUA_QS,
+      getstr(gt->name), gt->line, getstr(vname));
+    semerror(ls, msg);
+  }
+  luaK_patchlist(fs, gt->pc, label->pc);
+  /* remove goto from pending list */
+  for (i = g; i < gl->n - 1; i++)
+    gl->arr[i] = gl->arr[i + 1];
+  gl->n--;
+}
+
+
+/*
+** try to close a goto with existing labels; this solves backward jumps
+*/
+static int findlabel (LexState *ls, int g) {
+  int i;
+  BlockCnt *bl = ls->fs->bl;
+  Dyndata *dyd = ls->dyd;
+  Labeldesc *gt = &dyd->gt.arr[g];
+  /* check labels in current block for a match */
+  for (i = bl->firstlabel; i < dyd->label.n; i++) {
+    Labeldesc *lb = &dyd->label.arr[i];
+    if (luaS_eqstr(lb->name, gt->name)) {  /* correct label? */
+      if (gt->nactvar > lb->nactvar &&
+          (bl->upval || dyd->label.n > bl->firstlabel))
+        luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
+      closegoto(ls, g, lb);  /* close it */
+      return 1;
+    }
+  }
+  return 0;  /* label not found; cannot close goto */
+}
+
+
+static int newlabelentry (LexState *ls, Labellist *l, TString *name,
+                          int line, int pc) {
+  int n = l->n;
+  luaM_growvector(ls->L, l->arr, n, l->size,
+                  Labeldesc, SHRT_MAX, "labels/gotos");
+  l->arr[n].name = name;
+  l->arr[n].line = line;
+  l->arr[n].nactvar = ls->fs->nactvar;
+  l->arr[n].pc = pc;
+  l->n++;
+  return n;
+}
+
+
+/*
+** check whether new label 'lb' matches any pending gotos in current
+** block; solves forward jumps
+*/
+static void findgotos (LexState *ls, Labeldesc *lb) {
+  Labellist *gl = &ls->dyd->gt;
+  int i = ls->fs->bl->firstgoto;
+  while (i < gl->n) {
+    if (luaS_eqstr(gl->arr[i].name, lb->name))
+      closegoto(ls, i, lb);
+    else
+      i++;
+  }
+}
+
+
+/*
+** "export" pending gotos to outer level, to check them against
+** outer labels; if the block being exited has upvalues, and
+** the goto exits the scope of any variable (which can be the
+** upvalue), close those variables being exited.
+*/
+static void movegotosout (FuncState *fs, BlockCnt *bl) {
+  int i = bl->firstgoto;
+  Labellist *gl = &fs->ls->dyd->gt;
+  /* correct pending gotos to current block and try to close it
+     with visible labels */
+  while (i < gl->n) {
+    Labeldesc *gt = &gl->arr[i];
+    if (gt->nactvar > bl->nactvar) {
+      if (bl->upval)
+        luaK_patchclose(fs, gt->pc, bl->nactvar);
+      gt->nactvar = bl->nactvar;
+    }
+    if (!findlabel(fs->ls, i))
+      i++;  /* move to next one */
+  }
+}
+
+
+static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
+  bl->isloop = isloop;
+  bl->nactvar = fs->nactvar;
+  bl->firstlabel = fs->ls->dyd->label.n;
+  bl->firstgoto = fs->ls->dyd->gt.n;
+  bl->upval = 0;
+  bl->previous = fs->bl;
+  fs->bl = bl;
+  lua_assert(fs->freereg == fs->nactvar);
+}
+
+
+/*
+** create a label named "break" to resolve break statements
+*/
+static void breaklabel (LexState *ls) {
+  TString *n = luaS_new(ls->L, "break");
+  int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
+  findgotos(ls, &ls->dyd->label.arr[l]);
+}
+
+/*
+** generates an error for an undefined 'goto'; choose appropriate
+** message when label name is a reserved word (which can only be 'break')
+*/
+static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
+  const char *msg = isreserved(gt->name)
+                    ? "<%s> at line %d not inside a loop"
+                    : "no visible label " LUA_QS " for <goto> at line %d";
+  msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
+  semerror(ls, msg);
+}
+
+
+static void leaveblock (FuncState *fs) {
+  BlockCnt *bl = fs->bl;
+  LexState *ls = fs->ls;
+  if (bl->previous && bl->upval) {
+    /* create a 'jump to here' to close upvalues */
+    int j = luaK_jump(fs);
+    luaK_patchclose(fs, j, bl->nactvar);
+    luaK_patchtohere(fs, j);
+  }
+  if (bl->isloop)
+    breaklabel(ls);  /* close pending breaks */
+  fs->bl = bl->previous;
+  removevars(fs, bl->nactvar);
+  lua_assert(bl->nactvar == fs->nactvar);
+  fs->freereg = fs->nactvar;  /* free registers */
+  ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
+  if (bl->previous)  /* inner block? */
+    movegotosout(fs, bl);  /* update pending gotos to outer block */
+  else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
+    undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
+}
+
+
+/*
+** adds a new prototype into list of prototypes
+*/
+static Proto *addprototype (LexState *ls) {
+  Proto *clp;
+  lua_State *L = ls->L;
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;  /* prototype of current function */
+  if (fs->np >= f->sizep) {
+    int oldsize = f->sizep;
+    luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
+    while (oldsize < f->sizep) f->p[oldsize++] = NULL;
+  }
+  f->p[fs->np++] = clp = luaF_newproto(L);
+  luaC_objbarrier(L, f, clp);
+  return clp;
+}
+
+
+/*
+** codes instruction to create new closure in parent function.
+** The OP_CLOSURE instruction must use the last available register,
+** so that, if it invokes the GC, the GC knows which registers
+** are in use at that time.
+*/
+static void codeclosure (LexState *ls, expdesc *v) {
+  FuncState *fs = ls->fs->prev;
+  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
+  luaK_exp2nextreg(fs, v);  /* fix it at the last register */
+}
+
+
+static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
+  lua_State *L = ls->L;
+  Proto *f;
+  fs->prev = ls->fs;  /* linked list of funcstates */
+  fs->ls = ls;
+  ls->fs = fs;
+  fs->pc = 0;
+  fs->lasttarget = 0;
+  fs->jpc = NO_JUMP;
+  fs->freereg = 0;
+  fs->nk = 0;
+  fs->np = 0;
+  fs->nups = 0;
+  fs->nlocvars = 0;
+  fs->nactvar = 0;
+  fs->firstlocal = ls->dyd->actvar.n;
+  fs->bl = NULL;
+  f = fs->f;
+  f->source = ls->source;
+  f->maxstacksize = 2;  /* registers 0/1 are always valid */
+  fs->h = luaH_new(L);
+  /* anchor table of constants (to avoid being collected) */
+  sethvalue2s(L, L->top, fs->h);
+  incr_top(L);
+  enterblock(fs, bl, 0);
+}
+
+
+static void close_func (LexState *ls) {
+  lua_State *L = ls->L;
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;
+  luaK_ret(fs, 0, 0);  /* final return */
+  leaveblock(fs);
+  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
+  f->sizecode = fs->pc;
+  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
+  f->sizelineinfo = fs->pc;
+  luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
+  f->sizek = fs->nk;
+  luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
+  f->sizep = fs->np;
+  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
+  f->sizelocvars = fs->nlocvars;
+  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
+  f->sizeupvalues = fs->nups;
+  lua_assert(fs->bl == NULL);
+  ls->fs = fs->prev;
+  /* last token read was anchored in defunct function; must re-anchor it */
+  anchor_token(ls);
+  L->top--;  /* pop table of constants */
+  luaC_checkGC(L);
+}
+
+
+
+/*============================================================*/
+/* GRAMMAR RULES */
+/*============================================================*/
+
+
+/*
+** check whether current token is in the follow set of a block.
+** 'until' closes syntactical blocks, but do not close scope,
+** so it handled in separate.
+*/
+static int block_follow (LexState *ls, int withuntil) {
+  switch (ls->t.token) {
+    case TK_ELSE: case TK_ELSEIF:
+    case TK_END: case TK_EOS:
+      return 1;
+    case TK_UNTIL: return withuntil;
+    default: return 0;
+  }
+}
+
+
+static void statlist (LexState *ls) {
+  /* statlist -> { stat [`;'] } */
+  while (!block_follow(ls, 1)) {
+    if (ls->t.token == TK_RETURN) {
+      statement(ls);
+      return;  /* 'return' must be last statement */
+    }
+    statement(ls);
+  }
+}
+
+
+static void fieldsel (LexState *ls, expdesc *v) {
+  /* fieldsel -> ['.' | ':'] NAME */
+  FuncState *fs = ls->fs;
+  expdesc key;
+  luaK_exp2anyregup(fs, v);
+  luaX_next(ls);  /* skip the dot or colon */
+  checkname(ls, &key);
+  luaK_indexed(fs, v, &key);
+}
+
+
+static void yindex (LexState *ls, expdesc *v) {
+  /* index -> '[' expr ']' */
+  luaX_next(ls);  /* skip the '[' */
+  expr(ls, v);
+  luaK_exp2val(ls->fs, v);
+  checknext(ls, ']');
+}
+
+
+/*
+** {======================================================================
+** Rules for Constructors
+** =======================================================================
+*/
+
+
+struct ConsControl {
+  expdesc v;  /* last list item read */
+  expdesc *t;  /* table descriptor */
+  int nh;  /* total number of `record' elements */
+  int na;  /* total number of array elements */
+  int tostore;  /* number of array elements pending to be stored */
+};
+
+
+static void recfield (LexState *ls, struct ConsControl *cc) {
+  /* recfield -> (NAME | `['exp1`]') = exp1 */
+  FuncState *fs = ls->fs;
+  int reg = ls->fs->freereg;
+  expdesc key, val;
+  int rkkey;
+  if (ls->t.token == TK_NAME) {
+    checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
+    checkname(ls, &key);
+  }
+  else  /* ls->t.token == '[' */
+    yindex(ls, &key);
+  cc->nh++;
+  checknext(ls, '=');
+  rkkey = luaK_exp2RK(fs, &key);
+  expr(ls, &val);
+  luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
+  fs->freereg = reg;  /* free registers */
+}
+
+
+static void closelistfield (FuncState *fs, struct ConsControl *cc) {
+  if (cc->v.k == VVOID) return;  /* there is no list item */
+  luaK_exp2nextreg(fs, &cc->v);
+  cc->v.k = VVOID;
+  if (cc->tostore == LFIELDS_PER_FLUSH) {
+    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
+    cc->tostore = 0;  /* no more items pending */
+  }
+}
+
+
+static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
+  if (cc->tostore == 0) return;
+  if (hasmultret(cc->v.k)) {
+    luaK_setmultret(fs, &cc->v);
+    luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
+    cc->na--;  /* do not count last expression (unknown number of elements) */
+  }
+  else {
+    if (cc->v.k != VVOID)
+      luaK_exp2nextreg(fs, &cc->v);
+    luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
+  }
+}
+
+
+static void listfield (LexState *ls, struct ConsControl *cc) {
+  /* listfield -> exp */
+  expr(ls, &cc->v);
+  checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
+  cc->na++;
+  cc->tostore++;
+}
+
+
+static void field (LexState *ls, struct ConsControl *cc) {
+  /* field -> listfield | recfield */
+  switch(ls->t.token) {
+    case TK_NAME: {  /* may be 'listfield' or 'recfield' */
+      if (luaX_lookahead(ls) != '=')  /* expression? */
+        listfield(ls, cc);
+      else
+        recfield(ls, cc);
+      break;
+    }
+    case '[': {
+      recfield(ls, cc);
+      break;
+    }
+    default: {
+      listfield(ls, cc);
+      break;
+    }
+  }
+}
+
+
+static void constructor (LexState *ls, expdesc *t) {
+  /* constructor -> '{' [ field { sep field } [sep] ] '}'
+     sep -> ',' | ';' */
+  FuncState *fs = ls->fs;
+  int line = ls->linenumber;
+  int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
+  struct ConsControl cc;
+  cc.na = cc.nh = cc.tostore = 0;
+  cc.t = t;
+  init_exp(t, VRELOCABLE, pc);
+  init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
+  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top */
+  checknext(ls, '{');
+  do {
+    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
+    if (ls->t.token == '}') break;
+    closelistfield(fs, &cc);
+    field(ls, &cc);
+  } while (testnext(ls, ',') || testnext(ls, ';'));
+  check_match(ls, '}', '{', line);
+  lastlistfield(fs, &cc);
+  SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
+  SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh));  /* set initial table size */
+}
+
+/* }====================================================================== */
+
+
+
+static void parlist (LexState *ls) {
+  /* parlist -> [ param { `,' param } ] */
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;
+  int nparams = 0;
+  f->is_vararg = 0;
+  if (ls->t.token != ')') {  /* is `parlist' not empty? */
+    do {
+      switch (ls->t.token) {
+        case TK_NAME: {  /* param -> NAME */
+          new_localvar(ls, str_checkname(ls));
+          nparams++;
+          break;
+        }
+        case TK_DOTS: {  /* param -> `...' */
+          luaX_next(ls);
+          f->is_vararg = 1;
+          break;
+        }
+        default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
+      }
+    } while (!f->is_vararg && testnext(ls, ','));
+  }
+  adjustlocalvars(ls, nparams);
+  f->numparams = cast_byte(fs->nactvar);
+  luaK_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
+}
+
+
+static void body (LexState *ls, expdesc *e, int ismethod, int line) {
+  /* body ->  `(' parlist `)' block END */
+  FuncState new_fs;
+  BlockCnt bl;
+  new_fs.f = addprototype(ls);
+  new_fs.f->linedefined = line;
+  open_func(ls, &new_fs, &bl);
+  checknext(ls, '(');
+  if (ismethod) {
+    new_localvarliteral(ls, "self");  /* create 'self' parameter */
+    adjustlocalvars(ls, 1);
+  }
+  parlist(ls);
+  checknext(ls, ')');
+  statlist(ls);
+  new_fs.f->lastlinedefined = ls->linenumber;
+  check_match(ls, TK_END, TK_FUNCTION, line);
+  codeclosure(ls, e);
+  close_func(ls);
+}
+
+
+static int explist (LexState *ls, expdesc *v) {
+  /* explist -> expr { `,' expr } */
+  int n = 1;  /* at least one expression */
+  expr(ls, v);
+  while (testnext(ls, ',')) {
+    luaK_exp2nextreg(ls->fs, v);
+    expr(ls, v);
+    n++;
+  }
+  return n;
+}
+
+
+static void funcargs (LexState *ls, expdesc *f, int line) {
+  FuncState *fs = ls->fs;
+  expdesc args;
+  int base, nparams;
+  switch (ls->t.token) {
+    case '(': {  /* funcargs -> `(' [ explist ] `)' */
+      luaX_next(ls);
+      if (ls->t.token == ')')  /* arg list is empty? */
+        args.k = VVOID;
+      else {
+        explist(ls, &args);
+        luaK_setmultret(fs, &args);
+      }
+      check_match(ls, ')', '(', line);
+      break;
+    }
+    case '{': {  /* funcargs -> constructor */
+      constructor(ls, &args);
+      break;
+    }
+    case TK_STRING: {  /* funcargs -> STRING */
+      codestring(ls, &args, ls->t.seminfo.ts);
+      luaX_next(ls);  /* must use `seminfo' before `next' */
+      break;
+    }
+    default: {
+      luaX_syntaxerror(ls, "function arguments expected");
+    }
+  }
+  lua_assert(f->k == VNONRELOC);
+  base = f->u.info;  /* base register for call */
+  if (hasmultret(args.k))
+    nparams = LUA_MULTRET;  /* open call */
+  else {
+    if (args.k != VVOID)
+      luaK_exp2nextreg(fs, &args);  /* close last argument */
+    nparams = fs->freereg - (base+1);
+  }
+  init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
+  luaK_fixline(fs, line);
+  fs->freereg = base+1;  /* call remove function and arguments and leaves
+                            (unless changed) one result */
+}
+
+
+
+
+/*
+** {======================================================================
+** Expression parsing
+** =======================================================================
+*/
+
+
+static void primaryexp (LexState *ls, expdesc *v) {
+  /* primaryexp -> NAME | '(' expr ')' */
+  switch (ls->t.token) {
+    case '(': {
+      int line = ls->linenumber;
+      luaX_next(ls);
+      expr(ls, v);
+      check_match(ls, ')', '(', line);
+      luaK_dischargevars(ls->fs, v);
+      return;
+    }
+    case TK_NAME: {
+      singlevar(ls, v);
+      return;
+    }
+    default: {
+      luaX_syntaxerror(ls, "unexpected symbol");
+    }
+  }
+}
+
+
+static void suffixedexp (LexState *ls, expdesc *v) {
+  /* suffixedexp ->
+       primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
+  FuncState *fs = ls->fs;
+  int line = ls->linenumber;
+  primaryexp(ls, v);
+  for (;;) {
+    switch (ls->t.token) {
+      case '.': {  /* fieldsel */
+        fieldsel(ls, v);
+        break;
+      }
+      case '[': {  /* `[' exp1 `]' */
+        expdesc key;
+        luaK_exp2anyregup(fs, v);
+        yindex(ls, &key);
+        luaK_indexed(fs, v, &key);
+        break;
+      }
+      case ':': {  /* `:' NAME funcargs */
+        expdesc key;
+        luaX_next(ls);
+        checkname(ls, &key);
+        luaK_self(fs, v, &key);
+        funcargs(ls, v, line);
+        break;
+      }
+      case '(': case TK_STRING: case '{': {  /* funcargs */
+        luaK_exp2nextreg(fs, v);
+        funcargs(ls, v, line);
+        break;
+      }
+      default: return;
+    }
+  }
+}
+
+
+static void simpleexp (LexState *ls, expdesc *v) {
+  /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
+                  constructor | FUNCTION body | suffixedexp */
+  switch (ls->t.token) {
+    case TK_NUMBER: {
+      init_exp(v, VKNUM, 0);
+      v->u.nval = ls->t.seminfo.r;
+      break;
+    }
+    case TK_STRING: {
+      codestring(ls, v, ls->t.seminfo.ts);
+      break;
+    }
+    case TK_NIL: {
+      init_exp(v, VNIL, 0);
+      break;
+    }
+    case TK_TRUE: {
+      init_exp(v, VTRUE, 0);
+      break;
+    }
+    case TK_FALSE: {
+      init_exp(v, VFALSE, 0);
+      break;
+    }
+    case TK_DOTS: {  /* vararg */
+      FuncState *fs = ls->fs;
+      check_condition(ls, fs->f->is_vararg,
+                      "cannot use " LUA_QL("...") " outside a vararg function");
+      init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
+      break;
+    }
+    case '{': {  /* constructor */
+      constructor(ls, v);
+      return;
+    }
+    case TK_FUNCTION: {
+      luaX_next(ls);
+      body(ls, v, 0, ls->linenumber);
+      return;
+    }
+    default: {
+      suffixedexp(ls, v);
+      return;
+    }
+  }
+  luaX_next(ls);
+}
+
+
+static UnOpr getunopr (int op) {
+  switch (op) {
+    case TK_NOT: return OPR_NOT;
+    case '-': return OPR_MINUS;
+    case '#': return OPR_LEN;
+    default: return OPR_NOUNOPR;
+  }
+}
+
+
+static BinOpr getbinopr (int op) {
+  switch (op) {
+    case '+': return OPR_ADD;
+    case '-': return OPR_SUB;
+    case '*': return OPR_MUL;
+    case '/': return OPR_DIV;
+    case '%': return OPR_MOD;
+    case '^': return OPR_POW;
+    case TK_CONCAT: return OPR_CONCAT;
+    case TK_NE: return OPR_NE;
+    case TK_EQ: return OPR_EQ;
+    case '<': return OPR_LT;
+    case TK_LE: return OPR_LE;
+    case '>': return OPR_GT;
+    case TK_GE: return OPR_GE;
+    case TK_AND: return OPR_AND;
+    case TK_OR: return OPR_OR;
+    default: return OPR_NOBINOPR;
+  }
+}
+
+
+static const struct {
+  lu_byte left;  /* left priority for each binary operator */
+  lu_byte right; /* right priority */
+} priority[] = {  /* ORDER OPR */
+   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `*' `/' `%' */
+   {10, 9}, {5, 4},                 /* ^, .. (right associative) */
+   {3, 3}, {3, 3}, {3, 3},          /* ==, <, <= */
+   {3, 3}, {3, 3}, {3, 3},          /* ~=, >, >= */
+   {2, 2}, {1, 1}                   /* and, or */
+};
+
+#define UNARY_PRIORITY	8  /* priority for unary operators */
+
+
+/*
+** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
+** where `binop' is any binary operator with a priority higher than `limit'
+*/
+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
+  BinOpr op;
+  UnOpr uop;
+  enterlevel(ls);
+  uop = getunopr(ls->t.token);
+  if (uop != OPR_NOUNOPR) {
+    int line = ls->linenumber;
+    luaX_next(ls);
+    subexpr(ls, v, UNARY_PRIORITY);
+    luaK_prefix(ls->fs, uop, v, line);
+  }
+  else simpleexp(ls, v);
+  /* expand while operators have priorities higher than `limit' */
+  op = getbinopr(ls->t.token);
+  while (op != OPR_NOBINOPR && priority[op].left > limit) {
+    expdesc v2;
+    BinOpr nextop;
+    int line = ls->linenumber;
+    luaX_next(ls);
+    luaK_infix(ls->fs, op, v);
+    /* read sub-expression with higher priority */
+    nextop = subexpr(ls, &v2, priority[op].right);
+    luaK_posfix(ls->fs, op, v, &v2, line);
+    op = nextop;
+  }
+  leavelevel(ls);
+  return op;  /* return first untreated operator */
+}
+
+
+static void expr (LexState *ls, expdesc *v) {
+  subexpr(ls, v, 0);
+}
+
+/* }==================================================================== */
+
+
+
+/*
+** {======================================================================
+** Rules for Statements
+** =======================================================================
+*/
+
+
+static void block (LexState *ls) {
+  /* block -> statlist */
+  FuncState *fs = ls->fs;
+  BlockCnt bl;
+  enterblock(fs, &bl, 0);
+  statlist(ls);
+  leaveblock(fs);
+}
+
+
+/*
+** structure to chain all variables in the left-hand side of an
+** assignment
+*/
+struct LHS_assign {
+  struct LHS_assign *prev;
+  expdesc v;  /* variable (global, local, upvalue, or indexed) */
+};
+
+
+/*
+** check whether, in an assignment to an upvalue/local variable, the
+** upvalue/local variable is begin used in a previous assignment to a
+** table. If so, save original upvalue/local value in a safe place and
+** use this safe copy in the previous assignment.
+*/
+static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
+  FuncState *fs = ls->fs;
+  int extra = fs->freereg;  /* eventual position to save local variable */
+  int conflict = 0;
+  for (; lh; lh = lh->prev) {  /* check all previous assignments */
+    if (lh->v.k == VINDEXED) {  /* assigning to a table? */
+      /* table is the upvalue/local being assigned now? */
+      if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
+        conflict = 1;
+        lh->v.u.ind.vt = VLOCAL;
+        lh->v.u.ind.t = extra;  /* previous assignment will use safe copy */
+      }
+      /* index is the local being assigned? (index cannot be upvalue) */
+      if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
+        conflict = 1;
+        lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
+      }
+    }
+  }
+  if (conflict) {
+    /* copy upvalue/local value to a temporary (in position 'extra') */
+    OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+    luaK_codeABC(fs, op, extra, v->u.info, 0);
+    luaK_reserveregs(fs, 1);
+  }
+}
+
+
+static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
+  expdesc e;
+  check_condition(ls, vkisvar(lh->v.k), "syntax error");
+  if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
+    struct LHS_assign nv;
+    nv.prev = lh;
+    suffixedexp(ls, &nv.v);
+    if (nv.v.k != VINDEXED)
+      check_conflict(ls, lh, &nv.v);
+    checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
+                    "C levels");
+    assignment(ls, &nv, nvars+1);
+  }
+  else {  /* assignment -> `=' explist */
+    int nexps;
+    checknext(ls, '=');
+    nexps = explist(ls, &e);
+    if (nexps != nvars) {
+      adjust_assign(ls, nvars, nexps, &e);
+      if (nexps > nvars)
+        ls->fs->freereg -= nexps - nvars;  /* remove extra values */
+    }
+    else {
+      luaK_setoneret(ls->fs, &e);  /* close last expression */
+      luaK_storevar(ls->fs, &lh->v, &e);
+      return;  /* avoid default */
+    }
+  }
+  init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
+  luaK_storevar(ls->fs, &lh->v, &e);
+}
+
+
+static int cond (LexState *ls) {
+  /* cond -> exp */
+  expdesc v;
+  expr(ls, &v);  /* read condition */
+  if (v.k == VNIL) v.k = VFALSE;  /* `falses' are all equal here */
+  luaK_goiftrue(ls->fs, &v);
+  return v.f;
+}
+
+
+static void gotostat (LexState *ls, int pc) {
+  int line = ls->linenumber;
+  TString *label;
+  int g;
+  if (testnext(ls, TK_GOTO))
+    label = str_checkname(ls);
+  else {
+    luaX_next(ls);  /* skip break */
+    label = luaS_new(ls->L, "break");
+  }
+  g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+  findlabel(ls, g);  /* close it if label already defined */
+}
+
+
+/* check for repeated labels on the same block */
+static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
+  int i;
+  for (i = fs->bl->firstlabel; i < ll->n; i++) {
+    if (luaS_eqstr(label, ll->arr[i].name)) {
+      const char *msg = luaO_pushfstring(fs->ls->L,
+                          "label " LUA_QS " already defined on line %d",
+                          getstr(label), ll->arr[i].line);
+      semerror(fs->ls, msg);
+    }
+  }
+}
+
+
+/* skip no-op statements */
+static void skipnoopstat (LexState *ls) {
+  while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
+    statement(ls);
+}
+
+
+static void labelstat (LexState *ls, TString *label, int line) {
+  /* label -> '::' NAME '::' */
+  FuncState *fs = ls->fs;
+  Labellist *ll = &ls->dyd->label;
+  int l;  /* index of new label being created */
+  checkrepeated(fs, ll, label);  /* check for repeated labels */
+  checknext(ls, TK_DBCOLON);  /* skip double colon */
+  /* create new entry for this label */
+  l = newlabelentry(ls, ll, label, line, fs->pc);
+  skipnoopstat(ls);  /* skip other no-op statements */
+  if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
+    /* assume that locals are already out of scope */
+    ll->arr[l].nactvar = fs->bl->nactvar;
+  }
+  findgotos(ls, &ll->arr[l]);
+}
+
+
+static void whilestat (LexState *ls, int line) {
+  /* whilestat -> WHILE cond DO block END */
+  FuncState *fs = ls->fs;
+  int whileinit;
+  int condexit;
+  BlockCnt bl;
+  luaX_next(ls);  /* skip WHILE */
+  whileinit = luaK_getlabel(fs);
+  condexit = cond(ls);
+  enterblock(fs, &bl, 1);
+  checknext(ls, TK_DO);
+  block(ls);
+  luaK_jumpto(fs, whileinit);
+  check_match(ls, TK_END, TK_WHILE, line);
+  leaveblock(fs);
+  luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
+}
+
+
+static void repeatstat (LexState *ls, int line) {
+  /* repeatstat -> REPEAT block UNTIL cond */
+  int condexit;
+  FuncState *fs = ls->fs;
+  int repeat_init = luaK_getlabel(fs);
+  BlockCnt bl1, bl2;
+  enterblock(fs, &bl1, 1);  /* loop block */
+  enterblock(fs, &bl2, 0);  /* scope block */
+  luaX_next(ls);  /* skip REPEAT */
+  statlist(ls);
+  check_match(ls, TK_UNTIL, TK_REPEAT, line);
+  condexit = cond(ls);  /* read condition (inside scope block) */
+  if (bl2.upval)  /* upvalues? */
+    luaK_patchclose(fs, condexit, bl2.nactvar);
+  leaveblock(fs);  /* finish scope */
+  luaK_patchlist(fs, condexit, repeat_init);  /* close the loop */
+  leaveblock(fs);  /* finish loop */
+}
+
+
+static int exp1 (LexState *ls) {
+  expdesc e;
+  int reg;
+  expr(ls, &e);
+  luaK_exp2nextreg(ls->fs, &e);
+  lua_assert(e.k == VNONRELOC);
+  reg = e.u.info;
+  return reg;
+}
+
+
+static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
+  /* forbody -> DO block */
+  BlockCnt bl;
+  FuncState *fs = ls->fs;
+  int prep, endfor;
+  adjustlocalvars(ls, 3);  /* control variables */
+  checknext(ls, TK_DO);
+  prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
+  enterblock(fs, &bl, 0);  /* scope for declared variables */
+  adjustlocalvars(ls, nvars);
+  luaK_reserveregs(fs, nvars);
+  block(ls);
+  leaveblock(fs);  /* end of scope for declared variables */
+  luaK_patchtohere(fs, prep);
+  if (isnum)  /* numeric for? */
+    endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
+  else {  /* generic for */
+    luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
+    luaK_fixline(fs, line);
+    endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
+  }
+  luaK_patchlist(fs, endfor, prep + 1);
+  luaK_fixline(fs, line);
+}
+
+
+static void fornum (LexState *ls, TString *varname, int line) {
+  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
+  FuncState *fs = ls->fs;
+  int base = fs->freereg;
+  new_localvarliteral(ls, "(for index)");
+  new_localvarliteral(ls, "(for limit)");
+  new_localvarliteral(ls, "(for step)");
+  new_localvar(ls, varname);
+  checknext(ls, '=');
+  exp1(ls);  /* initial value */
+  checknext(ls, ',');
+  exp1(ls);  /* limit */
+  if (testnext(ls, ','))
+    exp1(ls);  /* optional step */
+  else {  /* default step = 1 */
+    luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
+    luaK_reserveregs(fs, 1);
+  }
+  forbody(ls, base, line, 1, 1);
+}
+
+
+static void forlist (LexState *ls, TString *indexname) {
+  /* forlist -> NAME {,NAME} IN explist forbody */
+  FuncState *fs = ls->fs;
+  expdesc e;
+  int nvars = 4;  /* gen, state, control, plus at least one declared var */
+  int line;
+  int base = fs->freereg;
+  /* create control variables */
+  new_localvarliteral(ls, "(for generator)");
+  new_localvarliteral(ls, "(for state)");
+  new_localvarliteral(ls, "(for control)");
+  /* create declared variables */
+  new_localvar(ls, indexname);
+  while (testnext(ls, ',')) {
+    new_localvar(ls, str_checkname(ls));
+    nvars++;
+  }
+  checknext(ls, TK_IN);
+  line = ls->linenumber;
+  adjust_assign(ls, 3, explist(ls, &e), &e);
+  luaK_checkstack(fs, 3);  /* extra space to call generator */
+  forbody(ls, base, line, nvars - 3, 0);
+}
+
+
+static void forstat (LexState *ls, int line) {
+  /* forstat -> FOR (fornum | forlist) END */
+  FuncState *fs = ls->fs;
+  TString *varname;
+  BlockCnt bl;
+  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
+  luaX_next(ls);  /* skip `for' */
+  varname = str_checkname(ls);  /* first variable name */
+  switch (ls->t.token) {
+    case '=': fornum(ls, varname, line); break;
+    case ',': case TK_IN: forlist(ls, varname); break;
+    default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
+  }
+  check_match(ls, TK_END, TK_FOR, line);
+  leaveblock(fs);  /* loop scope (`break' jumps to this point) */
+}
+
+
+static void test_then_block (LexState *ls, int *escapelist) {
+  /* test_then_block -> [IF | ELSEIF] cond THEN block */
+  BlockCnt bl;
+  FuncState *fs = ls->fs;
+  expdesc v;
+  int jf;  /* instruction to skip 'then' code (if condition is false) */
+  luaX_next(ls);  /* skip IF or ELSEIF */
+  expr(ls, &v);  /* read condition */
+  checknext(ls, TK_THEN);
+  if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+    luaK_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
+    enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
+    gotostat(ls, v.t);  /* handle goto/break */
+    skipnoopstat(ls);  /* skip other no-op statements */
+    if (block_follow(ls, 0)) {  /* 'goto' is the entire block? */
+      leaveblock(fs);
+      return;  /* and that is it */
+    }
+    else  /* must skip over 'then' part if condition is false */
+      jf = luaK_jump(fs);
+  }
+  else {  /* regular case (not goto/break) */
+    luaK_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
+    enterblock(fs, &bl, 0);
+    jf = v.f;
+  }
+  statlist(ls);  /* `then' part */
+  leaveblock(fs);
+  if (ls->t.token == TK_ELSE ||
+      ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
+    luaK_concat(fs, escapelist, luaK_jump(fs));  /* must jump over it */
+  luaK_patchtohere(fs, jf);
+}
+
+
+static void ifstat (LexState *ls, int line) {
+  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
+  FuncState *fs = ls->fs;
+  int escapelist = NO_JUMP;  /* exit list for finished parts */
+  test_then_block(ls, &escapelist);  /* IF cond THEN block */
+  while (ls->t.token == TK_ELSEIF)
+    test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
+  if (testnext(ls, TK_ELSE))
+    block(ls);  /* `else' part */
+  check_match(ls, TK_END, TK_IF, line);
+  luaK_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
+}
+
+
+static void localfunc (LexState *ls) {
+  expdesc b;
+  FuncState *fs = ls->fs;
+  new_localvar(ls, str_checkname(ls));  /* new local variable */
+  adjustlocalvars(ls, 1);  /* enter its scope */
+  body(ls, &b, 0, ls->linenumber);  /* function created in next register */
+  /* debug information will only see the variable after this point! */
+  getlocvar(fs, b.u.info)->startpc = fs->pc;
+}
+
+
+static void localstat (LexState *ls) {
+  /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
+  int nvars = 0;
+  int nexps;
+  expdesc e;
+  do {
+    new_localvar(ls, str_checkname(ls));
+    nvars++;
+  } while (testnext(ls, ','));
+  if (testnext(ls, '='))
+    nexps = explist(ls, &e);
+  else {
+    e.k = VVOID;
+    nexps = 0;
+  }
+  adjust_assign(ls, nvars, nexps, &e);
+  adjustlocalvars(ls, nvars);
+}
+
+
+static int funcname (LexState *ls, expdesc *v) {
+  /* funcname -> NAME {fieldsel} [`:' NAME] */
+  int ismethod = 0;
+  singlevar(ls, v);
+  while (ls->t.token == '.')
+    fieldsel(ls, v);
+  if (ls->t.token == ':') {
+    ismethod = 1;
+    fieldsel(ls, v);
+  }
+  return ismethod;
+}
+
+
+static void funcstat (LexState *ls, int line) {
+  /* funcstat -> FUNCTION funcname body */
+  int ismethod;
+  expdesc v, b;
+  luaX_next(ls);  /* skip FUNCTION */
+  ismethod = funcname(ls, &v);
+  body(ls, &b, ismethod, line);
+  luaK_storevar(ls->fs, &v, &b);
+  luaK_fixline(ls->fs, line);  /* definition `happens' in the first line */
+}
+
+
+static void exprstat (LexState *ls) {
+  /* stat -> func | assignment */
+  FuncState *fs = ls->fs;
+  struct LHS_assign v;
+  suffixedexp(ls, &v.v);
+  if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
+    v.prev = NULL;
+    assignment(ls, &v, 1);
+  }
+  else {  /* stat -> func */
+    check_condition(ls, v.v.k == VCALL, "syntax error");
+    SETARG_C(getcode(fs, &v.v), 1);  /* call statement uses no results */
+  }
+}
+
+
+static void retstat (LexState *ls) {
+  /* stat -> RETURN [explist] [';'] */
+  FuncState *fs = ls->fs;
+  expdesc e;
+  int first, nret;  /* registers with returned values */
+  if (block_follow(ls, 1) || ls->t.token == ';')
+    first = nret = 0;  /* return no values */
+  else {
+    nret = explist(ls, &e);  /* optional return values */
+    if (hasmultret(e.k)) {
+      luaK_setmultret(fs, &e);
+      if (e.k == VCALL && nret == 1) {  /* tail call? */
+        SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
+        lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
+      }
+      first = fs->nactvar;
+      nret = LUA_MULTRET;  /* return all values */
+    }
+    else {
+      if (nret == 1)  /* only one single value? */
+        first = luaK_exp2anyreg(fs, &e);
+      else {
+        luaK_exp2nextreg(fs, &e);  /* values must go to the `stack' */
+        first = fs->nactvar;  /* return all `active' values */
+        lua_assert(nret == fs->freereg - first);
+      }
+    }
+  }
+  luaK_ret(fs, first, nret);
+  testnext(ls, ';');  /* skip optional semicolon */
+}
+
+
+static void statement (LexState *ls) {
+  int line = ls->linenumber;  /* may be needed for error messages */
+  enterlevel(ls);
+  switch (ls->t.token) {
+    case ';': {  /* stat -> ';' (empty statement) */
+      luaX_next(ls);  /* skip ';' */
+      break;
+    }
+    case TK_IF: {  /* stat -> ifstat */
+      ifstat(ls, line);
+      break;
+    }
+    case TK_WHILE: {  /* stat -> whilestat */
+      whilestat(ls, line);
+      break;
+    }
+    case TK_DO: {  /* stat -> DO block END */
+      luaX_next(ls);  /* skip DO */
+      block(ls);
+      check_match(ls, TK_END, TK_DO, line);
+      break;
+    }
+    case TK_FOR: {  /* stat -> forstat */
+      forstat(ls, line);
+      break;
+    }
+    case TK_REPEAT: {  /* stat -> repeatstat */
+      repeatstat(ls, line);
+      break;
+    }
+    case TK_FUNCTION: {  /* stat -> funcstat */
+      funcstat(ls, line);
+      break;
+    }
+    case TK_LOCAL: {  /* stat -> localstat */
+      luaX_next(ls);  /* skip LOCAL */
+      if (testnext(ls, TK_FUNCTION))  /* local function? */
+        localfunc(ls);
+      else
+        localstat(ls);
+      break;
+    }
+    case TK_DBCOLON: {  /* stat -> label */
+      luaX_next(ls);  /* skip double colon */
+      labelstat(ls, str_checkname(ls), line);
+      break;
+    }
+    case TK_RETURN: {  /* stat -> retstat */
+      luaX_next(ls);  /* skip RETURN */
+      retstat(ls);
+      break;
+    }
+    case TK_BREAK:   /* stat -> breakstat */
+    case TK_GOTO: {  /* stat -> 'goto' NAME */
+      gotostat(ls, luaK_jump(ls->fs));
+      break;
+    }
+    default: {  /* stat -> func | assignment */
+      exprstat(ls);
+      break;
+    }
+  }
+  lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
+             ls->fs->freereg >= ls->fs->nactvar);
+  ls->fs->freereg = ls->fs->nactvar;  /* free registers */
+  leavelevel(ls);
+}
+
+/* }====================================================================== */
+
+
+/*
+** compiles the main function, which is a regular vararg function with an
+** upvalue named LUA_ENV
+*/
+static void mainfunc (LexState *ls, FuncState *fs) {
+  BlockCnt bl;
+  expdesc v;
+  open_func(ls, fs, &bl);
+  fs->f->is_vararg = 1;  /* main function is always vararg */
+  init_exp(&v, VLOCAL, 0);  /* create and... */
+  newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
+  luaX_next(ls);  /* read first token */
+  statlist(ls);  /* parse main body */
+  check(ls, TK_EOS);
+  close_func(ls);
+}
+
+
+Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+                      Dyndata *dyd, const char *name, int firstchar) {
+  LexState lexstate;
+  FuncState funcstate;
+  Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
+  /* anchor closure (to avoid being collected) */
+  setclLvalue(L, L->top, cl);
+  incr_top(L);
+  funcstate.f = cl->l.p = luaF_newproto(L);
+  funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
+  lexstate.buff = buff;
+  lexstate.dyd = dyd;
+  dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
+  luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
+  mainfunc(&lexstate, &funcstate);
+  lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
+  /* all scopes should be correctly finished */
+  lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+  return cl;  /* it's on the stack too */
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lparser.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,119 @@
+/*
+** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lparser_h
+#define lparser_h
+
+#include "llimits.h"
+#include "lobject.h"
+#include "lzio.h"
+
+
+/*
+** Expression descriptor
+*/
+
+typedef enum {
+  VVOID,	/* no value */
+  VNIL,
+  VTRUE,
+  VFALSE,
+  VK,		/* info = index of constant in `k' */
+  VKNUM,	/* nval = numerical value */
+  VNONRELOC,	/* info = result register */
+  VLOCAL,	/* info = local register */
+  VUPVAL,       /* info = index of upvalue in 'upvalues' */
+  VINDEXED,	/* t = table register/upvalue; idx = index R/K */
+  VJMP,		/* info = instruction pc */
+  VRELOCABLE,	/* info = instruction pc */
+  VCALL,	/* info = instruction pc */
+  VVARARG	/* info = instruction pc */
+} expkind;
+
+
+#define vkisvar(k)	(VLOCAL <= (k) && (k) <= VINDEXED)
+#define vkisinreg(k)	((k) == VNONRELOC || (k) == VLOCAL)
+
+typedef struct expdesc {
+  expkind k;
+  union {
+    struct {  /* for indexed variables (VINDEXED) */
+      short idx;  /* index (R/K) */
+      lu_byte t;  /* table (register or upvalue) */
+      lu_byte vt;  /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
+    } ind;
+    int info;  /* for generic use */
+    lua_Number nval;  /* for VKNUM */
+  } u;
+  int t;  /* patch list of `exit when true' */
+  int f;  /* patch list of `exit when false' */
+} expdesc;
+
+
+/* description of active local variable */
+typedef struct Vardesc {
+  short idx;  /* variable index in stack */
+} Vardesc;
+
+
+/* description of pending goto statements and label statements */
+typedef struct Labeldesc {
+  TString *name;  /* label identifier */
+  int pc;  /* position in code */
+  int line;  /* line where it appeared */
+  lu_byte nactvar;  /* local level where it appears in current block */
+} Labeldesc;
+
+
+/* list of labels or gotos */
+typedef struct Labellist {
+  Labeldesc *arr;  /* array */
+  int n;  /* number of entries in use */
+  int size;  /* array size */
+} Labellist;
+
+
+/* dynamic structures used by the parser */
+typedef struct Dyndata {
+  struct {  /* list of active local variables */
+    Vardesc *arr;
+    int n;
+    int size;
+  } actvar;
+  Labellist gt;  /* list of pending gotos */
+  Labellist label;   /* list of active labels */
+} Dyndata;
+
+
+/* control of blocks */
+struct BlockCnt;  /* defined in lparser.c */
+
+
+/* state needed to generate code for a given function */
+typedef struct FuncState {
+  Proto *f;  /* current function header */
+  Table *h;  /* table to find (and reuse) elements in `k' */
+  struct FuncState *prev;  /* enclosing function */
+  struct LexState *ls;  /* lexical state */
+  struct BlockCnt *bl;  /* chain of current blocks */
+  int pc;  /* next position to code (equivalent to `ncode') */
+  int lasttarget;   /* 'label' of last 'jump label' */
+  int jpc;  /* list of pending jumps to `pc' */
+  int nk;  /* number of elements in `k' */
+  int np;  /* number of elements in `p' */
+  int firstlocal;  /* index of first local var (in Dyndata array) */
+  short nlocvars;  /* number of elements in 'f->locvars' */
+  lu_byte nactvar;  /* number of active local variables */
+  lu_byte nups;  /* number of upvalues */
+  lu_byte freereg;  /* first free register */
+} FuncState;
+
+
+LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+                                Dyndata *dyd, const char *name, int firstchar);
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,328 @@
+/*
+** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+#include <string.h>
+
+#define lstate_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+#if !defined(LUAI_GCPAUSE)
+#define LUAI_GCPAUSE	200  /* 200% */
+#endif
+
+#if !defined(LUAI_GCMAJOR)
+#define LUAI_GCMAJOR	200  /* 200% */
+#endif
+
+#if !defined(LUAI_GCMUL)
+#define LUAI_GCMUL	200 /* GC runs 'twice the speed' of memory allocation */
+#endif
+
+
+#define MEMERRMSG	"not enough memory"
+
+
+/*
+** a macro to help the creation of a unique random seed when a state is
+** created; the seed is used to randomize hashes.
+*/
+#if !defined(luai_makeseed)
+#ifndef SYSLINUX
+#include <time.h>
+#define luai_makeseed()		cast(unsigned int, time(NULL))
+#else
+#include <sys/times.h>
+#define luai_makeseed()		cast(unsigned int, times(NULL))
+#endif /* SYSLINUX */
+#endif
+
+
+
+/*
+** thread state + extra space
+*/
+typedef struct LX {
+#if defined(LUAI_EXTRASPACE)
+  char buff[LUAI_EXTRASPACE];
+#endif
+  lua_State l;
+} LX;
+
+
+/*
+** Main thread combines a thread state and the global state
+*/
+typedef struct LG {
+  LX l;
+  global_State g;
+} LG;
+
+
+
+#define fromstate(L)	(cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
+
+
+/*
+** Compute an initial seed as random as possible. In ANSI, rely on
+** Address Space Layout Randomization (if present) to increase
+** randomness..
+*/
+#define addbuff(b,p,e) \
+  { size_t t = cast(size_t, e); \
+    memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); }
+
+static unsigned int makeseed (lua_State *L) {
+  char buff[4 * sizeof(size_t)];
+  unsigned int h = luai_makeseed();
+  int p = 0;
+  addbuff(buff, p, L);  /* heap variable */
+  addbuff(buff, p, &h);  /* local variable */
+  addbuff(buff, p, luaO_nilobject);  /* global variable */
+  addbuff(buff, p, &lua_newstate);  /* public function */
+  lua_assert(p == sizeof(buff));
+  return luaS_hash(buff, p, h);
+}
+
+
+/*
+** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
+** invariant
+*/
+void luaE_setdebt (global_State *g, l_mem debt) {
+  g->totalbytes -= (debt - g->GCdebt);
+  g->GCdebt = debt;
+}
+
+
+CallInfo *luaE_extendCI (lua_State *L) {
+  CallInfo *ci = luaM_new(L, CallInfo);
+  lua_assert(L->ci->next == NULL);
+  L->ci->next = ci;
+  ci->previous = L->ci;
+  ci->next = NULL;
+  return ci;
+}
+
+
+void luaE_freeCI (lua_State *L) {
+  CallInfo *ci = L->ci;
+  CallInfo *next = ci->next;
+  ci->next = NULL;
+  while ((ci = next) != NULL) {
+    next = ci->next;
+    luaM_free(L, ci);
+  }
+}
+
+
+static void stack_init (lua_State *L1, lua_State *L) {
+  int i; CallInfo *ci;
+  /* initialize stack array */
+  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
+  L1->stacksize = BASIC_STACK_SIZE;
+  for (i = 0; i < BASIC_STACK_SIZE; i++)
+    setnilvalue(L1->stack + i);  /* erase new stack */
+  L1->top = L1->stack;
+  L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
+  /* initialize first ci */
+  ci = &L1->base_ci;
+  ci->next = ci->previous = NULL;
+  ci->callstatus = 0;
+  ci->func = L1->top;
+  setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
+  ci->top = L1->top + LUA_MINSTACK;
+  L1->ci = ci;
+}
+
+
+static void freestack (lua_State *L) {
+  if (L->stack == NULL)
+    return;  /* stack not completely built yet */
+  L->ci = &L->base_ci;  /* free the entire 'ci' list */
+  luaE_freeCI(L);
+  luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
+}
+
+
+/*
+** Create registry table and its predefined values
+*/
+static void init_registry (lua_State *L, global_State *g) {
+  TValue mt;
+  /* create registry */
+  Table *registry = luaH_new(L);
+  sethvalue(L, &g->l_registry, registry);
+  luaH_resize(L, registry, LUA_RIDX_LAST, 0);
+  /* registry[LUA_RIDX_MAINTHREAD] = L */
+  setthvalue(L, &mt, L);
+  luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
+  /* registry[LUA_RIDX_GLOBALS] = table of globals */
+  sethvalue(L, &mt, luaH_new(L));
+  luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
+}
+
+
+/*
+** open parts of the state that may cause memory-allocation errors
+*/
+static void f_luaopen (lua_State *L, void *ud) {
+  global_State *g = G(L);
+  UNUSED(ud);
+  stack_init(L, L);  /* init stack */
+  init_registry(L, g);
+  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
+  luaT_init(L);
+  luaX_init(L);
+  /* pre-create memory-error message */
+  g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
+  luaS_fix(g->memerrmsg);  /* it should never be collected */
+  g->gcrunning = 1;  /* allow gc */
+  g->version = lua_version(NULL);
+  luai_userstateopen(L);
+}
+
+
+/*
+** preinitialize a state with consistent values without allocating
+** any memory (to avoid errors)
+*/
+static void preinit_state (lua_State *L, global_State *g) {
+  G(L) = g;
+  L->stack = NULL;
+  L->ci = NULL;
+  L->stacksize = 0;
+  L->errorJmp = NULL;
+  L->nCcalls = 0;
+  L->hook = NULL;
+  L->hookmask = 0;
+  L->basehookcount = 0;
+  L->allowhook = 1;
+  resethookcount(L);
+  L->openupval = NULL;
+  L->nny = 1;
+  L->status = LUA_OK;
+  L->errfunc = 0;
+}
+
+
+static void close_state (lua_State *L) {
+  global_State *g = G(L);
+  luaF_close(L, L->stack);  /* close all upvalues for this thread */
+  luaC_freeallobjects(L);  /* collect all objects */
+  if (g->version)  /* closing a fully built state? */
+    luai_userstateclose(L);
+  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
+  luaZ_freebuffer(L, &g->buff);
+  freestack(L);
+  lua_assert(gettotalbytes(g) == sizeof(LG));
+  (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
+}
+
+
+LUA_API lua_State *lua_newthread (lua_State *L) {
+  lua_State *L1;
+  lua_lock(L);
+  luaC_checkGC(L);
+  L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
+  setthvalue(L, L->top, L1);
+  api_incr_top(L);
+  preinit_state(L1, G(L));
+  L1->hookmask = L->hookmask;
+  L1->basehookcount = L->basehookcount;
+  L1->hook = L->hook;
+  resethookcount(L1);
+  luai_userstatethread(L, L1);
+  stack_init(L1, L);  /* init stack */
+  lua_unlock(L);
+  return L1;
+}
+
+
+void luaE_freethread (lua_State *L, lua_State *L1) {
+  LX *l = fromstate(L1);
+  luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
+  lua_assert(L1->openupval == NULL);
+  luai_userstatefree(L, L1);
+  freestack(L1);
+  luaM_free(L, l);
+}
+
+
+LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
+  int i;
+  lua_State *L;
+  global_State *g;
+  LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
+  if (l == NULL) return NULL;
+  L = &l->l.l;
+  g = &l->g;
+  L->next = NULL;
+  L->tt = LUA_TTHREAD;
+  g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
+  L->marked = luaC_white(g);
+  g->gckind = KGC_NORMAL;
+  preinit_state(L, g);
+  g->frealloc = f;
+  g->ud = ud;
+  g->mainthread = L;
+  g->seed = makeseed(L);
+  g->uvhead.u.l.prev = &g->uvhead;
+  g->uvhead.u.l.next = &g->uvhead;
+  g->gcrunning = 0;  /* no GC while building state */
+  g->GCestimate = 0;
+  g->strt.size = 0;
+  g->strt.nuse = 0;
+  g->strt.hash = NULL;
+  setnilvalue(&g->l_registry);
+  luaZ_initbuffer(L, &g->buff);
+  g->panic = NULL;
+  g->version = NULL;
+  g->gcstate = GCSpause;
+  g->allgc = NULL;
+  g->finobj = NULL;
+  g->tobefnz = NULL;
+  g->sweepgc = g->sweepfin = NULL;
+  g->gray = g->grayagain = NULL;
+  g->weak = g->ephemeron = g->allweak = NULL;
+  g->totalbytes = sizeof(LG);
+  g->GCdebt = 0;
+  g->gcpause = LUAI_GCPAUSE;
+  g->gcmajorinc = LUAI_GCMAJOR;
+  g->gcstepmul = LUAI_GCMUL;
+  for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
+  if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
+    /* memory allocation error: free partial state */
+    close_state(L);
+    L = NULL;
+  }
+  return L;
+}
+
+
+LUA_API void lua_close (lua_State *L) {
+  L = G(L)->mainthread;  /* only the main thread can be closed */
+  lua_lock(L);
+  close_state(L);
+}
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lstate.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,228 @@
+/*
+** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstate_h
+#define lstate_h
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "ltm.h"
+#include "lzio.h"
+
+
+/*
+
+** Some notes about garbage-collected objects:  All objects in Lua must
+** be kept somehow accessible until being freed.
+**
+** Lua keeps most objects linked in list g->allgc. The link uses field
+** 'next' of the CommonHeader.
+**
+** Strings are kept in several lists headed by the array g->strt.hash.
+**
+** Open upvalues are not subject to independent garbage collection. They
+** are collected together with their respective threads. Lua keeps a
+** double-linked list with all open upvalues (g->uvhead) so that it can
+** mark objects referred by them. (They are always gray, so they must
+** be remarked in the atomic step. Usually their contents would be marked
+** when traversing the respective threads, but the thread may already be
+** dead, while the upvalue is still accessible through closures.)
+**
+** Objects with finalizers are kept in the list g->finobj.
+**
+** The list g->tobefnz links all objects being finalized.
+
+*/
+
+
+struct lua_longjmp;  /* defined in ldo.c */
+
+
+
+/* extra stack space to handle TM calls and some other extras */
+#define EXTRA_STACK   5
+
+
+#define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
+
+
+/* kinds of Garbage Collection */
+#define KGC_NORMAL	0
+#define KGC_EMERGENCY	1	/* gc was forced by an allocation failure */
+#define KGC_GEN		2	/* generational collection */
+
+
+typedef struct stringtable {
+  GCObject **hash;
+  lu_int32 nuse;  /* number of elements */
+  int size;
+} stringtable;
+
+
+/*
+** information about a call
+*/
+typedef struct CallInfo {
+  StkId func;  /* function index in the stack */
+  StkId	top;  /* top for this function */
+  struct CallInfo *previous, *next;  /* dynamic call link */
+  short nresults;  /* expected number of results from this function */
+  lu_byte callstatus;
+  ptrdiff_t extra;
+  union {
+    struct {  /* only for Lua functions */
+      StkId base;  /* base for this function */
+      const Instruction *savedpc;
+    } l;
+    struct {  /* only for C functions */
+      int ctx;  /* context info. in case of yields */
+      lua_CFunction k;  /* continuation in case of yields */
+      ptrdiff_t old_errfunc;
+      lu_byte old_allowhook;
+      lu_byte status;
+    } c;
+  } u;
+} CallInfo;
+
+
+/*
+** Bits in CallInfo status
+*/
+#define CIST_LUA	(1<<0)	/* call is running a Lua function */
+#define CIST_HOOKED	(1<<1)	/* call is running a debug hook */
+#define CIST_REENTRY	(1<<2)	/* call is running on same invocation of
+                                   luaV_execute of previous call */
+#define CIST_YIELDED	(1<<3)	/* call reentered after suspension */
+#define CIST_YPCALL	(1<<4)	/* call is a yieldable protected call */
+#define CIST_STAT	(1<<5)	/* call has an error status (pcall) */
+#define CIST_TAIL	(1<<6)	/* call was tail called */
+#define CIST_HOOKYIELD	(1<<7)	/* last hook called yielded */
+
+
+#define isLua(ci)	((ci)->callstatus & CIST_LUA)
+
+
+/*
+** `global state', shared by all threads of this state
+*/
+typedef struct global_State {
+  lua_Alloc frealloc;  /* function to reallocate memory */
+  void *ud;         /* auxiliary data to `frealloc' */
+  lu_mem totalbytes;  /* number of bytes currently allocated - GCdebt */
+  l_mem GCdebt;  /* bytes allocated not yet compensated by the collector */
+  lu_mem GCmemtrav;  /* memory traversed by the GC */
+  lu_mem GCestimate;  /* an estimate of the non-garbage memory in use */
+  stringtable strt;  /* hash table for strings */
+  TValue l_registry;
+  unsigned int seed;  /* randomized seed for hashes */
+  lu_byte currentwhite;
+  lu_byte gcstate;  /* state of garbage collector */
+  lu_byte gckind;  /* kind of GC running */
+  lu_byte gcrunning;  /* true if GC is running */
+  int sweepstrgc;  /* position of sweep in `strt' */
+  GCObject *allgc;  /* list of all collectable objects */
+  GCObject *finobj;  /* list of collectable objects with finalizers */
+  GCObject **sweepgc;  /* current position of sweep in list 'allgc' */
+  GCObject **sweepfin;  /* current position of sweep in list 'finobj' */
+  GCObject *gray;  /* list of gray objects */
+  GCObject *grayagain;  /* list of objects to be traversed atomically */
+  GCObject *weak;  /* list of tables with weak values */
+  GCObject *ephemeron;  /* list of ephemeron tables (weak keys) */
+  GCObject *allweak;  /* list of all-weak tables */
+  GCObject *tobefnz;  /* list of userdata to be GC */
+  UpVal uvhead;  /* head of double-linked list of all open upvalues */
+  Mbuffer buff;  /* temporary buffer for string concatenation */
+  int gcpause;  /* size of pause between successive GCs */
+  int gcmajorinc;  /* pause between major collections (only in gen. mode) */
+  int gcstepmul;  /* GC `granularity' */
+  lua_CFunction panic;  /* to be called in unprotected errors */
+  struct lua_State *mainthread;
+  const lua_Number *version;  /* pointer to version number */
+  TString *memerrmsg;  /* memory-error message */
+  TString *tmname[TM_N];  /* array with tag-method names */
+  struct Table *mt[LUA_NUMTAGS];  /* metatables for basic types */
+} global_State;
+
+
+/*
+** `per thread' state
+*/
+struct lua_State {
+  CommonHeader;
+  lu_byte status;
+  StkId top;  /* first free slot in the stack */
+  global_State *l_G;
+  CallInfo *ci;  /* call info for current function */
+  const Instruction *oldpc;  /* last pc traced */
+  StkId stack_last;  /* last free slot in the stack */
+  StkId stack;  /* stack base */
+  int stacksize;
+  unsigned short nny;  /* number of non-yieldable calls in stack */
+  unsigned short nCcalls;  /* number of nested C calls */
+  lu_byte hookmask;
+  lu_byte allowhook;
+  int basehookcount;
+  int hookcount;
+  lua_Hook hook;
+  GCObject *openupval;  /* list of open upvalues in this stack */
+  GCObject *gclist;
+  struct lua_longjmp *errorJmp;  /* current error recover point */
+  ptrdiff_t errfunc;  /* current error handling function (stack index) */
+  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
+};
+
+
+#define G(L)	(L->l_G)
+
+
+/*
+** Union of all collectable objects
+*/
+union GCObject {
+  GCheader gch;  /* common header */
+  union TString ts;
+  union Udata u;
+  union Closure cl;
+  struct Table h;
+  struct Proto p;
+  struct UpVal uv;
+  struct lua_State th;  /* thread */
+};
+
+
+#define gch(o)		(&(o)->gch)
+
+/* macros to convert a GCObject into a specific value */
+#define rawgco2ts(o)  \
+	check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts))
+#define gco2ts(o)	(&rawgco2ts(o)->tsv)
+#define rawgco2u(o)	check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
+#define gco2u(o)	(&rawgco2u(o)->uv)
+#define gco2lcl(o)	check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l))
+#define gco2ccl(o)	check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c))
+#define gco2cl(o)  \
+	check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
+#define gco2t(o)	check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
+#define gco2p(o)	check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
+#define gco2uv(o)	check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
+#define gco2th(o)	check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
+
+/* macro to convert any Lua object into a GCObject */
+#define obj2gco(v)	(cast(GCObject *, (v)))
+
+
+/* actual number of total bytes allocated */
+#define gettotalbytes(g)	((g)->totalbytes + (g)->GCdebt)
+
+LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
+LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
+LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
+LUAI_FUNC void luaE_freeCI (lua_State *L);
+
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,185 @@
+/*
+** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 roberto Exp $
+** String table (keeps all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lstring_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+
+
+/*
+** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
+** compute its hash
+*/
+#if !defined(LUAI_HASHLIMIT)
+#define LUAI_HASHLIMIT		5
+#endif
+
+
+/*
+** equality for long strings
+*/
+int luaS_eqlngstr (TString *a, TString *b) {
+  size_t len = a->tsv.len;
+  lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR);
+  return (a == b) ||  /* same instance or... */
+    ((len == b->tsv.len) &&  /* equal length and ... */
+     (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
+}
+
+
+/*
+** equality for strings
+*/
+int luaS_eqstr (TString *a, TString *b) {
+  return (a->tsv.tt == b->tsv.tt) &&
+         (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b));
+}
+
+
+unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
+  unsigned int h = seed ^ cast(unsigned int, l);
+  size_t l1;
+  size_t step = (l >> LUAI_HASHLIMIT) + 1;
+  for (l1 = l; l1 >= step; l1 -= step)
+    h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1]));
+  return h;
+}
+
+
+/*
+** resizes the string table
+*/
+void luaS_resize (lua_State *L, int newsize) {
+  int i;
+  stringtable *tb = &G(L)->strt;
+  /* cannot resize while GC is traversing strings */
+  luaC_runtilstate(L, ~bitmask(GCSsweepstring));
+  if (newsize > tb->size) {
+    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
+    for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
+  }
+  /* rehash */
+  for (i=0; i<tb->size; i++) {
+    GCObject *p = tb->hash[i];
+    tb->hash[i] = NULL;
+    while (p) {  /* for each node in the list */
+      GCObject *next = gch(p)->next;  /* save next */
+      unsigned int h = lmod(gco2ts(p)->hash, newsize);  /* new position */
+      gch(p)->next = tb->hash[h];  /* chain it */
+      tb->hash[h] = p;
+      resetoldbit(p);  /* see MOVE OLD rule */
+      p = next;
+    }
+  }
+  if (newsize < tb->size) {
+    /* shrinking slice must be empty */
+    lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
+    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
+  }
+  tb->size = newsize;
+}
+
+
+/*
+** creates a new string object
+*/
+static TString *createstrobj (lua_State *L, const char *str, size_t l,
+                              int tag, unsigned int h, GCObject **list) {
+  TString *ts;
+  size_t totalsize;  /* total size of TString object */
+  totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
+  ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts;
+  ts->tsv.len = l;
+  ts->tsv.hash = h;
+  ts->tsv.extra = 0;
+  memcpy(ts+1, str, l*sizeof(char));
+  ((char *)(ts+1))[l] = '\0';  /* ending 0 */
+  return ts;
+}
+
+
+/*
+** creates a new short string, inserting it into string table
+*/
+static TString *newshrstr (lua_State *L, const char *str, size_t l,
+                                       unsigned int h) {
+  GCObject **list;  /* (pointer to) list where it will be inserted */
+  stringtable *tb = &G(L)->strt;
+  TString *s;
+  if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
+    luaS_resize(L, tb->size*2);  /* too crowded */
+  list = &tb->hash[lmod(h, tb->size)];
+  s = createstrobj(L, str, l, LUA_TSHRSTR, h, list);
+  tb->nuse++;
+  return s;
+}
+
+
+/*
+** checks whether short string exists and reuses it or creates a new one
+*/
+static TString *internshrstr (lua_State *L, const char *str, size_t l) {
+  GCObject *o;
+  global_State *g = G(L);
+  unsigned int h = luaS_hash(str, l, g->seed);
+  for (o = g->strt.hash[lmod(h, g->strt.size)];
+       o != NULL;
+       o = gch(o)->next) {
+    TString *ts = rawgco2ts(o);
+    if (h == ts->tsv.hash &&
+        l == ts->tsv.len &&
+        (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
+      if (isdead(G(L), o))  /* string is dead (but was not collected yet)? */
+        changewhite(o);  /* resurrect it */
+      return ts;
+    }
+  }
+  return newshrstr(L, str, l, h);  /* not found; create a new string */
+}
+
+
+/*
+** new string (with explicit length)
+*/
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+  if (l <= LUAI_MAXSHORTLEN)  /* short string? */
+    return internshrstr(L, str, l);
+  else {
+    if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
+      luaM_toobig(L);
+    return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL);
+  }
+}
+
+
+/*
+** new zero-terminated string
+*/
+TString *luaS_new (lua_State *L, const char *str) {
+  return luaS_newlstr(L, str, strlen(str));
+}
+
+
+Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
+  Udata *u;
+  if (s > MAX_SIZET - sizeof(Udata))
+    luaM_toobig(L);
+  u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
+  u->uv.len = s;
+  u->uv.metatable = NULL;
+  u->uv.env = e;
+  return u;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lstring.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,46 @@
+/*
+** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $
+** String table (keep all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstring_h
+#define lstring_h
+
+#include "lgc.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+#define sizestring(s)	(sizeof(union TString)+((s)->len+1)*sizeof(char))
+
+#define sizeudata(u)	(sizeof(union Udata)+(u)->len)
+
+#define luaS_newliteral(L, s)	(luaS_newlstr(L, "" s, \
+                                 (sizeof(s)/sizeof(char))-1))
+
+#define luaS_fix(s)	l_setbit((s)->tsv.marked, FIXEDBIT)
+
+
+/*
+** test whether a string is a reserved word
+*/
+#define isreserved(s)	((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0)
+
+
+/*
+** equality for short strings, which are always internalized
+*/
+#define eqshrstr(a,b)	check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b))
+
+
+LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
+LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
+LUAI_FUNC int luaS_eqstr (TString *a, TString *b);
+LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
+LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lstrlib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lstrlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lstrlib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1019 @@
+/*
+** $Id: lstrlib.c,v 1.178.1.1 2013/04/12 18:48:47 roberto Exp $
+** Standard library for string operations and pattern-matching
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lstrlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/*
+** maximum number of captures that a pattern can do during
+** pattern-matching. This limit is arbitrary.
+*/
+#if !defined(LUA_MAXCAPTURES)
+#define LUA_MAXCAPTURES		32
+#endif
+
+
+/* macro to `unsign' a character */
+#define uchar(c)	((unsigned char)(c))
+
+
+
+static int str_len (lua_State *L) {
+  size_t l;
+  luaL_checklstring(L, 1, &l);
+  lua_pushinteger(L, (lua_Integer)l);
+  return 1;
+}
+
+
+/* translate a relative string position: negative means back from end */
+static size_t posrelat (ptrdiff_t pos, size_t len) {
+  if (pos >= 0) return (size_t)pos;
+  else if (0u - (size_t)pos > len) return 0;
+  else return len - ((size_t)-pos) + 1;
+}
+
+
+static int str_sub (lua_State *L) {
+  size_t l;
+  const char *s = luaL_checklstring(L, 1, &l);
+  size_t start = posrelat(luaL_checkinteger(L, 2), l);
+  size_t end = posrelat(luaL_optinteger(L, 3, -1), l);
+  if (start < 1) start = 1;
+  if (end > l) end = l;
+  if (start <= end)
+    lua_pushlstring(L, s + start - 1, end - start + 1);
+  else lua_pushliteral(L, "");
+  return 1;
+}
+
+
+static int str_reverse (lua_State *L) {
+  size_t l, i;
+  luaL_Buffer b;
+  const char *s = luaL_checklstring(L, 1, &l);
+  char *p = luaL_buffinitsize(L, &b, l);
+  for (i = 0; i < l; i++)
+    p[i] = s[l - i - 1];
+  luaL_pushresultsize(&b, l);
+  return 1;
+}
+
+
+static int str_lower (lua_State *L) {
+  size_t l;
+  size_t i;
+  luaL_Buffer b;
+  const char *s = luaL_checklstring(L, 1, &l);
+  char *p = luaL_buffinitsize(L, &b, l);
+  for (i=0; i<l; i++)
+    p[i] = tolower(uchar(s[i]));
+  luaL_pushresultsize(&b, l);
+  return 1;
+}
+
+
+static int str_upper (lua_State *L) {
+  size_t l;
+  size_t i;
+  luaL_Buffer b;
+  const char *s = luaL_checklstring(L, 1, &l);
+  char *p = luaL_buffinitsize(L, &b, l);
+  for (i=0; i<l; i++)
+    p[i] = toupper(uchar(s[i]));
+  luaL_pushresultsize(&b, l);
+  return 1;
+}
+
+
+/* reasonable limit to avoid arithmetic overflow */
+#define MAXSIZE		((~(size_t)0) >> 1)
+
+static int str_rep (lua_State *L) {
+  size_t l, lsep;
+  const char *s = luaL_checklstring(L, 1, &l);
+  int n = luaL_checkint(L, 2);
+  const char *sep = luaL_optlstring(L, 3, "", &lsep);
+  if (n <= 0) lua_pushliteral(L, "");
+  else if (l + lsep < l || l + lsep >= MAXSIZE / n)  /* may overflow? */
+    return luaL_error(L, "resulting string too large");
+  else {
+    size_t totallen = n * l + (n - 1) * lsep;
+    luaL_Buffer b;
+    char *p = luaL_buffinitsize(L, &b, totallen);
+    while (n-- > 1) {  /* first n-1 copies (followed by separator) */
+      memcpy(p, s, l * sizeof(char)); p += l;
+      if (lsep > 0) {  /* avoid empty 'memcpy' (may be expensive) */
+        memcpy(p, sep, lsep * sizeof(char)); p += lsep;
+      }
+    }
+    memcpy(p, s, l * sizeof(char));  /* last copy (not followed by separator) */
+    luaL_pushresultsize(&b, totallen);
+  }
+  return 1;
+}
+
+
+static int str_byte (lua_State *L) {
+  size_t l;
+  const char *s = luaL_checklstring(L, 1, &l);
+  size_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
+  size_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
+  int n, i;
+  if (posi < 1) posi = 1;
+  if (pose > l) pose = l;
+  if (posi > pose) return 0;  /* empty interval; return no values */
+  n = (int)(pose -  posi + 1);
+  if (posi + n <= pose)  /* (size_t -> int) overflow? */
+    return luaL_error(L, "string slice too long");
+  luaL_checkstack(L, n, "string slice too long");
+  for (i=0; i<n; i++)
+    lua_pushinteger(L, uchar(s[posi+i-1]));
+  return n;
+}
+
+
+static int str_char (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  int i;
+  luaL_Buffer b;
+  char *p = luaL_buffinitsize(L, &b, n);
+  for (i=1; i<=n; i++) {
+    int c = luaL_checkint(L, i);
+    luaL_argcheck(L, uchar(c) == c, i, "value out of range");
+    p[i - 1] = uchar(c);
+  }
+  luaL_pushresultsize(&b, n);
+  return 1;
+}
+
+
+static int writer (lua_State *L, const void* b, size_t size, void* B) {
+  (void)L;
+  luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
+  return 0;
+}
+
+
+static int str_dump (lua_State *L) {
+  luaL_Buffer b;
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+  lua_settop(L, 1);
+  luaL_buffinit(L,&b);
+  if (lua_dump(L, writer, &b) != 0)
+    return luaL_error(L, "unable to dump given function");
+  luaL_pushresult(&b);
+  return 1;
+}
+
+
+
+/*
+** {======================================================
+** PATTERN MATCHING
+** =======================================================
+*/
+
+
+#define CAP_UNFINISHED	(-1)
+#define CAP_POSITION	(-2)
+
+
+typedef struct MatchState {
+  int matchdepth;  /* control for recursive depth (to avoid C stack overflow) */
+  const char *src_init;  /* init of source string */
+  const char *src_end;  /* end ('\0') of source string */
+  const char *p_end;  /* end ('\0') of pattern */
+  lua_State *L;
+  int level;  /* total number of captures (finished or unfinished) */
+  struct {
+    const char *init;
+    ptrdiff_t len;
+  } capture[LUA_MAXCAPTURES];
+} MatchState;
+
+
+/* recursive function */
+static const char *match (MatchState *ms, const char *s, const char *p);
+
+
+/* maximum recursion depth for 'match' */
+#if !defined(MAXCCALLS)
+#define MAXCCALLS	200
+#endif
+
+
+#define L_ESC		'%'
+#define SPECIALS	"^$*+?.([%-"
+
+
+static int check_capture (MatchState *ms, int l) {
+  l -= '1';
+  if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
+    return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
+  return l;
+}
+
+
+static int capture_to_close (MatchState *ms) {
+  int level = ms->level;
+  for (level--; level>=0; level--)
+    if (ms->capture[level].len == CAP_UNFINISHED) return level;
+  return luaL_error(ms->L, "invalid pattern capture");
+}
+
+
+static const char *classend (MatchState *ms, const char *p) {
+  switch (*p++) {
+    case L_ESC: {
+      if (p == ms->p_end)
+        luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
+      return p+1;
+    }
+    case '[': {
+      if (*p == '^') p++;
+      do {  /* look for a `]' */
+        if (p == ms->p_end)
+          luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
+        if (*(p++) == L_ESC && p < ms->p_end)
+          p++;  /* skip escapes (e.g. `%]') */
+      } while (*p != ']');
+      return p+1;
+    }
+    default: {
+      return p;
+    }
+  }
+}
+
+
+static int match_class (int c, int cl) {
+  int res;
+  switch (tolower(cl)) {
+    case 'a' : res = isalpha(c); break;
+    case 'c' : res = iscntrl(c); break;
+    case 'd' : res = isdigit(c); break;
+    case 'g' : res = isgraph(c); break;
+    case 'l' : res = islower(c); break;
+    case 'p' : res = ispunct(c); break;
+    case 's' : res = isspace(c); break;
+    case 'u' : res = isupper(c); break;
+    case 'w' : res = isalnum(c); break;
+    case 'x' : res = isxdigit(c); break;
+    case 'z' : res = (c == 0); break;  /* deprecated option */
+    default: return (cl == c);
+  }
+  return (islower(cl) ? res : !res);
+}
+
+
+static int matchbracketclass (int c, const char *p, const char *ec) {
+  int sig = 1;
+  if (*(p+1) == '^') {
+    sig = 0;
+    p++;  /* skip the `^' */
+  }
+  while (++p < ec) {
+    if (*p == L_ESC) {
+      p++;
+      if (match_class(c, uchar(*p)))
+        return sig;
+    }
+    else if ((*(p+1) == '-') && (p+2 < ec)) {
+      p+=2;
+      if (uchar(*(p-2)) <= c && c <= uchar(*p))
+        return sig;
+    }
+    else if (uchar(*p) == c) return sig;
+  }
+  return !sig;
+}
+
+
+static int singlematch (MatchState *ms, const char *s, const char *p,
+                        const char *ep) {
+  if (s >= ms->src_end)
+    return 0;
+  else {
+    int c = uchar(*s);
+    switch (*p) {
+      case '.': return 1;  /* matches any char */
+      case L_ESC: return match_class(c, uchar(*(p+1)));
+      case '[': return matchbracketclass(c, p, ep-1);
+      default:  return (uchar(*p) == c);
+    }
+  }
+}
+
+
+static const char *matchbalance (MatchState *ms, const char *s,
+                                   const char *p) {
+  if (p >= ms->p_end - 1)
+    luaL_error(ms->L, "malformed pattern "
+                      "(missing arguments to " LUA_QL("%%b") ")");
+  if (*s != *p) return NULL;
+  else {
+    int b = *p;
+    int e = *(p+1);
+    int cont = 1;
+    while (++s < ms->src_end) {
+      if (*s == e) {
+        if (--cont == 0) return s+1;
+      }
+      else if (*s == b) cont++;
+    }
+  }
+  return NULL;  /* string ends out of balance */
+}
+
+
+static const char *max_expand (MatchState *ms, const char *s,
+                                 const char *p, const char *ep) {
+  ptrdiff_t i = 0;  /* counts maximum expand for item */
+  while (singlematch(ms, s + i, p, ep))
+    i++;
+  /* keeps trying to match with the maximum repetitions */
+  while (i>=0) {
+    const char *res = match(ms, (s+i), ep+1);
+    if (res) return res;
+    i--;  /* else didn't match; reduce 1 repetition to try again */
+  }
+  return NULL;
+}
+
+
+static const char *min_expand (MatchState *ms, const char *s,
+                                 const char *p, const char *ep) {
+  for (;;) {
+    const char *res = match(ms, s, ep+1);
+    if (res != NULL)
+      return res;
+    else if (singlematch(ms, s, p, ep))
+      s++;  /* try with one more repetition */
+    else return NULL;
+  }
+}
+
+
+static const char *start_capture (MatchState *ms, const char *s,
+                                    const char *p, int what) {
+  const char *res;
+  int level = ms->level;
+  if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
+  ms->capture[level].init = s;
+  ms->capture[level].len = what;
+  ms->level = level+1;
+  if ((res=match(ms, s, p)) == NULL)  /* match failed? */
+    ms->level--;  /* undo capture */
+  return res;
+}
+
+
+static const char *end_capture (MatchState *ms, const char *s,
+                                  const char *p) {
+  int l = capture_to_close(ms);
+  const char *res;
+  ms->capture[l].len = s - ms->capture[l].init;  /* close capture */
+  if ((res = match(ms, s, p)) == NULL)  /* match failed? */
+    ms->capture[l].len = CAP_UNFINISHED;  /* undo capture */
+  return res;
+}
+
+
+static const char *match_capture (MatchState *ms, const char *s, int l) {
+  size_t len;
+  l = check_capture(ms, l);
+  len = ms->capture[l].len;
+  if ((size_t)(ms->src_end-s) >= len &&
+      memcmp(ms->capture[l].init, s, len) == 0)
+    return s+len;
+  else return NULL;
+}
+
+
+static const char *match (MatchState *ms, const char *s, const char *p) {
+  if (ms->matchdepth-- == 0)
+    luaL_error(ms->L, "pattern too complex");
+  init: /* using goto's to optimize tail recursion */
+  if (p != ms->p_end) {  /* end of pattern? */
+    switch (*p) {
+      case '(': {  /* start capture */
+        if (*(p + 1) == ')')  /* position capture? */
+          s = start_capture(ms, s, p + 2, CAP_POSITION);
+        else
+          s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
+        break;
+      }
+      case ')': {  /* end capture */
+        s = end_capture(ms, s, p + 1);
+        break;
+      }
+      case '$': {
+        if ((p + 1) != ms->p_end)  /* is the `$' the last char in pattern? */
+          goto dflt;  /* no; go to default */
+        s = (s == ms->src_end) ? s : NULL;  /* check end of string */
+        break;
+      }
+      case L_ESC: {  /* escaped sequences not in the format class[*+?-]? */
+        switch (*(p + 1)) {
+          case 'b': {  /* balanced string? */
+            s = matchbalance(ms, s, p + 2);
+            if (s != NULL) {
+              p += 4; goto init;  /* return match(ms, s, p + 4); */
+            }  /* else fail (s == NULL) */
+            break;
+          }
+          case 'f': {  /* frontier? */
+            const char *ep; char previous;
+            p += 2;
+            if (*p != '[')
+              luaL_error(ms->L, "missing " LUA_QL("[") " after "
+                                 LUA_QL("%%f") " in pattern");
+            ep = classend(ms, p);  /* points to what is next */
+            previous = (s == ms->src_init) ? '\0' : *(s - 1);
+            if (!matchbracketclass(uchar(previous), p, ep - 1) &&
+               matchbracketclass(uchar(*s), p, ep - 1)) {
+              p = ep; goto init;  /* return match(ms, s, ep); */
+            }
+            s = NULL;  /* match failed */
+            break;
+          }
+          case '0': case '1': case '2': case '3':
+          case '4': case '5': case '6': case '7':
+          case '8': case '9': {  /* capture results (%0-%9)? */
+            s = match_capture(ms, s, uchar(*(p + 1)));
+            if (s != NULL) {
+              p += 2; goto init;  /* return match(ms, s, p + 2) */
+            }
+            break;
+          }
+          default: goto dflt;
+        }
+        break;
+      }
+      default: dflt: {  /* pattern class plus optional suffix */
+        const char *ep = classend(ms, p);  /* points to optional suffix */
+        /* does not match at least once? */
+        if (!singlematch(ms, s, p, ep)) {
+          if (*ep == '*' || *ep == '?' || *ep == '-') {  /* accept empty? */
+            p = ep + 1; goto init;  /* return match(ms, s, ep + 1); */
+          }
+          else  /* '+' or no suffix */
+            s = NULL;  /* fail */
+        }
+        else {  /* matched once */
+          switch (*ep) {  /* handle optional suffix */
+            case '?': {  /* optional */
+              const char *res;
+              if ((res = match(ms, s + 1, ep + 1)) != NULL)
+                s = res;
+              else {
+                p = ep + 1; goto init;  /* else return match(ms, s, ep + 1); */
+              }
+              break;
+            }
+            case '+':  /* 1 or more repetitions */
+              s++;  /* 1 match already done */
+              /* go through */
+            case '*':  /* 0 or more repetitions */
+              s = max_expand(ms, s, p, ep);
+              break;
+            case '-':  /* 0 or more repetitions (minimum) */
+              s = min_expand(ms, s, p, ep);
+              break;
+            default:  /* no suffix */
+              s++; p = ep; goto init;  /* return match(ms, s + 1, ep); */
+          }
+        }
+        break;
+      }
+    }
+  }
+  ms->matchdepth++;
+  return s;
+}
+
+
+
+static const char *lmemfind (const char *s1, size_t l1,
+                               const char *s2, size_t l2) {
+  if (l2 == 0) return s1;  /* empty strings are everywhere */
+  else if (l2 > l1) return NULL;  /* avoids a negative `l1' */
+  else {
+    const char *init;  /* to search for a `*s2' inside `s1' */
+    l2--;  /* 1st char will be checked by `memchr' */
+    l1 = l1-l2;  /* `s2' cannot be found after that */
+    while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
+      init++;   /* 1st char is already checked */
+      if (memcmp(init, s2+1, l2) == 0)
+        return init-1;
+      else {  /* correct `l1' and `s1' to try again */
+        l1 -= init-s1;
+        s1 = init;
+      }
+    }
+    return NULL;  /* not found */
+  }
+}
+
+
+static void push_onecapture (MatchState *ms, int i, const char *s,
+                                                    const char *e) {
+  if (i >= ms->level) {
+    if (i == 0)  /* ms->level == 0, too */
+      lua_pushlstring(ms->L, s, e - s);  /* add whole match */
+    else
+      luaL_error(ms->L, "invalid capture index");
+  }
+  else {
+    ptrdiff_t l = ms->capture[i].len;
+    if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
+    if (l == CAP_POSITION)
+      lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
+    else
+      lua_pushlstring(ms->L, ms->capture[i].init, l);
+  }
+}
+
+
+static int push_captures (MatchState *ms, const char *s, const char *e) {
+  int i;
+  int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
+  luaL_checkstack(ms->L, nlevels, "too many captures");
+  for (i = 0; i < nlevels; i++)
+    push_onecapture(ms, i, s, e);
+  return nlevels;  /* number of strings pushed */
+}
+
+
+/* check whether pattern has no special characters */
+static int nospecials (const char *p, size_t l) {
+  size_t upto = 0;
+  do {
+    if (strpbrk(p + upto, SPECIALS))
+      return 0;  /* pattern has a special character */
+    upto += strlen(p + upto) + 1;  /* may have more after \0 */
+  } while (upto <= l);
+  return 1;  /* no special chars found */
+}
+
+
+static int str_find_aux (lua_State *L, int find) {
+  size_t ls, lp;
+  const char *s = luaL_checklstring(L, 1, &ls);
+  const char *p = luaL_checklstring(L, 2, &lp);
+  size_t init = posrelat(luaL_optinteger(L, 3, 1), ls);
+  if (init < 1) init = 1;
+  else if (init > ls + 1) {  /* start after string's end? */
+    lua_pushnil(L);  /* cannot find anything */
+    return 1;
+  }
+  /* explicit request or no special characters? */
+  if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
+    /* do a plain search */
+    const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
+    if (s2) {
+      lua_pushinteger(L, s2 - s + 1);
+      lua_pushinteger(L, s2 - s + lp);
+      return 2;
+    }
+  }
+  else {
+    MatchState ms;
+    const char *s1 = s + init - 1;
+    int anchor = (*p == '^');
+    if (anchor) {
+      p++; lp--;  /* skip anchor character */
+    }
+    ms.L = L;
+    ms.matchdepth = MAXCCALLS;
+    ms.src_init = s;
+    ms.src_end = s + ls;
+    ms.p_end = p + lp;
+    do {
+      const char *res;
+      ms.level = 0;
+      lua_assert(ms.matchdepth == MAXCCALLS);
+      if ((res=match(&ms, s1, p)) != NULL) {
+        if (find) {
+          lua_pushinteger(L, s1 - s + 1);  /* start */
+          lua_pushinteger(L, res - s);   /* end */
+          return push_captures(&ms, NULL, 0) + 2;
+        }
+        else
+          return push_captures(&ms, s1, res);
+      }
+    } while (s1++ < ms.src_end && !anchor);
+  }
+  lua_pushnil(L);  /* not found */
+  return 1;
+}
+
+
+static int str_find (lua_State *L) {
+  return str_find_aux(L, 1);
+}
+
+
+static int str_match (lua_State *L) {
+  return str_find_aux(L, 0);
+}
+
+
+static int gmatch_aux (lua_State *L) {
+  MatchState ms;
+  size_t ls, lp;
+  const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
+  const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
+  const char *src;
+  ms.L = L;
+  ms.matchdepth = MAXCCALLS;
+  ms.src_init = s;
+  ms.src_end = s+ls;
+  ms.p_end = p + lp;
+  for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
+       src <= ms.src_end;
+       src++) {
+    const char *e;
+    ms.level = 0;
+    lua_assert(ms.matchdepth == MAXCCALLS);
+    if ((e = match(&ms, src, p)) != NULL) {
+      lua_Integer newstart = e-s;
+      if (e == src) newstart++;  /* empty match? go at least one position */
+      lua_pushinteger(L, newstart);
+      lua_replace(L, lua_upvalueindex(3));
+      return push_captures(&ms, src, e);
+    }
+  }
+  return 0;  /* not found */
+}
+
+
+static int gmatch (lua_State *L) {
+  luaL_checkstring(L, 1);
+  luaL_checkstring(L, 2);
+  lua_settop(L, 2);
+  lua_pushinteger(L, 0);
+  lua_pushcclosure(L, gmatch_aux, 3);
+  return 1;
+}
+
+
+static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
+                                                   const char *e) {
+  size_t l, i;
+  const char *news = lua_tolstring(ms->L, 3, &l);
+  for (i = 0; i < l; i++) {
+    if (news[i] != L_ESC)
+      luaL_addchar(b, news[i]);
+    else {
+      i++;  /* skip ESC */
+      if (!isdigit(uchar(news[i]))) {
+        if (news[i] != L_ESC)
+          luaL_error(ms->L, "invalid use of " LUA_QL("%c")
+                           " in replacement string", L_ESC);
+        luaL_addchar(b, news[i]);
+      }
+      else if (news[i] == '0')
+          luaL_addlstring(b, s, e - s);
+      else {
+        push_onecapture(ms, news[i] - '1', s, e);
+        luaL_addvalue(b);  /* add capture to accumulated result */
+      }
+    }
+  }
+}
+
+
+static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
+                                       const char *e, int tr) {
+  lua_State *L = ms->L;
+  switch (tr) {
+    case LUA_TFUNCTION: {
+      int n;
+      lua_pushvalue(L, 3);
+      n = push_captures(ms, s, e);
+      lua_call(L, n, 1);
+      break;
+    }
+    case LUA_TTABLE: {
+      push_onecapture(ms, 0, s, e);
+      lua_gettable(L, 3);
+      break;
+    }
+    default: {  /* LUA_TNUMBER or LUA_TSTRING */
+      add_s(ms, b, s, e);
+      return;
+    }
+  }
+  if (!lua_toboolean(L, -1)) {  /* nil or false? */
+    lua_pop(L, 1);
+    lua_pushlstring(L, s, e - s);  /* keep original text */
+  }
+  else if (!lua_isstring(L, -1))
+    luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
+  luaL_addvalue(b);  /* add result to accumulator */
+}
+
+
+static int str_gsub (lua_State *L) {
+  size_t srcl, lp;
+  const char *src = luaL_checklstring(L, 1, &srcl);
+  const char *p = luaL_checklstring(L, 2, &lp);
+  int tr = lua_type(L, 3);
+  size_t max_s = luaL_optinteger(L, 4, srcl+1);
+  int anchor = (*p == '^');
+  size_t n = 0;
+  MatchState ms;
+  luaL_Buffer b;
+  luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
+                   tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
+                      "string/function/table expected");
+  luaL_buffinit(L, &b);
+  if (anchor) {
+    p++; lp--;  /* skip anchor character */
+  }
+  ms.L = L;
+  ms.matchdepth = MAXCCALLS;
+  ms.src_init = src;
+  ms.src_end = src+srcl;
+  ms.p_end = p + lp;
+  while (n < max_s) {
+    const char *e;
+    ms.level = 0;
+    lua_assert(ms.matchdepth == MAXCCALLS);
+    e = match(&ms, src, p);
+    if (e) {
+      n++;
+      add_value(&ms, &b, src, e, tr);
+    }
+    if (e && e>src) /* non empty match? */
+      src = e;  /* skip it */
+    else if (src < ms.src_end)
+      luaL_addchar(&b, *src++);
+    else break;
+    if (anchor) break;
+  }
+  luaL_addlstring(&b, src, ms.src_end-src);
+  luaL_pushresult(&b);
+  lua_pushinteger(L, n);  /* number of substitutions */
+  return 2;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** STRING FORMAT
+** =======================================================
+*/
+
+/*
+** LUA_INTFRMLEN is the length modifier for integer conversions in
+** 'string.format'; LUA_INTFRM_T is the integer type corresponding to
+** the previous length
+*/
+#if !defined(LUA_INTFRMLEN)	/* { */
+#if defined(LUA_USE_LONGLONG)
+
+#define LUA_INTFRMLEN		"ll"
+#define LUA_INTFRM_T		long long
+
+#else
+
+#define LUA_INTFRMLEN		"l"
+#define LUA_INTFRM_T		long
+
+#endif
+#endif				/* } */
+
+
+/*
+** LUA_FLTFRMLEN is the length modifier for float conversions in
+** 'string.format'; LUA_FLTFRM_T is the float type corresponding to
+** the previous length
+*/
+#if !defined(LUA_FLTFRMLEN)
+
+#define LUA_FLTFRMLEN		""
+#define LUA_FLTFRM_T		double
+
+#endif
+
+
+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
+#define MAX_ITEM	512
+/* valid flags in a format specification */
+#define FLAGS	"-+ #0"
+/*
+** maximum size of each format specification (such as '%-099.99d')
+** (+10 accounts for %99.99x plus margin of error)
+*/
+#define MAX_FORMAT	(sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
+
+
+static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
+  size_t l;
+  const char *s = luaL_checklstring(L, arg, &l);
+  luaL_addchar(b, '"');
+  while (l--) {
+    if (*s == '"' || *s == '\\' || *s == '\n') {
+      luaL_addchar(b, '\\');
+      luaL_addchar(b, *s);
+    }
+    else if (*s == '\0' || iscntrl(uchar(*s))) {
+      char buff[10];
+      if (!isdigit(uchar(*(s+1))))
+        sprintf(buff, "\\%d", (int)uchar(*s));
+      else
+        sprintf(buff, "\\%03d", (int)uchar(*s));
+      luaL_addstring(b, buff);
+    }
+    else
+      luaL_addchar(b, *s);
+    s++;
+  }
+  luaL_addchar(b, '"');
+}
+
+static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
+  const char *p = strfrmt;
+  while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++;  /* skip flags */
+  if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
+    luaL_error(L, "invalid format (repeated flags)");
+  if (isdigit(uchar(*p))) p++;  /* skip width */
+  if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
+  if (*p == '.') {
+    p++;
+    if (isdigit(uchar(*p))) p++;  /* skip precision */
+    if (isdigit(uchar(*p))) p++;  /* (2 digits at most) */
+  }
+  if (isdigit(uchar(*p)))
+    luaL_error(L, "invalid format (width or precision too long)");
+  *(form++) = '%';
+  memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
+  form += p - strfrmt + 1;
+  *form = '\0';
+  return p;
+}
+
+
+/*
+** add length modifier into formats
+*/
+static void addlenmod (char *form, const char *lenmod) {
+  size_t l = strlen(form);
+  size_t lm = strlen(lenmod);
+  char spec = form[l - 1];
+  strcpy(form + l - 1, lenmod);
+  form[l + lm - 1] = spec;
+  form[l + lm] = '\0';
+}
+
+
+static int str_format (lua_State *L) {
+  int top = lua_gettop(L);
+  int arg = 1;
+  size_t sfl;
+  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
+  const char *strfrmt_end = strfrmt+sfl;
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  while (strfrmt < strfrmt_end) {
+    if (*strfrmt != L_ESC)
+      luaL_addchar(&b, *strfrmt++);
+    else if (*++strfrmt == L_ESC)
+      luaL_addchar(&b, *strfrmt++);  /* %% */
+    else { /* format item */
+      char form[MAX_FORMAT];  /* to store the format (`%...') */
+      char *buff = luaL_prepbuffsize(&b, MAX_ITEM);  /* to put formatted item */
+      int nb = 0;  /* number of bytes in added item */
+      if (++arg > top)
+        luaL_argerror(L, arg, "no value");
+      strfrmt = scanformat(L, strfrmt, form);
+      switch (*strfrmt++) {
+        case 'c': {
+          nb = sprintf(buff, form, luaL_checkint(L, arg));
+          break;
+        }
+        case 'd': case 'i': {
+          lua_Number n = luaL_checknumber(L, arg);
+          LUA_INTFRM_T ni = (LUA_INTFRM_T)n;
+          lua_Number diff = n - (lua_Number)ni;
+          luaL_argcheck(L, -1 < diff && diff < 1, arg,
+                        "not a number in proper range");
+          addlenmod(form, LUA_INTFRMLEN);
+          nb = sprintf(buff, form, ni);
+          break;
+        }
+        case 'o': case 'u': case 'x': case 'X': {
+          lua_Number n = luaL_checknumber(L, arg);
+          unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n;
+          lua_Number diff = n - (lua_Number)ni;
+          luaL_argcheck(L, -1 < diff && diff < 1, arg,
+                        "not a non-negative number in proper range");
+          addlenmod(form, LUA_INTFRMLEN);
+          nb = sprintf(buff, form, ni);
+          break;
+        }
+        case 'e': case 'E': case 'f':
+#if defined(LUA_USE_AFORMAT)
+        case 'a': case 'A':
+#endif
+        case 'g': case 'G': {
+          addlenmod(form, LUA_FLTFRMLEN);
+          nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
+          break;
+        }
+        case 'q': {
+          addquoted(L, &b, arg);
+          break;
+        }
+        case 's': {
+          size_t l;
+          const char *s = luaL_tolstring(L, arg, &l);
+          if (!strchr(form, '.') && l >= 100) {
+            /* no precision and string is too long to be formatted;
+               keep original string */
+            luaL_addvalue(&b);
+            break;
+          }
+          else {
+            nb = sprintf(buff, form, s);
+            lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
+            break;
+          }
+        }
+        default: {  /* also treat cases `pnLlh' */
+          return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
+                               LUA_QL("format"), *(strfrmt - 1));
+        }
+      }
+      luaL_addsize(&b, nb);
+    }
+  }
+  luaL_pushresult(&b);
+  return 1;
+}
+
+/* }====================================================== */
+
+
+static const luaL_Reg strlib[] = {
+  {"byte", str_byte},
+  {"char", str_char},
+  {"dump", str_dump},
+  {"find", str_find},
+  {"format", str_format},
+  {"gmatch", gmatch},
+  {"gsub", str_gsub},
+  {"len", str_len},
+  {"lower", str_lower},
+  {"match", str_match},
+  {"rep", str_rep},
+  {"reverse", str_reverse},
+  {"sub", str_sub},
+  {"upper", str_upper},
+  {NULL, NULL}
+};
+
+
+static void createmetatable (lua_State *L) {
+  lua_createtable(L, 0, 1);  /* table to be metatable for strings */
+  lua_pushliteral(L, "");  /* dummy string */
+  lua_pushvalue(L, -2);  /* copy table */
+  lua_setmetatable(L, -2);  /* set table as metatable for strings */
+  lua_pop(L, 1);  /* pop dummy string */
+  lua_pushvalue(L, -2);  /* get string library */
+  lua_setfield(L, -2, "__index");  /* metatable.__index = string */
+  lua_pop(L, 1);  /* pop metatable */
+}
+
+
+/*
+** Open string library
+*/
+LUAMOD_API int luaopen_string (lua_State *L) {
+  luaL_newlib(L, strlib);
+  createmetatable(L);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,589 @@
+/*
+** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+
+/*
+** Implementation of tables (aka arrays, objects, or hash tables).
+** Tables keep its elements in two parts: an array part and a hash part.
+** Non-negative integer keys are all candidates to be kept in the array
+** part. The actual size of the array is the largest `n' such that at
+** least half the slots between 0 and n are in use.
+** Hash uses a mix of chained scatter table with Brent's variation.
+** A main invariant of these tables is that, if an element is not
+** in its main position (i.e. the `original' position that its hash gives
+** to it), then the colliding element is in its own main position.
+** Hence even when the load factor reaches 100%, performance remains good.
+*/
+
+#include <string.h>
+
+#define ltable_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lvm.h"
+
+
+/*
+** max size of array part is 2^MAXBITS
+*/
+#if LUAI_BITSINT >= 32
+#define MAXBITS		30
+#else
+#define MAXBITS		(LUAI_BITSINT-2)
+#endif
+
+#define MAXASIZE	(1 << MAXBITS)
+
+
+#define hashpow2(t,n)		(gnode(t, lmod((n), sizenode(t))))
+
+#define hashstr(t,str)		hashpow2(t, (str)->tsv.hash)
+#define hashboolean(t,p)	hashpow2(t, p)
+
+
+/*
+** for some types, it is better to avoid modulus by power of 2, as
+** they tend to have many 2 factors.
+*/
+#define hashmod(t,n)	(gnode(t, ((n) % ((sizenode(t)-1)|1))))
+
+
+#define hashpointer(t,p)	hashmod(t, IntPoint(p))
+
+
+#define dummynode		(&dummynode_)
+
+#define isdummy(n)		((n) == dummynode)
+
+static const Node dummynode_ = {
+  {NILCONSTANT},  /* value */
+  {{NILCONSTANT, NULL}}  /* key */
+};
+
+
+/*
+** hash for lua_Numbers
+*/
+/* Taken from Lua 5.1 to avoid frexp() */
+#define numints	cast_int(sizeof(lua_Number)/sizeof(int))
+static Node *hashnum (const Table *t, lua_Number n) {
+  unsigned int a[numints];
+  int i;
+  if (luai_numeq(n, 0))  /* avoid problems with -0 */
+    return gnode(t, 0);
+  memcpy(a, &n, sizeof(a));
+  for (i = 1; i < numints; i++) a[0] += a[i];
+  return hashmod(t, a[0]);
+}
+
+
+
+/*
+** returns the `main' position of an element in a table (that is, the index
+** of its hash value)
+*/
+static Node *mainposition (const Table *t, const TValue *key) {
+  switch (ttype(key)) {
+    case LUA_TNUMBER:
+      return hashnum(t, nvalue(key));
+    case LUA_TLNGSTR: {
+      TString *s = rawtsvalue(key);
+      if (s->tsv.extra == 0) {  /* no hash? */
+        s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
+        s->tsv.extra = 1;  /* now it has its hash */
+      }
+      return hashstr(t, rawtsvalue(key));
+    }
+    case LUA_TSHRSTR:
+      return hashstr(t, rawtsvalue(key));
+    case LUA_TBOOLEAN:
+      return hashboolean(t, bvalue(key));
+    case LUA_TLIGHTUSERDATA:
+      return hashpointer(t, pvalue(key));
+    case LUA_TLCF:
+      return hashpointer(t, fvalue(key));
+    default:
+      return hashpointer(t, gcvalue(key));
+  }
+}
+
+
+/*
+** returns the index for `key' if `key' is an appropriate key to live in
+** the array part of the table, -1 otherwise.
+*/
+static int arrayindex (const TValue *key) {
+  if (ttisnumber(key)) {
+    lua_Number n = nvalue(key);
+    int k;
+    lua_number2int(k, n);
+    if (luai_numeq(cast_num(k), n))
+      return k;
+  }
+  return -1;  /* `key' did not match some condition */
+}
+
+
+/*
+** returns the index of a `key' for table traversals. First goes all
+** elements in the array part, then elements in the hash part. The
+** beginning of a traversal is signaled by -1.
+*/
+static int findindex (lua_State *L, Table *t, StkId key) {
+  int i;
+  if (ttisnil(key)) return -1;  /* first iteration */
+  i = arrayindex(key);
+  if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */
+    return i-1;  /* yes; that's the index (corrected to C) */
+  else {
+    Node *n = mainposition(t, key);
+    for (;;) {  /* check whether `key' is somewhere in the chain */
+      /* key may be dead already, but it is ok to use it in `next' */
+      if (luaV_rawequalobj(gkey(n), key) ||
+            (ttisdeadkey(gkey(n)) && iscollectable(key) &&
+             deadvalue(gkey(n)) == gcvalue(key))) {
+        i = cast_int(n - gnode(t, 0));  /* key index in hash table */
+        /* hash elements are numbered after array ones */
+        return i + t->sizearray;
+      }
+      else n = gnext(n);
+      if (n == NULL)
+        luaG_runerror(L, "invalid key to " LUA_QL("next"));  /* key not found */
+    }
+  }
+}
+
+
+int luaH_next (lua_State *L, Table *t, StkId key) {
+  int i = findindex(L, t, key);  /* find original element */
+  for (i++; i < t->sizearray; i++) {  /* try first array part */
+    if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
+      setnvalue(key, cast_num(i+1));
+      setobj2s(L, key+1, &t->array[i]);
+      return 1;
+    }
+  }
+  for (i -= t->sizearray; i < sizenode(t); i++) {  /* then hash part */
+    if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
+      setobj2s(L, key, gkey(gnode(t, i)));
+      setobj2s(L, key+1, gval(gnode(t, i)));
+      return 1;
+    }
+  }
+  return 0;  /* no more elements */
+}
+
+
+/*
+** {=============================================================
+** Rehash
+** ==============================================================
+*/
+
+
+static int computesizes (int nums[], int *narray) {
+  int i;
+  int twotoi;  /* 2^i */
+  int a = 0;  /* number of elements smaller than 2^i */
+  int na = 0;  /* number of elements to go to array part */
+  int n = 0;  /* optimal size for array part */
+  for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
+    if (nums[i] > 0) {
+      a += nums[i];
+      if (a > twotoi/2) {  /* more than half elements present? */
+        n = twotoi;  /* optimal size (till now) */
+        na = a;  /* all elements smaller than n will go to array part */
+      }
+    }
+    if (a == *narray) break;  /* all elements already counted */
+  }
+  *narray = n;
+  lua_assert(*narray/2 <= na && na <= *narray);
+  return na;
+}
+
+
+static int countint (const TValue *key, int *nums) {
+  int k = arrayindex(key);
+  if (0 < k && k <= MAXASIZE) {  /* is `key' an appropriate array index? */
+    nums[luaO_ceillog2(k)]++;  /* count as such */
+    return 1;
+  }
+  else
+    return 0;
+}
+
+
+static int numusearray (const Table *t, int *nums) {
+  int lg;
+  int ttlg;  /* 2^lg */
+  int ause = 0;  /* summation of `nums' */
+  int i = 1;  /* count to traverse all array keys */
+  for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) {  /* for each slice */
+    int lc = 0;  /* counter */
+    int lim = ttlg;
+    if (lim > t->sizearray) {
+      lim = t->sizearray;  /* adjust upper limit */
+      if (i > lim)
+        break;  /* no more elements to count */
+    }
+    /* count elements in range (2^(lg-1), 2^lg] */
+    for (; i <= lim; i++) {
+      if (!ttisnil(&t->array[i-1]))
+        lc++;
+    }
+    nums[lg] += lc;
+    ause += lc;
+  }
+  return ause;
+}
+
+
+static int numusehash (const Table *t, int *nums, int *pnasize) {
+  int totaluse = 0;  /* total number of elements */
+  int ause = 0;  /* summation of `nums' */
+  int i = sizenode(t);
+  while (i--) {
+    Node *n = &t->node[i];
+    if (!ttisnil(gval(n))) {
+      ause += countint(gkey(n), nums);
+      totaluse++;
+    }
+  }
+  *pnasize += ause;
+  return totaluse;
+}
+
+
+static void setarrayvector (lua_State *L, Table *t, int size) {
+  int i;
+  luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
+  for (i=t->sizearray; i<size; i++)
+     setnilvalue(&t->array[i]);
+  t->sizearray = size;
+}
+
+
+static void setnodevector (lua_State *L, Table *t, int size) {
+  int lsize;
+  if (size == 0) {  /* no elements to hash part? */
+    t->node = cast(Node *, dummynode);  /* use common `dummynode' */
+    lsize = 0;
+  }
+  else {
+    int i;
+    lsize = luaO_ceillog2(size);
+    if (lsize > MAXBITS)
+      luaG_runerror(L, "table overflow");
+    size = twoto(lsize);
+    t->node = luaM_newvector(L, size, Node);
+    for (i=0; i<size; i++) {
+      Node *n = gnode(t, i);
+      gnext(n) = NULL;
+      setnilvalue(gkey(n));
+      setnilvalue(gval(n));
+    }
+  }
+  t->lsizenode = cast_byte(lsize);
+  t->lastfree = gnode(t, size);  /* all positions are free */
+}
+
+
+void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
+  int i;
+  int oldasize = t->sizearray;
+  int oldhsize = t->lsizenode;
+  Node *nold = t->node;  /* save old hash ... */
+  if (nasize > oldasize)  /* array part must grow? */
+    setarrayvector(L, t, nasize);
+  /* create new hash part with appropriate size */
+  setnodevector(L, t, nhsize);
+  if (nasize < oldasize) {  /* array part must shrink? */
+    t->sizearray = nasize;
+    /* re-insert elements from vanishing slice */
+    for (i=nasize; i<oldasize; i++) {
+      if (!ttisnil(&t->array[i]))
+        luaH_setint(L, t, i + 1, &t->array[i]);
+    }
+    /* shrink array */
+    luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
+  }
+  /* re-insert elements from hash part */
+  for (i = twoto(oldhsize) - 1; i >= 0; i--) {
+    Node *old = nold+i;
+    if (!ttisnil(gval(old))) {
+      /* doesn't need barrier/invalidate cache, as entry was
+         already present in the table */
+      setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
+    }
+  }
+  if (!isdummy(nold))
+    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
+}
+
+
+void luaH_resizearray (lua_State *L, Table *t, int nasize) {
+  int nsize = isdummy(t->node) ? 0 : sizenode(t);
+  luaH_resize(L, t, nasize, nsize);
+}
+
+
+static void rehash (lua_State *L, Table *t, const TValue *ek) {
+  int nasize, na;
+  int nums[MAXBITS+1];  /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
+  int i;
+  int totaluse;
+  for (i=0; i<=MAXBITS; i++) nums[i] = 0;  /* reset counts */
+  nasize = numusearray(t, nums);  /* count keys in array part */
+  totaluse = nasize;  /* all those keys are integer keys */
+  totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
+  /* count extra key */
+  nasize += countint(ek, nums);
+  totaluse++;
+  /* compute new size for array part */
+  na = computesizes(nums, &nasize);
+  /* resize the table to new computed sizes */
+  luaH_resize(L, t, nasize, totaluse - na);
+}
+
+
+
+/*
+** }=============================================================
+*/
+
+
+Table *luaH_new (lua_State *L) {
+  Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
+  t->metatable = NULL;
+  t->flags = cast_byte(~0);
+  t->array = NULL;
+  t->sizearray = 0;
+  setnodevector(L, t, 0);
+  return t;
+}
+
+
+void luaH_free (lua_State *L, Table *t) {
+  if (!isdummy(t->node))
+    luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
+  luaM_freearray(L, t->array, t->sizearray);
+  luaM_free(L, t);
+}
+
+
+static Node *getfreepos (Table *t) {
+  while (t->lastfree > t->node) {
+    t->lastfree--;
+    if (ttisnil(gkey(t->lastfree)))
+      return t->lastfree;
+  }
+  return NULL;  /* could not find a free place */
+}
+
+
+
+/*
+** inserts a new key into a hash table; first, check whether key's main
+** position is free. If not, check whether colliding node is in its main
+** position or not: if it is not, move colliding node to an empty place and
+** put new key in its main position; otherwise (colliding node is in its main
+** position), new key goes to an empty position.
+*/
+TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+  Node *mp;
+  if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+  else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
+    luaG_runerror(L, "table index is NaN");
+  mp = mainposition(t, key);
+  if (!ttisnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */
+    Node *othern;
+    Node *n = getfreepos(t);  /* get a free place */
+    if (n == NULL) {  /* cannot find a free place? */
+      rehash(L, t, key);  /* grow table */
+      /* whatever called 'newkey' take care of TM cache and GC barrier */
+      return luaH_set(L, t, key);  /* insert key into grown table */
+    }
+    lua_assert(!isdummy(n));
+    othern = mainposition(t, gkey(mp));
+    if (othern != mp) {  /* is colliding node out of its main position? */
+      /* yes; move colliding node into free position */
+      while (gnext(othern) != mp) othern = gnext(othern);  /* find previous */
+      gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
+      *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
+      gnext(mp) = NULL;  /* now `mp' is free */
+      setnilvalue(gval(mp));
+    }
+    else {  /* colliding node is in its own main position */
+      /* new node will go into free position */
+      gnext(n) = gnext(mp);  /* chain new position */
+      gnext(mp) = n;
+      mp = n;
+    }
+  }
+  setobj2t(L, gkey(mp), key);
+  luaC_barrierback(L, obj2gco(t), key);
+  lua_assert(ttisnil(gval(mp)));
+  return gval(mp);
+}
+
+
+/*
+** search function for integers
+*/
+const TValue *luaH_getint (Table *t, int key) {
+  /* (1 <= key && key <= t->sizearray) */
+  if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
+    return &t->array[key-1];
+  else {
+    lua_Number nk = cast_num(key);
+    Node *n = hashnum(t, nk);
+    do {  /* check whether `key' is somewhere in the chain */
+      if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
+        return gval(n);  /* that's it */
+      else n = gnext(n);
+    } while (n);
+    return luaO_nilobject;
+  }
+}
+
+
+/*
+** search function for short strings
+*/
+const TValue *luaH_getstr (Table *t, TString *key) {
+  Node *n = hashstr(t, key);
+  lua_assert(key->tsv.tt == LUA_TSHRSTR);
+  do {  /* check whether `key' is somewhere in the chain */
+    if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
+      return gval(n);  /* that's it */
+    else n = gnext(n);
+  } while (n);
+  return luaO_nilobject;
+}
+
+
+/*
+** main search function
+*/
+const TValue *luaH_get (Table *t, const TValue *key) {
+  switch (ttype(key)) {
+    case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
+    case LUA_TNIL: return luaO_nilobject;
+    case LUA_TNUMBER: {
+      int k;
+      lua_Number n = nvalue(key);
+      lua_number2int(k, n);
+      if (luai_numeq(cast_num(k), n)) /* index is int? */
+        return luaH_getint(t, k);  /* use specialized version */
+      /* else go through */
+    }
+    default: {
+      Node *n = mainposition(t, key);
+      do {  /* check whether `key' is somewhere in the chain */
+        if (luaV_rawequalobj(gkey(n), key))
+          return gval(n);  /* that's it */
+        else n = gnext(n);
+      } while (n);
+      return luaO_nilobject;
+    }
+  }
+}
+
+
+/*
+** beware: when using this function you probably need to check a GC
+** barrier and invalidate the TM cache.
+*/
+TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
+  const TValue *p = luaH_get(t, key);
+  if (p != luaO_nilobject)
+    return cast(TValue *, p);
+  else return luaH_newkey(L, t, key);
+}
+
+
+void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
+  const TValue *p = luaH_getint(t, key);
+  TValue *cell;
+  if (p != luaO_nilobject)
+    cell = cast(TValue *, p);
+  else {
+    TValue k;
+    setnvalue(&k, cast_num(key));
+    cell = luaH_newkey(L, t, &k);
+  }
+  setobj2t(L, cell, value);
+}
+
+
+static int unbound_search (Table *t, unsigned int j) {
+  unsigned int i = j;  /* i is zero or a present index */
+  j++;
+  /* find `i' and `j' such that i is present and j is not */
+  while (!ttisnil(luaH_getint(t, j))) {
+    i = j;
+    j *= 2;
+    if (j > cast(unsigned int, MAX_INT)) {  /* overflow? */
+      /* table was built with bad purposes: resort to linear search */
+      i = 1;
+      while (!ttisnil(luaH_getint(t, i))) i++;
+      return i - 1;
+    }
+  }
+  /* now do a binary search between them */
+  while (j - i > 1) {
+    unsigned int m = (i+j)/2;
+    if (ttisnil(luaH_getint(t, m))) j = m;
+    else i = m;
+  }
+  return i;
+}
+
+
+/*
+** Try to find a boundary in table `t'. A `boundary' is an integer index
+** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
+*/
+int luaH_getn (Table *t) {
+  unsigned int j = t->sizearray;
+  if (j > 0 && ttisnil(&t->array[j - 1])) {
+    /* there is a boundary in the array part: (binary) search for it */
+    unsigned int i = 0;
+    while (j - i > 1) {
+      unsigned int m = (i+j)/2;
+      if (ttisnil(&t->array[m - 1])) j = m;
+      else i = m;
+    }
+    return i;
+  }
+  /* else must find a boundary in hash part */
+  else if (isdummy(t->node))  /* hash part is empty? */
+    return j;  /* that is easy... */
+  else return unbound_search(t, j);
+}
+
+
+
+#if defined(LUA_DEBUG)
+
+Node *luaH_mainposition (const Table *t, const TValue *key) {
+  return mainposition(t, key);
+}
+
+int luaH_isdummy (Node *n) { return isdummy(n); }
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ltable.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/*
+** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 roberto Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltable_h
+#define ltable_h
+
+#include "lobject.h"
+
+
+#define gnode(t,i)	(&(t)->node[i])
+#define gkey(n)		(&(n)->i_key.tvk)
+#define gval(n)		(&(n)->i_val)
+#define gnext(n)	((n)->i_key.nk.next)
+
+#define invalidateTMcache(t)	((t)->flags = 0)
+
+/* returns the key, given the value of a table entry */
+#define keyfromval(v) \
+  (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
+
+
+LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
+LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
+LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
+LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
+LUAI_FUNC Table *luaH_new (lua_State *L);
+LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
+LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
+LUAI_FUNC void luaH_free (lua_State *L, Table *t);
+LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
+LUAI_FUNC int luaH_getn (Table *t);
+
+
+#if defined(LUA_DEBUG)
+LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
+LUAI_FUNC int luaH_isdummy (Node *n);
+#endif
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ltablib.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ltablib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ltablib.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,283 @@
+/*
+** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp $
+** Library for Table Manipulation
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define ltablib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#define aux_getn(L,n)	(luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
+
+
+
+#if defined(LUA_COMPAT_MAXN)
+static int maxn (lua_State *L) {
+  lua_Number max = 0;
+  luaL_checktype(L, 1, LUA_TTABLE);
+  lua_pushnil(L);  /* first key */
+  while (lua_next(L, 1)) {
+    lua_pop(L, 1);  /* remove value */
+    if (lua_type(L, -1) == LUA_TNUMBER) {
+      lua_Number v = lua_tonumber(L, -1);
+      if (v > max) max = v;
+    }
+  }
+  lua_pushnumber(L, max);
+  return 1;
+}
+#endif
+
+
+static int tinsert (lua_State *L) {
+  int e = aux_getn(L, 1) + 1;  /* first empty element */
+  int pos;  /* where to insert new element */
+  switch (lua_gettop(L)) {
+    case 2: {  /* called with only 2 arguments */
+      pos = e;  /* insert new element at the end */
+      break;
+    }
+    case 3: {
+      int i;
+      pos = luaL_checkint(L, 2);  /* 2nd argument is the position */
+      luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
+      for (i = e; i > pos; i--) {  /* move up elements */
+        lua_rawgeti(L, 1, i-1);
+        lua_rawseti(L, 1, i);  /* t[i] = t[i-1] */
+      }
+      break;
+    }
+    default: {
+      return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
+    }
+  }
+  lua_rawseti(L, 1, pos);  /* t[pos] = v */
+  return 0;
+}
+
+
+static int tremove (lua_State *L) {
+  int size = aux_getn(L, 1);
+  int pos = luaL_optint(L, 2, size);
+  if (pos != size)  /* validate 'pos' if given */
+    luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
+  lua_rawgeti(L, 1, pos);  /* result = t[pos] */
+  for ( ; pos < size; pos++) {
+    lua_rawgeti(L, 1, pos+1);
+    lua_rawseti(L, 1, pos);  /* t[pos] = t[pos+1] */
+  }
+  lua_pushnil(L);
+  lua_rawseti(L, 1, pos);  /* t[pos] = nil */
+  return 1;
+}
+
+
+static void addfield (lua_State *L, luaL_Buffer *b, int i) {
+  lua_rawgeti(L, 1, i);
+  if (!lua_isstring(L, -1))
+    luaL_error(L, "invalid value (%s) at index %d in table for "
+                  LUA_QL("concat"), luaL_typename(L, -1), i);
+  luaL_addvalue(b);
+}
+
+
+static int tconcat (lua_State *L) {
+  luaL_Buffer b;
+  size_t lsep;
+  int i, last;
+  const char *sep = luaL_optlstring(L, 2, "", &lsep);
+  luaL_checktype(L, 1, LUA_TTABLE);
+  i = luaL_optint(L, 3, 1);
+  last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1));
+  luaL_buffinit(L, &b);
+  for (; i < last; i++) {
+    addfield(L, &b, i);
+    luaL_addlstring(&b, sep, lsep);
+  }
+  if (i == last)  /* add last value (if interval was not empty) */
+    addfield(L, &b, i);
+  luaL_pushresult(&b);
+  return 1;
+}
+
+
+/*
+** {======================================================
+** Pack/unpack
+** =======================================================
+*/
+
+static int pack (lua_State *L) {
+  int n = lua_gettop(L);  /* number of elements to pack */
+  lua_createtable(L, n, 1);  /* create result table */
+  lua_pushinteger(L, n);
+  lua_setfield(L, -2, "n");  /* t.n = number of elements */
+  if (n > 0) {  /* at least one element? */
+    int i;
+    lua_pushvalue(L, 1);
+    lua_rawseti(L, -2, 1);  /* insert first element */
+    lua_replace(L, 1);  /* move table into index 1 */
+    for (i = n; i >= 2; i--)  /* assign other elements */
+      lua_rawseti(L, 1, i);
+  }
+  return 1;  /* return table */
+}
+
+
+static int unpack (lua_State *L) {
+  int i, e, n;
+  luaL_checktype(L, 1, LUA_TTABLE);
+  i = luaL_optint(L, 2, 1);
+  e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
+  if (i > e) return 0;  /* empty range */
+  n = e - i + 1;  /* number of elements */
+  if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
+    return luaL_error(L, "too many results to unpack");
+  lua_rawgeti(L, 1, i);  /* push arg[i] (avoiding overflow problems) */
+  while (i++ < e)  /* push arg[i + 1...e] */
+    lua_rawgeti(L, 1, i);
+  return n;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** Quicksort
+** (based on `Algorithms in MODULA-3', Robert Sedgewick;
+**  Addison-Wesley, 1993.)
+** =======================================================
+*/
+
+
+static void set2 (lua_State *L, int i, int j) {
+  lua_rawseti(L, 1, i);
+  lua_rawseti(L, 1, j);
+}
+
+static int sort_comp (lua_State *L, int a, int b) {
+  if (!lua_isnil(L, 2)) {  /* function? */
+    int res;
+    lua_pushvalue(L, 2);
+    lua_pushvalue(L, a-1);  /* -1 to compensate function */
+    lua_pushvalue(L, b-2);  /* -2 to compensate function and `a' */
+    lua_call(L, 2, 1);
+    res = lua_toboolean(L, -1);
+    lua_pop(L, 1);
+    return res;
+  }
+  else  /* a < b? */
+    return lua_compare(L, a, b, LUA_OPLT);
+}
+
+static void auxsort (lua_State *L, int l, int u) {
+  while (l < u) {  /* for tail recursion */
+    int i, j;
+    /* sort elements a[l], a[(l+u)/2] and a[u] */
+    lua_rawgeti(L, 1, l);
+    lua_rawgeti(L, 1, u);
+    if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
+      set2(L, l, u);  /* swap a[l] - a[u] */
+    else
+      lua_pop(L, 2);
+    if (u-l == 1) break;  /* only 2 elements */
+    i = (l+u)/2;
+    lua_rawgeti(L, 1, i);
+    lua_rawgeti(L, 1, l);
+    if (sort_comp(L, -2, -1))  /* a[i]<a[l]? */
+      set2(L, i, l);
+    else {
+      lua_pop(L, 1);  /* remove a[l] */
+      lua_rawgeti(L, 1, u);
+      if (sort_comp(L, -1, -2))  /* a[u]<a[i]? */
+        set2(L, i, u);
+      else
+        lua_pop(L, 2);
+    }
+    if (u-l == 2) break;  /* only 3 elements */
+    lua_rawgeti(L, 1, i);  /* Pivot */
+    lua_pushvalue(L, -1);
+    lua_rawgeti(L, 1, u-1);
+    set2(L, i, u-1);
+    /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
+    i = l; j = u-1;
+    for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
+      /* repeat ++i until a[i] >= P */
+      while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
+        if (i>=u) luaL_error(L, "invalid order function for sorting");
+        lua_pop(L, 1);  /* remove a[i] */
+      }
+      /* repeat --j until a[j] <= P */
+      while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
+        if (j<=l) luaL_error(L, "invalid order function for sorting");
+        lua_pop(L, 1);  /* remove a[j] */
+      }
+      if (j<i) {
+        lua_pop(L, 3);  /* pop pivot, a[i], a[j] */
+        break;
+      }
+      set2(L, i, j);
+    }
+    lua_rawgeti(L, 1, u-1);
+    lua_rawgeti(L, 1, i);
+    set2(L, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
+    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
+    /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
+    if (i-l < u-i) {
+      j=l; i=i-1; l=i+2;
+    }
+    else {
+      j=i+1; i=u; u=j-2;
+    }
+    auxsort(L, j, i);  /* call recursively the smaller one */
+  }  /* repeat the routine for the larger one */
+}
+
+static int sort (lua_State *L) {
+  int n = aux_getn(L, 1);
+  luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
+  if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
+    luaL_checktype(L, 2, LUA_TFUNCTION);
+  lua_settop(L, 2);  /* make sure there is two arguments */
+  auxsort(L, 1, n);
+  return 0;
+}
+
+/* }====================================================== */
+
+
+static const luaL_Reg tab_funcs[] = {
+  {"concat", tconcat},
+#if defined(LUA_COMPAT_MAXN)
+  {"maxn", maxn},
+#endif
+  {"insert", tinsert},
+  {"pack", pack},
+  {"unpack", unpack},
+  {"remove", tremove},
+  {"sort", sort},
+  {NULL, NULL}
+};
+
+
+LUAMOD_API int luaopen_table (lua_State *L) {
+  luaL_newlib(L, tab_funcs);
+#if defined(LUA_COMPAT_UNPACK)
+  /* _G.unpack = table.unpack */
+  lua_getfield(L, -1, "unpack");
+  lua_setglobal(L, "unpack");
+#endif
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,77 @@
+/*
+** $Id: ltm.c,v 2.14.1.1 2013/04/12 18:48:47 roberto Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define ltm_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+static const char udatatypename[] = "userdata";
+
+LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
+  "no value",
+  "nil", "boolean", udatatypename, "number",
+  "string", "table", "function", udatatypename, "thread",
+  "proto", "upval"  /* these last two cases are used for tests only */
+};
+
+
+void luaT_init (lua_State *L) {
+  static const char *const luaT_eventname[] = {  /* ORDER TM */
+    "__index", "__newindex",
+    "__gc", "__mode", "__len", "__eq",
+    "__add", "__sub", "__mul", "__div", "__mod",
+    "__pow", "__unm", "__lt", "__le",
+    "__concat", "__call"
+  };
+  int i;
+  for (i=0; i<TM_N; i++) {
+    G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+    luaS_fix(G(L)->tmname[i]);  /* never collect these names */
+  }
+}
+
+
+/*
+** function to be used with macro "fasttm": optimized for absence of
+** tag methods
+*/
+const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
+  const TValue *tm = luaH_getstr(events, ename);
+  lua_assert(event <= TM_EQ);
+  if (ttisnil(tm)) {  /* no tag method? */
+    events->flags |= cast_byte(1u<<event);  /* cache this fact */
+    return NULL;
+  }
+  else return tm;
+}
+
+
+const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
+  Table *mt;
+  switch (ttypenv(o)) {
+    case LUA_TTABLE:
+      mt = hvalue(o)->metatable;
+      break;
+    case LUA_TUSERDATA:
+      mt = uvalue(o)->metatable;
+      break;
+    default:
+      mt = G(L)->mt[ttypenv(o)];
+  }
+  return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/ltm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,57 @@
+/*
+** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 roberto Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltm_h
+#define ltm_h
+
+
+#include "lobject.h"
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER TM"
+*/
+typedef enum {
+  TM_INDEX,
+  TM_NEWINDEX,
+  TM_GC,
+  TM_MODE,
+  TM_LEN,
+  TM_EQ,  /* last tag method with `fast' access */
+  TM_ADD,
+  TM_SUB,
+  TM_MUL,
+  TM_DIV,
+  TM_MOD,
+  TM_POW,
+  TM_UNM,
+  TM_LT,
+  TM_LE,
+  TM_CONCAT,
+  TM_CALL,
+  TM_N		/* number of elements in the enum */
+} TMS;
+
+
+
+#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
+  ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
+
+#define fasttm(l,et,e)	gfasttm(G(l), et, e)
+
+#define ttypename(x)	luaT_typenames_[(x) + 1]
+#define objtypename(x)	ttypename(ttypenv(x))
+
+LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
+
+
+LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
+LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
+                                                       TMS event);
+LUAI_FUNC void luaT_init (lua_State *L);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,507 @@
+/*
+** $Id: lua.c,v 1.206.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua stand-alone interpreter
+** See Copyright Notice in lua.h
+*/
+
+
+#ifdef SYSLINUX
+#include <console.h>
+#define signal(x,y)
+#else
+#include <signal.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lua_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#if !defined(LUA_PROMPT)
+#define LUA_PROMPT		"> "
+#define LUA_PROMPT2		">> "
+#endif
+
+#if !defined(LUA_PROGNAME)
+#define LUA_PROGNAME		"lua"
+#endif
+
+#if !defined(LUA_MAXINPUT)
+#define LUA_MAXINPUT		512
+#endif
+
+#if !defined(LUA_INIT)
+#define LUA_INIT		"LUA_INIT"
+#endif
+
+#define LUA_INITVERSION  \
+	LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
+
+
+/*
+** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
+** is, whether we're running lua interactively).
+*/
+#if defined(LUA_USE_ISATTY)
+#include <unistd.h>
+#define lua_stdin_is_tty()	isatty(0)
+#elif defined(LUA_WIN)
+#include <io.h>
+#include <stdio.h>
+#define lua_stdin_is_tty()	_isatty(_fileno(stdin))
+#else
+#define lua_stdin_is_tty()	1  /* assume stdin is a tty */
+#endif
+
+
+/*
+** lua_readline defines how to show a prompt and then read a line from
+** the standard input.
+** lua_saveline defines how to "save" a read line in a "history".
+** lua_freeline defines how to free a line read by lua_readline.
+*/
+#if defined(LUA_USE_READLINE)
+
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#define lua_readline(L,b,p)	((void)L, ((b)=readline(p)) != NULL)
+#define lua_saveline(L,idx) \
+        if (lua_rawlen(L,idx) > 0)  /* non-empty line? */ \
+          add_history(lua_tostring(L, idx));  /* add it to history */
+#define lua_freeline(L,b)	((void)L, free(b))
+
+#elif !defined(lua_readline)
+
+#define lua_readline(L,b,p) \
+        ((void)L, fputs(p, stdout), fflush(stdout),  /* show prompt */ \
+        fgets(b, LUA_MAXINPUT, stdin) != NULL)  /* get line */
+#define lua_saveline(L,idx)	{ (void)L; (void)idx; }
+#define lua_freeline(L,b)	{ (void)L; (void)b; }
+
+#endif
+
+
+
+
+static lua_State *globalL = NULL;
+
+static const char *progname = LUA_PROGNAME;
+
+
+
+#ifndef SYSLINUX
+static void lstop (lua_State *L, lua_Debug *ar) {
+  (void)ar;  /* unused arg. */
+  lua_sethook(L, NULL, 0, 0);
+  luaL_error(L, "interrupted!");
+}
+
+
+static void laction (int i) {
+  signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
+                              terminate process (default action) */
+  lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
+}
+#endif
+
+
+static void print_usage (const char *badoption) {
+  luai_writestringerror("%s: ", progname);
+  if (badoption[1] == 'e' || badoption[1] == 'l')
+    luai_writestringerror("'%s' needs argument\n", badoption);
+  else
+    luai_writestringerror("unrecognized option '%s'\n", badoption);
+  luai_writestringerror(
+  "usage: %s [options] [script [args]]\n"
+  "Available options are:\n"
+  "  -e stat  execute string " LUA_QL("stat") "\n"
+  "  -i       enter interactive mode after executing " LUA_QL("script") "\n"
+  "  -l name  require library " LUA_QL("name") "\n"
+  "  -v       show version information\n"
+  "  -E       ignore environment variables\n"
+  "  --       stop handling options\n"
+  "  -        stop handling options and execute stdin\n"
+  ,
+  progname);
+}
+
+
+static void l_message (const char *pname, const char *msg) {
+  if (pname) luai_writestringerror("%s: ", pname);
+  luai_writestringerror("%s\n", msg);
+}
+
+
+static int report (lua_State *L, int status) {
+  if (status != LUA_OK && !lua_isnil(L, -1)) {
+    const char *msg = lua_tostring(L, -1);
+    if (msg == NULL) msg = "(error object is not a string)";
+    l_message(progname, msg);
+    lua_pop(L, 1);
+    /* force a complete garbage collection in case of errors */
+    lua_gc(L, LUA_GCCOLLECT, 0);
+  }
+  return status;
+}
+
+
+/* the next function is called unprotected, so it must avoid errors */
+static void finalreport (lua_State *L, int status) {
+  if (status != LUA_OK) {
+    const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
+                                                       : NULL;
+    if (msg == NULL) msg = "(error object is not a string)";
+    l_message(progname, msg);
+    lua_pop(L, 1);
+  }
+}
+
+
+static int traceback (lua_State *L) {
+  const char *msg = lua_tostring(L, 1);
+  if (msg)
+    luaL_traceback(L, L, msg, 1);
+  else if (!lua_isnoneornil(L, 1)) {  /* is there an error object? */
+    if (!luaL_callmeta(L, 1, "__tostring"))  /* try its 'tostring' metamethod */
+      lua_pushliteral(L, "(no error message)");
+  }
+  return 1;
+}
+
+
+static int docall (lua_State *L, int narg, int nres) {
+  int status;
+  int base = lua_gettop(L) - narg;  /* function index */
+  lua_pushcfunction(L, traceback);  /* push traceback function */
+  lua_insert(L, base);  /* put it under chunk and args */
+  globalL = L;  /* to be available to 'laction' */
+  signal(SIGINT, laction);
+  status = lua_pcall(L, narg, nres, base);
+  signal(SIGINT, SIG_DFL);
+  lua_remove(L, base);  /* remove traceback function */
+  return status;
+}
+
+
+static void print_version (void) {
+  luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
+  luai_writeline();
+}
+
+
+static int getargs (lua_State *L, char **argv, int n) {
+  int narg;
+  int i;
+  int argc = 0;
+  while (argv[argc]) argc++;  /* count total number of arguments */
+  narg = argc - (n + 1);  /* number of arguments to the script */
+  luaL_checkstack(L, narg + 3, "too many arguments to script");
+  for (i=n+1; i < argc; i++)
+    lua_pushstring(L, argv[i]);
+  lua_createtable(L, narg, n + 1);
+  for (i=0; i < argc; i++) {
+    lua_pushstring(L, argv[i]);
+    lua_rawseti(L, -2, i - n);
+  }
+  return narg;
+}
+
+
+static int dofile (lua_State *L, const char *name) {
+  int status = luaL_loadfile(L, name);
+  if (status == LUA_OK) status = docall(L, 0, 0);
+  return report(L, status);
+}
+
+
+static int dostring (lua_State *L, const char *s, const char *name) {
+  int status = luaL_loadbuffer(L, s, strlen(s), name);
+  if (status == LUA_OK) status = docall(L, 0, 0);
+  return report(L, status);
+}
+
+
+static int dolibrary (lua_State *L, const char *name) {
+  int status;
+  lua_getglobal(L, "require");
+  lua_pushstring(L, name);
+  status = docall(L, 1, 1);  /* call 'require(name)' */
+  if (status == LUA_OK)
+    lua_setglobal(L, name);  /* global[name] = require return */
+  return report(L, status);
+}
+
+
+static const char *get_prompt (lua_State *L, int firstline) {
+  const char *p;
+  lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
+  p = lua_tostring(L, -1);
+  if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
+  return p;
+}
+
+/* mark in error messages for incomplete statements */
+#define EOFMARK		"<eof>"
+#define marklen		(sizeof(EOFMARK)/sizeof(char) - 1)
+
+static int incomplete (lua_State *L, int status) {
+  if (status == LUA_ERRSYNTAX) {
+    size_t lmsg;
+    const char *msg = lua_tolstring(L, -1, &lmsg);
+    if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
+      lua_pop(L, 1);
+      return 1;
+    }
+  }
+  return 0;  /* else... */
+}
+
+
+static int pushline (lua_State *L, int firstline) {
+  char buffer[LUA_MAXINPUT];
+  char *b = buffer;
+  size_t l;
+  const char *prmt = get_prompt(L, firstline);
+  int readstatus = lua_readline(L, b, prmt);
+  lua_pop(L, 1);  /* remove result from 'get_prompt' */
+  if (readstatus == 0)
+    return 0;  /* no input */
+  l = strlen(b);
+  if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
+    b[l-1] = '\0';  /* remove it */
+  if (firstline && b[0] == '=')  /* first line starts with `=' ? */
+    lua_pushfstring(L, "return %s", b+1);  /* change it to `return' */
+  else
+    lua_pushstring(L, b);
+  lua_freeline(L, b);
+  return 1;
+}
+
+
+static int loadline (lua_State *L) {
+  int status;
+  lua_settop(L, 0);
+  if (!pushline(L, 1))
+    return -1;  /* no input */
+  for (;;) {  /* repeat until gets a complete line */
+    size_t l;
+    const char *line = lua_tolstring(L, 1, &l);
+    status = luaL_loadbuffer(L, line, l, "=stdin");
+    if (!incomplete(L, status)) break;  /* cannot try to add lines? */
+    if (!pushline(L, 0))  /* no more input? */
+      return -1;
+    lua_pushliteral(L, "\n");  /* add a new line... */
+    lua_insert(L, -2);  /* ...between the two lines */
+    lua_concat(L, 3);  /* join them */
+  }
+  lua_saveline(L, 1);
+  lua_remove(L, 1);  /* remove line */
+  return status;
+}
+
+
+static void dotty (lua_State *L) {
+  int status;
+  const char *oldprogname = progname;
+  progname = NULL;
+  while ((status = loadline(L)) != -1) {
+    if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET);
+    report(L, status);
+    if (status == LUA_OK && lua_gettop(L) > 0) {  /* any result to print? */
+      luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
+      lua_getglobal(L, "print");
+      lua_insert(L, 1);
+      if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK)
+        l_message(progname, lua_pushfstring(L,
+                               "error calling " LUA_QL("print") " (%s)",
+                               lua_tostring(L, -1)));
+    }
+  }
+  lua_settop(L, 0);  /* clear stack */
+  luai_writeline();
+  progname = oldprogname;
+}
+
+
+static int handle_script (lua_State *L, char **argv, int n) {
+  int status;
+  const char *fname;
+  int narg = getargs(L, argv, n);  /* collect arguments */
+  lua_setglobal(L, "arg");
+  fname = argv[n];
+  if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
+    fname = NULL;  /* stdin */
+  status = luaL_loadfile(L, fname);
+  lua_insert(L, -(narg+1));
+  if (status == LUA_OK)
+    status = docall(L, narg, LUA_MULTRET);
+  else
+    lua_pop(L, narg);
+  return report(L, status);
+}
+
+
+/* check that argument has no extra characters at the end */
+#define noextrachars(x)		{if ((x)[2] != '\0') return -1;}
+
+
+/* indices of various argument indicators in array args */
+#define has_i		0	/* -i */
+#define has_v		1	/* -v */
+#define has_e		2	/* -e */
+#define has_E		3	/* -E */
+
+#define num_has		4	/* number of 'has_*' */
+
+
+static int collectargs (char **argv, int *args) {
+  int i;
+  for (i = 1; argv[i] != NULL; i++) {
+    if (argv[i][0] != '-')  /* not an option? */
+        return i;
+    switch (argv[i][1]) {  /* option */
+      case '-':
+        noextrachars(argv[i]);
+        return (argv[i+1] != NULL ? i+1 : 0);
+      case '\0':
+        return i;
+      case 'E':
+        args[has_E] = 1;
+        break;
+      case 'i':
+        noextrachars(argv[i]);
+        args[has_i] = 1;  /* go through */
+      case 'v':
+        noextrachars(argv[i]);
+        args[has_v] = 1;
+        break;
+      case 'e':
+        args[has_e] = 1;  /* go through */
+      case 'l':  /* both options need an argument */
+        if (argv[i][2] == '\0') {  /* no concatenated argument? */
+          i++;  /* try next 'argv' */
+          if (argv[i] == NULL || argv[i][0] == '-')
+            return -(i - 1);  /* no next argument or it is another option */
+        }
+        break;
+      default:  /* invalid option; return its index... */
+        return -i;  /* ...as a negative value */
+    }
+  }
+  return 0;
+}
+
+
+static int runargs (lua_State *L, char **argv, int n) {
+  int i;
+  for (i = 1; i < n; i++) {
+    lua_assert(argv[i][0] == '-');
+    switch (argv[i][1]) {  /* option */
+      case 'e': {
+        const char *chunk = argv[i] + 2;
+        if (*chunk == '\0') chunk = argv[++i];
+        lua_assert(chunk != NULL);
+        if (dostring(L, chunk, "=(command line)") != LUA_OK)
+          return 0;
+        break;
+      }
+      case 'l': {
+        const char *filename = argv[i] + 2;
+        if (*filename == '\0') filename = argv[++i];
+        lua_assert(filename != NULL);
+        if (dolibrary(L, filename) != LUA_OK)
+          return 0;  /* stop if file fails */
+        break;
+      }
+      default: break;
+    }
+  }
+  return 1;
+}
+
+
+static int handle_luainit (lua_State *L) {
+  const char *name = "=" LUA_INITVERSION;
+  const char *init = getenv(name + 1);
+  if (init == NULL) {
+    name = "=" LUA_INIT;
+    init = getenv(name + 1);  /* try alternative name */
+  }
+  if (init == NULL) return LUA_OK;
+  else if (init[0] == '@')
+    return dofile(L, init+1);
+  else
+    return dostring(L, init, name);
+}
+
+
+static int pmain (lua_State *L) {
+  int argc = (int)lua_tointeger(L, 1);
+  char **argv = (char **)lua_touserdata(L, 2);
+  int script;
+  int args[num_has];
+  args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
+  if (argv[0] && argv[0][0]) progname = argv[0];
+  script = collectargs(argv, args);
+  if (script < 0) {  /* invalid arg? */
+    print_usage(argv[-script]);
+    return 0;
+  }
+  if (args[has_v]) print_version();
+  if (args[has_E]) {  /* option '-E'? */
+    lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
+    lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+  }
+  /* open standard libraries */
+  luaL_checkversion(L);
+  lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
+  luaL_openlibs(L);  /* open libraries */
+  lua_gc(L, LUA_GCRESTART, 0);
+  if (!args[has_E] && handle_luainit(L) != LUA_OK)
+    return 0;  /* error running LUA_INIT */
+  /* execute arguments -e and -l */
+  if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
+  /* execute main script (if there is one) */
+  if (script && handle_script(L, argv, script) != LUA_OK) return 0;
+  if (args[has_i])  /* -i option? */
+    dotty(L);
+  else if (script == 0 && !args[has_e] && !args[has_v]) {  /* no arguments? */
+    if (lua_stdin_is_tty()) {
+      print_version();
+      dotty(L);
+    }
+    else dofile(L, NULL);  /* executes stdin as a file */
+  }
+  lua_pushboolean(L, 1);  /* signal no errors */
+  return 1;
+}
+
+
+int main (int argc, char **argv) {
+  int status, result;
+  lua_State *L = luaL_newstate();  /* create state */
+  if (L == NULL) {
+    l_message(argv[0], "cannot create state: not enough memory");
+    return EXIT_FAILURE;
+  }
+#ifdef SYSLINUX
+  openconsole(&dev_stdcon_r, &dev_stdcon_w);
+#endif
+  /* call 'pmain' in protected mode */
+  lua_pushcfunction(L, &pmain);
+  lua_pushinteger(L, argc);  /* 1st argument */
+  lua_pushlightuserdata(L, argv); /* 2nd argument */
+  status = lua_pcall(L, 2, 1, 0);
+  result = lua_toboolean(L, -1);  /* get result */
+  finalreport(L, status);
+  lua_close(L);
+  return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,449 @@
+/*
+** $Id: lua.h,v 1.285.1.2 2013/11/11 12:09:16 roberto Exp $
+** Lua - A Scripting Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#include "luaconf.h"
+
+#ifdef SYSLINUX
+#define clearerr(x) (void)0
+#define feof(x) 0
+#define ferror(x) 0
+#endif
+
+#define LUA_VERSION_MAJOR	"5"
+#define LUA_VERSION_MINOR	"2"
+#define LUA_VERSION_NUM		502
+#define LUA_VERSION_RELEASE	"3"
+
+#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
+#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2013 Lua.org, PUC-Rio"
+#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+
+
+/* mark for precompiled code ('<esc>Lua') */
+#define LUA_SIGNATURE	"\033Lua"
+
+/* option for multiple returns in 'lua_pcall' and 'lua_call' */
+#define LUA_MULTRET	(-1)
+
+
+/*
+** pseudo-indices
+*/
+#define LUA_REGISTRYINDEX	LUAI_FIRSTPSEUDOIDX
+#define lua_upvalueindex(i)	(LUA_REGISTRYINDEX - (i))
+
+
+/* thread status */
+#define LUA_OK		0
+#define LUA_YIELD	1
+#define LUA_ERRRUN	2
+#define LUA_ERRSYNTAX	3
+#define LUA_ERRMEM	4
+#define LUA_ERRGCMM	5
+#define LUA_ERRERR	6
+
+
+typedef struct lua_State lua_State;
+
+typedef int (*lua_CFunction) (lua_State *L);
+
+
+/*
+** functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
+
+
+/*
+** prototype for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE		(-1)
+
+#define LUA_TNIL		0
+#define LUA_TBOOLEAN		1
+#define LUA_TLIGHTUSERDATA	2
+#define LUA_TNUMBER		3
+#define LUA_TSTRING		4
+#define LUA_TTABLE		5
+#define LUA_TFUNCTION		6
+#define LUA_TUSERDATA		7
+#define LUA_TTHREAD		8
+
+#define LUA_NUMTAGS		9
+
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK	20
+
+
+/* predefined values in the registry */
+#define LUA_RIDX_MAINTHREAD	1
+#define LUA_RIDX_GLOBALS	2
+#define LUA_RIDX_LAST		LUA_RIDX_GLOBALS
+
+
+/* type of numbers in Lua */
+typedef LUA_NUMBER lua_Number;
+
+
+/* type for integer functions */
+typedef LUA_INTEGER lua_Integer;
+
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
+
+/*
+** RCS ident string
+*/
+extern const char lua_ident[];
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void       (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
+
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+
+
+LUA_API const lua_Number *(lua_version) (lua_State *L);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int   (lua_absindex) (lua_State *L, int idx);
+LUA_API int   (lua_gettop) (lua_State *L);
+LUA_API void  (lua_settop) (lua_State *L, int idx);
+LUA_API void  (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void  (lua_remove) (lua_State *L, int idx);
+LUA_API void  (lua_insert) (lua_State *L, int idx);
+LUA_API void  (lua_replace) (lua_State *L, int idx);
+LUA_API void  (lua_copy) (lua_State *L, int fromidx, int toidx);
+LUA_API int   (lua_checkstack) (lua_State *L, int sz);
+
+LUA_API void  (lua_xmove) (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int             (lua_isnumber) (lua_State *L, int idx);
+LUA_API int             (lua_isstring) (lua_State *L, int idx);
+LUA_API int             (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int             (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int             (lua_type) (lua_State *L, int idx);
+LUA_API const char     *(lua_typename) (lua_State *L, int tp);
+
+LUA_API lua_Number      (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Integer     (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Unsigned    (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
+LUA_API int             (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char     *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+LUA_API size_t          (lua_rawlen) (lua_State *L, int idx);
+LUA_API lua_CFunction   (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void	       *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State      *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void     *(lua_topointer) (lua_State *L, int idx);
+
+
+/*
+** Comparison and arithmetic functions
+*/
+
+#define LUA_OPADD	0	/* ORDER TM */
+#define LUA_OPSUB	1
+#define LUA_OPMUL	2
+#define LUA_OPDIV	3
+#define LUA_OPMOD	4
+#define LUA_OPPOW	5
+#define LUA_OPUNM	6
+
+LUA_API void  (lua_arith) (lua_State *L, int op);
+
+#define LUA_OPEQ	0
+#define LUA_OPLT	1
+#define LUA_OPLE	2
+
+LUA_API int   (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int   (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void        (lua_pushnil) (lua_State *L);
+LUA_API void        (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void        (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API void        (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
+LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
+LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+                                                      va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void  (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void  (lua_pushboolean) (lua_State *L, int b);
+LUA_API void  (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int   (lua_pushthread) (lua_State *L);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API void  (lua_getglobal) (lua_State *L, const char *var);
+LUA_API void  (lua_gettable) (lua_State *L, int idx);
+LUA_API void  (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API void  (lua_rawget) (lua_State *L, int idx);
+LUA_API void  (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void  (lua_rawgetp) (lua_State *L, int idx, const void *p);
+LUA_API void  (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int   (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API void  (lua_getuservalue) (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void  (lua_setglobal) (lua_State *L, const char *var);
+LUA_API void  (lua_settable) (lua_State *L, int idx);
+LUA_API void  (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void  (lua_rawset) (lua_State *L, int idx);
+LUA_API void  (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API void  (lua_rawsetp) (lua_State *L, int idx, const void *p);
+LUA_API int   (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API void  (lua_setuservalue) (lua_State *L, int idx);
+
+
+/*
+** 'load' and 'call' functions (load and run Lua code)
+*/
+LUA_API void  (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
+                           lua_CFunction k);
+#define lua_call(L,n,r)		lua_callk(L, (n), (r), 0, NULL)
+
+LUA_API int   (lua_getctx) (lua_State *L, int *ctx);
+
+LUA_API int   (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+                            int ctx, lua_CFunction k);
+#define lua_pcall(L,n,r,f)	lua_pcallk(L, (n), (r), (f), 0, NULL)
+
+LUA_API int   (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+                                        const char *chunkname,
+                                        const char *mode);
+
+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int  (lua_yieldk) (lua_State *L, int nresults, int ctx,
+                           lua_CFunction k);
+#define lua_yield(L,n)		lua_yieldk(L, (n), 0, NULL)
+LUA_API int  (lua_resume) (lua_State *L, lua_State *from, int narg);
+LUA_API int  (lua_status) (lua_State *L);
+
+/*
+** garbage-collection function and options
+*/
+
+#define LUA_GCSTOP		0
+#define LUA_GCRESTART		1
+#define LUA_GCCOLLECT		2
+#define LUA_GCCOUNT		3
+#define LUA_GCCOUNTB		4
+#define LUA_GCSTEP		5
+#define LUA_GCSETPAUSE		6
+#define LUA_GCSETSTEPMUL	7
+#define LUA_GCSETMAJORINC	8
+#define LUA_GCISRUNNING		9
+#define LUA_GCGEN		10
+#define LUA_GCINC		11
+
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
+
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API int   (lua_error) (lua_State *L);
+
+LUA_API int   (lua_next) (lua_State *L, int idx);
+
+LUA_API void  (lua_concat) (lua_State *L, int n);
+LUA_API void  (lua_len)    (lua_State *L, int idx);
+
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
+
+
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_tonumber(L,i)	lua_tonumberx(L,i,NULL)
+#define lua_tointeger(L,i)	lua_tointegerx(L,i,NULL)
+#define lua_tounsigned(L,i)	lua_tounsignedx(L,i,NULL)
+
+#define lua_pop(L,n)		lua_settop(L, -(n)-1)
+
+#define lua_newtable(L)		lua_createtable(L, 0, 0)
+
+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+
+#define lua_pushcfunction(L,f)	lua_pushcclosure(L, (f), 0)
+
+#define lua_isfunction(L,n)	(lua_type(L, (n)) == LUA_TFUNCTION)
+#define lua_istable(L,n)	(lua_type(L, (n)) == LUA_TTABLE)
+#define lua_islightuserdata(L,n)	(lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n)		(lua_type(L, (n)) == LUA_TNIL)
+#define lua_isboolean(L,n)	(lua_type(L, (n)) == LUA_TBOOLEAN)
+#define lua_isthread(L,n)	(lua_type(L, (n)) == LUA_TTHREAD)
+#define lua_isnone(L,n)		(lua_type(L, (n)) == LUA_TNONE)
+#define lua_isnoneornil(L, n)	(lua_type(L, (n)) <= 0)
+
+#define lua_pushliteral(L, s)	\
+	lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+
+#define lua_pushglobaltable(L)  \
+	lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
+
+#define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
+
+
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL	0
+#define LUA_HOOKRET	1
+#define LUA_HOOKLINE	2
+#define LUA_HOOKCOUNT	3
+#define LUA_HOOKTAILCALL 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL	(1 << LUA_HOOKCALL)
+#define LUA_MASKRET	(1 << LUA_HOOKRET)
+#define LUA_MASKLINE	(1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT	(1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug;  /* activation record */
+
+
+/* Functions to be called by the debugger in specific events */
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
+
+LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+LUA_API void  (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+                                               int fidx2, int n2);
+
+LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook (lua_gethook) (lua_State *L);
+LUA_API int (lua_gethookmask) (lua_State *L);
+LUA_API int (lua_gethookcount) (lua_State *L);
+
+
+struct lua_Debug {
+  int event;
+  const char *name;	/* (n) */
+  const char *namewhat;	/* (n) 'global', 'local', 'field', 'method' */
+  const char *what;	/* (S) 'Lua', 'C', 'main', 'tail' */
+  const char *source;	/* (S) */
+  int currentline;	/* (l) */
+  int linedefined;	/* (S) */
+  int lastlinedefined;	/* (S) */
+  unsigned char nups;	/* (u) number of upvalues */
+  unsigned char nparams;/* (u) number of parameters */
+  char isvararg;        /* (u) */
+  char istailcall;	/* (t) */
+  char short_src[LUA_IDSIZE]; /* (S) */
+  /* private part */
+  struct CallInfo *i_ci;  /* active function */
+};
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.hpp
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.hpp	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lua.hpp	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+// lua.hpp
+// Lua header files for C++
+// <<extern "C">> not supplied automatically because Lua also compiles as C++
+
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/luac.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/luac.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/luac.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,432 @@
+/*
+** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $
+** Lua compiler (saves bytecodes to files; also list bytecodes)
+** See Copyright Notice in lua.h
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define luac_c
+#define LUA_CORE
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lundump.h"
+
+static void PrintFunction(const Proto* f, int full);
+#define luaU_print	PrintFunction
+
+#define PROGNAME	"luac"		/* default program name */
+#define OUTPUT		PROGNAME ".out"	/* default output file */
+
+static int listing=0;			/* list bytecodes? */
+static int dumping=1;			/* dump bytecodes? */
+static int stripping=0;			/* strip debug information? */
+static char Output[]={ OUTPUT };	/* default output file name */
+static const char* output=Output;	/* actual output file name */
+static const char* progname=PROGNAME;	/* actual program name */
+
+static void fatal(const char* message)
+{
+ fprintf(stderr,"%s: %s\n",progname,message);
+ exit(EXIT_FAILURE);
+}
+
+static void cannot(const char* what)
+{
+ fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
+ exit(EXIT_FAILURE);
+}
+
+static void usage(const char* message)
+{
+ if (*message=='-')
+  fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
+ else
+  fprintf(stderr,"%s: %s\n",progname,message);
+ fprintf(stderr,
+  "usage: %s [options] [filenames]\n"
+  "Available options are:\n"
+  "  -l       list (use -l -l for full listing)\n"
+  "  -o name  output to file " LUA_QL("name") " (default is \"%s\")\n"
+  "  -p       parse only\n"
+  "  -s       strip debug information\n"
+  "  -v       show version information\n"
+  "  --       stop handling options\n"
+  "  -        stop handling options and process stdin\n"
+  ,progname,Output);
+ exit(EXIT_FAILURE);
+}
+
+#define IS(s)	(strcmp(argv[i],s)==0)
+
+static int doargs(int argc, char* argv[])
+{
+ int i;
+ int version=0;
+ if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
+ for (i=1; i<argc; i++)
+ {
+  if (*argv[i]!='-')			/* end of options; keep it */
+   break;
+  else if (IS("--"))			/* end of options; skip it */
+  {
+   ++i;
+   if (version) ++version;
+   break;
+  }
+  else if (IS("-"))			/* end of options; use stdin */
+   break;
+  else if (IS("-l"))			/* list */
+   ++listing;
+  else if (IS("-o"))			/* output file */
+  {
+   output=argv[++i];
+   if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
+    usage(LUA_QL("-o") " needs argument");
+   if (IS("-")) output=NULL;
+  }
+  else if (IS("-p"))			/* parse only */
+   dumping=0;
+  else if (IS("-s"))			/* strip debug information */
+   stripping=1;
+  else if (IS("-v"))			/* show version */
+   ++version;
+  else					/* unknown option */
+   usage(argv[i]);
+ }
+ if (i==argc && (listing || !dumping))
+ {
+  dumping=0;
+  argv[--i]=Output;
+ }
+ if (version)
+ {
+  printf("%s\n",LUA_COPYRIGHT);
+  if (version==argc-1) exit(EXIT_SUCCESS);
+ }
+ return i;
+}
+
+#define FUNCTION "(function()end)();"
+
+static const char* reader(lua_State *L, void *ud, size_t *size)
+{
+ UNUSED(L);
+ if ((*(int*)ud)--)
+ {
+  *size=sizeof(FUNCTION)-1;
+  return FUNCTION;
+ }
+ else
+ {
+  *size=0;
+  return NULL;
+ }
+}
+
+#define toproto(L,i) getproto(L->top+(i))
+
+static const Proto* combine(lua_State* L, int n)
+{
+ if (n==1)
+  return toproto(L,-1);
+ else
+ {
+  Proto* f;
+  int i=n;
+  if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
+  f=toproto(L,-1);
+  for (i=0; i<n; i++)
+  {
+   f->p[i]=toproto(L,i-n-1);
+   if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
+  }
+  f->sizelineinfo=0;
+  return f;
+ }
+}
+
+static int writer(lua_State* L, const void* p, size_t size, void* u)
+{
+ UNUSED(L);
+ return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
+}
+
+static int pmain(lua_State* L)
+{
+ int argc=(int)lua_tointeger(L,1);
+ char** argv=(char**)lua_touserdata(L,2);
+ const Proto* f;
+ int i;
+ if (!lua_checkstack(L,argc)) fatal("too many input files");
+ for (i=0; i<argc; i++)
+ {
+  const char* filename=IS("-") ? NULL : argv[i];
+  if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
+ }
+ f=combine(L,argc);
+ if (listing) luaU_print(f,listing>1);
+ if (dumping)
+ {
+  FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
+  if (D==NULL) cannot("open");
+  lua_lock(L);
+  luaU_dump(L,f,writer,D,stripping);
+  lua_unlock(L);
+  if (ferror(D)) cannot("write");
+  if (fclose(D)) cannot("close");
+ }
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ lua_State* L;
+ int i=doargs(argc,argv);
+ argc-=i; argv+=i;
+ if (argc<=0) usage("no input files given");
+ L=luaL_newstate();
+ if (L==NULL) fatal("cannot create state: not enough memory");
+ lua_pushcfunction(L,&pmain);
+ lua_pushinteger(L,argc);
+ lua_pushlightuserdata(L,argv);
+ if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
+ lua_close(L);
+ return EXIT_SUCCESS;
+}
+
+/*
+** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $
+** print bytecodes
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdio.h>
+
+#define luac_c
+#define LUA_CORE
+
+#include "ldebug.h"
+#include "lobject.h"
+#include "lopcodes.h"
+
+#define VOID(p)		((const void*)(p))
+
+static void PrintString(const TString* ts)
+{
+ const char* s=getstr(ts);
+ size_t i,n=ts->tsv.len;
+ printf("%c",'"');
+ for (i=0; i<n; i++)
+ {
+  int c=(int)(unsigned char)s[i];
+  switch (c)
+  {
+   case '"':  printf("\\\""); break;
+   case '\\': printf("\\\\"); break;
+   case '\a': printf("\\a"); break;
+   case '\b': printf("\\b"); break;
+   case '\f': printf("\\f"); break;
+   case '\n': printf("\\n"); break;
+   case '\r': printf("\\r"); break;
+   case '\t': printf("\\t"); break;
+   case '\v': printf("\\v"); break;
+   default:	if (isprint(c))
+   			printf("%c",c);
+		else
+			printf("\\%03d",c);
+  }
+ }
+ printf("%c",'"');
+}
+
+static void PrintConstant(const Proto* f, int i)
+{
+ const TValue* o=&f->k[i];
+ switch (ttypenv(o))
+ {
+  case LUA_TNIL:
+	printf("nil");
+	break;
+  case LUA_TBOOLEAN:
+	printf(bvalue(o) ? "true" : "false");
+	break;
+  case LUA_TNUMBER:
+	printf(LUA_NUMBER_FMT,nvalue(o));
+	break;
+  case LUA_TSTRING:
+	PrintString(rawtsvalue(o));
+	break;
+  default:				/* cannot happen */
+	printf("? type=%d",ttype(o));
+	break;
+ }
+}
+
+#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
+#define MYK(x)		(-1-(x))
+
+static void PrintCode(const Proto* f)
+{
+ const Instruction* code=f->code;
+ int pc,n=f->sizecode;
+ for (pc=0; pc<n; pc++)
+ {
+  Instruction i=code[pc];
+  OpCode o=GET_OPCODE(i);
+  int a=GETARG_A(i);
+  int b=GETARG_B(i);
+  int c=GETARG_C(i);
+  int ax=GETARG_Ax(i);
+  int bx=GETARG_Bx(i);
+  int sbx=GETARG_sBx(i);
+  int line=getfuncline(f,pc);
+  printf("\t%d\t",pc+1);
+  if (line>0) printf("[%d]\t",line); else printf("[-]\t");
+  printf("%-9s\t",luaP_opnames[o]);
+  switch (getOpMode(o))
+  {
+   case iABC:
+    printf("%d",a);
+    if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
+    if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
+    break;
+   case iABx:
+    printf("%d",a);
+    if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
+    if (getBMode(o)==OpArgU) printf(" %d",bx);
+    break;
+   case iAsBx:
+    printf("%d %d",a,sbx);
+    break;
+   case iAx:
+    printf("%d",MYK(ax));
+    break;
+  }
+  switch (o)
+  {
+   case OP_LOADK:
+    printf("\t; "); PrintConstant(f,bx);
+    break;
+   case OP_GETUPVAL:
+   case OP_SETUPVAL:
+    printf("\t; %s",UPVALNAME(b));
+    break;
+   case OP_GETTABUP:
+    printf("\t; %s",UPVALNAME(b));
+    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+    break;
+   case OP_SETTABUP:
+    printf("\t; %s",UPVALNAME(a));
+    if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
+    if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
+    break;
+   case OP_GETTABLE:
+   case OP_SELF:
+    if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
+    break;
+   case OP_SETTABLE:
+   case OP_ADD:
+   case OP_SUB:
+   case OP_MUL:
+   case OP_DIV:
+   case OP_POW:
+   case OP_EQ:
+   case OP_LT:
+   case OP_LE:
+    if (ISK(b) || ISK(c))
+    {
+     printf("\t; ");
+     if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
+     printf(" ");
+     if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
+    }
+    break;
+   case OP_JMP:
+   case OP_FORLOOP:
+   case OP_FORPREP:
+   case OP_TFORLOOP:
+    printf("\t; to %d",sbx+pc+2);
+    break;
+   case OP_CLOSURE:
+    printf("\t; %p",VOID(f->p[bx]));
+    break;
+   case OP_SETLIST:
+    if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
+    break;
+   case OP_EXTRAARG:
+    printf("\t; "); PrintConstant(f,ax);
+    break;
+   default:
+    break;
+  }
+  printf("\n");
+ }
+}
+
+#define SS(x)	((x==1)?"":"s")
+#define S(x)	(int)(x),SS(x)
+
+static void PrintHeader(const Proto* f)
+{
+ const char* s=f->source ? getstr(f->source) : "=?";
+ if (*s=='@' || *s=='=')
+  s++;
+ else if (*s==LUA_SIGNATURE[0])
+  s="(bstring)";
+ else
+  s="(string)";
+ printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
+ 	(f->linedefined==0)?"main":"function",s,
+	f->linedefined,f->lastlinedefined,
+	S(f->sizecode),VOID(f));
+ printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
+	(int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
+	S(f->maxstacksize),S(f->sizeupvalues));
+ printf("%d local%s, %d constant%s, %d function%s\n",
+	S(f->sizelocvars),S(f->sizek),S(f->sizep));
+}
+
+static void PrintDebug(const Proto* f)
+{
+ int i,n;
+ n=f->sizek;
+ printf("constants (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+  printf("\t%d\t",i+1);
+  PrintConstant(f,i);
+  printf("\n");
+ }
+ n=f->sizelocvars;
+ printf("locals (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+  printf("\t%d\t%s\t%d\t%d\n",
+  i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
+ }
+ n=f->sizeupvalues;
+ printf("upvalues (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+  printf("\t%d\t%s\t%d\t%d\n",
+  i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
+ }
+}
+
+static void PrintFunction(const Proto* f, int full)
+{
+ int i,n=f->sizep;
+ PrintHeader(f);
+ PrintCode(f);
+ if (full) PrintDebug(f);
+ for (i=0; i<n; i++) PrintFunction(f->p[i],full);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/luaconf.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/luaconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/luaconf.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,609 @@
+/*
+** $Id: luaconf.h,v 1.176.1.1 2013/04/12 18:48:47 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lconfig_h
+#define lconfig_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ==================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+@@ LUA_ANSI controls the use of non-ansi features.
+** CHANGE it (define it) if you want Lua to avoid the use of any
+** non-ansi feature or library.
+*/
+#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
+#define LUA_ANSI
+#endif
+
+
+#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_WIN		/* enable goodies for regular Windows platforms */
+#endif
+
+#if defined(LUA_WIN)
+#define LUA_DL_DLL
+#define LUA_USE_AFORMAT		/* assume 'printf' handles 'aA' specifiers */
+#endif
+
+
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN		/* needs an extra library: -ldl */
+#define LUA_USE_READLINE	/* needs some extra libraries */
+#define LUA_USE_STRTODHEX	/* assume 'strtod' handles hex formats */
+#define LUA_USE_AFORMAT		/* assume 'printf' handles 'aA' specifiers */
+#define LUA_USE_LONGLONG	/* assume support for long long */
+#endif
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN		/* does not need -ldl */
+#define LUA_USE_READLINE	/* needs an extra library: -lreadline */
+#define LUA_USE_STRTODHEX	/* assume 'strtod' handles hex formats */
+#define LUA_USE_AFORMAT		/* assume 'printf' handles 'aA' specifiers */
+#define LUA_USE_LONGLONG	/* assume support for long long */
+#endif
+
+
+
+/*
+@@ LUA_USE_POSIX includes all functionality listed as X/Open System
+@* Interfaces Extension (XSI).
+** CHANGE it (define it) if your system is XSI compatible.
+*/
+#if defined(LUA_USE_POSIX)
+#define LUA_USE_MKSTEMP
+#define LUA_USE_ISATTY
+#define LUA_USE_POPEN
+#define LUA_USE_ULONGJMP
+#define LUA_USE_GMTIME_R
+#endif
+
+
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+@* Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+@* C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#if defined(_WIN32)	/* { */
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR	"!\\lua\\"
+#define LUA_CDIR	"!\\"
+#define LUA_PATH_DEFAULT  \
+		LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
+		LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" ".\\?.lua"
+#define LUA_CPATH_DEFAULT \
+		LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
+
+#elif defined(SYSLINUX)
+/* Extensions for converting the Syslinux path into package load paths */
+#define LUA_PATH_DEFAULT  ".lua"
+#define LUA_CPATH_DEFAULT ".c32"
+#else			/* }{ */
+
+#define LUA_VDIR	LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
+#define LUA_ROOT	"/usr/local/"
+#define LUA_LDIR	LUA_ROOT "share/lua/" LUA_VDIR
+#define LUA_CDIR	LUA_ROOT "lib/lua/" LUA_VDIR
+#define LUA_PATH_DEFAULT  \
+		LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \
+		LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" "./?.lua"
+#define LUA_CPATH_DEFAULT \
+		LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
+#endif			/* } */
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP	"\\"
+#else
+#define LUA_DIRSEP	"/"
+#endif
+
+
+/*
+@@ LUA_ENV is the name of the variable that holds the current
+@@ environment, used to access global names.
+** CHANGE it if you do not like this name.
+*/
+#define LUA_ENV		"_ENV"
+
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL)	/* { */
+
+#if defined(LUA_CORE) || defined(LUA_LIB)	/* { */
+#define LUA_API __declspec(dllexport)
+#else						/* }{ */
+#define LUA_API __declspec(dllimport)
+#endif						/* } */
+
+#else				/* }{ */
+
+#define LUA_API		extern
+
+#endif				/* } */
+
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API	LUA_API
+#define LUAMOD_API	LUALIB_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+@* exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+@* that are not to be exported to outside modules (LUAI_DDEF for
+@* definitions and LUAI_DDEC for declarations).
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
+*/
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+    defined(__ELF__)		/* { */
+#define LUAI_FUNC	__attribute__((visibility("hidden"))) extern
+#define LUAI_DDEC	LUAI_FUNC
+#define LUAI_DDEF	/* empty */
+
+#else				/* }{ */
+#define LUAI_FUNC	extern
+#define LUAI_DDEC	extern
+#define LUAI_DDEF	/* empty */
+#endif				/* } */
+
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** CHANGE it if you want a different appearance.
+*/
+#define LUA_QL(x)	"'" x "'"
+#define LUA_QS		LUA_QL("%s")
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@* of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE	60
+
+
+/*
+@@ luai_writestring/luai_writeline define how 'print' prints its results.
+** They are only used in libraries and the stand-alone program. (The #if
+** avoids including 'stdio.h' everywhere.)
+*/
+#if defined(LUA_LIB) || defined(lua_c)
+#include <stdio.h>
+#define luai_writestring(s,l)	fwrite((s), sizeof(char), (l), stdout)
+#define luai_writeline()	(luai_writestring("\n", 1), fflush(stdout))
+#endif
+
+/*
+@@ luai_writestringerror defines how to print error messages.
+** (A format string with one argument is enough for Lua...)
+*/
+#define luai_writestringerror(s,p) \
+	(fprintf(stderr, (s), (p)), fflush(stderr))
+
+
+/*
+@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
+** strings that are internalized. (Cannot be smaller than reserved words
+** or tags for metamethods, as these strings must be internalized;
+** #("function") = 8, #("__newindex") = 10.)
+*/
+#define LUAI_MAXSHORTLEN        40
+
+
+
+/*
+** {==================================================================
+** Compatibility with previous versions
+** ===================================================================
+*/
+
+/*
+@@ LUA_COMPAT_ALL controls all compatibility options.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_ALL)	/* { */
+
+/*
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
+*/
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u)  \
+	(lua_pushcfunction(L, (f)), \
+	 lua_pushlightuserdata(L,(u)), \
+	 lua_pcall(L,1,0,0))
+
+
+/*
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
+*/
+#define LUA_COMPAT_LOG10
+
+/*
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+*/
+#define LUA_COMPAT_LOADSTRING
+
+/*
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+*/
+#define LUA_COMPAT_MAXN
+
+/*
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
+*/
+#define lua_strlen(L,i)		lua_rawlen(L, (i))
+
+#define lua_objlen(L,i)		lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif				/* } */
+
+/* }================================================================== */
+
+
+
+/*
+@@ LUAI_BITSINT defines the number of bits in an int.
+** CHANGE here if Lua cannot automatically detect the number of bits of
+** your machine. Probably you do not need to change this.
+*/
+/* avoid overflows in comparison */
+#if INT_MAX-20 < 32760		/* { */
+#define LUAI_BITSINT	16
+#elif INT_MAX > 2147483640L	/* }{ */
+/* int has at least 32 bits */
+#define LUAI_BITSINT	32
+#else				/* }{ */
+#error "you must define LUA_BITSINT with number of bits in an integer"
+#endif				/* } */
+
+
+/*
+@@ LUA_INT32 is an signed integer with exactly 32 bits.
+@@ LUAI_UMEM is an unsigned integer big enough to count the total
+@* memory used by Lua.
+@@ LUAI_MEM is a signed integer big enough to count the total memory
+@* used by Lua.
+** CHANGE here if for some weird reason the default definitions are not
+** good enough for your machine. Probably you do not need to change
+** this.
+*/
+#if LUAI_BITSINT >= 32		/* { */
+#define LUA_INT32	int
+#define LUAI_UMEM	size_t
+#define LUAI_MEM	ptrdiff_t
+#else				/* }{ */
+/* 16-bit ints */
+#define LUA_INT32	long
+#define LUAI_UMEM	unsigned long
+#define LUAI_MEM	long
+#endif				/* } */
+
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua to consume unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK		1000000
+#else
+#define LUAI_MAXSTACK		15000
+#endif
+
+/* reserve some space for error handling */
+#define LUAI_FIRSTPSEUDOIDX	(-LUAI_MAXSTACK - 1000)
+
+
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space.
+*/
+#define LUAL_BUFFERSIZE		BUFSIZ
+
+
+
+
+/*
+** {==================================================================
+@@ LUA_NUMBER is the type of numbers in Lua.
+** CHANGE the following definitions only if you want to build Lua
+** with a number type different from double. You may also need to
+** change lua_number2int & lua_number2integer.
+** ===================================================================
+*/
+
+/* Define LUA_NUMBER_INTEGRAL to produce a system that uses no
+   floating point operations by changing the type of Lua numbers from
+   double to long.  It implements division and modulus so that 
+
+   x == (x / y) * y + x % y.  
+   
+   The exponentiation function returns zero for negative exponents.
+   Defining LUA_NUMBER_INTEGRAL also removes the difftime function,
+   and the math module should not be used.  The string.format function
+   no longer handles the floating point directives %e, %E, %f, %g, and
+   %G. */
+
+#define LUA_NUMBER_INTEGRAL
+#ifdef LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER	long
+#else
+#define LUA_NUMBER_DOUBLE
+#define LUA_NUMBER	double
+#endif
+
+/*
+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@* over a number.
+*/
+#define LUAI_UACNUMBER	LUA_NUMBER
+
+
+/*
+@@ LUA_NUMBER_SCAN is the format for reading numbers.
+@@ LUA_NUMBER_FMT is the format for writing numbers.
+@@ lua_number2str converts a number to a string.
+@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
+*/
+#ifdef LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER_SCAN		"%ld"
+#define LUA_NUMBER_FMT		"%ld"
+#else
+#define LUA_NUMBER_SCAN		"%lf"
+#define LUA_NUMBER_FMT		"%.14g"
+#endif
+#define lua_number2str(s,n)	sprintf((s), LUA_NUMBER_FMT, (n))
+#define LUAI_MAXNUMBER2STR	32 /* 16 digits, sign, point, and \0 */
+
+
+/*
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
+*/
+#define l_mathop(x)		(x)
+
+
+/*
+@@ lua_str2number converts a decimal numeric string to a number.
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does both conversions. C89, however, has no function
+** to convert floating hexadecimal strings to numbers. For these
+** systems, you can leave 'lua_strx2number' undefined and Lua will
+** provide its own implementation.
+*/
+#ifdef LUA_NUMBER_INTEGRAL
+#define lua_str2number(s,p)	strtol((s), (p), 10)
+#else
+#define lua_str2number(s,p)	strtod((s), (p))
+#endif
+
+#ifdef SYSLINUX
+#define lua_strx2number(s,p)	strtol((s), (p), 16)
+#endif
+
+
+/*
+@@ The luai_num* macros define the primitive operations over numbers.
+*/
+
+#ifndef LUA_NUMBER_INTEGRAL
+/* the following operations need the math library */
+#if defined(lobject_c) || defined(lvm_c)
+#include <math.h>
+#define luai_nummod(L,a,b)	((a) - l_mathop(floor)((a)/(b))*(b))
+#define luai_numpow(L,a,b)	(l_mathop(pow)(a,b))
+#endif
+#endif
+
+/* these are quite standard operations */
+#if defined(LUA_CORE)
+#define luai_numadd(L,a,b)	((a)+(b))
+#define luai_numsub(L,a,b)	((a)-(b))
+#define luai_nummul(L,a,b)	((a)*(b))
+#ifdef LUA_NUMBER_INTEGRAL
+#define luai_numdiv(L,a,b)		\
+  (-1/2?				\
+   (a)/(b):				\
+   (((a)<0)==((b)<0)||(a)%(b)==0?	\
+    (a)/(b):				\
+    (a)/(b)-1))
+#define luai_nummod(L,a,b)		\
+  (-1/2?				\
+   (a)%(b):				\
+   (((a)<0)==((b)<0)||(a)%(b)==0?	\
+    (a)%(b):				\
+    (a)%(b)+(b)))
+#define luai_lnumdiv(L,a,b)		\
+  ((b)==0?				\
+   (luaG_runerror(L,"divide by zero"),0): \
+   luai_numdiv(a,b))
+#define luai_lnummod(L,a,b)		\
+  ((b)==0?				\
+   (luaG_runerror(L,"modulo by zero"),0): \
+   luai_nummod(a,b))
+LUA_NUMBER luai_ipow(void *L, LUA_NUMBER, LUA_NUMBER);
+#define luai_numpow(L,a,b)	(luai_ipow(L,a,b))
+#else
+#define luai_numdiv(L,a,b)	((a)/(b))
+#endif
+#define luai_numunm(L,a)	(-(a))
+#define luai_numeq(a,b)		((a)==(b))
+#define luai_numlt(L,a,b)	((a)<(b))
+#define luai_numle(L,a,b)	((a)<=(b))
+#define luai_numisnan(L,a)	(!luai_numeq((a), (a)))
+#endif
+
+
+
+/*
+@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
+** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
+** machines, ptrdiff_t gives a good choice between int or long.)
+*/
+#define LUA_INTEGER	long
+/* Changed to long for use with integral Lua numbers. */
+
+/*
+@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
+** It must have at least 32 bits.
+*/
+#define LUA_UNSIGNED	unsigned LUA_INT32
+
+
+
+/*
+** Some tricks with doubles
+*/
+
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI)	/* { */
+/*
+** The next definitions activate some tricks to speed up the
+** conversion from doubles to integer types, mainly to LUA_UNSIGNED.
+**
+@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a
+** DirectX idiosyncrasy.
+**
+@@ LUA_IEEE754TRICK uses a trick that should work on any machine
+** using IEEE754 with a 32-bit integer type.
+**
+@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be
+** defined when LUA_INTEGER is a 32-bit integer.
+**
+@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
+** (0 for little endian, 1 for big endian); if not defined, Lua will
+** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK).
+**
+@@ LUA_NANTRICK controls the use of a trick to pack all types into
+** a single double value, using NaN values to represent non-number
+** values. The trick only works on 32-bit machines (ints and pointers
+** are 32-bit values) with numbers represented as IEEE 754-2008 doubles
+** with conventional endianess (12345678 or 87654321), in CPUs that do
+** not produce signaling NaN values (all NaNs are quiet).
+*/
+
+/* Microsoft compiler on a Pentium (32 bit) ? */
+#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86)	/* { */
+
+#define LUA_MSASMTRICK
+#define LUA_IEEEENDIAN		0
+#define LUA_NANTRICK
+
+
+/* pentium 32 bits? */
+#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEELL
+#define LUA_IEEEENDIAN		0
+#define LUA_NANTRICK
+
+/* pentium 64 bits? */
+#elif defined(__x86_64)						/* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN		0
+
+#elif defined(__POWERPC__) || defined(__ppc__)			/* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN		1
+
+#else								/* }{ */
+
+/* assume IEEE754 and a 32-bit integer type */
+#define LUA_IEEE754TRICK
+
+#endif								/* } */
+
+#endif							/* } */
+
+/* }================================================================== */
+
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+#endif
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lualib.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lualib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lualib.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,55 @@
+/*
+** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+
+
+LUAMOD_API int (luaopen_base) (lua_State *L);
+
+#define LUA_COLIBNAME	"coroutine"
+LUAMOD_API int (luaopen_coroutine) (lua_State *L);
+
+#define LUA_TABLIBNAME	"table"
+LUAMOD_API int (luaopen_table) (lua_State *L);
+
+#define LUA_IOLIBNAME	"io"
+LUAMOD_API int (luaopen_io) (lua_State *L);
+
+#define LUA_OSLIBNAME	"os"
+LUAMOD_API int (luaopen_os) (lua_State *L);
+
+#define LUA_STRLIBNAME	"string"
+LUAMOD_API int (luaopen_string) (lua_State *L);
+
+#define LUA_BITLIBNAME	"bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
+
+#define LUA_MATHLIBNAME	"math"
+LUAMOD_API int (luaopen_math) (lua_State *L);
+
+#define LUA_DBLIBNAME	"debug"
+LUAMOD_API int (luaopen_debug) (lua_State *L);
+
+#define LUA_LOADLIBNAME	"package"
+LUAMOD_API int (luaopen_package) (lua_State *L);
+
+
+/* open all previous libraries */
+LUALIB_API void (luaL_openlibs) (lua_State *L);
+
+
+
+#if !defined(lua_assert)
+#define lua_assert(x)	((void)0)
+#endif
+
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,258 @@
+/*
+** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $
+** load precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#include <string.h>
+
+#define lundump_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstring.h"
+#include "lundump.h"
+#include "lzio.h"
+
+typedef struct {
+ lua_State* L;
+ ZIO* Z;
+ Mbuffer* b;
+ const char* name;
+} LoadState;
+
+static l_noret error(LoadState* S, const char* why)
+{
+ luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
+ luaD_throw(S->L,LUA_ERRSYNTAX);
+}
+
+#define LoadMem(S,b,n,size)	LoadBlock(S,b,(n)*(size))
+#define LoadByte(S)		(lu_byte)LoadChar(S)
+#define LoadVar(S,x)		LoadMem(S,&x,1,sizeof(x))
+#define LoadVector(S,b,n,size)	LoadMem(S,b,n,size)
+
+#if !defined(luai_verifycode)
+#define luai_verifycode(L,b,f)	/* empty */
+#endif
+
+static void LoadBlock(LoadState* S, void* b, size_t size)
+{
+ if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
+}
+
+static int LoadChar(LoadState* S)
+{
+ char x;
+ LoadVar(S,x);
+ return x;
+}
+
+static int LoadInt(LoadState* S)
+{
+ int x;
+ LoadVar(S,x);
+ if (x<0) error(S,"corrupted");
+ return x;
+}
+
+static lua_Number LoadNumber(LoadState* S)
+{
+ lua_Number x;
+ LoadVar(S,x);
+ return x;
+}
+
+static TString* LoadString(LoadState* S)
+{
+ size_t size;
+ LoadVar(S,size);
+ if (size==0)
+  return NULL;
+ else
+ {
+  char* s=luaZ_openspace(S->L,S->b,size);
+  LoadBlock(S,s,size*sizeof(char));
+  return luaS_newlstr(S->L,s,size-1);		/* remove trailing '\0' */
+ }
+}
+
+static void LoadCode(LoadState* S, Proto* f)
+{
+ int n=LoadInt(S);
+ f->code=luaM_newvector(S->L,n,Instruction);
+ f->sizecode=n;
+ LoadVector(S,f->code,n,sizeof(Instruction));
+}
+
+static void LoadFunction(LoadState* S, Proto* f);
+
+static void LoadConstants(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->k=luaM_newvector(S->L,n,TValue);
+ f->sizek=n;
+ for (i=0; i<n; i++) setnilvalue(&f->k[i]);
+ for (i=0; i<n; i++)
+ {
+  TValue* o=&f->k[i];
+  int t=LoadChar(S);
+  switch (t)
+  {
+   case LUA_TNIL:
+	setnilvalue(o);
+	break;
+   case LUA_TBOOLEAN:
+	setbvalue(o,LoadChar(S));
+	break;
+   case LUA_TNUMBER:
+	setnvalue(o,LoadNumber(S));
+	break;
+   case LUA_TSTRING:
+	setsvalue2n(S->L,o,LoadString(S));
+	break;
+    default: lua_assert(0);
+  }
+ }
+ n=LoadInt(S);
+ f->p=luaM_newvector(S->L,n,Proto*);
+ f->sizep=n;
+ for (i=0; i<n; i++) f->p[i]=NULL;
+ for (i=0; i<n; i++)
+ {
+  f->p[i]=luaF_newproto(S->L);
+  LoadFunction(S,f->p[i]);
+ }
+}
+
+static void LoadUpvalues(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
+ f->sizeupvalues=n;
+ for (i=0; i<n; i++) f->upvalues[i].name=NULL;
+ for (i=0; i<n; i++)
+ {
+  f->upvalues[i].instack=LoadByte(S);
+  f->upvalues[i].idx=LoadByte(S);
+ }
+}
+
+static void LoadDebug(LoadState* S, Proto* f)
+{
+ int i,n;
+ f->source=LoadString(S);
+ n=LoadInt(S);
+ f->lineinfo=luaM_newvector(S->L,n,int);
+ f->sizelineinfo=n;
+ LoadVector(S,f->lineinfo,n,sizeof(int));
+ n=LoadInt(S);
+ f->locvars=luaM_newvector(S->L,n,LocVar);
+ f->sizelocvars=n;
+ for (i=0; i<n; i++) f->locvars[i].varname=NULL;
+ for (i=0; i<n; i++)
+ {
+  f->locvars[i].varname=LoadString(S);
+  f->locvars[i].startpc=LoadInt(S);
+  f->locvars[i].endpc=LoadInt(S);
+ }
+ n=LoadInt(S);
+ for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
+}
+
+static void LoadFunction(LoadState* S, Proto* f)
+{
+ f->linedefined=LoadInt(S);
+ f->lastlinedefined=LoadInt(S);
+ f->numparams=LoadByte(S);
+ f->is_vararg=LoadByte(S);
+ f->maxstacksize=LoadByte(S);
+ LoadCode(S,f);
+ LoadConstants(S,f);
+ LoadUpvalues(S,f);
+ LoadDebug(S,f);
+}
+
+/* the code below must be consistent with the code in luaU_header */
+#define N0	LUAC_HEADERSIZE
+#define N1	(sizeof(LUA_SIGNATURE)-sizeof(char))
+#define N2	N1+2
+#define N3	N2+6
+
+static void LoadHeader(LoadState* S)
+{
+ lu_byte h[LUAC_HEADERSIZE];
+ lu_byte s[LUAC_HEADERSIZE];
+ luaU_header(h);
+ memcpy(s,h,sizeof(char));			/* first char already read */
+ LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char));
+ if (memcmp(h,s,N0)==0) return;
+ if (memcmp(h,s,N1)!=0) error(S,"not a");
+ if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
+ if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
+}
+
+/*
+** load precompiled chunk
+*/
+Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
+{
+ LoadState S;
+ Closure* cl;
+ if (*name=='@' || *name=='=')
+  S.name=name+1;
+ else if (*name==LUA_SIGNATURE[0])
+  S.name="binary string";
+ else
+  S.name=name;
+ S.L=L;
+ S.Z=Z;
+ S.b=buff;
+ LoadHeader(&S);
+ cl=luaF_newLclosure(L,1);
+ setclLvalue(L,L->top,cl); incr_top(L);
+ cl->l.p=luaF_newproto(L);
+ LoadFunction(&S,cl->l.p);
+ if (cl->l.p->sizeupvalues != 1)
+ {
+  Proto* p=cl->l.p;
+  cl=luaF_newLclosure(L,cl->l.p->sizeupvalues);
+  cl->l.p=p;
+  setclLvalue(L,L->top-1,cl);
+ }
+ luai_verifycode(L,buff,cl->l.p);
+ return cl;
+}
+
+#define MYINT(s)	(s[0]-'0')
+#define VERSION		MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
+#define FORMAT		0		/* this is the official format */
+
+/*
+* make header for precompiled chunks
+* if you change the code below be sure to update LoadHeader and FORMAT above
+* and LUAC_HEADERSIZE in lundump.h
+*/
+void luaU_header (lu_byte* h)
+{
+ int x=1;
+ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));
+ h+=sizeof(LUA_SIGNATURE)-sizeof(char);
+ *h++=cast_byte(VERSION);
+ *h++=cast_byte(FORMAT);
+ *h++=cast_byte(*(char*)&x);			/* endianness */
+ *h++=cast_byte(sizeof(int));
+ *h++=cast_byte(sizeof(size_t));
+ *h++=cast_byte(sizeof(Instruction));
+ *h++=cast_byte(sizeof(lua_Number));
+ *h++=cast_byte(((lua_Number)0.5)==0);		/* is lua_Number integral? */
+ memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lundump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,28 @@
+/*
+** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $
+** load precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lundump_h
+#define lundump_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+/* load one chunk; from lundump.c */
+LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
+
+/* make header; from lundump.c */
+LUAI_FUNC void luaU_header (lu_byte* h);
+
+/* dump one chunk; from ldump.c */
+LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
+
+/* data to catch conversion errors */
+#define LUAC_TAIL		"\x19\x93\r\n\x1a\n"
+
+/* size in bytes of header of binary files */
+#define LUAC_HEADERSIZE		(sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char))
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,890 @@
+/*
+** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+
+#ifdef SYSLINUX
+#define strcoll strcmp
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lvm_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+#ifdef LUA_NUMBER_INTEGRAL
+LUA_NUMBER luai_ipow(void *L, LUA_NUMBER a, LUA_NUMBER b) {
+  (void)L;
+  if (b < 0)
+    return 0;
+  else if (b == 0)
+    return 1;
+  else {
+    LUA_NUMBER c = 1;
+    for (;;) {
+      if (b & 1)
+	c *= a;
+      b = b >> 1;
+      if (b == 0)
+	return c;
+      a *= a;
+    }
+  }
+}
+#endif
+
+/* limit for table tag-method chains (to avoid loops) */
+#define MAXTAGLOOP	100
+
+
+const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
+  lua_Number num;
+  if (ttisnumber(obj)) return obj;
+  if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
+    setnvalue(n, num);
+    return n;
+  }
+  else
+    return NULL;
+}
+
+
+int luaV_tostring (lua_State *L, StkId obj) {
+  if (!ttisnumber(obj))
+    return 0;
+  else {
+    char s[LUAI_MAXNUMBER2STR];
+    lua_Number n = nvalue(obj);
+    int l = lua_number2str(s, n);
+    setsvalue2s(L, obj, luaS_newlstr(L, s, l));
+    return 1;
+  }
+}
+
+
+static void traceexec (lua_State *L) {
+  CallInfo *ci = L->ci;
+  lu_byte mask = L->hookmask;
+  int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
+  if (counthook)
+    resethookcount(L);  /* reset count */
+  if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
+    ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
+    return;  /* do not call hook again (VM yielded, so it did not move) */
+  }
+  if (counthook)
+    luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
+  if (mask & LUA_MASKLINE) {
+    Proto *p = ci_func(ci)->p;
+    int npc = pcRel(ci->u.l.savedpc, p);
+    int newline = getfuncline(p, npc);
+    if (npc == 0 ||  /* call linehook when enter a new function, */
+        ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
+        newline != getfuncline(p, pcRel(L->oldpc, p)))  /* enter a new line */
+      luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
+  }
+  L->oldpc = ci->u.l.savedpc;
+  if (L->status == LUA_YIELD) {  /* did hook yield? */
+    if (counthook)
+      L->hookcount = 1;  /* undo decrement to zero */
+    ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
+    ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
+    ci->func = L->top - 1;  /* protect stack below results */
+    luaD_throw(L, LUA_YIELD);
+  }
+}
+
+
+static void callTM (lua_State *L, const TValue *f, const TValue *p1,
+                    const TValue *p2, TValue *p3, int hasres) {
+  ptrdiff_t result = savestack(L, p3);
+  setobj2s(L, L->top++, f);  /* push function */
+  setobj2s(L, L->top++, p1);  /* 1st argument */
+  setobj2s(L, L->top++, p2);  /* 2nd argument */
+  if (!hasres)  /* no result? 'p3' is third argument */
+    setobj2s(L, L->top++, p3);  /* 3rd argument */
+  /* metamethod may yield only when called from Lua code */
+  luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
+  if (hasres) {  /* if has result, move it to its place */
+    p3 = restorestack(L, result);
+    setobjs2s(L, p3, --L->top);
+  }
+}
+
+
+void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+  int loop;
+  for (loop = 0; loop < MAXTAGLOOP; loop++) {
+    const TValue *tm;
+    if (ttistable(t)) {  /* `t' is a table? */
+      Table *h = hvalue(t);
+      const TValue *res = luaH_get(h, key); /* do a primitive get */
+      if (!ttisnil(res) ||  /* result is not nil? */
+          (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
+        setobj2s(L, val, res);
+        return;
+      }
+      /* else will try the tag method */
+    }
+    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
+      luaG_typeerror(L, t, "index");
+    if (ttisfunction(tm)) {
+      callTM(L, tm, t, key, val, 1);
+      return;
+    }
+    t = tm;  /* else repeat with 'tm' */
+  }
+  luaG_runerror(L, "loop in gettable");
+}
+
+
+void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+  int loop;
+  for (loop = 0; loop < MAXTAGLOOP; loop++) {
+    const TValue *tm;
+    if (ttistable(t)) {  /* `t' is a table? */
+      Table *h = hvalue(t);
+      TValue *oldval = cast(TValue *, luaH_get(h, key));
+      /* if previous value is not nil, there must be a previous entry
+         in the table; moreover, a metamethod has no relevance */
+      if (!ttisnil(oldval) ||
+         /* previous value is nil; must check the metamethod */
+         ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
+         /* no metamethod; is there a previous entry in the table? */
+         (oldval != luaO_nilobject ||
+         /* no previous entry; must create one. (The next test is
+            always true; we only need the assignment.) */
+         (oldval = luaH_newkey(L, h, key), 1)))) {
+        /* no metamethod and (now) there is an entry with given key */
+        setobj2t(L, oldval, val);  /* assign new value to that entry */
+        invalidateTMcache(h);
+        luaC_barrierback(L, obj2gco(h), val);
+        return;
+      }
+      /* else will try the metamethod */
+    }
+    else  /* not a table; check metamethod */
+      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+        luaG_typeerror(L, t, "index");
+    /* there is a metamethod */
+    if (ttisfunction(tm)) {
+      callTM(L, tm, t, key, val, 0);
+      return;
+    }
+    t = tm;  /* else repeat with 'tm' */
+  }
+  luaG_runerror(L, "loop in settable");
+}
+
+
+static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
+                       StkId res, TMS event) {
+  const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
+  if (ttisnil(tm))
+    tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
+  if (ttisnil(tm)) return 0;
+  callTM(L, tm, p1, p2, res, 1);
+  return 1;
+}
+
+
+static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
+                                  TMS event) {
+  const TValue *tm1 = fasttm(L, mt1, event);
+  const TValue *tm2;
+  if (tm1 == NULL) return NULL;  /* no metamethod */
+  if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
+  tm2 = fasttm(L, mt2, event);
+  if (tm2 == NULL) return NULL;  /* no metamethod */
+  if (luaV_rawequalobj(tm1, tm2))  /* same metamethods? */
+    return tm1;
+  return NULL;
+}
+
+
+static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
+                         TMS event) {
+  if (!call_binTM(L, p1, p2, L->top, event))
+    return -1;  /* no metamethod */
+  else
+    return !l_isfalse(L->top);
+}
+
+
+static int l_strcmp (const TString *ls, const TString *rs) {
+  const char *l = getstr(ls);
+  size_t ll = ls->tsv.len;
+  const char *r = getstr(rs);
+  size_t lr = rs->tsv.len;
+  for (;;) {
+    int temp = strcoll(l, r);
+    if (temp != 0) return temp;
+    else {  /* strings are equal up to a `\0' */
+      size_t len = strlen(l);  /* index of first `\0' in both strings */
+      if (len == lr)  /* r is finished? */
+        return (len == ll) ? 0 : 1;
+      else if (len == ll)  /* l is finished? */
+        return -1;  /* l is smaller than r (because r is not finished) */
+      /* both strings longer than `len'; go on comparing (after the `\0') */
+      len++;
+      l += len; ll -= len; r += len; lr -= len;
+    }
+  }
+}
+
+
+int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
+  int res;
+  if (ttisnumber(l) && ttisnumber(r))
+    return luai_numlt(L, nvalue(l), nvalue(r));
+  else if (ttisstring(l) && ttisstring(r))
+    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+  else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
+    luaG_ordererror(L, l, r);
+  return res;
+}
+
+
+int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
+  int res;
+  if (ttisnumber(l) && ttisnumber(r))
+    return luai_numle(L, nvalue(l), nvalue(r));
+  else if (ttisstring(l) && ttisstring(r))
+    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+  else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0)  /* first try `le' */
+    return res;
+  else if ((res = call_orderTM(L, r, l, TM_LT)) < 0)  /* else try `lt' */
+    luaG_ordererror(L, l, r);
+  return !res;
+}
+
+
+/*
+** equality of Lua values. L == NULL means raw equality (no metamethods)
+*/
+int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
+  const TValue *tm;
+  lua_assert(ttisequal(t1, t2));
+  switch (ttype(t1)) {
+    case LUA_TNIL: return 1;
+    case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+    case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
+    case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+    case LUA_TLCF: return fvalue(t1) == fvalue(t2);
+    case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
+    case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
+    case LUA_TUSERDATA: {
+      if (uvalue(t1) == uvalue(t2)) return 1;
+      else if (L == NULL) return 0;
+      tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
+      break;  /* will try TM */
+    }
+    case LUA_TTABLE: {
+      if (hvalue(t1) == hvalue(t2)) return 1;
+      else if (L == NULL) return 0;
+      tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
+      break;  /* will try TM */
+    }
+    default:
+      lua_assert(iscollectable(t1));
+      return gcvalue(t1) == gcvalue(t2);
+  }
+  if (tm == NULL) return 0;  /* no TM? */
+  callTM(L, tm, t1, t2, L->top, 1);  /* call TM */
+  return !l_isfalse(L->top);
+}
+
+
+void luaV_concat (lua_State *L, int total) {
+  lua_assert(total >= 2);
+  do {
+    StkId top = L->top;
+    int n = 2;  /* number of elements handled in this pass (at least 2) */
+    if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
+      if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
+        luaG_concaterror(L, top-2, top-1);
+    }
+    else if (tsvalue(top-1)->len == 0)  /* second operand is empty? */
+      (void)tostring(L, top - 2);  /* result is first operand */
+    else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
+      setobjs2s(L, top - 2, top - 1);  /* result is second op. */
+    }
+    else {
+      /* at least two non-empty string values; get as many as possible */
+      size_t tl = tsvalue(top-1)->len;
+      char *buffer;
+      int i;
+      /* collect total length */
+      for (i = 1; i < total && tostring(L, top-i-1); i++) {
+        size_t l = tsvalue(top-i-1)->len;
+        if (l >= (MAX_SIZET/sizeof(char)) - tl)
+          luaG_runerror(L, "string length overflow");
+        tl += l;
+      }
+      buffer = luaZ_openspace(L, &G(L)->buff, tl);
+      tl = 0;
+      n = i;
+      do {  /* concat all strings */
+        size_t l = tsvalue(top-i)->len;
+        memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
+        tl += l;
+      } while (--i > 0);
+      setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
+    }
+    total -= n-1;  /* got 'n' strings to create 1 new */
+    L->top -= n-1;  /* popped 'n' strings and pushed one */
+  } while (total > 1);  /* repeat until only 1 result left */
+}
+
+
+void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
+  const TValue *tm;
+  switch (ttypenv(rb)) {
+    case LUA_TTABLE: {
+      Table *h = hvalue(rb);
+      tm = fasttm(L, h->metatable, TM_LEN);
+      if (tm) break;  /* metamethod? break switch to call it */
+      setnvalue(ra, cast_num(luaH_getn(h)));  /* else primitive len */
+      return;
+    }
+    case LUA_TSTRING: {
+      setnvalue(ra, cast_num(tsvalue(rb)->len));
+      return;
+    }
+    default: {  /* try metamethod */
+      tm = luaT_gettmbyobj(L, rb, TM_LEN);
+      if (ttisnil(tm))  /* no metamethod? */
+        luaG_typeerror(L, rb, "get length of");
+      break;
+    }
+  }
+  callTM(L, tm, rb, rb, ra, 1);
+}
+
+
+void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
+                 const TValue *rc, TMS op) {
+  TValue tempb, tempc;
+  const TValue *b, *c;
+  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
+      (c = luaV_tonumber(rc, &tempc)) != NULL) {
+    lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
+    setnvalue(ra, res);
+  }
+  else if (!call_binTM(L, rb, rc, ra, op))
+    luaG_aritherror(L, rb, rc);
+}
+
+
+/*
+** check whether cached closure in prototype 'p' may be reused, that is,
+** whether there is a cached closure with the same upvalues needed by
+** new closure to be created.
+*/
+static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
+  Closure *c = p->cache;
+  if (c != NULL) {  /* is there a cached closure? */
+    int nup = p->sizeupvalues;
+    Upvaldesc *uv = p->upvalues;
+    int i;
+    for (i = 0; i < nup; i++) {  /* check whether it has right upvalues */
+      TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
+      if (c->l.upvals[i]->v != v)
+        return NULL;  /* wrong upvalue; cannot reuse closure */
+    }
+  }
+  return c;  /* return cached closure (or NULL if no cached closure) */
+}
+
+
+/*
+** create a new Lua closure, push it in the stack, and initialize
+** its upvalues. Note that the call to 'luaC_barrierproto' must come
+** before the assignment to 'p->cache', as the function needs the
+** original value of that field.
+*/
+static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
+                         StkId ra) {
+  int nup = p->sizeupvalues;
+  Upvaldesc *uv = p->upvalues;
+  int i;
+  Closure *ncl = luaF_newLclosure(L, nup);
+  ncl->l.p = p;
+  setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
+  for (i = 0; i < nup; i++) {  /* fill in its upvalues */
+    if (uv[i].instack)  /* upvalue refers to local variable? */
+      ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
+    else  /* get upvalue from enclosing function */
+      ncl->l.upvals[i] = encup[uv[i].idx];
+  }
+  luaC_barrierproto(L, p, ncl);
+  p->cache = ncl;  /* save it on cache for reuse */
+}
+
+
+/*
+** finish execution of an opcode interrupted by an yield
+*/
+void luaV_finishOp (lua_State *L) {
+  CallInfo *ci = L->ci;
+  StkId base = ci->u.l.base;
+  Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
+  OpCode op = GET_OPCODE(inst);
+  switch (op) {  /* finish its execution */
+    case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
+    case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
+    case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
+      setobjs2s(L, base + GETARG_A(inst), --L->top);
+      break;
+    }
+    case OP_LE: case OP_LT: case OP_EQ: {
+      int res = !l_isfalse(L->top - 1);
+      L->top--;
+      /* metamethod should not be called when operand is K */
+      lua_assert(!ISK(GETARG_B(inst)));
+      if (op == OP_LE &&  /* "<=" using "<" instead? */
+          ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
+        res = !res;  /* invert result */
+      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
+      if (res != GETARG_A(inst))  /* condition failed? */
+        ci->u.l.savedpc++;  /* skip jump instruction */
+      break;
+    }
+    case OP_CONCAT: {
+      StkId top = L->top - 1;  /* top when 'call_binTM' was called */
+      int b = GETARG_B(inst);      /* first element to concatenate */
+      int total = cast_int(top - 1 - (base + b));  /* yet to concatenate */
+      setobj2s(L, top - 2, top);  /* put TM result in proper position */
+      if (total > 1) {  /* are there elements to concat? */
+        L->top = top - 1;  /* top is one after last element (at top-2) */
+        luaV_concat(L, total);  /* concat them (may yield again) */
+      }
+      /* move final result to final position */
+      setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
+      L->top = ci->top;  /* restore top */
+      break;
+    }
+    case OP_TFORCALL: {
+      lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+      L->top = ci->top;  /* correct top */
+      break;
+    }
+    case OP_CALL: {
+      if (GETARG_C(inst) - 1 >= 0)  /* nresults >= 0? */
+        L->top = ci->top;  /* adjust results */
+      break;
+    }
+    case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
+      break;
+    default: lua_assert(0);
+  }
+}
+
+
+
+/*
+** some macros for common tasks in `luaV_execute'
+*/
+
+#if !defined luai_runtimecheck
+#define luai_runtimecheck(L, c)		/* void */
+#endif
+
+
+#define RA(i)	(base+GETARG_A(i))
+/* to be used after possible stack reallocation */
+#define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
+#define RC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
+#define RKB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
+	ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
+#define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
+	ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
+#define KBx(i)  \
+  (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
+
+
+/* execute a jump instruction */
+#define dojump(ci,i,e) \
+  { int a = GETARG_A(i); \
+    if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
+    ci->u.l.savedpc += GETARG_sBx(i) + e; }
+
+/* for test instructions, execute the jump instruction that follows it */
+#define donextjump(ci)	{ i = *ci->u.l.savedpc; dojump(ci, i, 1); }
+
+
+#define Protect(x)	{ {x;}; base = ci->u.l.base; }
+
+#define checkGC(L,c)  \
+  Protect( luaC_condGC(L,{L->top = (c);  /* limit of live values */ \
+                          luaC_step(L); \
+                          L->top = ci->top;})  /* restore top */ \
+           luai_threadyield(L); )
+
+
+#define arith_op(op,tm) { \
+        TValue *rb = RKB(i); \
+        TValue *rc = RKC(i); \
+        if (ttisnumber(rb) && ttisnumber(rc)) { \
+          lua_Number nb = nvalue(rb), nc = nvalue(rc); \
+          setnvalue(ra, op(L, nb, nc)); \
+        } \
+        else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
+
+
+#define vmdispatch(o)	switch(o)
+#define vmcase(l,b)	case l: {b}  break;
+#define vmcasenb(l,b)	case l: {b}		/* nb = no break */
+
+void luaV_execute (lua_State *L) {
+  CallInfo *ci = L->ci;
+  LClosure *cl;
+  TValue *k;
+  StkId base;
+ newframe:  /* reentry point when frame changes (call/return) */
+  lua_assert(ci == L->ci);
+  cl = clLvalue(ci->func);
+  k = cl->p->k;
+  base = ci->u.l.base;
+  /* main loop of interpreter */
+  for (;;) {
+    Instruction i = *(ci->u.l.savedpc++);
+    StkId ra;
+    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
+        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
+      Protect(traceexec(L));
+    }
+    /* WARNING: several calls may realloc the stack and invalidate `ra' */
+    ra = RA(i);
+    lua_assert(base == ci->u.l.base);
+    lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
+    vmdispatch (GET_OPCODE(i)) {
+      vmcase(OP_MOVE,
+        setobjs2s(L, ra, RB(i));
+      )
+      vmcase(OP_LOADK,
+        TValue *rb = k + GETARG_Bx(i);
+        setobj2s(L, ra, rb);
+      )
+      vmcase(OP_LOADKX,
+        TValue *rb;
+        lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+        rb = k + GETARG_Ax(*ci->u.l.savedpc++);
+        setobj2s(L, ra, rb);
+      )
+      vmcase(OP_LOADBOOL,
+        setbvalue(ra, GETARG_B(i));
+        if (GETARG_C(i)) ci->u.l.savedpc++;  /* skip next instruction (if C) */
+      )
+      vmcase(OP_LOADNIL,
+        int b = GETARG_B(i);
+        do {
+          setnilvalue(ra++);
+        } while (b--);
+      )
+      vmcase(OP_GETUPVAL,
+        int b = GETARG_B(i);
+        setobj2s(L, ra, cl->upvals[b]->v);
+      )
+      vmcase(OP_GETTABUP,
+        int b = GETARG_B(i);
+        Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
+      )
+      vmcase(OP_GETTABLE,
+        Protect(luaV_gettable(L, RB(i), RKC(i), ra));
+      )
+      vmcase(OP_SETTABUP,
+        int a = GETARG_A(i);
+        Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
+      )
+      vmcase(OP_SETUPVAL,
+        UpVal *uv = cl->upvals[GETARG_B(i)];
+        setobj(L, uv->v, ra);
+        luaC_barrier(L, uv, ra);
+      )
+      vmcase(OP_SETTABLE,
+        Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
+      )
+      vmcase(OP_NEWTABLE,
+        int b = GETARG_B(i);
+        int c = GETARG_C(i);
+        Table *t = luaH_new(L);
+        sethvalue(L, ra, t);
+        if (b != 0 || c != 0)
+          luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
+        checkGC(L, ra + 1);
+      )
+      vmcase(OP_SELF,
+        StkId rb = RB(i);
+        setobjs2s(L, ra+1, rb);
+        Protect(luaV_gettable(L, rb, RKC(i), ra));
+      )
+      vmcase(OP_ADD,
+        arith_op(luai_numadd, TM_ADD);
+      )
+      vmcase(OP_SUB,
+        arith_op(luai_numsub, TM_SUB);
+      )
+      vmcase(OP_MUL,
+        arith_op(luai_nummul, TM_MUL);
+      )
+      vmcase(OP_DIV,
+        arith_op(luai_numdiv, TM_DIV);
+      )
+      vmcase(OP_MOD,
+        arith_op(luai_nummod, TM_MOD);
+      )
+      vmcase(OP_POW,
+        arith_op(luai_numpow, TM_POW);
+      )
+      vmcase(OP_UNM,
+        TValue *rb = RB(i);
+        if (ttisnumber(rb)) {
+          lua_Number nb = nvalue(rb);
+          setnvalue(ra, luai_numunm(L, nb));
+        }
+        else {
+          Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
+        }
+      )
+      vmcase(OP_NOT,
+        TValue *rb = RB(i);
+        int res = l_isfalse(rb);  /* next assignment may change this value */
+        setbvalue(ra, res);
+      )
+      vmcase(OP_LEN,
+        Protect(luaV_objlen(L, ra, RB(i)));
+      )
+      vmcase(OP_CONCAT,
+        int b = GETARG_B(i);
+        int c = GETARG_C(i);
+        StkId rb;
+        L->top = base + c + 1;  /* mark the end of concat operands */
+        Protect(luaV_concat(L, c - b + 1));
+        ra = RA(i);  /* 'luav_concat' may invoke TMs and move the stack */
+        rb = b + base;
+        setobjs2s(L, ra, rb);
+        checkGC(L, (ra >= rb ? ra + 1 : rb));
+        L->top = ci->top;  /* restore top */
+      )
+      vmcase(OP_JMP,
+        dojump(ci, i, 0);
+      )
+      vmcase(OP_EQ,
+        TValue *rb = RKB(i);
+        TValue *rc = RKC(i);
+        Protect(
+          if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
+            ci->u.l.savedpc++;
+          else
+            donextjump(ci);
+        )
+      )
+      vmcase(OP_LT,
+        Protect(
+          if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
+            ci->u.l.savedpc++;
+          else
+            donextjump(ci);
+        )
+      )
+      vmcase(OP_LE,
+        Protect(
+          if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
+            ci->u.l.savedpc++;
+          else
+            donextjump(ci);
+        )
+      )
+      vmcase(OP_TEST,
+        if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
+            ci->u.l.savedpc++;
+          else
+          donextjump(ci);
+      )
+      vmcase(OP_TESTSET,
+        TValue *rb = RB(i);
+        if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
+          ci->u.l.savedpc++;
+        else {
+          setobjs2s(L, ra, rb);
+          donextjump(ci);
+        }
+      )
+      vmcase(OP_CALL,
+        int b = GETARG_B(i);
+        int nresults = GETARG_C(i) - 1;
+        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
+        if (luaD_precall(L, ra, nresults)) {  /* C function? */
+          if (nresults >= 0) L->top = ci->top;  /* adjust results */
+          base = ci->u.l.base;
+        }
+        else {  /* Lua function */
+          ci = L->ci;
+          ci->callstatus |= CIST_REENTRY;
+          goto newframe;  /* restart luaV_execute over new Lua function */
+        }
+      )
+      vmcase(OP_TAILCALL,
+        int b = GETARG_B(i);
+        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
+        lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
+        if (luaD_precall(L, ra, LUA_MULTRET))  /* C function? */
+          base = ci->u.l.base;
+        else {
+          /* tail call: put called frame (n) in place of caller one (o) */
+          CallInfo *nci = L->ci;  /* called frame */
+          CallInfo *oci = nci->previous;  /* caller frame */
+          StkId nfunc = nci->func;  /* called function */
+          StkId ofunc = oci->func;  /* caller function */
+          /* last stack slot filled by 'precall' */
+          StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
+          int aux;
+          /* close all upvalues from previous call */
+          if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
+          /* move new frame into old one */
+          for (aux = 0; nfunc + aux < lim; aux++)
+            setobjs2s(L, ofunc + aux, nfunc + aux);
+          oci->u.l.base = ofunc + (nci->u.l.base - nfunc);  /* correct base */
+          oci->top = L->top = ofunc + (L->top - nfunc);  /* correct top */
+          oci->u.l.savedpc = nci->u.l.savedpc;
+          oci->callstatus |= CIST_TAIL;  /* function was tail called */
+          ci = L->ci = oci;  /* remove new frame */
+          lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
+          goto newframe;  /* restart luaV_execute over new Lua function */
+        }
+      )
+      vmcasenb(OP_RETURN,
+        int b = GETARG_B(i);
+        if (b != 0) L->top = ra+b-1;
+        if (cl->p->sizep > 0) luaF_close(L, base);
+        b = luaD_poscall(L, ra);
+        if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
+          return;  /* external invocation: return */
+        else {  /* invocation via reentry: continue execution */
+          ci = L->ci;
+          if (b) L->top = ci->top;
+          lua_assert(isLua(ci));
+          lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+          goto newframe;  /* restart luaV_execute over new Lua function */
+        }
+      )
+      vmcase(OP_FORLOOP,
+        lua_Number step = nvalue(ra+2);
+        lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
+        lua_Number limit = nvalue(ra+1);
+        if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
+                                   : luai_numle(L, limit, idx)) {
+          ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
+          setnvalue(ra, idx);  /* update internal index... */
+          setnvalue(ra+3, idx);  /* ...and external index */
+        }
+      )
+      vmcase(OP_FORPREP,
+        const TValue *init = ra;
+        const TValue *plimit = ra+1;
+        const TValue *pstep = ra+2;
+        if (!tonumber(init, ra))
+          luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+        else if (!tonumber(plimit, ra+1))
+          luaG_runerror(L, LUA_QL("for") " limit must be a number");
+        else if (!tonumber(pstep, ra+2))
+          luaG_runerror(L, LUA_QL("for") " step must be a number");
+        setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
+        ci->u.l.savedpc += GETARG_sBx(i);
+      )
+      vmcasenb(OP_TFORCALL,
+        StkId cb = ra + 3;  /* call base */
+        setobjs2s(L, cb+2, ra+2);
+        setobjs2s(L, cb+1, ra+1);
+        setobjs2s(L, cb, ra);
+        L->top = cb + 3;  /* func. + 2 args (state and index) */
+        Protect(luaD_call(L, cb, GETARG_C(i), 1));
+        L->top = ci->top;
+        i = *(ci->u.l.savedpc++);  /* go to next instruction */
+        ra = RA(i);
+        lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
+        goto l_tforloop;
+      )
+      vmcase(OP_TFORLOOP,
+        l_tforloop:
+        if (!ttisnil(ra + 1)) {  /* continue loop? */
+          setobjs2s(L, ra, ra + 1);  /* save control variable */
+           ci->u.l.savedpc += GETARG_sBx(i);  /* jump back */
+        }
+      )
+      vmcase(OP_SETLIST,
+        int n = GETARG_B(i);
+        int c = GETARG_C(i);
+        int last;
+        Table *h;
+        if (n == 0) n = cast_int(L->top - ra) - 1;
+        if (c == 0) {
+          lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+          c = GETARG_Ax(*ci->u.l.savedpc++);
+        }
+        luai_runtimecheck(L, ttistable(ra));
+        h = hvalue(ra);
+        last = ((c-1)*LFIELDS_PER_FLUSH) + n;
+        if (last > h->sizearray)  /* needs more space? */
+          luaH_resizearray(L, h, last);  /* pre-allocate it at once */
+        for (; n > 0; n--) {
+          TValue *val = ra+n;
+          luaH_setint(L, h, last--, val);
+          luaC_barrierback(L, obj2gco(h), val);
+        }
+        L->top = ci->top;  /* correct top (in case of previous open call) */
+      )
+      vmcase(OP_CLOSURE,
+        Proto *p = cl->p->p[GETARG_Bx(i)];
+        Closure *ncl = getcached(p, cl->upvals, base);  /* cached closure */
+        if (ncl == NULL)  /* no match? */
+          pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
+        else
+          setclLvalue(L, ra, ncl);  /* push cashed closure */
+        checkGC(L, ra + 1);
+      )
+      vmcase(OP_VARARG,
+        int b = GETARG_B(i) - 1;
+        int j;
+        int n = cast_int(base - ci->func) - cl->p->numparams - 1;
+        if (b < 0) {  /* B == 0? */
+          b = n;  /* get all var. arguments */
+          Protect(luaD_checkstack(L, n));
+          ra = RA(i);  /* previous call may change the stack */
+          L->top = ra + n;
+        }
+        for (j = 0; j < b; j++) {
+          if (j < n) {
+            setobjs2s(L, ra + j, base - n + j);
+          }
+          else {
+            setnilvalue(ra + j);
+          }
+        }
+      )
+      vmcase(OP_EXTRAARG,
+        lua_assert(0);
+      )
+    }
+  }
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lvm.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,44 @@
+/*
+** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 roberto Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lvm_h
+#define lvm_h
+
+
+#include "ldo.h"
+#include "lobject.h"
+#include "ltm.h"
+
+
+#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
+
+#define tonumber(o,n)	(ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
+
+#define equalobj(L,o1,o2)  (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
+
+#define luaV_rawequalobj(o1,o2)		equalobj(NULL,o1,o2)
+
+
+/* not to called directly */
+LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2);
+
+
+LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
+LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
+LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
+LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
+                                            StkId val);
+LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
+                                            StkId val);
+LUAI_FUNC void luaV_finishOp (lua_State *L);
+LUAI_FUNC void luaV_execute (lua_State *L);
+LUAI_FUNC void luaV_concat (lua_State *L, int total);
+LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
+                           const TValue *rc, TMS op);
+LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/*
+** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $
+** Buffered streams
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lzio_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "llimits.h"
+#include "lmem.h"
+#include "lstate.h"
+#include "lzio.h"
+
+
+int luaZ_fill (ZIO *z) {
+  size_t size;
+  lua_State *L = z->L;
+  const char *buff;
+  lua_unlock(L);
+  buff = z->reader(L, z->data, &size);
+  lua_lock(L);
+  if (buff == NULL || size == 0)
+    return EOZ;
+  z->n = size - 1;  /* discount char being returned */
+  z->p = buff;
+  return cast_uchar(*(z->p++));
+}
+
+
+void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
+  z->L = L;
+  z->reader = reader;
+  z->data = data;
+  z->n = 0;
+  z->p = NULL;
+}
+
+
+/* --------------------------------------------------------------- read --- */
+size_t luaZ_read (ZIO *z, void *b, size_t n) {
+  while (n) {
+    size_t m;
+    if (z->n == 0) {  /* no bytes in buffer? */
+      if (luaZ_fill(z) == EOZ)  /* try to read more */
+        return n;  /* no more input; return number of missing bytes */
+      else {
+        z->n++;  /* luaZ_fill consumed first byte; put it back */
+        z->p--;
+      }
+    }
+    m = (n <= z->n) ? n : z->n;  /* min. between n and z->n */
+    memcpy(b, z->p, m);
+    z->n -= m;
+    z->p += m;
+    b = (char *)b + m;
+    n -= m;
+  }
+  return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
+  if (n > buff->buffsize) {
+    if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
+    luaZ_resizebuffer(L, buff, n);
+  }
+  return buff->buffer;
+}
+
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/lzio.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,65 @@
+/*
+** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 roberto Exp $
+** Buffered streams
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lzio_h
+#define lzio_h
+
+#include "lua.h"
+
+#include "lmem.h"
+
+
+#define EOZ	(-1)			/* end of stream */
+
+typedef struct Zio ZIO;
+
+#define zgetc(z)  (((z)->n--)>0 ?  cast_uchar(*(z)->p++) : luaZ_fill(z))
+
+
+typedef struct Mbuffer {
+  char *buffer;
+  size_t n;
+  size_t buffsize;
+} Mbuffer;
+
+#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
+
+#define luaZ_buffer(buff)	((buff)->buffer)
+#define luaZ_sizebuffer(buff)	((buff)->buffsize)
+#define luaZ_bufflen(buff)	((buff)->n)
+
+#define luaZ_resetbuffer(buff) ((buff)->n = 0)
+
+
+#define luaZ_resizebuffer(L, buff, size) \
+	(luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
+	(buff)->buffsize = size)
+
+#define luaZ_freebuffer(L, buff)	luaZ_resizebuffer(L, buff, 0)
+
+
+LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
+LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
+                                        void *data);
+LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n);	/* read next n bytes */
+
+
+
+/* --------- Private Part ------------------ */
+
+struct Zio {
+  size_t n;			/* bytes still unread */
+  const char *p;		/* current position in buffer */
+  lua_Reader reader;		/* reader function */
+  void* data;			/* additional data */
+  lua_State *L;			/* Lua state (for reader) */
+};
+
+
+LUAI_FUNC int luaZ_fill (ZIO *z);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#define lpcilib_c       /* Define the library */
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include <sys/pci.h>
+
+/* removing any \n found in a string */
+static void remove_eol(char *string)
+{
+    int j = strlen(string);
+    int i = 0;
+    for (i = 0; i < j; i++)
+        if (string[i] == '\n')
+            string[i] = 0;
+}
+
+static int pci_getinfo(lua_State *L)
+{
+  struct pci_domain *pci_domain;
+  struct pci_device *pci_device;
+  int pci_dev = 1;
+
+  pci_domain = pci_scan();
+
+  lua_newtable(L);	/* list of busses */
+
+  for_each_pci_func(pci_device, pci_domain) {
+    lua_pushnumber(L, pci_dev++);
+
+    lua_newtable(L); /* device infos */
+
+    lua_pushstring(L, "bus");
+    lua_pushnumber(L, __pci_bus);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "slot");
+    lua_pushnumber(L, __pci_slot);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "func");
+    lua_pushnumber(L, __pci_func);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "vendor");
+    lua_pushnumber(L, pci_device->vendor);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "product");
+    lua_pushnumber(L, pci_device->product);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "sub_vendor");
+    lua_pushnumber(L, pci_device->sub_vendor);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "sub_product");
+    lua_pushnumber(L, pci_device->sub_product);
+    lua_settable(L,-3);
+
+    lua_settable(L,-3); /* end device infos */
+  }
+
+  return 1;
+}
+
+/* Try to match any pci device to the appropriate kernel module */
+/* it uses the modules.pcimap from the boot device*/
+static int pci_getidlist(lua_State *L)
+{
+  const char *pciidfile;
+  char line[1024];
+  char vendor[255];
+  char vendor_id[5];
+  char product[255];
+  char productvendor[9];
+  char productvendorsub[17];
+  FILE *f;
+
+  if (lua_gettop(L) == 1) {
+    pciidfile = luaL_checkstring(L, 1);
+  } else {
+    pciidfile = "pci.ids";
+  }
+
+  lua_newtable(L);	/* list of vendors */
+
+  /* Opening the pci.ids from the boot device*/
+  f=fopen(pciidfile,"r");
+  if (!f)
+        return -1;
+
+  /* for each line we found in the pci.ids*/
+  while ( fgets(line, sizeof line, f) ) {
+    /* Skipping uncessary lines */
+    if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') ||
+	(line[0] == 10))
+        continue;
+
+    /* If the line doesn't start with a tab, it means that's a vendor id */
+    if (line[0] != '\t') {
+
+	/* the 4th first chars are the vendor_id */
+        strlcpy(vendor_id,line,4);
+
+	/* the vendor name is the next field*/
+        vendor_id[4]=0;
+        strlcpy(vendor,skipspace(strstr(line," ")),255);
+        remove_eol(vendor);
+
+	/* ffff is an invalid vendor id */
+	if (strstr(vendor_id,"ffff")) break;
+
+	lua_pushstring(L, vendor_id);
+	lua_pushstring(L, vendor);
+	lua_settable(L,-3);
+
+    /* if we have a tab + a char, it means this is a product id */
+    } else if ((line[0] == '\t') && (line[1] != '\t')) {
+
+	/* the product name the second field */
+        strlcpy(product,skipspace(strstr(line," ")),255);
+        remove_eol(product);
+
+	/* the 4th first chars are the vendor_id */
+	strlcpy(productvendor,vendor_id,4);
+	/* the product id is first field */
+	strlcpy(productvendor+4,&line[1],4);
+        productvendor[8]=0;
+
+	lua_pushstring(L, productvendor);
+	lua_pushstring(L, product);
+	lua_settable(L,-3);
+
+    /* if we have two tabs, it means this is a sub product */
+    } else if ((line[0] == '\t') && (line[1] == '\t')) {
+
+      /* the product name is last field */
+      strlcpy(product,skipspace(strstr(line," ")),255);
+      strlcpy(product,skipspace(strstr(product," ")),255);
+      remove_eol(product);
+
+      strlcpy(productvendorsub, productvendor,8);
+      strlcpy(productvendorsub+8, &line[2],4);
+      strlcpy(productvendorsub+12, &line[7],4);
+      productvendorsub[16]=0;
+
+      lua_pushstring(L, productvendorsub);
+      lua_pushstring(L, product);
+      lua_settable(L,-3);
+
+    }
+  }
+  fclose(f);
+  return(1);
+}
+
+static const luaL_Reg pcilib[] = {
+  {"getinfo", pci_getinfo},
+  {"getidlist", pci_getidlist},
+  {NULL, NULL}
+};
+
+/* This defines a function that opens up your library. */
+
+LUALIB_API int luaopen_pci (lua_State *L) {
+  luaL_newlib(L, pcilib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,525 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <getkey.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+
+#define lnetlib_c		/* Define the library */
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "syslinux/boot.h"
+#include "syslinux/loadfile.h"
+#include "syslinux/linux.h"
+#include "syslinux/config.h"
+#include "syslinux/reboot.h"
+
+int __parse_argv(char ***argv, const char *str);
+
+#define SYSLINUX_FILE "syslinux_file"
+
+typedef struct syslinux_file {
+    char *data;
+    char *name;
+    size_t size;
+} syslinux_file;
+
+/*
+ * Most code taken from:
+ *	com32/modules/linux.c
+ */
+
+/* Find the last instance of a particular command line argument
+   (which should include the final =; do not use for boolean arguments) */
+static char *find_argument(char **argv, const char *argument)
+{
+    int la = strlen(argument);
+    char **arg;
+    char *ptr = NULL;
+
+    for (arg = argv; *arg; arg++) {
+	if (!memcmp(*arg, argument, la))
+	    ptr = *arg + la;
+    }
+
+    return ptr;
+}
+
+/* Get a value with a potential suffix (k/m/g/t/p/e) */
+static unsigned long long suffix_number(const char *str)
+{
+    char *ep;
+    unsigned long long v;
+    int shift;
+
+    v = strtoull(str, &ep, 0);
+    switch (*ep | 0x20) {
+    case 'k':
+	shift = 10;
+	break;
+    case 'm':
+	shift = 20;
+	break;
+    case 'g':
+	shift = 30;
+	break;
+    case 't':
+	shift = 40;
+	break;
+    case 'p':
+	shift = 50;
+	break;
+    case 'e':
+	shift = 60;
+	break;
+    default:
+	shift = 0;
+	break;
+    }
+    v <<= shift;
+
+    return v;
+}
+
+/* Truncate to 32 bits, with saturate */
+static inline uint32_t saturate32(unsigned long long v)
+{
+    return (v > 0xffffffff) ? 0xffffffff : (uint32_t) v;
+}
+
+/* Stitch together the command line from a set of argv's */
+static char *make_cmdline(char **argv)
+{
+    char **arg;
+    size_t bytes;
+    char *cmdline, *p;
+
+    bytes = 1;			/* Just in case we have a zero-entry cmdline */
+    for (arg = argv; *arg; arg++) {
+	bytes += strlen(*arg) + 1;
+    }
+
+    p = cmdline = malloc(bytes);
+    if (!cmdline)
+	return NULL;
+
+    for (arg = argv; *arg; arg++) {
+	int len = strlen(*arg);
+	memcpy(p, *arg, len);
+	p[len] = ' ';
+	p += len + 1;
+    }
+
+    if (p > cmdline)
+	p--;			/* Remove the last space */
+    *p = '\0';
+
+    return cmdline;
+}
+
+static int sl_run_command(lua_State * L)
+{
+    const char *cmd = luaL_checkstring(L, 1);	/* Reads the string parameter */
+    syslinux_run_command(cmd);
+    return 0;
+}
+
+/* do default boot */
+static int sl_run_default(lua_State * L)
+{
+    /* Preventing GCC to complain against unused L */
+    L=L;
+    syslinux_run_default();
+    return 0;
+}
+
+/* do local boot */
+static int sl_local_boot(lua_State * L)
+{
+    uint16_t flags = luaL_checkint(L, 1);
+    syslinux_local_boot(flags);
+    return 0;
+}
+
+static int sl_final_cleanup(lua_State * L)
+{
+    uint16_t flags = luaL_checkint(L, 1);
+    syslinux_local_boot(flags);
+    return 0;
+}
+
+/* boot linux kernel and initrd */
+static int sl_boot_linux(lua_State * L)
+{
+    const char *kernel = luaL_checkstring(L, 1);
+    const char *cmdline = luaL_optstring(L, 2, "");
+    char *initrd;
+    void *kernel_data, *file_data;
+    size_t kernel_len, file_len;
+    struct initramfs *initramfs;
+    char *newcmdline;
+    uint32_t mem_limit = luaL_optint(L, 3, 0);
+    uint16_t video_mode = luaL_optint(L, 4, 0);
+    int ret;
+    char **argv, **argp, *arg, *p;
+
+    (void)mem_limit;
+    (void)video_mode;
+
+    ret = __parse_argv(&argv, cmdline);
+
+    newcmdline = malloc(strlen(kernel) + 12);
+    if (!newcmdline)
+	printf("Mem alloc failed: cmdline\n");
+
+    strcpy(newcmdline, "BOOT_IMAGE=");
+    strcpy(newcmdline + strlen(newcmdline), kernel);
+    argv[0] = newcmdline;
+    argp = argv;
+
+    /* DEBUG
+       for (i=0; i<ret; i++)
+       printf("%d: %s\n", i, argv[i]);
+     */
+
+    newcmdline = make_cmdline(argp);
+    if (!newcmdline)
+	printf("Creating command line failed!\n");
+
+    /* DEBUG
+       printf("Command line: %s\n", newcmdline);
+       msleep(1000);
+     */
+
+    printf("Loading kernel %s...\n", kernel);
+    if (loadfile(kernel, &kernel_data, &kernel_len))
+	printf("failed!\n");
+    else
+	printf("ok\n");
+
+    initramfs = initramfs_init();
+    if (!initramfs)
+	printf("Initializing initrd failed!\n");
+
+    if ((arg = find_argument(argp, "initrd="))) {
+	do {
+	    p = strchr(arg, ',');
+	    if (p)
+		*p = '\0';
+
+	    initrd = arg;
+	    printf("Loading initrd %s... ", initrd);
+	    if (initramfs_load_archive(initramfs, initrd)) {
+		printf("failed!\n");
+	    }
+	    printf("ok\n");
+
+	    if (p)
+		*p++ = ',';
+	} while ((arg = p));
+    }
+
+    ret = syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, newcmdline);
+
+    printf("syslinux_boot_linux returned %d\n", ret);
+
+    return 0;
+}
+
+/* sleep for sec seconds */
+static int sl_sleep(lua_State * L)
+{
+    unsigned int sec = luaL_checkint(L, 1);
+    sleep(sec);
+    return 0;
+}
+
+/* sleep for msec milliseconds */
+static int sl_msleep(lua_State * L)
+{
+    unsigned int msec = luaL_checkint(L, 1);
+    msleep(msec);
+    return 0;
+}
+
+static int sl_run_kernel_image(lua_State * L)
+{
+    const char *filename = luaL_checkstring(L, 1);
+    const char *cmdline = luaL_checkstring(L, 2);
+    uint32_t ipappend_flags = luaL_checkint(L, 3);
+    uint32_t type = luaL_checkint(L, 4);
+
+    syslinux_run_kernel_image(filename, cmdline, ipappend_flags, type);
+    return 0;
+}
+
+static int sl_loadfile(lua_State * L)
+{
+    const char *filename = luaL_checkstring(L, 1);
+    syslinux_file *file;
+
+    void *file_data;
+    size_t file_len;
+
+    if (loadfile(filename, &file_data, &file_len)) {
+	lua_pushstring(L, "Could not load file");
+	lua_error(L);
+    }
+
+    file = malloc(sizeof(syslinux_file));
+    strlcpy(file->name,filename,sizeof(syslinux_file));
+    file->size = file_len;
+    file->data = file_data;
+
+    lua_pushlightuserdata(L, file);
+    luaL_getmetatable(L, SYSLINUX_FILE);
+    lua_setmetatable(L, -2);
+
+    return 1;
+}
+
+static int sl_filesize(lua_State * L)
+{
+    const syslinux_file *file = luaL_checkudata(L, 1, SYSLINUX_FILE);
+
+    lua_pushinteger(L, file->size);
+
+    return 1;
+}
+
+static int sl_filename(lua_State * L)
+{
+    const syslinux_file *file = luaL_checkudata(L, 1, SYSLINUX_FILE);
+
+    lua_pushstring(L, file->name);
+
+    return 1;
+}
+
+static int sl_initramfs_init(lua_State * L)
+{
+    struct initramfs *initramfs;
+
+    initramfs = initramfs_init();
+    if (!initramfs)
+	printf("Initializing initrd failed!\n");
+
+    lua_pushlightuserdata(L, initramfs);
+    luaL_getmetatable(L, SYSLINUX_FILE);
+    lua_setmetatable(L, -2);
+
+    return 1;
+}
+
+static int sl_initramfs_load_archive(lua_State * L)
+{
+    struct initramfs *initramfs = luaL_checkudata(L, 1, SYSLINUX_FILE);
+    const char *filename = luaL_checkstring(L, 2);
+
+    if (initramfs_load_archive(initramfs, filename)) {
+	printf("failed!\n");
+    }
+
+    return 0;
+}
+
+static int sl_initramfs_add_file(lua_State * L)
+{
+    struct initramfs *initramfs = luaL_checkudata(L, 1, SYSLINUX_FILE);
+    const char *filename = luaL_checkstring(L, 2);
+    void *file_data = NULL;
+    size_t file_len = 0;
+
+    return initramfs_add_file(initramfs, file_data, file_len, file_len,
+			      filename, 0, 0755);
+}
+
+static int sl_boot_it(lua_State * L)
+{
+    const syslinux_file *kernel = luaL_checkudata(L, 1, SYSLINUX_FILE);
+    struct initramfs *initramfs = luaL_checkudata(L, 2, SYSLINUX_FILE);
+    const char *cmdline = luaL_optstring(L, 3, "");
+    uint32_t mem_limit = luaL_optint(L, 4, 0);
+    uint16_t video_mode = luaL_optint(L, 5, 0);
+    /* Preventing gcc to complain about unused variables */
+    (void)video_mode;
+    (void)mem_limit;
+
+    return syslinux_boot_linux(kernel->data, kernel->size,
+			       initramfs, NULL, (char *)cmdline);
+}
+
+static int sl_config_file(lua_State * L)
+{
+    const char *config_file = syslinux_config_file();
+    lua_pushstring(L, config_file);
+    return 1;
+}
+
+static int sl_reboot(lua_State * L)
+{
+    int warm_boot = luaL_optint(L, 1, 0);
+    /* explicitly convert it to 1 or 0 */
+    warm_boot = warm_boot? 1 : 0;
+    syslinux_reboot(warm_boot);
+    return 0;
+}
+
+static int sl_ipappend_strs(lua_State * L)
+{
+    int i;
+    const struct syslinux_ipappend_strings *ip_strs = syslinux_ipappend_strings();
+    lua_newtable(L);
+    for (i = 0; i < ip_strs->count; i++) {
+        lua_pushinteger(L, i + 1);
+        lua_pushstring(L, ip_strs->ptr[i]);
+        lua_settable(L,-3);
+    }
+    return 1;
+}
+
+static int sl_derivative(lua_State * L)
+{
+    const struct syslinux_version *sv;
+
+    sv = syslinux_version();
+
+    switch (sv->filesystem) {
+    case SYSLINUX_FS_SYSLINUX:
+	lua_pushstring(L, "SYSLINUX");
+	break;
+    case SYSLINUX_FS_PXELINUX:
+	lua_pushstring(L, "PXELINUX");
+	break;
+    case SYSLINUX_FS_ISOLINUX:
+	lua_pushstring(L, "ISOLINUX");
+	break;
+    case SYSLINUX_FS_UNKNOWN:
+    default:
+	lua_pushstring(L, "Unknown Syslinux derivative");
+	break;
+    }
+
+    return 1;
+}
+
+static int sl_version(lua_State * L)
+{
+    const struct syslinux_version *sv;
+
+    sv = syslinux_version();
+    lua_pushstring(L, sv->version_string);
+
+    return 1;
+}
+
+static int sl_get_key (lua_State * L)
+{
+    int timeout = luaL_checkint (L, 1);
+    lua_pushinteger (L, get_key (stdin, timeout));
+    return 1;
+}
+
+static int sl_KEY_CTRL (lua_State * L)
+{
+    lua_pushinteger (L, KEY_CTRL (luaL_checkint (L, 1)));
+    return 1;
+}
+
+static const luaL_Reg syslinuxlib[] = {
+    {"run_command", sl_run_command},
+    {"run_default", sl_run_default},
+    {"local_boot", sl_local_boot},
+    {"final_cleanup", sl_final_cleanup},
+    {"boot_linux", sl_boot_linux},
+    {"run_kernel_image", sl_run_kernel_image},
+    {"sleep", sl_sleep},
+    {"msleep", sl_msleep},
+    {"loadfile", sl_loadfile},
+    {"filesize", sl_filesize},
+    {"filename", sl_filename},
+    {"initramfs_init", sl_initramfs_init},
+    {"initramfs_load_archive", sl_initramfs_load_archive},
+    {"initramfs_add_file", sl_initramfs_add_file},
+    {"boot_it", sl_boot_it},
+    {"config_file", sl_config_file},
+    {"ipappend_strs", sl_ipappend_strs},
+    {"reboot", sl_reboot},
+    {"derivative", sl_derivative},
+    {"version", sl_version},
+    {"get_key", sl_get_key},
+    {"KEY_CTRL", sl_KEY_CTRL},
+    {NULL, NULL}
+};
+
+/* This defines a function that opens up your library. */
+
+LUALIB_API int luaopen_syslinux(lua_State * L)
+{
+
+    luaL_newmetatable(L, SYSLINUX_FILE);
+
+    luaL_newlib(L, syslinuxlib);
+
+    lua_newtable (L);
+#define export_key(x) lua_pushinteger (L, KEY_##x); lua_setfield (L, -2, #x);
+    export_key (NONE);
+    export_key (BACKSPACE);
+    export_key (TAB);
+    export_key (ENTER);
+    export_key (ESC);
+    export_key (DEL);
+    export_key (F1);
+    export_key (F2);
+    export_key (F3);
+    export_key (F4);
+    export_key (F5);
+    export_key (F6);
+    export_key (F7);
+    export_key (F8);
+    export_key (F9);
+    export_key (F10);
+    export_key (F11);
+    export_key (F12);
+    export_key (UP);
+    export_key (DOWN);
+    export_key (LEFT);
+    export_key (RIGHT);
+    export_key (PGUP);
+    export_key (PGDN);
+    export_key (HOME);
+    export_key (END);
+    export_key (INSERT);
+    export_key (DELETE);
+    lua_setfield (L, -2, "KEY");
+
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/src/vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/src/vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/src/vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,139 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "../../include/console.h"
+#include "../../lib/sys/vesa/vesa.h"
+#include "../../lib/sys/vesa/video.h"
+
+int vesacon_load_background(const char *filename);
+
+static int vesa_getmodes(lua_State *L)
+{
+  com32sys_t rm;
+  uint16_t mode, *mode_ptr;
+  struct vesa_general_info *gi;
+  struct vesa_mode_info *mi;
+  int nmode = 1;
+  int rv = -1;
+
+  gi = lmalloc(sizeof *gi);
+  if (!gi)
+      return -1;
+
+  mi = lmalloc(sizeof *mi);
+  if (!mi)
+      goto out;
+
+  memset(&rm, 0, sizeof(rm));
+  memset(gi, 0, sizeof *gi);
+
+  gi->signature = VBE2_MAGIC;   /* Get VBE2 extended data */
+  rm.eax.w[0] = 0x4F00;         /* Get SVGA general information */
+  rm.edi.w[0] = OFFS(gi);
+  rm.es      = SEG(gi);
+  __intcall(0x10, &rm, &rm);
+
+  if ( rm.eax.w[0] != 0x004F )
+    goto out;                   /* Function call failed */
+  if ( gi->signature != VESA_MAGIC ) {
+    rv = -2;                   /* No magic */
+    goto out;
+  }
+  if ( gi->version < 0x0102 ) {
+    rv = -3;                   /* VESA 1.2+ required */
+    goto out;
+  }
+
+  lua_newtable(L);      /* list of modes */
+
+  /* Copy general info */
+  memcpy(&__vesa_info.gi, gi, sizeof *gi);
+
+  /* Search for a 640x480 mode with a suitable color and memory model... */
+
+  mode_ptr = GET_PTR(gi->video_mode_ptr);
+
+  while ((mode = *mode_ptr++) != 0xFFFF) {
+    mode &= 0x1FF;              /* The rest are attributes of sorts */
+
+    printf("Found mode: 0x%04x (%dx%dx%d)\n", mode, mi->h_res, mi->v_res, mi->bpp);
+
+    memset(&rm, 0, sizeof(rm));
+    memset(mi, 0, sizeof *mi);
+    rm.eax.w[0] = 0x4F01;       /* Get SVGA mode information */
+    rm.ecx.w[0] = mode;
+    rm.edi.w[0] = OFFS(mi);
+    rm.es  = SEG(mi);
+    __intcall(0x10, &rm, &rm);
+
+    /* Must be a supported mode */
+    if ( rm.eax.w[0] != 0x004f )
+      continue;
+
+    lua_pushnumber(L, nmode++);
+    lua_newtable(L); /* mode info */
+
+    lua_pushstring(L, "mode");
+    lua_pushnumber(L, mode);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "hres");
+    lua_pushnumber(L, mi->h_res);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "vres");
+    lua_pushnumber(L, mi->v_res);
+    lua_settable(L,-3);
+
+    lua_pushstring(L, "bpp");
+    lua_pushnumber(L, mi->bpp);
+    lua_settable(L,-3);
+
+    lua_settable(L, -3); /* add to mode list */
+
+  }
+
+  rv = 1;
+out:
+  lfree(mi);
+  lfree(gi);
+  return rv;
+}
+
+
+static int vesa_setmode(lua_State *L)
+{
+  /* Preventing GCC to complain about unused L*/
+  L=L;
+  openconsole(&dev_rawcon_r, &dev_vesaserial_w);
+
+  return 0;
+}
+
+
+static int vesa_load_background(lua_State *L)
+{
+  const char *filename = luaL_checkstring(L, 1);
+
+  vesacon_load_background(filename);
+
+  return 0;
+}
+
+static const luaL_Reg vesalib[] = {
+  {"getmodes", vesa_getmodes},
+  {"setmode", vesa_setmode},
+  {"load_background", vesa_load_background},
+  {NULL, NULL}
+};
+
+/* This defines a function that opens up your library. */
+
+LUALIB_API int luaopen_vesa (lua_State *L) {
+  luaL_newlib(L, vesalib);
+  return 1;
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/lua/test/automenu.lua
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/test/automenu.lua	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/test/automenu.lua	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,152 @@
+--[[
+Automatically generated boot menu of the installed Linux kernels
+
+Example:
+
+m = require "automenu"
+m.run { dir = "/",
+        default = 1,
+        timeout = 5,
+        append = "root=/dev/hda2 ro",
+}
+
+TODO:
+- add hooks
+- demo adding break options from user config
+- kernel flavor preference (pae/rt)
+]]
+
+local lfs = require "lfs"
+local sl = require "syslinux"
+
+local single = false
+local verbosity = 2
+
+local function modifiers ()
+   return (single and " single" or "") .. ({" quiet",""," debug"})[verbosity]
+end
+
+local function scan (params)
+   local sep = string.sub (params.dir, -1) == "/" and "" or "/"
+   if not params.items then params.items = {} end
+   for name in lfs.dir (params.dir) do
+      local path = params.dir .. sep .. name
+      if lfs.attributes (path, "mode") == "file" then
+         local from,to,version = string.find (name, "^vmlinuz%-(.*)")
+         if from then
+            local initrd = params.dir .. sep .. "initrd.img-" .. version
+            local initrd_param = ""
+            if lfs.attributes (initrd, "size") then
+               initrd_param = "initrd=" .. initrd .. " "
+            end
+            table.insert (params.items, {
+                             show = function () return name end,
+                             version = version,
+                             execute = function () sl.boot_linux (path, initrd_param .. params.append .. modifiers ()) end
+                          })
+         end
+      end
+   end
+end
+
+local function version_gt (v1, v2)
+   local negatives = {"rc", "pre"}
+   local m1, r1 = string.match (v1, "^(%D*)(.*)")
+   local m2, r2 = string.match (v2, "^(%D*)(.*)")
+   if m1 ~= m2 then
+      for _, suffix in ipairs (negatives) do
+         suffix = "-" .. suffix
+         if m1 == suffix and m2 ~= suffix then
+            return false
+         elseif m1 ~= suffix and m2 == suffix then
+            return true
+         end
+      end
+      return m1 > m2
+   end
+   m1, r1 = string.match (r1, "^(%d*)(.*)")
+   m2, r2 = string.match (r2, "^(%d*)(.*)")
+   m1 = tonumber (m1) or 0
+   m2 = tonumber (m2) or 0
+   if m1 ~= m2 then
+      return m1 > m2
+   end
+   if r1 == "" and r2 == "" then
+      return false
+   end
+   return version_gt (r1, r2)
+end
+
+local function kernel_gt (k1, k2)
+   return version_gt (k1.version, k2.version)
+end
+
+local function print_or_call (x, def)
+   local t = type (x)
+   if t == "nil" then
+      if def then print (def) end
+   elseif t == "function" then
+      x ()
+   else
+      print (x)
+   end
+end
+
+local function draw (params)
+   print_or_call (params.title, "\n=== Boot menu ===")
+   for i, item in ipairs (params.items) do
+      print ((i == params.default and " > " or "   ") .. i .. "  " .. item.show ())
+   end
+   print ("\nKernel arguments:\n  " .. params.append .. modifiers ())
+   print ("\nHit a number to select from the menu,\n    ENTER to accept default,\n    ESC to exit\n or any other key to print menu again")
+end
+
+local function choose (params)
+   draw (params)
+   print ("\nBooting in " .. params.timeout .. " s...")
+   while true do
+      local i = sl.get_key (params.timeout * 1000)
+      if i == sl.KEY.ESC then
+         break
+      else
+         if i == sl.KEY.NONE or i == sl.KEY.ENTER then
+            i = params.default
+         elseif i == sl.KEY.DOWN then
+            params.default = params.default < #params.items and params.default + 1 or #params.items
+         elseif i == sl.KEY.UP then
+            params.default = params.default > 1 and params.default - 1 or 1
+         else
+            i = i - string.byte "0"
+         end
+         if params.items[i] then
+            params.items[i].execute ()
+         end
+         params.timeout = 0
+         draw (params)
+      end
+   end
+end
+
+local function run (params)
+   scan (params)
+   if not next (params.items) then
+      print ("No kernels found in directory " .. params.dir)
+      os.exit (false)
+   end
+   table.sort (params.items, kernel_gt)
+   table.insert (params.items, {
+                    show = function () return "Single user: " .. (single and "true" or "false") end,
+                    execute = function () single = not single end
+                 })
+   table.insert (params.items, {
+                    show = function () return "Verbosity: " .. ({"quiet","normal","debug"})[verbosity] end,
+                    execute = function () verbosity = verbosity < 3 and verbosity + 1 or 1 end
+                 })
+   choose (params)
+end
+
+return {
+   scan = scan,
+   choose = choose,
+   run = run
+}
Index: bootcd/isolinux/syslinux-6.03/com32/lua/test/simplemenu.lua
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/lua/test/simplemenu.lua	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/lua/test/simplemenu.lua	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,34 @@
+-- A translation of com32/cmenu/simple.c into Lua
+
+local m = require "cmenu"
+local sl = require "syslinux"
+
+m.init()
+m.set_window_size(1, 1, 23, 78)
+local testing = m.add_named_menu("testing", " Testing ")
+-- demonstrate identifying (named) submenu by number:
+m.add_item("Self Loop", "Go to testing", m.action.SUBMENU, nil, testing)
+m.add_item("Memory Test", "Perform extensive memory testing", m.action.RUN, "memtest")
+m.add_item("Exit this menu", "Go one level up", m.action.EXITMENU, "exit")
+
+local rescue = m.add_menu(" Rescue Options ")
+m.add_item("Linux Rescue", "linresc", m.action.RUN, "linresc")
+m.add_item("Dos Rescue", "dosresc", m.action.RUN, "dosresc")
+m.add_item("Windows Rescue", "winresc", m.action.RUN, "winresc")
+m.add_item("Exit this menu", "Go one level up", m.action.EXITMENU, "exit")
+
+m.add_named_menu("main", " Main Menu ")
+m.add_item("Prepare", "prep", m.action.RUN, "prep")
+m.add_item("Rescue options...", "Troubleshoot a system", m.action.SUBMENU, nil, rescue)
+-- demonstrate identifying submenu by name:
+m.add_item("Testing...", "Options to test hardware", m.action.SUBMENU, "testing")
+m.add_item("Exit to prompt", "Exit the menu system", m.action.EXITMENU, "exit")
+
+-- demonstrate finding menu explicitly:
+local action, data = m.showmenus(m.find_menu_num("main"))
+
+if action == m.action.RUN then
+  sl.run_command (data)
+else
+  print (action, data)
+end
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Multiboot module
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LNXLIBS	   = $(objdir)/com32/libutil/libutil_lnx.a
+
+MODULES	  = mboot.c32
+TESTFILES =
+
+OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o syslinux.o
+
+all: $(MODULES) $(TESTFILES)
+
+mboot.elf : $(OBJS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ *   Based on code from the Linux kernel:
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
+ *   (sfr@canb.auug.org.au)
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * apm.c
+ *
+ * APM information for Multiboot
+ */
+
+#include "mboot.h"
+#include <com32.h>
+
+void mboot_apm(void)
+{
+    static struct apm_info apm;
+    com32sys_t ireg, oreg;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0x5300;
+    __intcall(0x15, &ireg, &oreg);
+
+    if (oreg.eflags.l & EFLAGS_CF)
+	return;			/* No APM BIOS */
+
+    if (oreg.ebx.w[0] != 0x504d)
+	return;			/* No "PM" signature */
+
+    if (!(oreg.ecx.w[0] & 0x02))
+	return;			/* 32 bits not supported */
+
+    /* Disconnect first, just in case */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[0] = 0x04;
+    __intcall(0x15, &ireg, &oreg);
+
+    /* 32-bit connect */
+    ireg.eax.b[0] = 0x03;
+    __intcall(0x15, &ireg, &oreg);
+
+    apm.cseg = oreg.eax.w[0];
+    apm.offset = oreg.ebx.l;
+    apm.cseg_16 = oreg.ecx.w[0];
+    apm.dseg_16 = oreg.edx.w[0];
+    apm.cseg_len = oreg.esi.w[0];
+    apm.cseg_16_len = oreg.esi.w[1];
+    apm.dseg_16_len = oreg.edi.w[0];
+
+    /* Redo the installation check as the 32-bit connect;
+       some BIOSes return different flags this way... */
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[0] = 0x00;
+    __intcall(0x15, &ireg, &oreg);
+
+    if ((oreg.eflags.l & EFLAGS_CF) || (oreg.ebx.w[0] != 0x504d)) {
+	/* Failure with 32-bit connect, try to disconect and ignore */
+	ireg.eax.b[0] = 0x04;
+	__intcall(0x15, &ireg, NULL);
+	return;
+    }
+
+    apm.version = oreg.eax.w[0];
+
+    mbinfo.apm_table = map_data(&apm, sizeof apm, 4, false);
+    if (mbinfo.apm_table)
+	mbinfo.flags |= MB_INFO_APM_TABLE;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,233 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initvesa.c
+ *
+ * Query the VESA BIOS and select a 640x480x32 mode with local mapping
+ * support, if one exists.
+ */
+
+#include <inttypes.h>
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <graphics.h>
+
+#include "vesa.h"
+#include "mboot.h"
+
+struct vesa_info vesa_info;
+
+void set_graphics_mode(const struct multiboot_header *mbh,
+		       struct multiboot_info *mbi)
+{
+    com32sys_t rm;
+    uint16_t mode, bestmode, *mode_ptr;
+    struct vesa_general_info *gi;
+    struct vesa_mode_info *mi;
+    int pxf, bestpxf;
+    int wantx, wanty;
+    int err, besterr;
+    bool better;
+    addr_t viaddr;
+
+    /* Only do this if requested by the OS image */
+    if (!(mbh->flags & MULTIBOOT_VIDEO_MODE) || mbh->mode_type != 0)
+	return;
+
+    gi = lmalloc(sizeof *gi);
+    if (!gi)
+	return;
+
+    mi = lmalloc(sizeof *mi);
+    if (!mi)
+	goto out;
+
+    memset(&rm, 0, sizeof rm);
+    memset(gi, 0, sizeof *gi);
+
+    gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gi);
+    rm.es = SEG(gi);
+    __intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F)
+	goto out;		/* Function call failed */
+    if (gi->signature != VESA_MAGIC)
+	goto out;		/* No magic */
+    if (gi->version < 0x0102)
+	goto out;		/* VESA 1.2+ required */
+
+    memcpy(&vesa_info.gi, gi, sizeof *gi);
+
+    /* Search for a suitable mode with a suitable color and memory model... */
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+    bestmode = 0;
+    bestpxf = 0;
+    wantx = mbh->width  ? mbh->width  : 0xffff;
+    wanty = mbh->height ? mbh->height : 0xffff;
+    besterr = wantx + wanty;
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	mode &= 0x1FF;		/* The rest are attributes of sorts */
+
+        memset(&rm, 0, sizeof rm);
+	memset(mi, 0, sizeof *mi);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mi);
+	rm.es = SEG(mi);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	/* Must be an LFB color graphics mode supported by the hardware.
+
+	   The bits tested are:
+	   7 - linear frame buffer
+	   4 - graphics mode
+	   3 - color mode
+	   1 - mode information available (mandatory in VBE 1.2+)
+	   0 - mode supported by hardware
+	 */
+	if ((mi->mode_attr & 0x009b) != 0x009b)
+	    continue;
+
+	/* We don't support multibank (interlaced memory) modes */
+	/*
+	 *  Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the
+	 * specification which states that banks == 1 for unbanked modes;
+	 * fortunately it does report bank_size == 0 for those.
+	 */
+	if (mi->banks > 1 && mi->bank_size)
+	    continue;
+
+	/* Must either be a packed-pixel mode or a direct color mode
+	   (depending on VESA version ); must be a supported pixel format */
+
+	if (mi->bpp == 32 &&
+	    (mi->memory_layout == 4 ||
+	     (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+	      mi->bpos == 0)))
+	    pxf = 32;
+	else if (mi->bpp == 24 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+		   mi->bpos == 0)))
+	    pxf = 24;
+	else if (mi->bpp == 16 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 &&
+		   mi->bpos == 0)))
+	    pxf = 16;
+	else if (mi->bpp == 15 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 &&
+		   mi->bpos == 0)))
+	    pxf = 15;
+	else
+	    continue;
+
+	better = false;
+	err = abs(mi->h_res - wantx) + abs(mi->v_res - wanty);
+
+#define IS_GOOD(mi, bestx, besty) \
+	((mi)->h_res >= (bestx) && (mi)->v_res >= (besty))
+
+	if (!bestpxf)
+	    better = true;
+	else if (!IS_GOOD(&vesa_info.mi, wantx, wanty) &&
+		 IS_GOOD(mi, wantx, wanty))
+	    /* This matches criteria, which the previous one didn't */
+	    better = true;
+	else if (IS_GOOD(&vesa_info.mi, wantx, wanty) &&
+		 !IS_GOOD(mi, wantx, wanty))
+	    /* This doesn't match criteria, and the previous one did */
+	    better = false;
+	else if (err < besterr)
+	    better = true;
+	else if (err == besterr && (pxf == (int)mbh->depth || pxf > bestpxf))
+	    better = true;
+
+	if (better) {
+	    bestmode = mode;
+	    bestpxf = pxf;
+	    memcpy(&vesa_info.mi, mi, sizeof *mi);
+	}
+    }
+
+    if (!bestpxf)
+	goto out;		/* No mode found */
+
+    mi = &vesa_info.mi;
+    mode = bestmode;
+
+    /* Now set video mode */
+    memset(&rm, 0, sizeof rm);
+    rm.eax.w[0] = 0x4F02;	/* Set SVGA video mode */
+    mode |= 0x4000;		/* Request linear framebuffer */
+    rm.ebx.w[0] = mode;
+    __intcall(0x10, &rm, &rm);
+    if (rm.eax.w[0] != 0x004F)
+	goto out;		/* Failed to set mode */
+
+    mbi->flags |= MB_INFO_VIDEO_INFO;
+    mbi->vbe_mode = mode;
+    viaddr = map_data(&vesa_info, sizeof vesa_info, 4, 0);
+    mbi->vbe_control_info = viaddr + offsetof(struct vesa_info, gi);
+    mbi->vbe_mode_info = viaddr + offsetof(struct vesa_info, mi);
+
+    /* Get the VBE 2.x PM entry point if supported */
+    rm.eax.w[0] = 0x4F0A;
+    rm.ebx.w[0] = 0;
+    __intcall(0x10, &rm, &rm);
+    if (rm.eax.w[0] == 0x004F) {
+	mbi->vbe_interface_seg = rm.es;
+	mbi->vbe_interface_off = rm.edi.w[0];
+	mbi->vbe_interface_len = rm.ecx.w[0];
+    }
+
+    /* In theory this should be:
+     *
+     * UsingVga = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
+     *
+     * However, that would assume all systems that claim to handle text
+     * output in VESA modes actually do that...
+     */
+    graphics_using_vga(0x0F, vesa_info.mi.h_res, vesa_info.mi.v_res);
+
+out:
+    lfree(mi);
+    lfree(gi);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/map.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/map.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/map.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,352 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * map.c
+ *
+ * Functions that deal with the memory map of various objects
+ */
+
+#include "mboot.h"
+
+static struct syslinux_movelist *ml = NULL;
+static struct syslinux_memmap *mmap = NULL, *amap = NULL;
+static addr_t mboot_high_water_mark = 0x100000;
+
+/*
+ * Note: although there is no such thing in the spec, at least Xen makes
+ * assumptions as to where in the memory space Grub would have loaded
+ * certain things.  To support that, if "high" is set, then allocate this
+ * at an address strictly above any previous allocations.
+ *
+ * As a precaution, this also pads the data with zero up to the next
+ * alignment datum.
+ */
+addr_t map_data(const void *data, size_t len, size_t align, int flags)
+{
+    addr_t start = (flags & MAP_HIGH) ? mboot_high_water_mark : 0x2000;
+    addr_t pad = (flags & MAP_NOPAD) ? 0 : -len & (align - 1);
+    addr_t xlen = len + pad;
+
+    if (syslinux_memmap_find_type(amap, SMT_FREE, &start, &xlen, align) ||
+	syslinux_add_memmap(&amap, start, len + pad, SMT_ALLOC) ||
+	syslinux_add_movelist(&ml, start, (addr_t) data, len) ||
+	(pad && syslinux_add_memmap(&mmap, start + len, pad, SMT_ZERO))) {
+	printf("Cannot map %zu bytes\n", len + pad);
+	return 0;
+    }
+
+    dprintf("Mapping 0x%08x bytes (%#x pad) at 0x%08x\n", len, pad, start);
+
+    if (start + len + pad > mboot_high_water_mark)
+	mboot_high_water_mark = start + len + pad;
+
+    return start;
+}
+
+addr_t map_string(const char *string)
+{
+    if (!string)
+	return 0;
+    else
+	return map_data(string, strlen(string) + 1, 1, 0);
+}
+
+int init_map(void)
+{
+    /*
+     * Note: mmap is the memory map (containing free and zeroed regions)
+     * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
+     * track ourselves which target memory ranges have already been
+     * allocated.
+     */
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap) {
+	error("Failed to allocate initial memory map!\n");
+	return -1;
+    }
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    return 0;
+}
+
+struct multiboot_header *map_image(void *ptr, size_t len)
+{
+    struct multiboot_header *mbh;
+    int mbh_len;
+    char *cptr = ptr;
+    Elf32_Ehdr *eh = ptr;
+    Elf32_Phdr *ph;
+    Elf32_Shdr *sh;
+    unsigned int i, mbh_offset;
+    uint32_t bad_flags;
+
+    /*
+     * Search for the multiboot header...
+     */
+    mbh_len = 0;
+    for (mbh_offset = 0; mbh_offset < MULTIBOOT_SEARCH; mbh_offset += 4) {
+	mbh = (struct multiboot_header *)((char *)ptr + mbh_offset);
+	if (mbh->magic != MULTIBOOT_MAGIC)
+	    continue;
+	if (mbh->magic + mbh->flags + mbh->checksum)
+	    continue;
+	if (mbh->flags & MULTIBOOT_VIDEO_MODE)
+	    mbh_len = 48;
+	else if (mbh->flags & MULTIBOOT_AOUT_KLUDGE)
+	    mbh_len = 32;
+	else
+	    mbh_len = 12;
+
+	if (mbh_offset + mbh_len > len)
+	    mbh_len = 0;	/* Invalid... */
+	else
+	    break;		/* Found something... */
+    }
+
+    if (mbh_len) {
+	bad_flags = mbh->flags & MULTIBOOT_UNSUPPORTED;
+	if (bad_flags) {
+	    printf("Unsupported Multiboot flags set: %#x\n", bad_flags);
+	    return NULL;
+	}
+    }
+
+    if (len < sizeof(Elf32_Ehdr) ||
+	memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6) ||
+	(eh->e_machine != EM_386 && eh->e_machine != EM_486 &&
+	 eh->e_machine != EM_X86_64) ||
+	eh->e_version != EV_CURRENT ||
+	eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len ||
+	eh->e_phentsize < sizeof(Elf32_Phdr) ||
+	!eh->e_phnum || eh->e_phoff + eh->e_phentsize * eh->e_phnum > len)
+	eh = NULL;		/* No valid ELF header found */
+
+    /* Is this a Solaris kernel? */
+    if (!set.solaris && eh && kernel_is_solaris(eh))
+	opt.solaris = true;
+
+    /*
+     * Note: the Multiboot Specification implies that AOUT_KLUDGE should
+     * have precedence over the ELF header.  However, Grub disagrees, and
+     * Grub is "the reference bootloader" for the Multiboot Specification.
+     * This is insane, since it makes the AOUT_KLUDGE bit functionally
+     * useless, but at least Solaris apparently depends on this behavior.
+     */
+    if (eh && !(opt.aout && mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE))) {
+	regs.eip = eh->e_entry;	/* Can be overridden further down... */
+
+	ph = (Elf32_Phdr *) (cptr + eh->e_phoff);
+
+	for (i = 0; i < eh->e_phnum; i++) {
+	    if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) {
+		/*
+		 * This loads at p_paddr, which matches Grub.  However, if
+		 * e_entry falls within the p_vaddr range of this PHDR, then
+		 * adjust it to match the p_paddr range... this is how Grub
+		 * behaves, so it's by definition correct (it doesn't have to
+		 * make sense...)
+		 */
+		addr_t addr = ph->p_paddr;
+		addr_t msize = ph->p_memsz;
+		addr_t dsize = min(msize, ph->p_filesz);
+
+		if (eh->e_entry >= ph->p_vaddr
+		    && eh->e_entry < ph->p_vaddr + msize)
+		    regs.eip = eh->e_entry + (ph->p_paddr - ph->p_vaddr);
+
+		dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n",
+			addr, dsize, msize);
+
+		if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) {
+		    printf
+			("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+			 addr, msize);
+		    return NULL;	/* Memory region unavailable */
+		}
+
+		/* Mark this region as allocated in the available map */
+		if (syslinux_add_memmap(&amap, addr, msize, SMT_ALLOC)) {
+		    error("Overlapping segments found in ELF header\n");
+		    return NULL;
+		}
+
+		if (ph->p_filesz) {
+		    /* Data present region.  Create a move entry for it. */
+		    if (syslinux_add_movelist
+			(&ml, addr, (addr_t) cptr + ph->p_offset, dsize)) {
+			error("Failed to map PHDR data\n");
+			return NULL;
+		    }
+		}
+		if (msize > dsize) {
+		    /* Zero-filled region.  Mark as a zero region in the memory map. */
+		    if (syslinux_add_memmap
+			(&mmap, addr + dsize, msize - dsize, SMT_ZERO)) {
+			error("Failed to map PHDR zero region\n");
+			return NULL;
+		    }
+		}
+		if (addr + msize > mboot_high_water_mark)
+		    mboot_high_water_mark = addr + msize;
+	    } else {
+		/* Ignore this program header */
+	    }
+
+	    ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize);
+	}
+
+	/* Load the ELF symbol table */
+	if (eh->e_shoff) {
+	    addr_t addr, len;
+
+	    sh = (Elf32_Shdr *) ((char *)eh + eh->e_shoff);
+
+	    len = eh->e_shentsize * eh->e_shnum;
+	    /*
+	     * Align this, but don't pad -- in general this means a bunch of
+	     * smaller sections gets packed into a single page.
+	     */
+	    addr = map_data(sh, len, 4096, MAP_HIGH | MAP_NOPAD);
+	    if (!addr) {
+		error("Failed to map symbol table\n");
+		return NULL;
+	    }
+
+	    mbinfo.flags |= MB_INFO_ELF_SHDR;
+	    mbinfo.syms.e.addr = addr;
+	    mbinfo.syms.e.num = eh->e_shnum;
+	    mbinfo.syms.e.size = eh->e_shentsize;
+	    mbinfo.syms.e.shndx = eh->e_shstrndx;
+
+	    for (i = 0; i < eh->e_shnum; i++) {
+		addr_t align;
+
+		if (!sh[i].sh_size)
+		    continue;	/* Empty section */
+		if (sh[i].sh_flags & SHF_ALLOC)
+		    continue;	/* SHF_ALLOC sections should have PHDRs */
+
+		align = sh[i].sh_addralign ? sh[i].sh_addralign : 0;
+		addr = map_data((char *)ptr + sh[i].sh_offset, sh[i].sh_size,
+				align, MAP_HIGH);
+		if (!addr) {
+		    error("Failed to map symbol section\n");
+		    return NULL;
+		}
+		sh[i].sh_addr = addr;
+	    }
+	}
+    } else if (mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE)) {
+	/*
+	 * a.out kludge thing...
+	 */
+	char *data_ptr;
+	addr_t data_len, bss_len;
+	addr_t bss_addr;
+
+	regs.eip = mbh->entry_addr;
+
+	data_ptr = (char *)mbh - (mbh->header_addr - mbh->load_addr);
+
+	if (mbh->load_end_addr)
+	    data_len = mbh->load_end_addr - mbh->load_addr;
+	else
+	    data_len = len - mbh_offset + (mbh->header_addr - mbh->load_addr);
+
+	bss_addr = mbh->load_addr + data_len;
+
+	if (mbh->bss_end_addr)
+	    bss_len = mbh->bss_end_addr - mbh->load_end_addr;
+	else
+	    bss_len = 0;
+
+	if (syslinux_memmap_type(amap, mbh->load_addr, data_len + bss_len)
+	    != SMT_FREE) {
+	    printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+		   mbh->load_addr, data_len + bss_len);
+	    return NULL;		/* Memory region unavailable */
+	}
+	if (syslinux_add_memmap(&amap, mbh->load_addr,
+				data_len + bss_len, SMT_ALLOC)) {
+	    error("Failed to claim a.out address space!\n");
+	    return NULL;
+	}
+	if (data_len)
+	    if (syslinux_add_movelist(&ml, mbh->load_addr, (addr_t) data_ptr,
+				      data_len)) {
+		error("Failed to map a.out data\n");
+		return NULL;
+	    }
+	if (bss_len)
+	    if (syslinux_add_memmap
+		(&mmap, bss_addr, bss_len, SMT_ZERO)) {
+		error("Failed to map a.out bss\n");
+		return NULL;
+	    }
+	if (bss_addr + bss_len > mboot_high_water_mark)
+	    mboot_high_water_mark = bss_addr + bss_len;
+    } else {
+	error
+	    ("Invalid Multiboot image: neither ELF header nor a.out kludge found\n");
+	return NULL;
+    }
+
+    return mbh;
+}
+
+/*
+ * Set up a stack.  This isn't actually required by the spec, but it seems
+ * like a prudent thing to do.  Also, put enough zeros at the top of the
+ * stack that something that looks for an ELF invocation record will know
+ * there isn't one.
+ */
+static void mboot_map_stack(void)
+{
+    addr_t start, len;
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &start, &len) || len < 64)
+	return;			/* Not much we can do, here... */
+
+    regs.esp = (start + len - 32) & ~15;
+    dprintf("Mapping stack at 0x%08x\n", regs.esp);
+    syslinux_add_memmap(&mmap, regs.esp, 32, SMT_ZERO);
+}
+
+void mboot_run(int bootflags)
+{
+    mboot_map_stack();
+
+    dprintf("Running, eip = 0x%08x, ebx = 0x%08x\n", regs.eip, regs.ebx);
+
+    regs.eax = MULTIBOOT_VALID;
+    syslinux_shuffle_boot_pm(ml, mmap, bootflags, &regs);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000   Free Software Foundation, Inc.
+ *
+ *  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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MBOOT_MB_HEADER_H
+#define MBOOT_MB_HEADER_H
+
+#include <inttypes.h>
+
+/*
+ *  MultiBoot Header description
+ */
+
+struct multiboot_header {
+    /* Must be MULTIBOOT_MAGIC - see below.  */
+    uint32_t magic;
+
+    /* Feature flags - see below.  */
+    uint32_t flags;
+
+    /*
+     * Checksum
+     *
+     * The above fields plus this one must equal 0 mod 2^32.
+     */
+    uint32_t checksum;
+
+    /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+    uint32_t header_addr;
+    uint32_t load_addr;
+    uint32_t load_end_addr;
+    uint32_t bss_end_addr;
+    uint32_t entry_addr;
+
+    /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+    uint32_t mode_type;
+    uint32_t width;
+    uint32_t height;
+    uint32_t depth;
+};
+
+/*
+ * The entire multiboot_header must be contained
+ * within the first MULTIBOOT_SEARCH bytes of the kernel image.
+ */
+#define MULTIBOOT_SEARCH		8192
+
+/* Magic value identifying the multiboot_header.  */
+#define MULTIBOOT_MAGIC			0x1BADB002
+
+/*
+ * Features flags for 'flags'.
+ * If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
+ * and it doesn't understand it, it must fail.
+ */
+#define MULTIBOOT_MUSTKNOW		0x0000FFFF
+
+/* currently unsupported flags...  this is a kind of version number.  */
+#define MULTIBOOT_UNSUPPORTED		0x0000FFF8
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN		0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO		0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE		0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE		0x00010000
+
+#endif /* MBOOT_MB_HEADER_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,207 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  Free Software Foundation, Inc.
+ *
+ *  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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  The structure type "mod_list" is used by the "multiboot_info" structure.
+ */
+
+#ifndef MBOOT_MB_INFO_H
+#define MBOOT_MB_INFO_H
+
+#include <inttypes.h>
+
+struct mod_list {
+    /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+    uint32_t mod_start;
+    uint32_t mod_end;
+
+    /* Module command line */
+    uint32_t cmdline;
+
+    /* padding to take it to 16 bytes (must be zero) */
+    uint32_t pad;
+};
+
+/*
+ *  INT-15, AX=E820 style "AddressRangeDescriptor"
+ *  ...with a "size" parameter on the front which is the structure size - 4,
+ *  pointing to the next one, up until the full buffer length of the memory
+ *  map has been reached.
+ */
+
+struct AddrRangeDesc {
+    uint32_t size;
+    uint64_t BaseAddr;
+    uint64_t Length;
+    uint32_t Type;
+    /* unspecified optional padding... */
+} __attribute__ ((packed));
+
+/* usable memory "Type", all others are reserved.  */
+#define MB_ARD_MEMORY		1
+
+/* Drive Info structure.  */
+struct drive_info {
+    /* The size of this structure.  */
+    uint32_t size;
+
+    /* The BIOS drive number.  */
+    uint8_t drive_number;
+
+    /* The access mode (see below).  */
+    uint8_t drive_mode;
+
+    /* The BIOS geometry.  */
+    uint16_t drive_cylinders;
+    uint8_t drive_heads;
+    uint8_t drive_sectors;
+
+    /* The array of I/O ports used for the drive.  */
+    uint16_t drive_ports[0];
+};
+
+/* Drive Mode.  */
+#define MB_DI_CHS_MODE		0
+#define MB_DI_LBA_MODE		1
+
+/* APM BIOS info.  */
+struct apm_info {
+    uint16_t version;
+    uint16_t cseg;
+    uint32_t offset;
+    uint16_t cseg_16;
+    uint16_t dseg_16;
+    uint16_t cseg_len;
+    uint16_t cseg_16_len;
+    uint16_t dseg_16_len;
+};
+
+/*
+ *  MultiBoot Info description
+ *
+ *  This is the struct passed to the boot image.  This is done by placing
+ *  its address in the EAX register.
+ */
+
+struct multiboot_info {
+    /* MultiBoot info version number */
+    uint32_t flags;
+
+    /* Available memory from BIOS */
+    uint32_t mem_lower;
+    uint32_t mem_upper;
+
+    /* "root" partition */
+    uint32_t boot_device;
+
+    /* Kernel command line */
+    uint32_t cmdline;
+
+    /* Boot-Module list */
+    uint32_t mods_count;
+    uint32_t mods_addr;
+
+    union {
+	struct {
+	    /* (a.out) Kernel symbol table info */
+	    uint32_t tabsize;
+	    uint32_t strsize;
+	    uint32_t addr;
+	    uint32_t pad;
+	} a;
+	struct {
+	    /* (ELF) Kernel section header table */
+	    uint32_t num;
+	    uint32_t size;
+	    uint32_t addr;
+	    uint32_t shndx;
+	} e;
+    } syms;
+
+    /* Memory Mapping buffer */
+    uint32_t mmap_length;
+    uint32_t mmap_addr;
+
+    /* Drive Info buffer */
+    uint32_t drives_length;
+    uint32_t drives_addr;
+
+    /* ROM configuration table */
+    uint32_t config_table;
+
+    /* Boot Loader Name */
+    uint32_t boot_loader_name;
+
+    /* APM table */
+    uint32_t apm_table;
+
+    /* Video */
+    uint32_t vbe_control_info;
+    uint32_t vbe_mode_info;
+    uint16_t vbe_mode;
+    uint16_t vbe_interface_seg;
+    uint16_t vbe_interface_off;
+    uint16_t vbe_interface_len;
+};
+
+/*
+ *  Flags to be set in the 'flags' parameter above
+ */
+
+/* is there basic lower/upper memory information? */
+#define MB_INFO_MEMORY			0x00000001
+/* is there a boot device set? */
+#define MB_INFO_BOOTDEV			0x00000002
+/* is the command-line defined? */
+#define MB_INFO_CMDLINE			0x00000004
+/* are there modules to do something with? */
+#define MB_INFO_MODS			0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MB_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MB_INFO_ELF_SHDR		0x00000020
+
+/* is there a full memory map? */
+#define MB_INFO_MEM_MAP			0x00000040
+
+/* Is there drive info?  */
+#define MB_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MB_INFO_CONFIG_TABLE		0x00000100
+
+/* Is there a boot loader name?  */
+#define MB_INFO_BOOT_LOADER_NAME	0x00000200
+
+/* Is there a APM table?  */
+#define MB_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MB_INFO_VIDEO_INFO		0x00000800
+
+/*
+ *  The following value must be present in the EAX register.
+ */
+
+#define MULTIBOOT_VALID			0x2BADB002
+
+#endif /* MBOOT_MB_INFO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,247 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mboot.c
+ *
+ * Module to load a multiboot kernel
+ */
+
+#include "mboot.h"
+
+struct multiboot_info mbinfo;
+struct syslinux_pm_regs regs;
+struct my_options opt, set;
+
+struct module_data {
+    void *data;
+    size_t len;
+    const char *cmdline;
+};
+
+static int map_modules(struct module_data *modules, int nmodules)
+{
+    struct mod_list *mod_list;
+    addr_t map_list = 0;
+    size_t list_size = nmodules * sizeof *mod_list;
+    int i;
+
+    mod_list = malloc(list_size);
+    if (!mod_list) {
+	printf("Failed to allocate module list\n");
+	return -1;
+    }
+
+    map_list = map_data(mod_list, list_size, 16, 0);
+    if (!map_list) {
+	printf("Cannot map module list\n");
+	return -1;
+    }
+
+    for (i = 0; i < nmodules; i++) {
+	addr_t mod_map = 0;
+	addr_t cmd_map = 0;
+
+	dprintf("Module %d cmdline: \"%s\"\n", i, modules[i].cmdline);
+
+	cmd_map = map_string(modules[i].cmdline);
+
+	mod_map = map_data(modules[i].data, modules[i].len, 4096, MAP_HIGH);
+	if (!mod_map) {
+	    printf("Failed to map module (memory fragmentation issue?)\n");
+	    return -1;
+	}
+	mod_list[i].mod_start = mod_map;
+	mod_list[i].mod_end = mod_map + modules[i].len;
+	mod_list[i].cmdline = cmd_map;
+	mod_list[i].pad = 0;
+    }
+
+    mbinfo.flags |= MB_INFO_MODS;
+    mbinfo.mods_count = nmodules;
+    mbinfo.mods_addr = map_list;
+    return 0;
+}
+
+static int get_modules(char **argv, struct module_data **mdp)
+{
+    char **argp, **argx;
+    struct module_data *mp;
+    int rv;
+    int module_count = 1;
+    int arglen;
+    const char module_separator[] = "---";
+
+    for (argp = argv; *argp; argp++) {
+	if (!strcmp(*argp, module_separator))
+	    module_count++;
+    }
+
+    *mdp = mp = malloc(module_count * sizeof(struct module_data));
+    if (!mp) {
+	error("Out of memory!\n");
+	return -1;
+    }
+
+    argp = argv;
+    while (*argp) {
+	/* Note: it seems Grub transparently decompresses all compressed files,
+	   not just the primary kernel. */
+	printf("Loading %s... ", *argp);
+	rv = zloadfile(*argp, &mp->data, &mp->len);
+
+	if (rv) {
+	    printf("failed!\n");
+	    return -1;
+	}
+	printf("ok\n");
+
+	/* 
+	 * Note: Grub includes the kernel filename in the command line, so we
+	 * want to match that behavior.
+	 */
+	arglen = 0;
+	for (argx = argp; *argx && strcmp(*argx, module_separator); argx++)
+	    arglen += strlen(*argx) + 1;
+
+	if (arglen == 0) {
+	    mp->cmdline = strdup("");
+	} else {
+	    char *p;
+	    mp->cmdline = p = malloc(arglen);
+	    for (; *argp && strcmp(*argp, module_separator); argp++) {
+		p = stpcpy(p, *argp);
+		*p++ = ' ';
+	    }
+	    *--p = '\0';
+	}
+	mp++;
+	if (*argp)
+	    argp++;		/* Advance past module_separator */
+    }
+
+    return module_count;
+}
+
+int main(int argc, char *argv[])
+{
+    int nmodules;
+    struct module_data *modules;
+    struct multiboot_header *mbh;
+    bool keeppxe = false;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    (void)argc;			/* Unused */
+    argv++;
+
+    while (*argv) {
+	bool v = true;
+	const char *p = *argv;
+
+	if (!memcmp(p, "-no", 3)) {
+	    v = false;
+	    p += 3;
+	}
+
+	if (!strcmp(p, "-solaris")) {
+	    opt.solaris = v;
+	    set.solaris = true;
+	} else if (!strcmp(p, "-aout")) {
+	    opt.aout = v;
+	    set.aout = true;
+	} else
+	    break;
+	argv++;
+    }
+
+    if (!*argv) {
+	error
+	    ("Usage: mboot.c32 [opts] mboot_file args... [--- module args...]...\n"
+	     "Options:\n"
+	     "  -solaris  Enable Solaris DHCP information passing\n"
+	     "  -aout     Use the \"a.out kludge\" if enabled, even for ELF\n"
+	     "            This matches the Multiboot spec, but differs from Grub\n");
+	return 1;
+    }
+
+    /* Load the files */
+    nmodules = get_modules(argv, &modules);
+    if (nmodules < 1) {
+	error("No files found!\n");
+	return 1;		/* Failure */
+    }
+
+    if (init_map())
+	return 1;		/* Failed to allocate initial map */
+
+    /*
+     * Map the primary image.  This should be done before mapping anything
+     * else, since it will have fixed address requirements.
+     */
+    mbh = map_image(modules[0].data, modules[0].len);
+    if (!mbh)
+	return 1;
+
+    /* Map the mbinfo structure */
+    regs.ebx = map_data(&mbinfo, sizeof mbinfo, 4, 0);
+    if (!regs.ebx) {
+	error("Failed to map Multiboot info structure!\n");
+	return 1;
+    }
+
+    /* Map the primary command line */
+    if (modules[0].cmdline) {
+	mbinfo.cmdline = map_string(modules[0].cmdline);
+	dprintf("Main cmdline: \"%s\"\n", modules[0].cmdline);
+	if (mbinfo.cmdline)
+	    mbinfo.flags |= MB_INFO_CMDLINE;
+    }
+
+    /* Map auxilliary images */
+    if (nmodules > 1) {
+	if (map_modules(modules + 1, nmodules - 1))
+	    return 1;
+    }
+
+    /* Add auxilliary information */
+    mboot_make_memmap();
+    mboot_apm();
+    mboot_syslinux_info();
+
+    if (opt.solaris)
+	mboot_solaris_dhcp_hack();
+
+    /* Set the graphics mode if requested */
+    set_graphics_mode(mbh, &mbinfo);
+
+    /* Run it */
+    mboot_run(keeppxe ? 3 : 0);
+    error("mboot.c32: boot failed\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mboot.h
+ *
+ * Module to load a multiboot kernel
+ */
+
+#ifndef MBOOT_H
+
+#include <dprintf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+#include <syslinux/config.h>
+
+#include "mb_header.h"
+#include "mb_info.h"
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+/* mboot.c */
+extern struct multiboot_info mbinfo;
+extern struct syslinux_pm_regs regs;
+extern struct my_options {
+    bool solaris;
+    bool aout;
+} opt, set;
+
+/* map.c */
+#define MAP_HIGH	1
+#define MAP_NOPAD	2
+addr_t map_data(const void *data, size_t len, size_t align, int flags);
+addr_t map_string(const char *string);
+struct multiboot_header *map_image(void *ptr, size_t len);
+void mboot_run(int bootflags);
+int init_map(void);
+
+/* mem.c */
+void mboot_make_memmap(void);
+
+/* apm.c */
+void mboot_apm(void);
+
+/* solaris.c */
+bool kernel_is_solaris(const Elf32_Ehdr *);
+void mboot_solaris_dhcp_hack(void);
+
+/* syslinux.c */
+void mboot_syslinux_info(void);
+
+/* initvesa.c */
+void set_graphics_mode(const struct multiboot_header *mbh,
+		       struct multiboot_info *mbi);
+
+#endif /* MBOOT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,223 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mem.c
+ *
+ * Obtain a memory map for a Multiboot OS
+ *
+ * This differs from the libcom32 memory map functions in that it doesn't
+ * attempt to filter out memory regions...
+ */
+
+#include "mboot.h"
+#include <com32.h>
+
+struct e820_entry {
+    uint64_t start;
+    uint64_t len;
+    uint32_t type;
+};
+
+#define RANGE_ALLOC_BLOCK	128
+
+static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
+{
+    com32sys_t ireg, oreg;
+    struct e820_entry *e820buf;
+    struct AddrRangeDesc *ard;
+    size_t ard_count, ard_space;
+    int rv = 0;
+
+    /* Use INT 12h to get DOS memory */
+    __intcall(0x12, &__com32_zero_regs, &oreg);
+    *dosmem = oreg.eax.w[0] << 10;
+    if (*dosmem < 32 * 1024 || *dosmem > 640 * 1024) {
+	/* INT 12h reports nonsense... now what? */
+	uint16_t ebda_seg = *(uint16_t *) 0x40e;
+	if (ebda_seg >= 0x8000 && ebda_seg < 0xa000)
+	    *dosmem = ebda_seg << 4;
+	else
+	    *dosmem = 640 * 1024;	/* Hope for the best... */
+    }
+
+    e820buf = lmalloc(sizeof(*e820buf));
+    if (!e820buf)
+	return 0;
+
+    /* Allocate initial space */
+    *ardp = ard = malloc(RANGE_ALLOC_BLOCK * sizeof *ard);
+    if (!ard)
+	goto out;
+
+    ard_count = 0;
+    ard_space = RANGE_ALLOC_BLOCK;
+
+    /* First try INT 15h AX=E820h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.l = 0xe820;
+    ireg.edx.l = 0x534d4150;
+    /* ireg.ebx.l    = 0; */
+    ireg.ecx.l = sizeof(*e820buf);
+    ireg.es = SEG(e820buf);
+    ireg.edi.w[0] = OFFS(e820buf);
+    memset(e820buf, 0, sizeof *e820buf);
+
+    do {
+	__intcall(0x15, &ireg, &oreg);
+
+	if ((oreg.eflags.l & EFLAGS_CF) ||
+	    (oreg.eax.l != 0x534d4150) || (oreg.ecx.l < 20))
+	    break;
+
+	if (ard_count >= ard_space) {
+	    ard_space += RANGE_ALLOC_BLOCK;
+	    *ardp = ard = realloc(ard, ard_space * sizeof *ard);
+	    if (!ard) {
+		rv = ard_count;
+		goto out;
+	    }
+	}
+
+	ard[ard_count].size = 20;
+	ard[ard_count].BaseAddr = e820buf->start;
+	ard[ard_count].Length = e820buf->len;
+	ard[ard_count].Type = e820buf->type;
+	ard_count++;
+
+	ireg.ebx.l = oreg.ebx.l;
+    } while (oreg.ebx.l);
+
+    if (ard_count) {
+	rv = ard_count;
+	goto out;
+    };
+
+    ard[0].size = 20;
+    ard[0].BaseAddr = 0;
+    ard[0].Length = *dosmem << 10;
+    ard[0].Type = 1;
+
+    /* Next try INT 15h AX=E801h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0xe801;
+    __intcall(0x15, &ireg, &oreg);
+
+    if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) {
+	ard[1].size = 20;
+	ard[1].BaseAddr = 1 << 20;
+	ard[1].Length = oreg.ecx.w[0] << 10;
+	ard[1].Type = 1;
+
+	if (oreg.edx.w[0]) {
+	    ard[2].size = 20;
+	    ard[2].BaseAddr = 16 << 20;
+	    ard[2].Length = oreg.edx.w[0] << 16;
+	    ard[2].Type = 1;
+	    rv = 3;
+	} else {
+	    rv = 2;
+	}
+
+	goto out;
+    }
+
+    /* Finally try INT 15h AH=88h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0x8800;
+    __intcall(0x15, &ireg, &oreg);
+    if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) {
+	ard[1].size = 20;
+	ard[1].BaseAddr = 1 << 20;
+	ard[1].Length = oreg.ecx.w[0] << 10;
+	ard[1].Type = 1;
+	rv = 2;
+	goto out;
+    }
+
+    rv = 1;			/* ... problematic ... */
+out:
+    lfree(e820buf);
+    return rv;
+}
+
+void mboot_make_memmap(void)
+{
+    int i, nmap;
+    struct AddrRangeDesc *ard;
+    uint32_t lowmem, highmem;
+    uint32_t highrsvd;
+
+    /* Always report DOS memory as "lowmem", this may be overly conservative
+       (e.g. if we're dropping PXE), but it should be *safe*... */
+
+    nmap = mboot_scan_memory(&ard, &lowmem);
+
+    highmem = 0x100000;
+    highrsvd = 0xfff00000;
+
+again:
+    for (i = 0; i < nmap; i++) {
+	uint64_t start, end;
+
+	start = ard[i].BaseAddr;
+	end = start + ard[i].Length;
+
+	if (end < start)
+	    end = ~0ULL;
+
+	if (start & 0xffffffff00000000ULL)
+	    continue;		/* Not interested in 64-bit memory */
+
+	if (start < highmem)
+	    start = highmem;
+
+	if (end <= start)
+	    continue;
+
+	if (ard[i].Type == 1 && start == highmem) {
+	    highmem = end;
+	    goto again;
+	} else if (ard[i].Type != 1 && start < highrsvd)
+	    highrsvd = start;
+    }
+
+    if (highmem > highrsvd)
+	highmem = highrsvd;
+
+    mbinfo.mem_lower = lowmem >> 10;
+    mbinfo.mem_upper = (highmem - 0x100000) >> 10;
+    mbinfo.flags |= MB_INFO_MEMORY;
+
+    /* The spec says this address should be +4, but Grub disagrees */
+    mbinfo.mmap_addr = map_data(ard, nmap * sizeof *ard, 4, false);
+    if (mbinfo.mmap_addr) {
+	mbinfo.mmap_length = nmap * sizeof *ard;
+	mbinfo.flags |= MB_INFO_MEM_MAP;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * solaris.c
+ *
+ * Solaris DHCP hack
+ *
+ * Solaris uses a nonstandard hack to pass DHCP information from a netboot.
+ */
+
+#include "mboot.h"
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+
+bool kernel_is_solaris(const Elf32_Ehdr *eh)
+{
+    return eh->e_ident[EI_OSABI] == 6;	/* ABI == Solaris */
+}
+
+void mboot_solaris_dhcp_hack(void)
+{
+    void *dhcpdata;
+    size_t dhcplen;
+
+    if (syslinux_derivative_info()->c.filesystem != SYSLINUX_FS_PXELINUX)
+	return;
+    
+    if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	mbinfo.drives_addr = map_data(dhcpdata, dhcplen, 4, 0);
+	if (mbinfo.drives_addr) {
+	    mbinfo.drives_length = dhcplen;
+	    mbinfo.boot_device = 0x20ffffff;
+	    mbinfo.flags =
+		(mbinfo.flags & ~MB_INFO_DRIVE_INFO) | MB_INFO_BOOTDEV;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux.c
+ *
+ * Syslinux-specific information for the kernel
+ */
+
+#include <syslinux/config.h>
+#include "mboot.h"
+
+void mboot_syslinux_info(void)
+{
+    const struct syslinux_version *sv;
+
+    sv = syslinux_version();
+    mbinfo.boot_loader_name = map_string(sv->version_string);
+    if (mbinfo.boot_loader_name)
+	mbinfo.flags |= MB_INFO_BOOT_LOADER_NAME;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,100 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_H
+#define LIB_SYS_VESA_H
+
+#include <inttypes.h>
+#include <com32.h>
+
+/* VESA General Information table */
+struct vesa_general_info {
+    uint32_t signature;		/* Magic number = "VESA" */
+    uint16_t version;
+    far_ptr_t vendor_string;
+    uint8_t capabilities[4];
+    far_ptr_t video_mode_ptr;
+    uint16_t total_memory;
+
+    uint16_t oem_software_rev;
+    far_ptr_t oem_vendor_name_ptr;
+    far_ptr_t oem_product_name_ptr;
+    far_ptr_t oem_product_rev_ptr;
+
+    uint8_t reserved[222];
+    uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+    uint16_t mode_attr;
+    uint8_t win_attr[2];
+    uint16_t win_grain;
+    uint16_t win_size;
+    uint16_t win_seg[2];
+    far_ptr_t win_scheme;
+    uint16_t logical_scan;
+
+    uint16_t h_res;
+    uint16_t v_res;
+    uint8_t char_width;
+    uint8_t char_height;
+    uint8_t memory_planes;
+    uint8_t bpp;
+    uint8_t banks;
+    uint8_t memory_layout;
+    uint8_t bank_size;
+    uint8_t image_pages;
+    uint8_t page_function;
+
+    uint8_t rmask;
+    uint8_t rpos;
+    uint8_t gmask;
+    uint8_t gpos;
+    uint8_t bmask;
+    uint8_t bpos;
+    uint8_t resv_mask;
+    uint8_t resv_pos;
+    uint8_t dcm_info;
+
+    uint8_t *lfb_ptr;		/* Linear frame buffer address */
+    uint8_t *offscreen_ptr;	/* Offscreen memory address */
+    uint16_t offscreen_size;
+
+    uint8_t reserved[206];
+} __attribute__ ((packed));
+
+struct vesa_info {
+    struct vesa_general_info gi;
+    struct vesa_mode_info mi;
+};
+
+extern struct vesa_info vesa_info;
+
+#endif /* LIB_SYS_VESA_H */
Index: bootcd/isolinux/syslinux-6.03/com32/menu/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,48 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Simple menu system
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LNXLIBS	   = $(objdir)/com32/libutil/libutil_lnx.a
+
+MODULES	  = menu.c32 vesamenu.c32
+TESTFILES =
+
+COMMONOBJS = menumain.o readconfig.o passwd.o drain.o \
+		printmsg.o colors.o background.o refstr.o
+
+all: $(MODULES) $(TESTFILES)
+
+menu.elf : menu.o $(COMMONOBJS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+vesamenu.elf : vesamenu.o $(COMMONOBJS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/menu/background.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/background.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/background.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <consoles.h>
+#include <string.h>
+#include "menu.h"
+
+const char *current_background = NULL;
+
+void set_background(const char *new_background)
+{
+    if (!current_background || !new_background ||
+	strcmp(current_background, new_background)) {
+	draw_background(new_background);
+	current_background = new_background;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/colors.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <colortbl.h>
+#include "menu.h"
+
+/*
+ * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows
+ *
+ * 00 - screen		Rest of the screen
+ * 01 - border		Border area
+ * 02 - title		Title bar
+ * 03 - unsel		Unselected menu item
+ * 04 - hotkey		Unselected hotkey
+ * 05 - sel		Selection bar
+ * 06 - hotsel		Selected hotkey
+ * 07 - scrollbar	Scroll bar
+ * 08 - tabmsg		Press [Tab] message
+ * 09 - cmdmark		Command line marker
+ * 10 - cmdline		Command line
+ * 11 - pwdborder	Password box border
+ * 12 - pwdheader	Password box header
+ * 13 - pwdentry	Password box contents
+ * 14 - timeout_msg	Timeout message
+ * 15 - timeout		Timeout counter
+ * 16 - help		Current entry help text
+ * 17 - disabled        Disabled menu item
+ */
+
+static const struct color_table default_colors[] = {
+    {"screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL},
+    {"unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL},
+    {"hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL},
+    {"sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL},
+    {"hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL},
+    {"scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL},
+    {"cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL},
+    {"cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL},
+};
+
+#define NCOLORS (sizeof default_colors/sizeof default_colors[0])
+const int message_base_color = NCOLORS;
+const int menu_color_table_size = NCOLORS + 256;
+
+/* Algorithmically generate the msgXX colors */
+void set_msg_colors_global(struct color_table *tbl,
+			   unsigned int fg, unsigned int bg,
+			   enum color_table_shadow shadow)
+{
+    struct color_table *cp = tbl + message_base_color;
+    unsigned int i;
+    unsigned int fga, bga;
+    unsigned int fgh, bgh;
+    unsigned int fg_idx, bg_idx;
+    unsigned int fg_rgb, bg_rgb;
+
+    static const unsigned int pc2rgb[8] =
+	{ 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00,
+	0xffffff
+    };
+
+    /* Converting PC RGBI to sensible RGBA values is an "interesting"
+       proposition.  This algorithm may need plenty of tweaking. */
+
+    fga = fg & 0xff000000;
+    fgh = ((fg >> 1) & 0xff000000) | 0x80000000;
+
+    bga = bg & 0xff000000;
+    bgh = ((bg >> 1) & 0xff000000) | 0x80000000;
+
+    for (i = 0; i < 256; i++) {
+	fg_idx = i & 15;
+	bg_idx = i >> 4;
+
+	fg_rgb = pc2rgb[fg_idx & 7] & fg;
+	bg_rgb = pc2rgb[bg_idx & 7] & bg;
+
+	if (fg_idx & 8) {
+	    /* High intensity foreground */
+	    fg_rgb |= fgh;
+	} else {
+	    fg_rgb |= fga;
+	}
+
+	if (bg_idx == 0) {
+	    /* Default black background, assume transparent */
+	    bg_rgb = 0;
+	} else if (bg_idx & 8) {
+	    bg_rgb |= bgh;
+	} else {
+	    bg_rgb |= bga;
+	}
+
+	cp->argb_fg = fg_rgb;
+	cp->argb_bg = bg_rgb;
+	cp->shadow = shadow;
+	cp++;
+    }
+}
+
+struct color_table *default_color_table(void)
+{
+    unsigned int i;
+    const struct color_table *dp;
+    struct color_table *cp;
+    struct color_table *color_table;
+    static const int pc2ansi[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+    static char msg_names[6 * 256];
+    char *mp;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = default_colors;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS; i++) {
+	*cp = *dp;
+	cp->ansi = refstrdup(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    mp = msg_names;
+    for (i = 0; i < 256; i++) {
+	cp->name = mp;
+	mp += sprintf(mp, "msg%02x", i) + 1;
+
+	rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "",
+		 pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]);
+	cp++;
+    }
+
+  /*** XXX: This needs to move to run_menu() ***/
+    console_color_table = color_table;
+    console_color_table_size = NCOLORS + 256;
+
+    set_msg_colors_global(color_table, MSG_COLORS_DEF_FG,
+			  MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW);
+
+    return color_table;
+}
+
+struct color_table *copy_color_table(const struct color_table *master)
+{
+    const struct color_table *dp;
+    struct color_table *color_table, *cp;
+    unsigned int i;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = master;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS + 256; i++) {
+	*cp = *dp;
+	cp->ansi = refstr_get(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    return color_table;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/drain.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/drain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/drain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/cpu.h>
+
+void drain_keyboard(void)
+{
+    /* Prevent "ghost typing" and keyboard buffer snooping */
+    volatile char junk;
+    int rv;
+
+    do {
+	rv = read(0, (char *)&junk, 1);
+    } while (rv > 0);
+
+    junk = 0;
+
+    cli();
+    *(volatile uint8_t *)0x419 = 0;	/* Alt-XXX keyboard area */
+    *(volatile uint16_t *)0x41a = 0x1e;	/* Keyboard buffer empty */
+    *(volatile uint16_t *)0x41c = 0x1e;
+    memset((void *)0x41e, 0, 32);	/* Clear the actual keyboard buffer */
+    sti();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/menu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * menu.c
+ *
+ * Simple menu system which displays a list and allows the user to select
+ * a command line and/or edit it.
+ */
+
+#include <consoles.h>
+#include "menu.h"
+
+int draw_background(const char *arg)
+{
+    /* Nothing to do... */
+    (void)arg;
+    return 0;
+}
+
+void set_resolution(int x, int y)
+{
+    (void)x;
+    (void)y;
+}
+
+void local_cursor_enable(bool enabled)
+{
+    (void)enabled;
+}
+
+void start_console(void)
+{
+    console_ansi_raw();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/menumain.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/menumain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/menumain.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1166 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * menumain.c
+ *
+ * Simple menu system which displays a list and allows the user to select
+ * a command line and/or edit it.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <consoles.h>
+#include <getkey.h>
+#include <minmax.h>
+#include <setjmp.h>
+#include <limits.h>
+#include <com32.h>
+#include <core.h>
+#include <syslinux/adv.h>
+#include <syslinux/boot.h>
+
+#include "menu.h"
+
+/* The symbol "cm" always refers to the current menu across this file... */
+static struct menu *cm;
+
+const struct menu_parameter mparm[NPARAMS] = {
+    [P_WIDTH] = {"width", 0},
+    [P_MARGIN] = {"margin", 10},
+    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
+    [P_MENU_ROWS] = {"rows", 12},
+    [P_TABMSG_ROW] = {"tabmsgrow", 18},
+    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
+    [P_END_ROW] = {"endrow", -1},
+    [P_PASSWD_ROW] = {"passwordrow", 11},
+    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
+    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
+    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
+    [P_HSHIFT] = {"hshift", 0},
+    [P_VSHIFT] = {"vshift", 0},
+    [P_HIDDEN_ROW] = {"hiddenrow", -2},
+};
+
+/* These macros assume "cm" is a pointer to the current menu */
+#define WIDTH		(cm->mparm[P_WIDTH])
+#define MARGIN		(cm->mparm[P_MARGIN])
+#define PASSWD_MARGIN	(cm->mparm[P_PASSWD_MARGIN])
+#define MENU_ROWS	(cm->mparm[P_MENU_ROWS])
+#define TABMSG_ROW	(cm->mparm[P_TABMSG_ROW]+VSHIFT)
+#define CMDLINE_ROW	(cm->mparm[P_CMDLINE_ROW]+VSHIFT)
+#define END_ROW		(cm->mparm[P_END_ROW])
+#define PASSWD_ROW	(cm->mparm[P_PASSWD_ROW]+VSHIFT)
+#define TIMEOUT_ROW	(cm->mparm[P_TIMEOUT_ROW]+VSHIFT)
+#define HELPMSG_ROW	(cm->mparm[P_HELPMSG_ROW]+VSHIFT)
+#define HELPMSGEND_ROW	(cm->mparm[P_HELPMSGEND_ROW])
+#define HSHIFT		(cm->mparm[P_HSHIFT])
+#define VSHIFT		(cm->mparm[P_VSHIFT])
+#define HIDDEN_ROW	(cm->mparm[P_HIDDEN_ROW])
+
+static char *pad_line(const char *text, int align, int width)
+{
+    static char buffer[MAX_CMDLINE_LEN];
+    int n, p;
+
+    if (width >= (int)sizeof buffer)
+	return NULL;		/* Can't do it */
+
+    n = strlen(text);
+    if (n >= width)
+	n = width;
+
+    memset(buffer, ' ', width);
+    buffer[width] = 0;
+    p = ((width - n) * align) >> 1;
+    memcpy(buffer + p, text, n);
+
+    return buffer;
+}
+
+/* Display an entry, with possible hotkey highlight.  Assumes
+   that the current attribute is the non-hotkey one, and will
+   guarantee that as an exit condition as well. */
+static void
+display_entry(const struct menu_entry *entry, const char *attrib,
+	      const char *hotattrib, int width)
+{
+    const char *p = entry->displayname;
+    char marker;
+
+    if (!p)
+	p = "";
+
+    switch (entry->action) {
+    case MA_SUBMENU:
+	marker = '>';
+	break;
+    case MA_EXIT:
+	marker = '<';
+	break;
+    default:
+	marker = 0;
+	break;
+    }
+
+    if (marker)
+	width -= 2;
+
+    while (width) {
+	if (*p) {
+	    if (*p == '^') {
+		p++;
+		if (*p && ((unsigned char)*p & ~0x20) == entry->hotkey) {
+		    fputs(hotattrib, stdout);
+		    putchar(*p++);
+		    fputs(attrib, stdout);
+		    width--;
+		}
+	    } else {
+		putchar(*p++);
+		width--;
+	    }
+	} else {
+	    putchar(' ');
+	    width--;
+	}
+    }
+
+    if (marker) {
+	putchar(' ');
+	putchar(marker);
+    }
+}
+
+static void draw_row(int y, int sel, int top, int sbtop, int sbbot)
+{
+    int i = (y - 4 - VSHIFT) + top;
+    int dis = (i < cm->nentries) && is_disabled(cm->menu_entries[i]);
+
+    printf("\033[%d;%dH\1#1\016x\017%s ",
+	   y, MARGIN + 1 + HSHIFT,
+	   (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3");
+
+    if (i >= cm->nentries) {
+	fputs(pad_line("", 0, WIDTH - 2 * MARGIN - 4), stdout);
+    } else {
+	display_entry(cm->menu_entries[i],
+		      (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3",
+		      (i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4",
+		      WIDTH - 2 * MARGIN - 4);
+    }
+
+    if (cm->nentries <= MENU_ROWS) {
+	printf(" \1#1\016x\017");
+    } else if (sbtop > 0) {
+	if (y >= sbtop && y <= sbbot)
+	    printf(" \1#7\016a\017");
+	else
+	    printf(" \1#1\016x\017");
+    } else {
+	putchar(' ');		/* Don't modify the scrollbar */
+    }
+}
+
+static jmp_buf timeout_jump;
+
+int mygetkey(clock_t timeout)
+{
+    clock_t t0, t;
+    clock_t tto, to;
+    int key;
+
+    if (!totaltimeout)
+	return get_key(stdin, timeout);
+
+    for (;;) {
+	tto = min(totaltimeout, INT_MAX);
+	to = timeout ? min(tto, timeout) : tto;
+
+	t0 = times(NULL);
+	key = get_key(stdin, to);
+	t = times(NULL) - t0;
+
+	if (totaltimeout <= t)
+	    longjmp(timeout_jump, 1);
+
+	totaltimeout -= t;
+
+	if (key != KEY_NONE)
+	    return key;
+
+	if (timeout) {
+	    if (timeout <= t)
+		return KEY_NONE;
+
+	    timeout -= t;
+	}
+    }
+}
+
+static int ask_passwd(const char *menu_entry)
+{
+    char user_passwd[WIDTH], *p;
+    int done;
+    int key;
+    int x;
+    int rv;
+
+    printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+	putchar('q');
+
+    printf("k\033[%d;%dHx", PASSWD_ROW + 1, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+	putchar(' ');
+
+    printf("x\033[%d;%dHm", PASSWD_ROW + 2, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+	putchar('q');
+
+    printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13",
+	   PASSWD_ROW, (WIDTH - (strlen(cm->messages[MSG_PASSPROMPT]) + 2)) / 2,
+	   cm->messages[MSG_PASSPROMPT], PASSWD_ROW + 1, PASSWD_MARGIN + 3);
+
+    drain_keyboard();
+
+    /* Actually allow user to type a password, then compare to the SHA1 */
+    done = 0;
+    p = user_passwd;
+
+    while (!done) {
+	key = mygetkey(0);
+
+	switch (key) {
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    done = 1;
+	    break;
+
+	case KEY_ESC:
+	case KEY_CTRL('C'):
+	    p = user_passwd;	/* No password entered */
+	    done = 1;
+	    break;
+
+	case KEY_BACKSPACE:
+	case KEY_DEL:
+	case KEY_DELETE:
+	    if (p > user_passwd) {
+		printf("\b \b");
+		p--;
+	    }
+	    break;
+
+	case KEY_CTRL('U'):
+	    while (p > user_passwd) {
+		printf("\b \b");
+		p--;
+	    }
+	    break;
+
+	default:
+	    if (key >= ' ' && key <= 0xFF &&
+		(p - user_passwd) < WIDTH - 2 * PASSWD_MARGIN - 5) {
+		*p++ = key;
+		putchar('*');
+	    }
+	    break;
+	}
+    }
+
+    if (p == user_passwd)
+	return 0;		/* No password entered */
+
+    *p = '\0';
+
+    rv = (cm->menu_master_passwd &&
+	  passwd_compare(cm->menu_master_passwd, user_passwd))
+	|| (menu_entry && passwd_compare(menu_entry, user_passwd));
+
+    /* Clean up */
+    memset(user_passwd, 0, WIDTH);
+    drain_keyboard();
+
+    return rv;
+}
+
+static void draw_menu(int sel, int top, int edit_line)
+{
+    int x, y;
+    int sbtop = 0, sbbot = 0;
+    const char *tabmsg;
+    int tabmsg_len;
+
+    if (cm->nentries > MENU_ROWS) {
+	int sblen = max(MENU_ROWS * MENU_ROWS / cm->nentries, 1);
+	sbtop = (MENU_ROWS - sblen + 1) * top / (cm->nentries - MENU_ROWS + 1);
+	sbbot = sbtop + sblen - 1;
+	sbtop += 4;
+	sbbot += 4;		/* Starting row of scrollbar */
+    }
+
+    printf("\033[%d;%dH\1#1\016l", VSHIFT + 1, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+	putchar('q');
+
+    printf("k\033[%d;%dH\1#1x\017\1#2 %s \1#1\016x",
+	   VSHIFT + 2,
+	   HSHIFT + MARGIN + 1, pad_line(cm->title, 1, WIDTH - 2 * MARGIN - 4));
+
+    printf("\033[%d;%dH\1#1t", VSHIFT + 3, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+	putchar('q');
+    fputs("u\017", stdout);
+
+    for (y = 4 + VSHIFT; y < 4 + VSHIFT + MENU_ROWS; y++)
+	draw_row(y, sel, top, sbtop, sbbot);
+
+    printf("\033[%d;%dH\1#1\016m", y, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+	putchar('q');
+    fputs("j\017", stdout);
+
+    if (edit_line && cm->allowedit && !cm->menu_master_passwd)
+	tabmsg = cm->messages[MSG_TAB];
+    else
+	tabmsg = cm->messages[MSG_NOTAB];
+
+    tabmsg_len = strlen(tabmsg);
+
+    printf("\1#8\033[%d;%dH%s",
+	   TABMSG_ROW, 1 + HSHIFT + ((WIDTH - tabmsg_len) >> 1), tabmsg);
+    printf("\1#0\033[%d;1H", END_ROW);
+}
+
+static void clear_screen(void)
+{
+    fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+}
+
+static void display_help(const char *text)
+{
+    int row;
+    const char *p;
+
+    if (!text) {
+	text = "";
+	printf("\1#0\033[%d;1H", HELPMSG_ROW);
+    } else {
+	printf("\2#16\033[%d;1H", HELPMSG_ROW);
+    }
+
+    for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) {
+	switch (*p) {
+	case '\r':
+	case '\f':
+	case '\v':
+	case '\033':
+	    break;
+	case '\n':
+	    printf("\033[K\033[%d;1H", ++row);
+	    break;
+	default:
+	    putchar(*p);
+	}
+    }
+
+    fputs("\033[K", stdout);
+
+    while (row <= HELPMSGEND_ROW) {
+	printf("\033[K\033[%d;1H", ++row);
+    }
+}
+
+static void show_fkey(int key)
+{
+    int fkey;
+
+    while (1) {
+	switch (key) {
+	case KEY_F1:
+	    fkey = 0;
+	    break;
+	case KEY_F2:
+	    fkey = 1;
+	    break;
+	case KEY_F3:
+	    fkey = 2;
+	    break;
+	case KEY_F4:
+	    fkey = 3;
+	    break;
+	case KEY_F5:
+	    fkey = 4;
+	    break;
+	case KEY_F6:
+	    fkey = 5;
+	    break;
+	case KEY_F7:
+	    fkey = 6;
+	    break;
+	case KEY_F8:
+	    fkey = 7;
+	    break;
+	case KEY_F9:
+	    fkey = 8;
+	    break;
+	case KEY_F10:
+	    fkey = 9;
+	    break;
+	case KEY_F11:
+	    fkey = 10;
+	    break;
+	case KEY_F12:
+	    fkey = 11;
+	    break;
+	default:
+	    fkey = -1;
+	    break;
+	}
+
+	if (fkey == -1)
+	    break;
+
+	if (cm->fkeyhelp[fkey].textname)
+	    key = show_message_file(cm->fkeyhelp[fkey].textname,
+				    cm->fkeyhelp[fkey].background);
+	else
+	    break;
+    }
+}
+
+static const char *edit_cmdline(const char *input, int top)
+{
+    static char cmdline[MAX_CMDLINE_LEN];
+    int key, len, prev_len, cursor;
+    int redraw = 1;		/* We enter with the menu already drawn */
+
+    strlcpy(cmdline, input, MAX_CMDLINE_LEN);
+    cmdline[MAX_CMDLINE_LEN - 1] = '\0';
+
+    len = cursor = strlen(cmdline);
+    prev_len = 0;
+
+    for (;;) {
+	if (redraw > 1) {
+	    /* Clear and redraw whole screen */
+	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+	       to avoid confusing the Linux console */
+	    clear_screen();
+	    draw_menu(-1, top, 1);
+	    prev_len = 0;
+	}
+
+	if (redraw > 0) {
+	    /* Redraw the command line */
+	    printf("\033[?25l\033[%d;1H\1#9> \2#10%s",
+		   CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len)));
+	    printf("\2#10\033[%d;3H%s\033[?25h",
+		   CMDLINE_ROW, pad_line(cmdline, 0, cursor));
+	    prev_len = len;
+	    redraw = 0;
+	}
+
+	key = mygetkey(0);
+
+	switch (key) {
+	case KEY_CTRL('L'):
+	    redraw = 2;
+	    break;
+
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    return cmdline;
+
+	case KEY_ESC:
+	case KEY_CTRL('C'):
+	    return NULL;
+
+	case KEY_BACKSPACE:
+	case KEY_DEL:
+	    if (cursor) {
+		memmove(cmdline + cursor - 1, cmdline + cursor,
+			len - cursor + 1);
+		len--;
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('D'):
+	case KEY_DELETE:
+	    if (cursor < len) {
+		memmove(cmdline + cursor, cmdline + cursor + 1, len - cursor);
+		len--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('U'):
+	    if (len) {
+		len = cursor = 0;
+		cmdline[len] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('W'):
+	    if (cursor) {
+		int prevcursor = cursor;
+
+		while (cursor && my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+		while (cursor && !my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+		memmove(cmdline + cursor, cmdline + prevcursor,
+			len - prevcursor + 1);
+		len -= (prevcursor - cursor);
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_LEFT:
+	case KEY_CTRL('B'):
+	    if (cursor) {
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	case KEY_CTRL('F'):
+	    if (cursor < len) {
+		putchar(cmdline[cursor++]);
+	    }
+	    break;
+
+	case KEY_CTRL('K'):
+	    if (cursor < len) {
+		cmdline[len = cursor] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_HOME:
+	case KEY_CTRL('A'):
+	    if (cursor) {
+		cursor = 0;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_END:
+	case KEY_CTRL('E'):
+	    if (cursor != len) {
+		cursor = len;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_F1:
+	case KEY_F2:
+	case KEY_F3:
+	case KEY_F4:
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+	    show_fkey(key);
+	    redraw = 1;
+	    break;
+
+	default:
+	    if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
+		if (cursor == len) {
+		    cmdline[len] = key;
+		    cmdline[++len] = '\0';
+		    cursor++;
+		    putchar(key);
+		    prev_len++;
+		} else {
+		    memmove(cmdline + cursor + 1, cmdline + cursor,
+			    len - cursor + 1);
+		    cmdline[cursor++] = key;
+		    len++;
+		    redraw = 1;
+		}
+	    }
+	    break;
+	}
+    }
+}
+
+static void print_timeout_message(int tol, int row, const char *msg)
+{
+    static int last_msg_len = 0;
+    char buf[256];
+    int nc = 0, nnc, padc;
+    const char *tp = msg;
+    char tc;
+    char *tq = buf;
+
+    while ((size_t) (tq - buf) < (sizeof buf - 16) && (tc = *tp)) {
+	tp++;
+	if (tc == '#') {
+	    nnc = sprintf(tq, "\2#15%d\2#14", tol);
+	    tq += nnc;
+	    nc += nnc - 8;	/* 8 formatting characters */
+	} else if (tc == '{') {
+	    /* Deal with {singular[,dual],plural} constructs */
+	    struct {
+		const char *s, *e;
+	    } tx[3];
+	    const char *tpp;
+	    int n = 0;
+
+	    memset(tx, 0, sizeof tx);
+
+	    tx[0].s = tp;
+
+	    while (*tp && *tp != '}') {
+		if (*tp == ',' && n < 2) {
+		    tx[n].e = tp;
+		    n++;
+		    tx[n].s = tp + 1;
+		}
+		tp++;
+	    }
+	    tx[n].e = tp;
+
+	    if (*tp)
+		tp++;		/* Skip final bracket */
+
+	    if (!tx[1].s)
+		tx[1] = tx[0];
+	    if (!tx[2].s)
+		tx[2] = tx[1];
+
+	    /* Now [0] is singular, [1] is dual, and [2] is plural,
+	       even if the user only specified some of them. */
+
+	    switch (tol) {
+	    case 1:
+		n = 0;
+		break;
+	    case 2:
+		n = 1;
+		break;
+	    default:
+		n = 2;
+		break;
+	    }
+
+	    for (tpp = tx[n].s; tpp < tx[n].e; tpp++) {
+		if ((size_t) (tq - buf) < (sizeof buf)) {
+		    *tq++ = *tpp;
+		    nc++;
+		}
+	    }
+	} else {
+	    *tq++ = tc;
+	    nc++;
+	}
+    }
+    *tq = '\0';
+
+    if (nc >= last_msg_len) {
+	padc = 0;
+    } else {
+	padc = (last_msg_len - nc + 1) >> 1;
+    }
+
+    printf("\033[%d;%dH\2#14%*s%s%*s", row,
+	   HSHIFT + 1 + ((WIDTH - nc) >> 1) - padc,
+	   padc, "", buf, padc, "");
+
+    last_msg_len = nc;
+}
+
+/* Set the background screen, etc. */
+static void prepare_screen_for_menu(void)
+{
+    console_color_table = cm->color_table;
+    console_color_table_size = menu_color_table_size;
+    set_background(cm->menu_background);
+}
+
+static const char *do_hidden_menu(void)
+{
+    int key;
+    int timeout_left, this_timeout;
+
+    clear_screen();
+
+    if (!setjmp(timeout_jump)) {
+	timeout_left = cm->timeout;
+
+	while (!cm->timeout || timeout_left) {
+	    int tol = timeout_left / CLK_TCK;
+
+	    print_timeout_message(tol, HIDDEN_ROW, cm->messages[MSG_AUTOBOOT]);
+
+	    this_timeout = min(timeout_left, CLK_TCK);
+	    key = mygetkey(this_timeout);
+
+	    if (key != KEY_NONE) {
+		/* Clear the message from the screen */
+		print_timeout_message(0, HIDDEN_ROW, "");
+		return hide_key[key]; /* NULL if no MENU HIDEKEY in effect */
+	    }
+
+	    timeout_left -= this_timeout;
+	}
+    }
+
+    /* Clear the message from the screen */
+    print_timeout_message(0, HIDDEN_ROW, "");
+
+    if (cm->ontimeout)
+	return cm->ontimeout;
+    else
+	return cm->menu_entries[cm->defentry]->cmdline; /* Default entry */
+}
+
+static const char *run_menu(void)
+{
+    int key;
+    int done = 0;
+    volatile int entry = cm->curentry;
+    int prev_entry = -1;
+    volatile int top = cm->curtop;
+    int prev_top = -1;
+    int clear = 1, to_clear;
+    const char *cmdline = NULL;
+    volatile clock_t key_timeout, timeout_left, this_timeout;
+    const struct menu_entry *me;
+    bool hotkey = false;
+
+    /* Note: for both key_timeout and timeout == 0 means no limit */
+    timeout_left = key_timeout = cm->timeout;
+
+    /* If we're in shiftkey mode, exit immediately unless a shift key
+       is pressed */
+    if (shiftkey && !shift_is_held()) {
+	return cm->menu_entries[cm->defentry]->cmdline;
+    } else {
+	shiftkey = 0;
+    }
+
+    /* Do this before hiddenmenu handling, so we show the background */
+    prepare_screen_for_menu();
+
+    /* Handle hiddenmenu */
+    if (hiddenmenu) {
+	cmdline = do_hidden_menu();
+	if (cmdline)
+	    return cmdline;
+
+	/* Otherwise display the menu now; the timeout has already been
+	   cancelled, since the user pressed a key. */
+	hiddenmenu = 0;
+	key_timeout = 0;
+    }
+
+    /* Handle both local and global timeout */
+    if (setjmp(timeout_jump)) {
+	entry = cm->defentry;
+
+	if (top < 0 || top < entry - MENU_ROWS + 1)
+	    top = max(0, entry - MENU_ROWS + 1);
+	else if (top > entry || top > max(0, cm->nentries - MENU_ROWS))
+	    top = min(entry, max(0, cm->nentries - MENU_ROWS));
+
+	draw_menu(cm->ontimeout ? -1 : entry, top, 1);
+	cmdline =
+	    cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline;
+	done = 1;
+    }
+
+    while (!done) {
+	if (entry <= 0) {
+	    entry = 0;
+	    while (entry < cm->nentries && is_disabled(cm->menu_entries[entry]))
+		entry++;
+	}
+	if (entry >= cm->nentries - 1) {
+	    entry = cm->nentries - 1;
+	    while (entry > 0 && is_disabled(cm->menu_entries[entry]))
+		entry--;
+	}
+
+	me = cm->menu_entries[entry];
+
+	if (top < 0 || top < entry - MENU_ROWS + 1)
+	    top = max(0, entry - MENU_ROWS + 1);
+	else if (top > entry || top > max(0, cm->nentries - MENU_ROWS))
+	    top = min(entry, max(0, cm->nentries - MENU_ROWS));
+
+	/* Start with a clear screen */
+	if (clear) {
+	    /* Clear and redraw whole screen */
+	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+	       to avoid confusing the Linux console */
+	    if (clear >= 2)
+		prepare_screen_for_menu();
+	    clear_screen();
+	    clear = 0;
+	    prev_entry = prev_top = -1;
+	}
+
+	if (top != prev_top) {
+	    draw_menu(entry, top, 1);
+	    display_help(me->helptext);
+	} else if (entry != prev_entry) {
+	    draw_row(prev_entry - top + 4 + VSHIFT, entry, top, 0, 0);
+	    draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0);
+	    display_help(me->helptext);
+	}
+
+	prev_entry = entry;
+	prev_top = top;
+	cm->curentry = entry;
+	cm->curtop = top;
+
+	/* Cursor movement cancels timeout */
+	if (entry != cm->defentry)
+	    key_timeout = 0;
+
+	if (key_timeout) {
+	    int tol = timeout_left / CLK_TCK;
+	    print_timeout_message(tol, TIMEOUT_ROW, cm->messages[MSG_AUTOBOOT]);
+	    to_clear = 1;
+	} else {
+	    to_clear = 0;
+	}
+
+	if (hotkey && me->immediate) {
+	    /* If the hotkey was flagged immediate, simulate pressing ENTER */
+	    key = KEY_ENTER;
+	} else {
+	    this_timeout = min(min(key_timeout, timeout_left),
+			       (clock_t) CLK_TCK);
+	    key = mygetkey(this_timeout);
+
+	    if (key != KEY_NONE) {
+		timeout_left = key_timeout;
+		if (to_clear)
+		    printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW);
+	    }
+	}
+
+	hotkey = false;
+
+	switch (key) {
+	case KEY_NONE:		/* Timeout */
+	    /* This is somewhat hacky, but this at least lets the user
+	       know what's going on, and still deals with "phantom inputs"
+	       e.g. on serial ports.
+
+	       Warning: a timeout will boot the default entry without any
+	       password! */
+	    if (key_timeout) {
+		if (timeout_left <= this_timeout)
+		    longjmp(timeout_jump, 1);
+
+		timeout_left -= this_timeout;
+	    }
+	    break;
+
+	case KEY_CTRL('L'):
+	    clear = 1;
+	    break;
+
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    key_timeout = 0;	/* Cancels timeout */
+	    if (me->passwd) {
+		clear = 1;
+		done = ask_passwd(me->passwd);
+	    } else {
+		done = 1;
+	    }
+	    cmdline = NULL;
+	    if (done) {
+		switch (me->action) {
+		case MA_CMD:
+		    cmdline = me->cmdline;
+		    break;
+		case MA_SUBMENU:
+		case MA_GOTO:
+		case MA_EXIT:
+		    done = 0;
+		    clear = 2;
+		    cm = me->submenu;
+		    entry = cm->curentry;
+		    top = cm->curtop;
+		    break;
+		case MA_QUIT:
+		    /* Quit menu system */
+		    done = 1;
+		    clear = 1;
+		    draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+		    break;
+		case MA_HELP:
+		    key = show_message_file(me->cmdline, me->background);
+		    /* If the exit was an F-key, display that help screen */
+		    show_fkey(key);
+		    done = 0;
+		    clear = 1;
+		    break;
+		default:
+		    done = 0;
+		    break;
+		}
+	    }
+	    if (done && !me->passwd) {
+		/* Only save a new default if we don't have a password... */
+		if (me->save && me->label) {
+		    syslinux_setadv(ADV_MENUSAVE, strlen(me->label), me->label);
+		    syslinux_adv_write();
+		}
+	    }
+	    break;
+
+	case KEY_UP:
+	case KEY_CTRL('P'):
+	    while (entry > 0) {
+		entry--;
+		if (entry < top)
+		    top -= MENU_ROWS;
+		if (!is_disabled(cm->menu_entries[entry]))
+		    break;
+	    }
+	    break;
+
+	case KEY_DOWN:
+	case KEY_CTRL('N'):
+	    while (entry < cm->nentries - 1) {
+		entry++;
+		if (entry >= top + MENU_ROWS)
+		    top += MENU_ROWS;
+		if (!is_disabled(cm->menu_entries[entry]))
+		    break;
+	    }
+	    break;
+
+	case KEY_PGUP:
+	case KEY_LEFT:
+	case KEY_CTRL('B'):
+	case '<':
+	    entry -= MENU_ROWS;
+	    top -= MENU_ROWS;
+	    while (entry > 0 && is_disabled(cm->menu_entries[entry])) {
+		entry--;
+		if (entry < top)
+		    top -= MENU_ROWS;
+	    }
+	    break;
+
+	case KEY_PGDN:
+	case KEY_RIGHT:
+	case KEY_CTRL('F'):
+	case '>':
+	case ' ':
+	    entry += MENU_ROWS;
+	    top += MENU_ROWS;
+	    while (entry < cm->nentries - 1
+		   && is_disabled(cm->menu_entries[entry])) {
+		entry++;
+		if (entry >= top + MENU_ROWS)
+		    top += MENU_ROWS;
+	    }
+	    break;
+
+	case '-':
+	    while (entry > 0) {
+		entry--;
+		top--;
+		if (!is_disabled(cm->menu_entries[entry]))
+		    break;
+	    }
+	    break;
+
+	case '+':
+	    while (entry < cm->nentries - 1) {
+		entry++;
+		top++;
+		if (!is_disabled(cm->menu_entries[entry]))
+		    break;
+	    }
+	    break;
+
+	case KEY_CTRL('A'):
+	case KEY_HOME:
+	    top = entry = 0;
+	    break;
+
+	case KEY_CTRL('E'):
+	case KEY_END:
+	    entry = cm->nentries - 1;
+	    top = max(0, cm->nentries - MENU_ROWS);
+	    break;
+
+	case KEY_F1:
+	case KEY_F2:
+	case KEY_F3:
+	case KEY_F4:
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+	    show_fkey(key);
+	    clear = 1;
+	    break;
+
+	case KEY_TAB:
+	    if (cm->allowedit && me->action == MA_CMD) {
+		int ok = 1;
+
+		key_timeout = 0;	/* Cancels timeout */
+		draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+
+		if (cm->menu_master_passwd) {
+		    ok = ask_passwd(NULL);
+		    clear_screen();
+		    draw_menu(-1, top, 0);
+		} else {
+		    /* Erase [Tab] message and help text */
+		    printf("\033[%d;1H\1#0\033[K", TABMSG_ROW);
+		    display_help(NULL);
+		}
+
+		if (ok) {
+		    cmdline = edit_cmdline(me->cmdline, top);
+		    done = !!cmdline;
+		    clear = 1;	/* In case we hit [Esc] and done is null */
+		} else {
+		    draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0);
+		}
+	    }
+	    break;
+	case KEY_CTRL('C'):	/* Ctrl-C */
+	case KEY_ESC:		/* Esc */
+	    if (cm->parent) {
+		cm = cm->parent;
+		clear = 2;
+		entry = cm->curentry;
+		top = cm->curtop;
+	    } else if (cm->allowedit) {
+		done = 1;
+		clear = 1;
+		key_timeout = 0;
+
+		draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+
+		if (cm->menu_master_passwd)
+		    done = ask_passwd(NULL);
+	    }
+	    break;
+	default:
+	    if (key > 0 && key < 0xFF) {
+		key &= ~0x20;	/* Upper case */
+		if (cm->menu_hotkeys[key]) {
+		    key_timeout = 0;
+		    entry = cm->menu_hotkeys[key]->entry;
+		    /* Should we commit at this point? */
+		    hotkey = true;
+		}
+	    }
+	    break;
+	}
+    }
+
+    printf("\033[?25h");	/* Show cursor */
+
+    /* Return the label name so localboot and ipappend work */
+    return cmdline;
+}
+
+int main(int argc, char *argv[])
+{
+    const char *cmdline;
+    struct menu *m;
+    int rows, cols;
+    int i;
+
+    (void)argc;
+
+    parse_configs(argv + 1);
+
+    /*
+     * We don't start the console until we have parsed the configuration
+     * file, since the configuration file might impact the console
+     * configuration, e.g. MENU RESOLUTION.
+     */
+    start_console();
+    if (getscreensize(1, &rows, &cols)) {
+	/* Unknown screen size? */
+	rows = 24;
+	cols = 80;
+    }
+
+    /* Some postprocessing for all menus */
+    for (m = menu_list; m; m = m->next) {
+	if (!m->mparm[P_WIDTH])
+	    m->mparm[P_WIDTH] = cols;
+
+	/* If anyone has specified negative parameters, consider them
+	   relative to the bottom row of the screen. */
+	for (i = 0; i < NPARAMS; i++)
+	    if (m->mparm[i] < 0)
+		m->mparm[i] = max(m->mparm[i] + rows, 0);
+    }
+
+    cm = start_menu;
+
+    if (!cm->nentries) {
+	fputs("Initial menu has no LABEL entries!\n", stdout);
+	return 1;		/* Error! */
+    }
+
+    for (;;) {
+	local_cursor_enable(true);
+	cmdline = run_menu();
+
+	if (clearmenu)
+	    clear_screen();
+
+	local_cursor_enable(false);
+	printf("\033[?25h\033[%d;1H\033[0m", END_ROW);
+
+	if (cmdline) {
+	    uint32_t type = parse_image_type(cmdline);
+
+	    execute(cmdline, type, false);
+	    if (cm->onerror) {
+		type = parse_image_type(cm->onerror);
+		execute(cm->onerror, type, true);
+	    }
+	} else {
+	    return 0;		/* Exit */
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/passwd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/passwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/passwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <string.h>
+#include <xcrypt.h>
+#include <sha1.h>
+#include <base64.h>
+
+#include "menu.h"
+
+static int passwd_compare_sha1(const char *passwd, const char *entry)
+{
+    struct {
+	SHA1_CTX ctx;
+	unsigned char sha1[20], pwdsha1[20];
+    } d;
+    const char *p;
+    int rv;
+
+    SHA1Init(&d.ctx);
+
+    if ((p = strchr(passwd + 3, '$'))) {
+	SHA1Update(&d.ctx, (void *)passwd + 3, p - (passwd + 3));
+	p++;
+    } else {
+	p = passwd + 3;		/* Assume no salt */
+    }
+
+    SHA1Update(&d.ctx, (void *)entry, strlen(entry));
+    SHA1Final(d.sha1, &d.ctx);
+
+    memset(d.pwdsha1, 0, 20);
+    unbase64(d.pwdsha1, 20, p);
+
+    rv = !memcmp(d.sha1, d.pwdsha1, 20);
+
+    memset(&d, 0, sizeof d);
+    return rv;
+}
+
+static int passwd_compare_md5(const char *passwd, const char *entry)
+{
+    const char *crypted = crypt_md5(entry, passwd + 3);
+    int len = strlen(crypted);
+
+    return !strncmp(crypted, passwd, len) &&
+	(passwd[len] == '\0' || passwd[len] == '$');
+}
+
+static int passwd_compare_sha256(const char *passwd, const char *entry)
+{
+    const char *crypted = sha256_crypt(entry, passwd + 3);
+    int len = strlen(crypted);
+
+    return !strncmp(crypted, passwd, len) &&
+	(passwd[len] == '\0' || passwd[len] == '$');
+}
+
+static int passwd_compare_sha512(const char *passwd, const char *entry)
+{
+    const char *crypted = sha512_crypt(entry, passwd + 3);
+    int len = strlen(crypted);
+
+    return !strncmp(crypted, passwd, len) &&
+	(passwd[len] == '\0' || passwd[len] == '$');
+}
+
+int passwd_compare(const char *passwd, const char *entry)
+{
+    if (passwd[0] != '$' || !passwd[1] || passwd[2] != '$') {
+	/* Plaintext passwd, yuck! */
+	return !strcmp(entry, passwd);
+    } else {
+	switch (passwd[1]) {
+	case '1':
+	    return passwd_compare_md5(passwd, entry);
+	case '4':
+	    return passwd_compare_sha1(passwd, entry);
+	case '5':
+	    return passwd_compare_sha256(passwd, entry);
+	case '6':
+	    return passwd_compare_sha512(passwd, entry);
+	default:
+	    return 0;		/* Unknown encryption algorithm -> false */
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/printmsg.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/printmsg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/printmsg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <consoles.h>
+#include <getkey.h>
+#include <minmax.h>
+#include <setjmp.h>
+#include <limits.h>
+#include <sha1.h>
+#include <base64.h>
+#include <colortbl.h>
+#ifdef __COM32__
+#include <com32.h>
+#endif
+
+#include "menu.h"
+
+static int draw_message_file(const char *filename)
+{
+    FILE *f;
+    int ch;
+    enum msgname_state {
+	st_init,		/* Base state */
+	st_si_1,		/* <SI> digit 1 */
+	st_si_2,		/* <SI> digit 2 */
+	st_skipline,		/* Skip until NL */
+    } state = st_init;
+    int eof = 0;
+    int attr = 0;
+
+    f = fopen(filename, "r");
+    if (!f)
+	return -1;
+
+    /* Clear screen, hide cursor, default attribute */
+    printf("\033e\033%%@\033)0\033(B\3#%03d\033[?25l\033[2J\033[H",
+	   message_base_color + 0x07);
+
+    while (!eof && (ch = getc(f)) != EOF) {
+	switch (state) {
+	case st_init:
+	    switch (ch) {
+	    case '\f':
+		fputs("\033[2J\033[H", stdout);
+		break;
+	    case 15:		/* SI */
+		state = st_si_1;
+		break;
+	    case 24:
+		state = st_skipline;
+		break;
+	    case 26:
+		eof = 1;
+		break;
+	    case '\a':
+	    case '\n':
+	    case '\r':
+		putchar(ch);
+		break;
+	    default:
+		if (ch >= 32)
+		    putchar(ch);
+		break;
+	    }
+	    break;
+
+	case st_si_1:
+	    attr = hexval(ch) << 4;
+	    state = st_si_2;
+	    break;
+
+	case st_si_2:
+	    attr |= hexval(ch);
+	    printf("\3#%03d", attr + message_base_color);
+	    state = st_init;
+	    break;
+
+	case st_skipline:
+	    if (ch == '\n')
+		state = st_init;
+	    break;
+	}
+    }
+
+    fclose(f);
+    return 0;
+}
+
+int show_message_file(const char *filename, const char *background)
+{
+    int rv = KEY_NONE;
+    const char *old_background = NULL;
+
+    if (background) {
+	old_background = current_background;
+	set_background(background);
+    }
+
+    if (!(rv = draw_message_file(filename)))
+	rv = mygetkey(0);	/* Wait for keypress */
+
+    if (old_background)
+	set_background(old_background);
+
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/readconfig.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1177 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2011 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <minmax.h>
+#include <alloca.h>
+#include <inttypes.h>
+#include <colortbl.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+
+#include "menu.h"
+
+/* Empty refstring */
+const char *empty_string;
+
+/* Root menu, starting menu, hidden menu, and list of all menus */
+struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
+
+/* These are global parameters regardless of which menu we're displaying */
+int shiftkey = 0;		/* Only display menu if shift key pressed */
+int hiddenmenu = 0;
+int clearmenu = 0;
+long long totaltimeout = 0;
+const char *hide_key[KEY_MAX];
+
+/* Keep track of global default */
+static int has_ui = 0;		/* DEFAULT only counts if UI is found */
+static const char *globaldefault = NULL;
+static bool menusave = false;	/* True if there is any "menu save" */
+
+/* Linked list of all entires, hidden or not; used by unlabel() */
+static struct menu_entry *all_entries;
+static struct menu_entry **all_entries_end = &all_entries;
+
+static const struct messages messages[MSG_COUNT] = {
+    [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."},
+    [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"},
+    [MSG_NOTAB] = {"notabmsg", ""},
+    [MSG_PASSPROMPT] = {"passprompt", "Password required"},
+};
+
+#define astrdup(x) ({ char *__x = (x); \
+                      size_t __n = strlen(__x) + 1; \
+                      char *__p = alloca(__n); \
+                      if ( __p ) memcpy(__p, __x, __n); \
+                      __p; })
+
+/* Must match enum kernel_type */
+static const char *const kernel_types[] = {
+    "none",
+    "localboot",
+    "kernel",
+    "linux",
+    "boot",
+    "bss",
+    "pxe",
+    "fdimage",
+    "comboot",
+    "com32",
+    "config",
+    NULL
+};
+
+/*
+ * Search the list of all menus for a specific label
+ */
+static struct menu *find_menu(const char *label)
+{
+    struct menu *m;
+
+    for (m = menu_list; m; m = m->next) {
+	if (!strcmp(label, m->label))
+	    return m;
+    }
+
+    return NULL;
+}
+
+#define MAX_LINE 4096
+
+/* Strip ^ from a string, returning a new reference to the same refstring
+   if none present */
+static const char *strip_caret(const char *str)
+{
+    const char *p, *r;
+    char *q;
+    int carets = 0;
+
+    p = str;
+    for (;;) {
+	p = strchr(p, '^');
+	if (!p)
+	    break;
+	carets++;
+	p++;
+    }
+
+    if (!carets)
+	return refstr_get(str);
+
+    r = q = refstr_alloc(strlen(str) - carets);
+    for (p = str; *p; p++)
+	if (*p != '^')
+	    *q++ = *p;
+
+    *q = '\0';			/* refstr_alloc() already did this... */
+
+    return r;
+}
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+/* Returns a pointer to the first character past the keyword */
+static char *looking_at(char *line, const char *kwd)
+{
+    char *p = line;
+    const char *q = kwd;
+
+    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
+	p++;
+	q++;
+    }
+
+    if (*q)
+	return NULL;		/* Didn't see the keyword */
+
+    return my_isspace(*p) ? p : NULL;	/* Must be EOL or whitespace */
+}
+
+/* Get a single word into a new refstr; advances the input pointer */
+static char *get_word(char *str, char **word)
+{
+    char *p = str;
+    char *q;
+
+    while (*p && !my_isspace(*p))
+	p++;
+
+    *word = q = refstr_alloc(p - str);
+    memcpy(q, str, p - str);
+    /* refstr_alloc() already inserted a terminating NUL */
+
+    return p;
+}
+
+static struct menu *new_menu(struct menu *parent,
+			     struct menu_entry *parent_entry, const char *label)
+{
+    struct menu *m = calloc(1, sizeof(struct menu));
+    int i;
+
+    m->label = label;
+    m->title = refstr_get(empty_string);
+
+    if (parent) {
+	/* Submenu */
+	m->parent = parent;
+	m->parent_entry = parent_entry;
+	parent_entry->action = MA_SUBMENU;
+	parent_entry->submenu = m;
+
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstr_get(parent->messages[i]);
+
+	memcpy(m->mparm, parent->mparm, sizeof m->mparm);
+
+	m->allowedit = parent->allowedit;
+	m->timeout = parent->timeout;
+	m->save = parent->save;
+	m->immediate = parent->immediate;
+
+	m->ontimeout = refstr_get(parent->ontimeout);
+	m->onerror = refstr_get(parent->onerror);
+	m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
+	m->menu_background = refstr_get(parent->menu_background);
+
+	m->color_table = copy_color_table(parent->color_table);
+
+	for (i = 0; i < 12; i++) {
+	    m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname);
+	    m->fkeyhelp[i].background =
+		refstr_get(parent->fkeyhelp[i].background);
+	}
+    } else {
+	/* Root menu */
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstrdup(messages[i].defmsg);
+	for (i = 0; i < NPARAMS; i++)
+	    m->mparm[i] = mparm[i].value;
+
+	m->allowedit = true;	/* Allow edits of the command line */
+	m->color_table = default_color_table();
+    }
+
+    m->next = menu_list;
+    menu_list = m;
+
+    return m;
+}
+
+struct labeldata {
+    const char *label;
+    const char *kernel;
+    enum kernel_type type;
+    const char *append;
+    const char *initrd;
+    const char *menulabel;
+    const char *passwd;
+    char *helptext;
+    unsigned int ipappend;
+    unsigned int menuhide;
+    unsigned int menudefault;
+    unsigned int menuseparator;
+    unsigned int menudisabled;
+    unsigned int menuindent;
+    enum menu_action action;
+    int save;
+    int immediate;
+    struct menu *submenu;
+};
+
+/* Menu currently being parsed */
+static struct menu *current_menu;
+
+static void clear_label_data(struct labeldata *ld)
+{
+    refstr_put(ld->label);
+    refstr_put(ld->kernel);
+    refstr_put(ld->append);
+    refstr_put(ld->initrd);
+    refstr_put(ld->menulabel);
+    refstr_put(ld->passwd);
+
+    memset(ld, 0, sizeof *ld);
+}
+
+static struct menu_entry *new_entry(struct menu *m)
+{
+    struct menu_entry *me;
+
+    if (m->nentries >= m->nentries_space) {
+	if (!m->nentries_space)
+	    m->nentries_space = 1;
+	else
+	    m->nentries_space <<= 1;
+
+	m->menu_entries = realloc(m->menu_entries, m->nentries_space *
+				  sizeof(struct menu_entry *));
+    }
+
+    me = calloc(1, sizeof(struct menu_entry));
+    me->menu = m;
+    me->entry = m->nentries;
+    m->menu_entries[m->nentries++] = me;
+    *all_entries_end = me;
+    all_entries_end = &me->next;
+
+    return me;
+}
+
+static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
+{
+    const char *p = strchr(me->displayname, '^');
+
+    if (me->action != MA_DISABLED) {
+	if (p && p[1]) {
+	    unsigned char hotkey = p[1] & ~0x20;
+	    if (!m->menu_hotkeys[hotkey]) {
+		me->hotkey = hotkey;
+		m->menu_hotkeys[hotkey] = me;
+	    }
+	}
+    }
+}
+
+/*
+ * Copy a string, converting whitespace characters to underscores
+ * and compacting them.  Return a pointer to the final null.
+ */
+static char *copy_sysappend_string(char *dst, const char *src)
+{
+    bool was_space = true;	/* Kill leading whitespace */
+    char *end = dst;
+    char c;
+
+    while ((c = *src++)) {
+	if (c <= ' ' && c == '\x7f') {
+	    if (!was_space)
+		*dst++ = '_';
+	    was_space = true;
+	} else {
+	    *dst++ = c;
+	    end = dst;
+	    was_space = false;
+	}
+    }
+    *end = '\0';
+    return end;
+}
+
+static void record(struct menu *m, struct labeldata *ld, const char *append)
+{
+    int i;
+    struct menu_entry *me;
+    const struct syslinux_ipappend_strings *ipappend;
+
+    if (!ld->label)
+	return;			/* Nothing defined */
+
+    /* Hidden entries are recorded on a special "hidden menu" */
+    if (ld->menuhide)
+	m = hide_menu;
+
+    if (ld->label) {
+	char ipoptions[4096], *ipp;
+	const char *a;
+	char *s;
+
+	me = new_entry(m);
+
+	me->displayname = ld->menulabel
+	    ? refstr_get(ld->menulabel) : refstr_get(ld->label);
+	me->label = refstr_get(ld->label);
+	me->passwd = refstr_get(ld->passwd);
+	me->helptext = ld->helptext;
+	me->hotkey = 0;
+	me->action = ld->action ? ld->action : MA_CMD;
+	me->save = ld->save ? (ld->save > 0) : m->save;
+	me->immediate = ld->immediate ? (ld->immediate > 0) : m->immediate;
+
+	if (ld->menuindent) {
+	    const char *dn;
+
+	    rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname);
+	    refstr_put(me->displayname);
+	    me->displayname = dn;
+	}
+
+	if (ld->menuseparator) {
+	    refstr_put(me->displayname);
+	    me->displayname = refstr_get(empty_string);
+	}
+
+	if (ld->menuseparator || ld->menudisabled) {
+	    me->action = MA_DISABLED;
+	    refstr_put(me->label);
+	    me->label = NULL;
+	    refstr_put(me->passwd);
+	    me->passwd = NULL;
+	}
+
+	if (ld->menulabel)
+	    consider_for_hotkey(m, me);
+
+	switch (me->action) {
+	case MA_CMD:
+	    ipp = ipoptions;
+	    *ipp = '\0';
+
+	    if (ld->initrd)
+		ipp += sprintf(ipp, " initrd=%s", ld->initrd);
+
+	    if (ld->ipappend) {
+		ipappend = syslinux_ipappend_strings();
+		for (i = 0; i < ipappend->count; i++) {
+		    if ((ld->ipappend & (1U << i)) &&
+			ipappend->ptr[i] && ipappend->ptr[i][0]) {
+			*ipp++ = ' ';
+			ipp = copy_sysappend_string(ipp, ipappend->ptr[i]);
+		    }
+		}
+	    }
+
+	    a = ld->append;
+	    if (!a)
+		a = append;
+	    if (!a || (a[0] == '-' && !a[1]))
+		a = "";
+	    s = a[0] ? " " : "";
+	    if (ld->type == KT_KERNEL) {
+		rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
+	    } else {
+		rsprintf(&me->cmdline, ".%s %s%s%s%s",
+			 kernel_types[ld->type], ld->kernel, s, a, ipoptions);
+	    }
+	    break;
+
+	case MA_GOTO_UNRES:
+	case MA_EXIT_UNRES:
+	    me->cmdline = refstr_get(ld->kernel);
+	    break;
+
+	case MA_GOTO:
+	case MA_EXIT:
+	    me->submenu = ld->submenu;
+	    break;
+
+	case MA_HELP:
+	    me->cmdline = refstr_get(ld->kernel);
+	    me->background = refstr_get(ld->append);
+	    break;
+
+	default:
+	    break;
+	}
+
+	if (ld->menudefault && (me->action == MA_CMD ||
+				me->action == MA_GOTO ||
+				me->action == MA_GOTO_UNRES))
+	    m->defentry = m->nentries - 1;
+    }
+
+    clear_label_data(ld);
+}
+
+static struct menu *begin_submenu(const char *tag)
+{
+    struct menu_entry *me;
+
+    if (!tag[0])
+	tag = NULL;
+
+    me = new_entry(current_menu);
+    me->displayname = refstrdup(tag);
+    return new_menu(current_menu, me, refstr_get(me->displayname));
+}
+
+static struct menu *end_submenu(void)
+{
+    return current_menu->parent ? current_menu->parent : current_menu;
+}
+
+static struct menu_entry *find_label(const char *str)
+{
+    const char *p;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos])
+	    return me;
+    }
+
+    return NULL;
+}
+
+static const char *unlabel(const char *str)
+{
+    /* Convert a CLI-style command line to an executable command line */
+    const char *p;
+    const char *q;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos]) {
+	    /* Found matching label */
+	    rsprintf(&q, "%s%s", me->cmdline, p);
+	    refstr_put(str);
+	    return q;
+	}
+    }
+
+    return str;
+}
+
+static const char *refdup_word(char **p)
+{
+    char *sp = *p;
+    char *ep = sp;
+
+    while (*ep && !my_isspace(*ep))
+	ep++;
+
+    *p = ep;
+    return refstrndup(sp, ep - sp);
+}
+
+int my_isxdigit(char c)
+{
+    unsigned int uc = c;
+
+    return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6;
+}
+
+unsigned int hexval(char c)
+{
+    unsigned char uc = c | 0x20;
+    unsigned int v;
+
+    v = uc - '0';
+    if (v < 10)
+	return v;
+
+    return uc - 'a' + 10;
+}
+
+unsigned int hexval2(const char *p)
+{
+    return (hexval(p[0]) << 4) + hexval(p[1]);
+}
+
+uint32_t parse_argb(char **p)
+{
+    char *sp = *p;
+    char *ep;
+    uint32_t argb;
+    size_t len, dl;
+
+    if (*sp == '#')
+	sp++;
+
+    ep = sp;
+
+    while (my_isxdigit(*ep))
+	ep++;
+
+    *p = ep;
+    len = ep - sp;
+
+    switch (len) {
+    case 3:			/* #rgb */
+	argb =
+	    0xff000000 +
+	    (hexval(sp[0]) * 0x11 << 16) +
+	    (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11);
+	break;
+    case 4:			/* #argb */
+	argb =
+	    (hexval(sp[0]) * 0x11 << 24) +
+	    (hexval(sp[1]) * 0x11 << 16) +
+	    (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11);
+	break;
+    case 6:			/* #rrggbb */
+    case 9:			/* #rrrgggbbb */
+    case 12:			/* #rrrrggggbbbb */
+	dl = len / 3;
+	argb =
+	    0xff000000 +
+	    (hexval2(sp + 0) << 16) +
+	    (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2);
+	break;
+    case 8:			/* #aarrggbb */
+	/* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb,
+	   assume the latter is a more common format */
+    case 16:			/* #aaaarrrrggggbbbb */
+	dl = len / 4;
+	argb =
+	    (hexval2(sp + 0) << 24) +
+	    (hexval2(sp + dl) << 16) +
+	    (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3);
+	break;
+    default:
+	argb = 0xffff0000;	/* Bright red (error indication) */
+	break;
+    }
+
+    return argb;
+}
+
+/*
+ * Parser state.  This is global so that including multiple
+ * files work as expected, which is that everything works the
+ * same way as if the files had been concatenated together.
+ */
+static const char *append = NULL;
+static unsigned int ipappend = 0;
+static struct labeldata ld;
+
+static int parse_one_config(const char *filename);
+
+static char *is_kernel_type(char *cmdstr, enum kernel_type *type)
+{
+    const char *const *p;
+    char *q;
+    enum kernel_type t = KT_NONE;
+
+    for (p = kernel_types; *p; p++, t++) {
+	if ((q = looking_at(cmdstr, *p))) {
+	    *type = t;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+static char *is_message_name(char *cmdstr, enum message_number *msgnr)
+{
+    char *q;
+    enum message_number i;
+
+    for (i = 0; i < MSG_COUNT; i++) {
+	if ((q = looking_at(cmdstr, messages[i].name))) {
+	    *msgnr = i;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+static char *is_fkey(char *cmdstr, int *fkeyno)
+{
+    char *q;
+    int no;
+
+    if ((cmdstr[0] | 0x20) != 'f')
+	return NULL;
+
+    no = strtoul(cmdstr + 1, &q, 10);
+    if (!my_isspace(*q))
+	return NULL;
+
+    if (no < 0 || no > 12)
+	return NULL;
+
+    *fkeyno = (no == 0) ? 10 : no - 1;
+    return q;
+}
+
+static void parse_config_file(FILE * f)
+{
+    char line[MAX_LINE], *p, *ep, ch;
+    enum kernel_type type = -1;
+    enum message_number msgnr = -1;
+    int fkeyno = 0;
+    struct menu *m = current_menu;
+
+    while (fgets(line, sizeof line, f)) {
+	p = strchr(line, '\r');
+	if (p)
+	    *p = '\0';
+	p = strchr(line, '\n');
+	if (p)
+	    *p = '\0';
+
+	p = skipspace(line);
+
+	if (looking_at(p, "menu")) {
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "label")) {
+		if (ld.label) {
+		    refstr_put(ld.menulabel);
+		    ld.menulabel = refstrdup(skipspace(p + 5));
+		} else if (m->parent_entry) {
+		    refstr_put(m->parent_entry->displayname);
+		    m->parent_entry->displayname = refstrdup(skipspace(p + 5));
+		    consider_for_hotkey(m->parent, m->parent_entry);
+		    if (!m->title[0]) {
+			/* MENU LABEL -> MENU TITLE on submenu */
+			refstr_put(m->title);
+			m->title = strip_caret(m->parent_entry->displayname);
+		    }
+		}
+	    } else if (looking_at(p, "title")) {
+		refstr_put(m->title);
+		m->title = refstrdup(skipspace(p + 5));
+		if (m->parent_entry) {
+		    /* MENU TITLE -> MENU LABEL on submenu */
+		    if (m->parent_entry->displayname == m->label) {
+			refstr_put(m->parent_entry->displayname);
+			m->parent_entry->displayname = refstr_get(m->title);
+		    }
+		}
+	    } else if (looking_at(p, "default")) {
+		if (ld.label) {
+		    ld.menudefault = 1;
+		} else if (m->parent_entry) {
+		    m->parent->defentry = m->parent_entry->entry;
+		}
+	    } else if (looking_at(p, "hide")) {
+		ld.menuhide = 1;
+	    } else if (looking_at(p, "passwd")) {
+		if (ld.label) {
+		    refstr_put(ld.passwd);
+		    ld.passwd = refstrdup(skipspace(p + 6));
+		} else if (m->parent_entry) {
+		    refstr_put(m->parent_entry->passwd);
+		    m->parent_entry->passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if (looking_at(p, "shiftkey")) {
+		shiftkey = 1;
+	    } else if (looking_at(p, "save")) {
+		menusave = true;
+		if (ld.label)
+		    ld.save = 1;
+		else
+		    m->save = true;
+	    } else if (looking_at(p, "nosave")) {
+		if (ld.label)
+		    ld.save = -1;
+		else
+		    m->save = false;
+	    } else if (looking_at(p, "immediate")) {
+		if (ld.label)
+		    ld.immediate = 1;
+		else
+		    m->immediate = true;
+	    } else if (looking_at(p, "noimmediate")) {
+		if (ld.label)
+		    ld.immediate = -1;
+		else
+		    m->immediate = false;
+	    } else if (looking_at(p, "onerror")) {
+		refstr_put(m->onerror);
+		m->onerror = refstrdup(skipspace(p + 7));
+	    } else if (looking_at(p, "master")) {
+		p = skipspace(p + 6);
+		if (looking_at(p, "passwd")) {
+		    refstr_put(m->menu_master_passwd);
+		    m->menu_master_passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if ((ep = looking_at(p, "include"))) {
+		goto do_include;
+	    } else if ((ep = looking_at(p, "background"))) {
+		p = skipspace(ep);
+		refstr_put(m->menu_background);
+		m->menu_background = refdup_word(&p);
+	    } else if ((ep = looking_at(p, "hidden"))) {
+		hiddenmenu = 1;
+	    } else if (looking_at(p, "hiddenkey")) {
+		char *key_name, *k, *ek;
+		const char *command;
+		int key;
+		p = get_word(skipspace(p + 9), &key_name);
+		command = refstrdup(skipspace(p));
+		k = key_name;
+		for (;;) {
+		    ek = strchr(k+1, ',');
+		    if (ek)
+			*ek = '\0';
+		    key = key_name_to_code(k);
+		    if (key >= 0) {
+			refstr_put(hide_key[key]);
+			hide_key[key] = refstr_get(command);
+		    }
+		    if (!ek)
+			break;
+		    k = ek+1;
+		}
+		refstr_put(key_name);
+		refstr_put(command);
+	    } else if ((ep = looking_at(p, "clear"))) {
+		clearmenu = 1;
+	    } else if ((ep = is_message_name(p, &msgnr))) {
+		refstr_put(m->messages[msgnr]);
+		m->messages[msgnr] = refstrdup(skipspace(ep));
+	    } else if ((ep = looking_at(p, "color")) ||
+		       (ep = looking_at(p, "colour"))) {
+		int i;
+		struct color_table *cptr;
+		p = skipspace(ep);
+		cptr = m->color_table;
+		for (i = 0; i < menu_color_table_size; i++) {
+		    if ((ep = looking_at(p, cptr->name))) {
+			p = skipspace(ep);
+			if (*p) {
+			    if (looking_at(p, "*")) {
+				p++;
+			    } else {
+				refstr_put(cptr->ansi);
+				cptr->ansi = refdup_word(&p);
+			    }
+
+			    p = skipspace(p);
+			    if (*p) {
+				if (looking_at(p, "*"))
+				    p++;
+				else
+				    cptr->argb_fg = parse_argb(&p);
+
+				p = skipspace(p);
+				if (*p) {
+				    if (looking_at(p, "*"))
+					p++;
+				    else
+					cptr->argb_bg = parse_argb(&p);
+
+				    /* Parse a shadow mode */
+				    p = skipspace(p);
+				    ch = *p | 0x20;
+				    if (ch == 'n')	/* none */
+					cptr->shadow = SHADOW_NONE;
+				    else if (ch == 's')	/* std, standard */
+					cptr->shadow = SHADOW_NORMAL;
+				    else if (ch == 'a')	/* all */
+					cptr->shadow = SHADOW_ALL;
+				    else if (ch == 'r')	/* rev, reverse */
+					cptr->shadow = SHADOW_REVERSE;
+				}
+			    }
+			}
+			break;
+		    }
+		    cptr++;
+		}
+	    } else if ((ep = looking_at(p, "msgcolor")) ||
+		       (ep = looking_at(p, "msgcolour"))) {
+		unsigned int fg_mask = MSG_COLORS_DEF_FG;
+		unsigned int bg_mask = MSG_COLORS_DEF_BG;
+		enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW;
+
+		p = skipspace(ep);
+		if (*p) {
+		    if (!looking_at(p, "*"))
+			fg_mask = parse_argb(&p);
+
+		    p = skipspace(p);
+		    if (*p) {
+			if (!looking_at(p, "*"))
+			    bg_mask = parse_argb(&p);
+
+			p = skipspace(p);
+			switch (*p | 0x20) {
+			case 'n':
+			    shadow = SHADOW_NONE;
+			    break;
+			case 's':
+			    shadow = SHADOW_NORMAL;
+			    break;
+			case 'a':
+			    shadow = SHADOW_ALL;
+			    break;
+			case 'r':
+			    shadow = SHADOW_REVERSE;
+			    break;
+			default:
+			    /* go with default */
+			    break;
+			}
+		    }
+		}
+		set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow);
+	    } else if (looking_at(p, "separator")) {
+		record(m, &ld, append);
+		ld.label = refstr_get(empty_string);
+		ld.menuseparator = 1;
+		record(m, &ld, append);
+	    } else if (looking_at(p, "disable") || looking_at(p, "disabled")) {
+		ld.menudisabled = 1;
+	    } else if (looking_at(p, "indent")) {
+		ld.menuindent = atoi(skipspace(p + 6));
+	    } else if (looking_at(p, "begin")) {
+		record(m, &ld, append);
+		m = current_menu = begin_submenu(skipspace(p + 5));
+	    } else if (looking_at(p, "end")) {
+		record(m, &ld, append);
+		m = current_menu = end_submenu();
+	    } else if (looking_at(p, "quit")) {
+		if (ld.label)
+		    ld.action = MA_QUIT;
+	    } else if (looking_at(p, "goto")) {
+		if (ld.label) {
+		    ld.action = MA_GOTO_UNRES;
+		    refstr_put(ld.kernel);
+		    ld.kernel = refstrdup(skipspace(p + 4));
+		}
+	    } else if (looking_at(p, "exit")) {
+		p = skipspace(p + 4);
+		if (ld.label && m->parent) {
+		    if (*p) {
+			/* This is really just a goto, except for the marker */
+			ld.action = MA_EXIT_UNRES;
+			refstr_put(ld.kernel);
+			ld.kernel = refstrdup(p);
+		    } else {
+			ld.action = MA_EXIT;
+			ld.submenu = m->parent;
+		    }
+		}
+	    } else if (looking_at(p, "start")) {
+		start_menu = m;
+	    } else if (looking_at(p, "help")) {
+		if (ld.label) {
+		    ld.action = MA_HELP;
+		    p = skipspace(p + 4);
+
+		    refstr_put(ld.kernel);
+		    ld.kernel = refdup_word(&p);
+
+		    if (ld.append) {
+			refstr_put(ld.append);
+			ld.append = NULL;
+		    }
+
+		    if (*p) {
+			p = skipspace(p);
+			ld.append = refdup_word(&p); /* Background */
+		    }
+		}
+	    } else if ((ep = looking_at(p, "resolution"))) {
+		int x, y;
+		x = strtoul(ep, &ep, 0);
+		y = strtoul(skipspace(ep), NULL, 0);
+		set_resolution(x, y);
+	    } else {
+		/* Unknown, check for layout parameters */
+		enum parameter_number mp;
+		for (mp = 0; mp < NPARAMS; mp++) {
+		    if ((ep = looking_at(p, mparm[mp].name))) {
+			m->mparm[mp] = atoi(skipspace(ep));
+			break;
+		    }
+		}
+	    }
+	} else if (looking_at(p, "text")) {
+	    enum text_cmd {
+		TEXT_UNKNOWN,
+		TEXT_HELP
+	    } cmd = TEXT_UNKNOWN;
+	    int len = ld.helptext ? strlen(ld.helptext) : 0;
+	    int xlen;
+
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "help"))
+		cmd = TEXT_HELP;
+
+	    while (fgets(line, sizeof line, f)) {
+		p = skipspace(line);
+		if (looking_at(p, "endtext"))
+		    break;
+
+		xlen = strlen(line);
+
+		switch (cmd) {
+		case TEXT_UNKNOWN:
+		    break;
+		case TEXT_HELP:
+		    ld.helptext = realloc(ld.helptext, len + xlen + 1);
+		    memcpy(ld.helptext + len, line, xlen + 1);
+		    len += xlen;
+		    break;
+		}
+	    }
+	} else if ((ep = is_fkey(p, &fkeyno))) {
+	    p = skipspace(ep);
+	    if (m->fkeyhelp[fkeyno].textname) {
+		refstr_put(m->fkeyhelp[fkeyno].textname);
+		m->fkeyhelp[fkeyno].textname = NULL;
+	    }
+	    if (m->fkeyhelp[fkeyno].background) {
+		refstr_put(m->fkeyhelp[fkeyno].background);
+		m->fkeyhelp[fkeyno].background = NULL;
+	    }
+
+	    refstr_put(m->fkeyhelp[fkeyno].textname);
+	    m->fkeyhelp[fkeyno].textname = refdup_word(&p);
+	    if (*p) {
+		p = skipspace(p);
+		m->fkeyhelp[fkeyno].background = refdup_word(&p);
+	    }
+	} else if ((ep = looking_at(p, "include"))) {
+do_include:
+	    {
+		const char *file;
+		p = skipspace(ep);
+		file = refdup_word(&p);
+		p = skipspace(p);
+		if (*p) {
+		    record(m, &ld, append);
+		    m = current_menu = begin_submenu(p);
+		    parse_one_config(file);
+		    record(m, &ld, append);
+		    m = current_menu = end_submenu();
+		} else {
+		    parse_one_config(file);
+		}
+		refstr_put(file);
+	    }
+	} else if (looking_at(p, "append")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.append);
+		ld.append = a;
+	    } else {
+		refstr_put(append);
+		append = a;
+	    }
+	} else if (looking_at(p, "initrd")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.initrd);
+		ld.initrd = a;
+	    } else {
+		/* Ignore */
+	    }
+	} else if (looking_at(p, "label")) {
+	    p = skipspace(p + 5);
+	    record(m, &ld, append);
+	    ld.label = refstrdup(p);
+	    ld.kernel = refstrdup(p);
+	    ld.type = KT_KERNEL;
+	    ld.passwd = NULL;
+	    ld.append = NULL;
+	    ld.initrd = NULL;
+	    ld.menulabel = NULL;
+	    ld.helptext = NULL;
+	    ld.ipappend = ipappend;
+	    ld.menudefault = ld.menuhide = ld.menuseparator =
+		ld.menudisabled = ld.menuindent = 0;
+	} else if ((ep = is_kernel_type(p, &type))) {
+	    if (ld.label) {
+		refstr_put(ld.kernel);
+		ld.kernel = refstrdup(skipspace(ep));
+		ld.type = type;
+	    }
+	} else if (looking_at(p, "timeout")) {
+	    m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "totaltimeout")) {
+	    totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "ontimeout")) {
+	    m->ontimeout = refstrdup(skipspace(p + 9));
+	} else if (looking_at(p, "allowoptions")) {
+	    m->allowedit = !!atoi(skipspace(p + 12));
+	} else if ((ep = looking_at(p, "ipappend")) ||
+		   (ep = looking_at(p, "sysappend"))) {
+	    uint32_t s = strtoul(skipspace(ep), NULL, 0);
+	    if (ld.label)
+		ld.ipappend = s;
+	    else
+		ipappend = s;
+	} else if (looking_at(p, "default")) {
+	    refstr_put(globaldefault);
+	    globaldefault = refstrdup(skipspace(p + 7));
+	} else if (looking_at(p, "ui")) {
+	    has_ui = 1;
+	}
+    }
+}
+
+static int parse_one_config(const char *filename)
+{
+    FILE *f;
+
+    if (!strcmp(filename, "~"))
+	filename = syslinux_config_file();
+
+    dprintf("Opening config file: %s ", filename);
+
+    f = fopen(filename, "r");
+    dprintf("%s\n", f ? "ok" : "failed");
+    
+    if (!f)
+	return -1;
+
+    parse_config_file(f);
+    fclose(f);
+
+    return 0;
+}
+
+static void resolve_gotos(void)
+{
+    struct menu_entry *me;
+    struct menu *m;
+
+    for (me = all_entries; me; me = me->next) {
+	if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) {
+	    m = find_menu(me->cmdline);
+	    refstr_put(me->cmdline);
+	    me->cmdline = NULL;
+	    if (m) {
+		me->submenu = m;
+		me->action--;	/* Drop the _UNRES */
+	    } else {
+		me->action = MA_DISABLED;
+	    }
+	}
+    }
+}
+
+void parse_configs(char **argv)
+{
+    const char *filename;
+    struct menu *m;
+    struct menu_entry *me;
+    int k;
+
+    empty_string = refstrdup("");
+
+    /* Initialize defaults for the root and hidden menus */
+    hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
+    root_menu = new_menu(NULL, NULL, refstrdup(".top"));
+    start_menu = root_menu;
+
+    /* Other initialization */
+    memset(&ld, 0, sizeof(struct labeldata));
+
+    /* Actually process the files */
+    current_menu = root_menu;
+    if (!*argv) {
+	parse_one_config("~");
+    } else {
+	while ((filename = *argv++))
+	    parse_one_config(filename);
+    }
+
+    /* On final EOF process the last label statement */
+    record(current_menu, &ld, append);
+
+    /* Common postprocessing */
+    resolve_gotos();
+
+    /* Handle global default */
+    if (has_ui && globaldefault) {
+	me = find_label(globaldefault);
+	if (me && me->menu != hide_menu) {
+	    me->menu->defentry = me->entry;
+	    start_menu = me->menu;
+	}
+    }
+
+    /* If "menu save" is active, let the ADV override the global default */
+    if (menusave) {
+	size_t len;
+	const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
+	char *lstr;
+	if (lbl && len) {
+	    lstr = refstr_alloc(len);
+	    memcpy(lstr, lbl, len);	/* refstr_alloc() adds the final null */
+	    me = find_label(lstr);
+	    if (me && me->menu != hide_menu) {
+		me->menu->defentry = me->entry;
+		start_menu = me->menu;
+	    }
+	    refstr_put(lstr);
+	}
+    }
+
+    /* Final per-menu initialization, with all labels known */
+    for (m = menu_list; m; m = m->next) {
+	m->curentry = m->defentry;	/* All menus start at their defaults */
+
+	if (m->ontimeout)
+	    m->ontimeout = unlabel(m->ontimeout);
+	if (m->onerror)
+	    m->onerror = unlabel(m->onerror);
+    }
+
+    /* Final global initialization, with all labels known */
+    for (k = 0; k < KEY_MAX; k++) {
+	if (hide_key[k])
+	    hide_key[k] = unlabel(hide_key[k]);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/refstr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,105 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * refstr.c
+ *
+ * Simple reference-counted strings
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "refstr.h"
+
+/* Allocate space for a refstring of len bytes, plus final null */
+/* The final null is inserted in the string; the rest is uninitialized. */
+char *refstr_alloc(size_t len)
+{
+    char *r = malloc(sizeof(unsigned int) + len + 1);
+    if (!r)
+	return NULL;
+    *(unsigned int *)r = 1;
+    r += sizeof(unsigned int);
+    r[len] = '\0';
+    return r;
+}
+
+const char *refstrndup(const char *str, size_t len)
+{
+    char *r;
+
+    if (!str)
+	return NULL;
+
+    len = strnlen(str, len);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+const char *refstrdup(const char *str)
+{
+    char *r;
+    size_t len;
+
+    if (!str)
+	return NULL;
+
+    len = strlen(str);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+int vrsprintf(const char **bufp, const char *fmt, va_list ap)
+{
+    va_list ap1;
+    int len;
+    char *p;
+
+    va_copy(ap1, ap);
+    len = vsnprintf(NULL, 0, fmt, ap1);
+    va_end(ap1);
+
+    *bufp = p = refstr_alloc(len);
+    if (!p)
+	return -1;
+
+    return vsnprintf(p, len + 1, fmt, ap);
+}
+
+int rsprintf(const char **bufp, const char *fmt, ...)
+{
+    int rv;
+    va_list ap;
+
+    va_start(ap, fmt);
+    rv = vrsprintf(bufp, fmt, ap);
+    va_end(ap);
+
+    return rv;
+}
+
+void refstr_put(const char *r)
+{
+    unsigned int *ref;
+
+    if (r) {
+	ref = (unsigned int *)r - 1;
+
+	if (!--*ref)
+	    free(ref);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/menu/vesamenu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/menu/vesamenu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/menu/vesamenu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * vesamenu.c
+ *
+ * Simple menu system which displays a list and allows the user to select
+ * a command line and/or edit it.
+ *
+ * VESA graphics version.
+ */
+
+#include <stdio.h>
+#include <console.h>
+#include <syslinux/vesacon.h>
+
+#include "menu.h"
+
+int draw_background(const char *what)
+{
+    if (!what)
+	return vesacon_default_background();
+    else if (what[0] == '#')
+	return vesacon_set_background(parse_argb((char **)&what));
+    else
+	return vesacon_load_background(what);
+}
+
+void set_resolution(int x, int y)
+{
+    vesacon_set_resolution(x, y);
+}
+
+void local_cursor_enable(bool enabled)
+{
+    vesacon_cursor_enable(enabled);
+}
+
+void start_console(void)
+{
+    openconsole(&dev_rawcon_r, &dev_vesaserial_w);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 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.
+##
+## -----------------------------------------------------------------------
+
+##
+## COM32 standard modules
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+MODULES	  = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
+	    disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
+	    meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
+	    kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \
+	    ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \
+	    whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \
+	    hexdump.c32 poweroff.c32 cptime.c32 debug.c32
+
+TESTFILES =
+
+all: $(MODULES) $(TESTFILES)
+
+.PRECIOUS: %.o
+dmitest.o: dmitest.c
+	$(CC) $(CFLAGS) $(GPLINCLUDE) -c -o $@ $<
+
+dmitest.elf : dmi_utils.o dmitest.o $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+
+int main(int argc, char *argv[])
+{
+    FILE *f;
+    int i;
+    int len;
+    char buf[4096];
+
+    if (argc < 2) {
+	fprintf(stderr, "Usage: %s filename...\n", argv[0]);
+	return 1;
+    }
+
+    for (i = 1; i < argc; i++) {
+	f = fopen(argv[i], "r");
+	if (!f) {
+	    fprintf(stderr, "%s: %s: file not found\n", argv[0], argv[i]);
+	    return 1;
+	}
+
+	while ((len = fread(buf, 1, sizeof buf, f)) > 0)
+	    fwrite(buf, 1, len, stdout);
+	
+	fclose(f);
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 Michael Brown - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * cmd.c
+ *
+ * Execute arbitrary commands
+ */
+
+#include <com32.h>
+#include <syslinux/boot.h>
+
+int main(void)
+{
+    syslinux_run_command(com32_cmdline());
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/config.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/config.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/config.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * config.c
+ *
+ * Loads a new configuration file
+ *
+ * Usage: config filename
+ */
+
+#include <stdio.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+int main(int argc, char *argv[])
+{
+    if (argc < 2 || argc > 3) {
+	fprintf(stderr, "Usage: config <filename> [<directory>]\n");
+	return 1;
+    }
+
+    syslinux_run_kernel_image(argv[1], argv[2] ? argv[2] : "",
+			      0, IMAGE_TYPE_CONFIG);
+
+    fprintf(stderr, "config: %s: failed to load (missing file?)\n", argv[1]);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2011 Gene Cumm
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * cptime.c	Version 1.4
+ *
+ * Timed copy; read entire file then output total time, bytes transferred,
+ * and compute transfer rate.
+ *
+ * cptime [-s|-l] [-v|-q] [-b _SIZE_] [-n _LEN_] _FILE_...
+ *	-s	Change to simple output mode without computing transfer rate
+ *	-l	Change to long output mode (to allow for overriding previous -s)
+ *	-v	Verbose output
+ *	-q	Quiet output
+ *	-b _SIZE_	use _SIZE_ for transfer size
+ *	-n _LEN_	maximum length to fetch
+ *	_FILE_...	Space delimited list of files to dump
+ * Note: The last instance of -s or -l wins, along with the last use of -b and -n and the winning option will be applied to all operations
+ *
+ * Hisory:
+ * 1.4	Use fread() rather than read(); use CLK_TCK when available.
+ * 1.3	Added -v/-q; rework some argument processing.
+ * 1.2	Added -n
+ * 1.1	Added -l and -b switches; more flexible command line processing
+ * 1.0	First release
+ */
+
+/*
+ * ToDos:
+ * - Refine timing to be more precise.  Low priority.
+ * - Add -o for offset.  Wishlist.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <consoles.h>
+#include <minmax.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <console.h>
+
+#ifdef __COM32__
+#  define BUFSZ_DEF	(size_t)2048
+/* What's optimal?  Under 4k?
+ *	layout.inc: xfer_buf_seg	equ 1000h
+ *	com32.inc: push dword (1 << 16)		; 64K bounce buffer
+ */
+/* typedef size_t off_t */
+
+#  define TPS_T	float
+#  ifdef CLK_TCK
+static inline TPS_T get_tps(void) {	return CLK_TCK;	}
+#  else
+static inline TPS_T get_tps(void) {	return 18.2;	}
+#  endif
+
+#else /* __COM32__ */
+
+#  define BUFSZ_DEF	(size_t)16384
+/* Need to check what might be a "best" buffer/fetch block size here */
+
+#  define TPS_T	long
+static inline TPS_T get_tps(void) {	return sysconf(_SC_CLK_TCK);	}
+
+#endif /* __COM32__ */
+
+#ifndef SSIZE_MAX
+#  define SSIZE_MAX	PTRDIFF_MAX
+#endif
+/* typedef ptrdiff_t ssize_t; */
+#define BUFSZ_MAX	(size_t)SSIZE_MAX
+/* ssize_t max */
+#define BUFSZ_MIN	(size_t)1
+
+
+/* Please note: I don't know the origin of these two macros nor their license */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+#define TYPE_MAX(t) \
+  ((t) (! TYPE_SIGNED (t) \
+        ? (t) -1 \
+	: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+
+#ifndef OFF_T_MAX
+#  define OFF_T_MAX	TYPE_MAX(off_t)
+#endif
+/* Can't be SIZE_MAX or SSIZE_MAX as Syslinux/COM32 is unsigned while Linux 
+ * is signed.
+ */
+
+#define LEN_MAX		OFF_T_MAX
+/* off_t max */
+#define LEN_MIN		(off_t)0
+
+void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs)
+{
+	size_t dr;
+	/* prevent divide by 0 */
+	dr = max(bcnt, (bcnt * tps)) / max((clock_t)1, (et + offs));
+	printf("  %+d %zu B/s; %zu KiB/s; %zu MiB/s\n", offs, dr, dr/1024, dr/1048576);
+}	/* void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs) */
+
+void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+	TPS_T tps;
+	if (do_verbose > 2)
+		printf("Enter print_cp_result_long()\n");
+	tps = get_tps();
+	printf("  %zu B in %d ticks from '%s'\n", bcnt, (int)(ec - bc), fn);
+	printf("  ~%d ticks per second; %zu B block/transfer size\n", (int)tps, bufsz);
+	print_cp_result_tick(bcnt, (ec - bc), tps, 0);
+	print_cp_result_tick(bcnt, (ec - bc), tps, 1);
+	print_cp_result_tick(bcnt, (ec - bc), tps, -1);
+}	/* void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz) */
+
+void print_cp_result_simple(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+	if (do_verbose) {}
+	printf("  %zuB  %dt %zux '%s'\n", bcnt, (int)(ec - bc), bufsz, fn);
+}	/* void print_cp_result_simple(char *fn, int bcnt, clock_t bc, clock_t ec, char do_verbose) */
+
+size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen)
+{
+	return min(bufsz, (maxlen - bcnt));
+}	/* size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen) */
+
+int time_copy(char *fn, char do_simple, char do_verbose, size_t ibufsz, off_t maxlen)
+{
+// 	int fd;
+	int rv = 0;
+	int i = 0;
+	FILE *f;
+	size_t bufsz, bcnt = 0;
+	int numrd;
+	struct tms tm;
+	clock_t bc, ec;
+	char buf[ibufsz + 1];
+
+	buf[0] = 0;
+	if (do_verbose)
+		printf("Trying file '%s'\n", fn);
+	errno = 0;
+// 	fd = open(fn, O_RDONLY);
+	f = fopen(fn, "r");
+// 	if (fd == -1) {
+	if (!f) {
+		switch (errno) {
+		case ENOENT :
+			printf("File '%s' does not exist\n", fn);
+			break;
+		case EBADF:
+			printf("File '%s': Bad File Descriptor\n", fn);
+			break;
+		default :
+			printf("Error '%d' opening file '%s'\n", errno, fn);
+		}
+		rv = 1;
+	} else {
+		if (do_verbose)
+			printf("File '%s' opened\n", fn);
+		bufsz = time_copy_bufsz(ibufsz, bcnt, maxlen);
+		bc = times(&tm);
+// 		numrd = read(fd, buf, bufsz);
+// 		numrd = fread(buf, bufsz, 1, f);
+		numrd = fread(buf, 1, bufsz, f);
+		i++;
+		if (numrd > 0)
+			bcnt = numrd;
+		while ((numrd > 0) && (bufsz > 0)) {
+			bufsz = time_copy_bufsz(bufsz, bcnt, maxlen);
+// 			numrd = read(fd, buf, bufsz);
+// 			numrd = fread(buf, bufsz, 1, f);
+			numrd = fread(buf, 1, bufsz, f);
+			i++;
+			if (numrd >= 0)
+// 				bcnt = bcnt + numrd;
+				bcnt += numrd;
+		}
+		ec = times(&tm);
+// 		close(fd);
+		fclose(f);
+		if (do_verbose)
+			printf("File '%s' closed\n", fn);
+		if (numrd < 0) {
+			switch (errno) {
+			case EIO :
+				printf("IO Error at %zu B reading file '%s'\n", bcnt, fn);
+				break;
+			case EINVAL :
+				printf("Invalid Mode at %zu B reading file '%s'\n", bcnt, fn);
+				break;
+			default :
+				printf("Error '%d' at %zu B reading file '%s'\n", errno, bcnt, fn);
+			}
+			rv = 2;
+		}
+		if (bcnt > 0) {
+			if (bufsz == 0)
+				printf("maxed out on maxln\n");
+			if (do_simple)
+				print_cp_result_simple(fn, bcnt, bc, ec, ibufsz, do_verbose);
+			else
+				print_cp_result_long(fn, bcnt, bc, ec, ibufsz, do_verbose);
+		}
+		if (do_verbose)
+			printf("  numrd %d bcnt %d bufsz %d i %d\n", numrd, bcnt, bufsz, i);
+	}
+	return rv;
+}	/* int time_copy(char *fn, char do_simple, int bufsz, off_t maxlen) */
+
+int main(int argc, char *argv[])
+{
+	int i;
+	char do_simple = 0, do_pbuf = 0, do_plen = 0, do_verbose = 0;
+	char *arg;
+	size_t tbufsz, bufsz = min((BUFSZ_DEF), (BUFSZ_MAX));
+	off_t tmaxlen, maxlen = LEN_MAX;
+	int numfl = 0;
+	console_ansi_std();
+// 	openconsole(&dev_stdcon_r, &dev_stdcon_w);
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-') {
+			arg = argv[i] + 1;
+			if (strcmp(arg, "b") == 0) {
+				i++;
+				if (i < argc) {
+					tbufsz = atoi(argv[i]);
+					if (tbufsz > 0)
+						bufsz = min(max((BUFSZ_MIN), tbufsz), (BUFSZ_MAX));
+					do_pbuf = 1;
+				}
+			} else if (strcmp(arg, "n") == 0) {
+				i++;
+				if (i < argc) {
+					tmaxlen = atoi(argv[i]);
+					if (tmaxlen > 0)
+						maxlen = min(max((LEN_MIN), tmaxlen), (LEN_MAX));
+					do_plen = 1;
+				}
+			} else if (strcmp(arg, "s") == 0)
+				do_simple = 1;
+			else if (strcmp(arg, "l") == 0)
+				do_simple = 0;
+			else if (strcmp(arg, "v") == 0)
+				do_verbose = 1;
+			else if (strcmp(arg, "q") == 0)
+				do_verbose = 0;
+		}
+	}
+	if (do_pbuf || do_verbose)
+		printf("Using bufsz %zu\n", bufsz);
+	if (do_plen || do_verbose)
+		printf("Using maxlen %zu\n", maxlen);
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-') {
+			arg = argv[i] + 1;
+			if ((strcmp(arg, "b") == 0) || (strcmp(arg, "n") == 0))
+				i++; 	/* Skip next arg */
+			else if (!((strcmp(arg, "s") == 0) || (strcmp(arg, "l") == 0) || (strcmp(arg, "v") == 0) || (strcmp(arg, "q") == 0))) {
+				time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+				numfl++;
+			}
+		} else {
+			time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+			numfl++;
+		}
+	}
+	if (numfl == 0)
+		fprintf(stderr, "%s: Please specify a file\n", argv[0]);
+	return 0;
+}	/* int main(int argc, char *argv[]) */
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include <console.h>
+#include <com32.h>
+
+static void dump_reg(const char *name, uint32_t val)
+{
+    int i;
+
+    printf("%-3s : %10u 0x%08x ", name, val, val);
+
+    for (i = 3; i >= 0; i--) {
+	uint8_t c = val >> (i*8);
+	putchar((c >= ' ' && c <= '~') ? c : '.');
+    }
+    putchar('\n');
+}
+
+int main(int argc, char *argv[])
+{
+    uint32_t leaf, counter;
+    uint32_t eax, ebx, ecx, edx;
+
+    if (argc < 2 || argc > 4) {
+	printf("Usage: %s leaf [counter]\n", argv[0]);
+	exit(1);
+    }
+
+    leaf = strtoul(argv[1], NULL, 0);
+    counter = (argc > 2) ? strtoul(argv[2], NULL, 0) : 0;
+
+    if (!cpu_has_eflag(EFLAGS_ID)) {
+	printf("The CPUID instruction is not supported\n");
+	exit(1);
+    }
+
+    cpuid_count(leaf, counter, &eax, &ebx, &ecx, &edx);
+
+    dump_reg("eax", eax);
+    dump_reg("ebx", ebx);
+    dump_reg("ecx", ecx);
+    dump_reg("edx", edx);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,137 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * cpuidtest.c
+ *
+ * A CPUID demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "cpuid.h"
+
+char display_line;
+
+int main(void)
+{
+    s_cpu cpu;
+
+    for (;;) {
+	detect_cpu(&cpu);
+	printf("Vendor      = %s\n", cpu.vendor);
+	printf("Model       = %s\n", cpu.model);
+	printf("Vendor ID   = %d\n", cpu.vendor_id);
+	printf("Family      = %d\n", cpu.family);
+	printf("Model ID    = %d\n", cpu.model_id);
+	printf("Stepping    = %d\n", cpu.stepping);
+	printf("Flags       = ");
+	if (cpu.flags.fpu)
+	    printf("fpu ");
+	if (cpu.flags.vme)
+	    printf("vme ");
+	if (cpu.flags.de)
+	    printf("de ");
+	if (cpu.flags.pse)
+	    printf("pse ");
+	if (cpu.flags.tsc)
+	    printf("tsc ");
+	if (cpu.flags.msr)
+	    printf("msr ");
+	if (cpu.flags.pae)
+	    printf("pae ");
+	if (cpu.flags.mce)
+	    printf("mce ");
+	if (cpu.flags.cx8)
+	    printf("cx8 ");
+	if (cpu.flags.apic)
+	    printf("apic ");
+	if (cpu.flags.sep)
+	    printf("sep ");
+	if (cpu.flags.mtrr)
+	    printf("mtrr ");
+	if (cpu.flags.pge)
+	    printf("pge ");
+	if (cpu.flags.mca)
+	    printf("mca ");
+	if (cpu.flags.cmov)
+	    printf("cmov ");
+	if (cpu.flags.pat)
+	    printf("pat ");
+	if (cpu.flags.pse_36)
+	    printf("pse_36 ");
+	if (cpu.flags.psn)
+	    printf("psn ");
+	if (cpu.flags.clflsh)
+	    printf("clflsh ");
+	if (cpu.flags.dts)
+	    printf("dts ");
+	if (cpu.flags.acpi)
+	    printf("acpi ");
+	if (cpu.flags.mmx)
+	    printf("mmx ");
+	if (cpu.flags.sse)
+	    printf("sse ");
+	if (cpu.flags.sse2)
+	    printf("sse2 ");
+	if (cpu.flags.ss)
+	    printf("ss ");
+	if (cpu.flags.htt)
+	    printf("ht ");
+	if (cpu.flags.acc)
+	    printf("acc ");
+	if (cpu.flags.syscall)
+	    printf("syscall ");
+	if (cpu.flags.mp)
+	    printf("mp ");
+	if (cpu.flags.nx)
+	    printf("nx ");
+	if (cpu.flags.mmxext)
+	    printf("mmxext ");
+	if (cpu.flags.lm)
+	    printf("lm ");
+	if (cpu.flags.nowext)
+	    printf("3dnowext ");
+	if (cpu.flags.now)
+	    printf("3dnow! ");
+	if (cpu.flags.vmx)
+	    printf("vmx ");
+	if (cpu.flags.svm)
+	    printf("svm ");
+	printf("\n");
+	printf("SMP         = ");
+	if (cpu.flags.smp)
+	    printf("yes\n");
+	else
+	    printf("no\n");
+	break;
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/debug.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2013 Intel Corporation; author: Matt Fleming
+ *
+ *   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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <syslinux/debug.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *progname;
+
+static void usage(void)
+{
+    fprintf(stderr, "Usage: %s [-e|-d] <func1> [<func2>, ...]\n", progname);
+}
+
+int main(int argc, char *argv[])
+{
+    bool enable;
+    int i;
+
+    progname = argv[0];
+
+    if (argc < 3) {
+	usage();
+	return -1;
+    }
+
+    if (!strncmp(argv[1], "-e", 2))
+	enable = true;
+    else if (!strncmp(argv[1], "-d", 2))
+	enable = false;
+    else {
+	usage();
+	return -1;
+    }
+
+    for (i = 2; i < argc; i++) {
+	char *str = argv[i];
+
+	if (syslinux_debug(str, enable) < 0)
+	    fprintf(stderr, "Failed to debug symbol \"%s\"\n", str);
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dir.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <dirent.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <getkey.h>
+
+static int rows, cols;		/* Screen parameters */
+
+#define DIR_CHUNK	1024
+
+static const char *type_str(int type)
+{
+    switch (type) {
+    case DT_FIFO:
+	return "[fif]";
+    case DT_CHR:
+	return "[chr]";
+    case DT_DIR:
+	return "[dir]";
+    case DT_BLK:
+	return "[blk]";
+    case DT_UNKNOWN:
+    case DT_REG:
+	return "";
+    case DT_LNK:
+	return "[lnk]";
+    case DT_SOCK:
+	return "[sck]";
+    case DT_WHT:
+	return "[wht]";
+    default:
+	return "[???]";
+    }
+}
+
+static void free_dirents(struct dirent **dex, size_t n_de)
+{
+    size_t i;
+
+    for (i = 0; i < n_de; i++)
+	free(dex[i]);
+
+    free(dex);
+}
+
+static int compare_dirent(const void *p_de1, const void *p_de2)
+{
+    const struct dirent *de1 = *(const struct dirent **)p_de1;
+    const struct dirent *de2 = *(const struct dirent **)p_de2;
+    int ndir1, ndir2;
+
+    ndir1 = de1->d_type != DT_DIR;
+    ndir2 = de2->d_type != DT_DIR;
+
+    if (ndir1 != ndir2)
+	return ndir1 - ndir2;
+
+    return strcmp(de1->d_name, de2->d_name);
+}
+
+static int display_directory(const char *dirname)
+{
+    DIR *dir;
+    struct dirent *de;
+    struct dirent **dex = NULL;
+    size_t n_dex = 0, n_de = 0;
+    size_t i, j, k;
+    size_t nrows, ncols, perpage;
+    size_t endpage;
+    int maxlen = 0;
+    int pos, tpos, colwidth;
+
+    dir = opendir(dirname);
+    if (!dir) {
+	printf("Unable to read directory: %s\n", dirname);
+	return -1;
+    }
+
+    while ((de = readdir(dir)) != NULL) {
+	struct dirent *nde;
+
+	if (n_de >= n_dex) {
+	    struct dirent **ndex;
+
+	    ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
+	    if (!ndex)
+		goto nomem;
+
+	    dex = ndex;
+	    n_dex += DIR_CHUNK;
+	}
+
+	nde = malloc(de->d_reclen);
+	if (!nde)
+	    goto nomem;
+
+	memcpy(nde, de, de->d_reclen);
+	dex[n_de++] = nde;
+
+	maxlen = max(maxlen, de->d_reclen);
+    }
+
+    closedir(dir);
+
+    qsort(dex, n_de, sizeof *dex, compare_dirent);
+
+    maxlen -= offsetof(struct dirent, d_name) + 1;
+    ncols = (cols + 2)/(maxlen + 8);
+    ncols = min(ncols, n_de);
+    ncols = max(ncols, 1U);
+    colwidth = (cols + 2)/ncols;
+    perpage = ncols * (rows - 1);
+
+    for (i = 0; i < n_de; i += perpage) {
+	/* Rows on this page */
+	endpage = min(i+perpage, n_de);
+	nrows = ((endpage-i) + ncols - 1)/ncols;
+
+	for (j = 0; j < nrows; j++) {
+	    pos = tpos = 0;
+	    for (k = i+j; k < endpage; k += nrows) {
+		pos += printf("%*s%-5s %s",
+			      (tpos - pos), "",
+			      type_str(dex[k]->d_type),
+			      dex[k]->d_name);
+		tpos += colwidth;
+	    }
+	    printf("\n");
+	}
+
+	if (endpage >= n_de)
+	    break;
+
+	get_key(stdin, 0);
+    }
+
+    free_dirents(dex, n_de);
+    return 0;
+
+nomem:
+    closedir(dir);
+    printf("Out of memory error!\n");
+    free_dirents(dex, n_de);
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv;
+
+    if (getscreensize(1, &rows, &cols)) {
+	/* Unknown screen size? */
+	rows = 24;
+	cols = 80;
+    }
+
+    if (argc < 2)
+	rv = display_directory(".");
+    else if (argc == 2)
+	rv = display_directory(argv[1]);
+    else {
+	printf("Usage: dir directory\n");
+	rv = 1;
+    }
+
+    return rv ? 1 : 0;
+}
+  
Index: bootcd/isolinux/syslinux-6.03/com32/modules/disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <console.h>
+#include <stdlib.h>
+#include <string.h>
+#include <disk/geom.h>
+#include <disk/util.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
+
+int main(int argc, char *argv[])
+{
+	struct driveinfo drive;
+	struct driveinfo *d = &drive;
+
+	(void)argc;
+	(void)argv;
+
+	for (int disk = 0x80; disk < 0xff; disk++) {
+		memset(d, 0, sizeof(struct driveinfo));
+		d->disk = disk;
+		get_drive_parameters(d);
+
+		/* Do not print output when drive does not exists */
+		if (errno_disk == -1 || !d->cbios)
+			continue;
+
+		if (errno_disk) {
+			get_error("reading disk");
+			continue;
+		}
+
+		printf("DISK 0x%X:\n", d->disk);
+		printf("  C/H/S: %d heads, %d cylinders\n",
+			d->legacy_max_head + 1, d->legacy_max_cylinder + 1);
+		printf("         %d sectors/track, %d drives\n",
+			d->legacy_sectors_per_track, d->legacy_max_drive);
+		printf("  EDD:   ebios=%d, EDD version: %X\n",
+			d->ebios, d->edd_version);
+		printf("         %d heads, %d cylinders\n",
+			(int) d->edd_params.heads, (int) d->edd_params.cylinders);
+		printf("         %d sectors, %d bytes/sector, %d sectors/track\n",
+			(int) d->edd_params.sectors, (int) d->edd_params.bytes_per_sector,
+			(int) d->edd_params.sectors_per_track);
+		printf("         Host bus: %s, Interface type: %s\n\n",
+			d->edd_params.host_bus_type, d->edd_params.interface_type);
+	}
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "stdio.h"
+#include "dmi/dmi.h"
+
+void display_bios_characteristics(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_strings[i]);
+	}
+    }
+    for (i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics_x1))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_x1_strings[i]);
+	}
+    }
+
+    for (i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics_x2))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_x2_strings[i]);
+	}
+    }
+}
+
+void display_base_board_features(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->base_board.features))[i] == true) {
+	    moreprintf("\t\t%s\n", base_board_features_strings[i]);
+	}
+    }
+}
+
+void display_processor_flags(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	if (((bool *) (&dmi->processor.cpu_flags))[i] == true) {
+	    moreprintf("\t\t%s\n", cpu_flags_strings[i]);
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * dmitest.c
+ *
+ * DMI demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "dmi/dmi.h"
+
+char display_line;
+
+void display_memory(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < dmi->memory_count; i++) {
+	moreprintf("Memory Bank %d\n", i);
+	moreprintf("\tForm Factor  : %s\n", dmi->memory[i].form_factor);
+	moreprintf("\tType         : %s\n", dmi->memory[i].type);
+	moreprintf("\tType Detail  : %s\n", dmi->memory[i].type_detail);
+	moreprintf("\tSpeed        : %s\n", dmi->memory[i].speed);
+	moreprintf("\tSize         : %s\n", dmi->memory[i].size);
+	moreprintf("\tDevice Set   : %s\n", dmi->memory[i].device_set);
+	moreprintf("\tDevice Loc.  : %s\n", dmi->memory[i].device_locator);
+	moreprintf("\tBank Locator : %s\n", dmi->memory[i].bank_locator);
+	moreprintf("\tTotal Width  : %s\n", dmi->memory[i].total_width);
+	moreprintf("\tData Width   : %s\n", dmi->memory[i].data_width);
+	moreprintf("\tError        : %s\n", dmi->memory[i].error);
+	moreprintf("\tVendor       : %s\n", dmi->memory[i].manufacturer);
+	moreprintf("\tSerial       : %s\n", dmi->memory[i].serial);
+	moreprintf("\tAsset Tag    : %s\n", dmi->memory[i].asset_tag);
+	moreprintf("\tPart Number  : %s\n", dmi->memory[i].part_number);
+    }
+}
+
+void display_battery(s_dmi * dmi)
+{
+    moreprintf("Battery\n");
+    moreprintf("\tVendor              : %s\n", dmi->battery.manufacturer);
+    moreprintf("\tManufacture Date    : %s\n", dmi->battery.manufacture_date);
+    moreprintf("\tSerial              : %s\n", dmi->battery.serial);
+    moreprintf("\tName                : %s\n", dmi->battery.name);
+    moreprintf("\tChemistry           : %s\n", dmi->battery.chemistry);
+    moreprintf("\tDesign Capacity     : %s\n", dmi->battery.design_capacity);
+    moreprintf("\tDesign Voltage      : %s\n", dmi->battery.design_voltage);
+    moreprintf("\tSBDS                : %s\n", dmi->battery.sbds);
+    moreprintf("\tSBDS Manufact. Date : %s\n",
+	       dmi->battery.sbds_manufacture_date);
+    moreprintf("\tSBDS Chemistry      : %s\n", dmi->battery.sbds_chemistry);
+    moreprintf("\tMaximum Error       : %s\n", dmi->battery.maximum_error);
+    moreprintf("\tOEM Info            : %s\n", dmi->battery.oem_info);
+}
+
+void display_bios(s_dmi * dmi)
+{
+    moreprintf("BIOS\n");
+    moreprintf("\tVendor:   %s\n", dmi->bios.vendor);
+    moreprintf("\tVersion:  %s\n", dmi->bios.version);
+    moreprintf("\tRelease:  %s\n", dmi->bios.release_date);
+    moreprintf("\tBios Revision     %s\n", dmi->bios.bios_revision);
+    moreprintf("\tFirmware Revision %s\n", dmi->bios.firmware_revision);
+    moreprintf("\tAddress:  0x%04X0\n", dmi->bios.address);
+    moreprintf("\tRuntime address: %u %s\n", dmi->bios.runtime_size,
+	       dmi->bios.runtime_size_unit);
+    moreprintf("\tRom size: %u %s\n", dmi->bios.rom_size,
+	       dmi->bios.rom_size_unit);
+    display_bios_characteristics(dmi);
+}
+
+void display_system(s_dmi * dmi)
+{
+    moreprintf("\nSystem\n");
+    moreprintf("\tManufacturer %s\n", dmi->system.manufacturer);
+    moreprintf("\tProduct Name %s\n", dmi->system.product_name);
+    moreprintf("\tVersion      %s\n", dmi->system.version);
+    moreprintf("\tSerial       %s\n", dmi->system.serial);
+    moreprintf("\tUUID         %s\n", dmi->system.uuid);
+    moreprintf("\tWakeup Type  %s\n", dmi->system.wakeup_type);
+    moreprintf("\tSKU Number   %s\n", dmi->system.sku_number);
+    moreprintf("\tFamily       %s\n", dmi->system.family);
+}
+
+void display_base_board(s_dmi * dmi)
+{
+    moreprintf("Base board\n");
+    moreprintf("\tManufacturer %s\n", dmi->base_board.manufacturer);
+    moreprintf("\tProduct Name %s\n", dmi->base_board.product_name);
+    moreprintf("\tVersion      %s\n", dmi->base_board.version);
+    moreprintf("\tSerial       %s\n", dmi->base_board.serial);
+    moreprintf("\tAsset Tag    %s\n", dmi->base_board.asset_tag);
+    moreprintf("\tLocation     %s\n", dmi->base_board.location);
+    moreprintf("\tType         %s\n", dmi->base_board.type);
+    display_base_board_features(dmi);
+}
+
+void display_chassis(s_dmi * dmi)
+{
+    moreprintf("\nChassis\n");
+    moreprintf("\tManufacturer %s\n", dmi->chassis.manufacturer);
+    moreprintf("\tType	   %s\n", dmi->chassis.type);
+    moreprintf("\tLock	   %s\n", dmi->chassis.lock);
+    moreprintf("\tVersion      %s\n", dmi->chassis.version);
+    moreprintf("\tSerial       %s\n", dmi->chassis.serial);
+    moreprintf("\tAsset Tag    %s\n", dmi->chassis.asset_tag);
+    moreprintf("\tBoot up state %s\n", dmi->chassis.boot_up_state);
+    moreprintf("\tPower supply state %s\n", dmi->chassis.power_supply_state);
+    moreprintf("\tThermal state %s\n", dmi->chassis.thermal_state);
+    moreprintf("\tSecurity Status    %s\n", dmi->chassis.security_status);
+    moreprintf("\tOEM Information    %s\n", dmi->chassis.oem_information);
+    moreprintf("\tHeight       %u\n", dmi->chassis.height);
+    moreprintf("\tNB Power Cords     %u\n", dmi->chassis.nb_power_cords);
+}
+
+void display_cpu(s_dmi * dmi)
+{
+    moreprintf("\nCPU\n");
+    moreprintf("\tSocket Designation %s\n", dmi->processor.socket_designation);
+    moreprintf("\tType         %s\n", dmi->processor.type);
+    moreprintf("\tFamily       %s\n", dmi->processor.family);
+    moreprintf("\tManufacturer %s\n", dmi->processor.manufacturer);
+    moreprintf("\tVersion      %s\n", dmi->processor.version);
+    moreprintf("\tExternal Clock    %u\n", dmi->processor.external_clock);
+    moreprintf("\tMax Speed         %u\n", dmi->processor.max_speed);
+    moreprintf("\tCurrent Speed     %u\n", dmi->processor.current_speed);
+    moreprintf("\tCpu Type     %u\n", dmi->processor.signature.type);
+    moreprintf("\tCpu Family   %u\n", dmi->processor.signature.family);
+    moreprintf("\tCpu Model    %u\n", dmi->processor.signature.model);
+    moreprintf("\tCpu Stepping %u\n", dmi->processor.signature.stepping);
+    moreprintf("\tCpu Minor Stepping %u\n",
+	       dmi->processor.signature.minor_stepping);
+    moreprintf("\tVoltage      %d mV\n", dmi->processor.voltage_mv);
+    moreprintf("\tStatus       %s\n", dmi->processor.status);
+    moreprintf("\tUpgrade      %s\n", dmi->processor.upgrade);
+    moreprintf("\tCache L1 Handle %s\n", dmi->processor.cache1);
+    moreprintf("\tCache L2 Handle %s\n", dmi->processor.cache2);
+    moreprintf("\tCache L3 Handle %s\n", dmi->processor.cache3);
+    moreprintf("\tSerial       %s\n", dmi->processor.serial);
+    moreprintf("\tPart Number  %s\n", dmi->processor.part_number);
+    if (dmi->processor.core_count != 0)
+        moreprintf("\tCores Count   %d\n", dmi->processor.core_count);
+    if (dmi->processor.core_enabled != 0)
+        moreprintf("\tCores Enabled %d\n", dmi->processor.core_enabled);
+    if (dmi->processor.thread_count != 0)
+        moreprintf("\tThreads Count %d\n", dmi->processor.thread_count);
+    moreprintf("\tID           %s\n", dmi->processor.id);
+    display_processor_flags(dmi);
+}
+
+int main(void)
+{
+    char buffer[1024];
+    s_dmi dmi;
+
+    if (dmi_iterate(&dmi) == -ENODMITABLE) {
+	printf("No DMI Structure found\n");
+	return -1;
+    } else {
+	printf("DMI %u.%u present.\n", dmi.dmitable.major_version,
+	       dmi.dmitable.minor_version);
+	printf("%d structures occupying %d bytes.\n", dmi.dmitable.num,
+	       dmi.dmitable.len);
+	printf("DMI table at 0x%08X.\n", dmi.dmitable.base);
+    }
+
+    parse_dmitable(&dmi);
+
+    for (;;) {
+	printf
+	    ("Available commands are system, chassis, base_board, cpu, bios, memory, battery, all, exit\n");
+	printf("dmi: ");
+	fgets(buffer, sizeof buffer, stdin);
+	if (!strncmp(buffer, "exit", 4))
+	    break;
+	if (!strncmp(buffer, "system", 6))
+	    display_system(&dmi);
+	if (!strncmp(buffer, "chassis", 6))
+	    display_chassis(&dmi);
+	if (!strncmp(buffer, "base_board", 10))
+	    display_base_board(&dmi);
+	if (!strncmp(buffer, "cpu", 3))
+	    display_cpu(&dmi);
+	if (!strncmp(buffer, "bios", 4))
+	    display_bios(&dmi);
+	if (!strncmp(buffer, "memory", 6))
+	    display_memory(&dmi);
+	if (!strncmp(buffer, "battery", 7))
+	    display_battery(&dmi);
+	if (!strncmp(buffer, "all", 3)) {
+	    display_bios(&dmi);
+	    display_system(&dmi);
+	    display_chassis(&dmi);
+	    display_base_board(&dmi);
+	    display_cpu(&dmi);
+	    display_memory(&dmi);
+	    display_battery(&dmi);
+	}
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/elf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/elf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/elf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,279 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * elf.c
+ *
+ * Module to load a protected-mode ELF kernel
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+/* If we don't have this much memory for the stack, signal failure */
+#define MIN_STACK	512
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int boot_elf(void *ptr, size_t len, char **argv)
+{
+    char *cptr = ptr;
+    Elf32_Ehdr *eh = ptr;
+    Elf32_Phdr *ph;
+    unsigned int i;
+    struct syslinux_movelist *ml = NULL;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_pm_regs regs;
+    int argc;
+    addr_t argsize;
+    char **argp;
+    addr_t lstart, llen;
+    char *stack_frame = NULL;
+    addr_t stack_frame_size;
+    addr_t stack_pointer;
+    uint32_t *spp;
+    char *sfp;
+    addr_t sfa;
+
+    memset(&regs, 0, sizeof regs);
+
+    /*
+     * Note: mmap is the memory map (containing free and zeroed regions)
+     * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
+     * track ourselves which target memory ranges have already been
+     * allocated.
+     */
+
+    if (len < sizeof(Elf32_Ehdr))
+	goto bail;
+
+    /* Must be ELF, 32-bit, littleendian, version 1 */
+    if (memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6))
+	goto bail;
+
+    /* Is this a worthwhile test?  In particular x86-64 normally
+       would imply ELF64 support, which we could do as long as
+       the addresses are 32-bit addresses, and entry is 32 bits.
+       64-bit addresses would take a lot more work. */
+    if (eh->e_machine != EM_386 && eh->e_machine != EM_486 &&
+	eh->e_machine != EM_X86_64)
+	goto bail;
+
+    if (eh->e_version != EV_CURRENT)
+	goto bail;
+
+    if (eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len)
+	goto bail;
+
+    if (eh->e_phentsize < sizeof(Elf32_Phdr))
+	goto bail;
+
+    if (!eh->e_phnum)
+	goto bail;
+
+    if (eh->e_phoff + eh->e_phentsize * eh->e_phnum > len)
+	goto bail;
+
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    ph = (Elf32_Phdr *) (cptr + eh->e_phoff);
+
+    for (i = 0; i < eh->e_phnum; i++) {
+	if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) {
+	    /* This loads at p_paddr, which is arguably the correct semantics.
+	       The SysV spec says that SysV loads at p_vaddr (and thus Linux does,
+	       too); that is, however, a major brainfuckage in the spec. */
+	    addr_t addr = ph->p_paddr;
+	    addr_t msize = ph->p_memsz;
+	    addr_t dsize = min(msize, ph->p_filesz);
+
+	    dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n",
+		    addr, dsize, msize);
+
+	    if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) {
+		printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+		       addr, msize);
+		goto bail;	/* Memory region unavailable */
+	    }
+
+	    /* Mark this region as allocated in the available map */
+	    if (syslinux_add_memmap(&amap, addr, dsize, SMT_ALLOC))
+		goto bail;
+
+	    if (ph->p_filesz) {
+		/* Data present region.  Create a move entry for it. */
+		if (syslinux_add_movelist
+		    (&ml, addr, (addr_t) cptr + ph->p_offset, dsize))
+		    goto bail;
+	    }
+	    if (msize > dsize) {
+		/* Zero-filled region.  Mark as a zero region in the memory map. */
+		if (syslinux_add_memmap
+		    (&mmap, addr + dsize, msize - dsize, SMT_ZERO))
+		    goto bail;
+	    }
+	} else {
+	    /* Ignore this program header */
+	}
+
+	ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize);
+    }
+
+    /* Create the invocation record (initial stack frame) */
+
+    argsize = argc = 0;
+    for (argp = argv; *argp; argp++) {
+	dprintf("argv[%2d] = \"%s\"\n", argc, *argp);
+	argc++;
+	argsize += strlen(*argp) + 1;
+    }
+
+    /* We need the argument strings, argument pointers,
+       argc, plus four zero-word terminators. */
+    stack_frame_size = argsize + argc * sizeof(char *) + 5 * sizeof(long);
+    stack_frame_size = (stack_frame_size + 15) & ~15;
+    stack_frame = calloc(stack_frame_size, 1);
+    if (!stack_frame)
+	goto bail;
+
+    dprintf("Right before syslinux_memmap_largest()...\n");
+    syslinux_dump_memmap(amap);
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen))
+	goto bail;		/* NO free memory?! */
+
+    if (llen < stack_frame_size + MIN_STACK + 16)
+	goto bail;		/* Insufficient memory  */
+
+    /* Initial stack pointer address */
+    stack_pointer = (lstart + llen - stack_frame_size) & ~15;
+
+    dprintf("Stack frame at 0x%08x len 0x%08x\n",
+	    stack_pointer, stack_frame_size);
+
+    /* Create the stack frame.  sfp is the pointer in current memory for
+       the next argument string, sfa is the address in its final resting place.
+       spp is the pointer into the argument array in current memory. */
+    spp = (uint32_t *) stack_frame;
+    sfp = stack_frame + argc * sizeof(char *) + 5 * sizeof(long);
+    sfa = stack_pointer + argc * sizeof(char *) + 5 * sizeof(long);
+
+    *spp++ = argc;
+    for (argp = argv; *argp; argp++) {
+	int bytes = strlen(*argp) + 1;	/* Including final null */
+	*spp++ = sfa;
+	memcpy(sfp, *argp, bytes);
+	sfp += bytes;
+	sfa += bytes;
+    }
+    /* Zero fields are aready taken care of by calloc() */
+
+    /* ... and we'll want to move it into the right place... */
+#if DEBUG
+    if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size)
+	!= SMT_FREE) {
+	dprintf("Stack frame area not free (how did that happen?)!\n");
+	goto bail;		/* Memory region unavailable */
+    }
+#endif
+
+    if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC))
+	goto bail;
+
+    if (syslinux_add_movelist(&ml, stack_pointer, (addr_t) stack_frame,
+			      stack_frame_size))
+	goto bail;
+
+    memset(&regs, 0, sizeof regs);
+    regs.eip = eh->e_entry;
+    regs.esp = stack_pointer;
+
+    dprintf("Final memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Final available map:\n");
+    syslinux_dump_memmap(amap);
+
+    dprintf("Movelist:\n");
+    syslinux_dump_movelist(ml);
+
+    /* This should not return... */
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_pm(ml, mmap, 0, &regs);
+
+bail:
+    if (stack_frame)
+	free(stack_frame);
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+
+    if (argc < 2) {
+	error("Usage: elf.c32 elf_file arguments...\n");
+	return 1;
+    }
+
+    if (zloadfile(argv[1], &data, &data_len)) {
+	error("Unable to load file\n");
+	return 1;
+    }
+
+    boot_elf(data, data_len, &argv[1]);
+    error("Invalid ELF file or insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ethersel.c
+ *
+ * Search for an Ethernet card with a known PCI signature, and run
+ * the corresponding Ethernet module.
+ *
+ * To use this, set up a syslinux config file like this:
+ *
+ * PROMPT 0
+ * DEFAULT ethersel.c32
+ * # DEV [DID xxxx:yyyy[/mask]] [RID zz-zz] [SID uuuu:vvvv[/mask]] commandline
+ * # ...
+ *
+ * DID = PCI device ID
+ * RID = Revision ID (range)
+ * SID = Subsystem ID
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <sys/pci.h>
+#include <com32.h>
+#include <syslinux/boot.h>
+#include <syslinux/config.h>
+#include <dprintf.h>
+
+#define MAX_LINE 512
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+static int looking_at(const char *line, const char *kwd)
+{
+    const char *p = line;
+    const char *q = kwd;
+
+    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
+	p++;
+	q++;
+    }
+
+    if (*q)
+	return 0;		/* Didn't see the keyword */
+
+    return *p <= ' ';		/* Must be EOL or whitespace */
+}
+
+static char *get_did(char *p, uint32_t * idptr, uint32_t * maskptr)
+{
+    unsigned long vid, did, m1, m2;
+
+    *idptr = -1;
+    *maskptr = 0xffffffff;
+
+    vid = strtoul(p, &p, 16);
+    if (*p != ':')
+	return p;		/* Bogus ID */
+    did = strtoul(p + 1, &p, 16);
+
+    *idptr = (did << 16) + vid;
+
+    if (*p == '/') {
+	m1 = strtoul(p + 1, &p, 16);
+	if (*p != ':') {
+	    *maskptr = (m1 << 16) | 0xffff;
+	} else {
+	    m2 = strtoul(p + 1, &p, 16);
+	    *maskptr = (m1 << 16) | m2;
+	}
+    }
+
+    return p;
+}
+
+static char *get_rid_range(char *p, uint8_t * rid_min, uint8_t * rid_max)
+{
+    unsigned long r0, r1;
+
+    p = skipspace(p + 3);
+
+    r0 = strtoul(p, &p, 16);
+    if (*p == '-') {
+	r1 = strtoul(p + 1, &p, 16);
+    } else {
+	r1 = r0;
+    }
+
+    *rid_min = r0;
+    *rid_max = r1;
+
+    return p;
+}
+
+static struct match *parse_config(const char *filename)
+{
+    char line[MAX_LINE], *p;
+    FILE *f;
+    struct match *list = NULL;
+    struct match **ep = &list;
+    struct match *m;
+
+    if (!filename)
+	filename = syslinux_config_file();
+
+    f = fopen(filename, "r");
+    if (!f)
+	return list;
+
+    while (fgets(line, sizeof line, f)) {
+	p = skipspace(line);
+
+	if (!looking_at(p, "#"))
+	    continue;
+	p = skipspace(p + 1);
+
+	if (!looking_at(p, "dev"))
+	    continue;
+	p = skipspace(p + 3);
+
+	m = malloc(sizeof(struct match));
+	if (!m)
+	    continue;
+
+	memset(m, 0, sizeof *m);
+	m->rid_max = 0xff;
+
+	for (;;) {
+	    p = skipspace(p);
+
+	    if (looking_at(p, "did")) {
+		p = get_did(p + 3, &m->did, &m->did_mask);
+	    } else if (looking_at(p, "sid")) {
+		p = get_did(p + 3, &m->sid, &m->sid_mask);
+	    } else if (looking_at(p, "rid")) {
+		p = get_rid_range(p + 3, &m->rid_min, &m->rid_max);
+	    } else {
+		char *e;
+
+		e = strchr(p, '\n');
+		if (*e)
+		    *e = '\0';
+		e = strchr(p, '\r');
+		if (*e)
+		    *e = '\0';
+
+		m->filename = strdup(p);
+		if (!m->filename)
+		    m->did = -1;
+		break;		/* Done with this line */
+	    }
+	}
+
+	dprintf("DEV DID %08x/%08x SID %08x/%08x RID %02x-%02x CMD %s\n",
+		m->did, m->did_mask, m->sid, m->sid_mask,
+		m->rid_min, m->rid_max, m->filename);
+
+	*ep = m;
+	ep = &m->next;
+    }
+
+    return list;
+}
+
+int main(int argc, char *argv[])
+{
+    struct match *list, *match;
+    struct pci_domain *pci_domain;
+
+    pci_domain = pci_scan();
+
+    if (pci_domain) {
+	list = parse_config(argc < 2 ? NULL : argv[1]);
+
+	match = find_pci_device(pci_domain, list);
+
+	if (match)
+	    syslinux_run_command(match->filename);
+    }
+
+    /* On error, return to the command line */
+    fputs("Error: no recognized network card found!\n", stderr);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * gpxecmd.c
+ *
+ * Invoke an arbitrary gPXE command, if available.
+ */
+
+#include <alloca.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <string.h>
+
+#include <sys/gpxe.h>
+#include <syslinux/pxe_api.h>
+
+struct segoff16 {
+    uint16_t offs, seg;
+};
+
+struct s_PXENV_FILE_EXEC {
+    uint16_t Status;
+    struct segoff16 Command;
+};
+
+static void gpxecmd(const char **args)
+{
+    char *q;
+    struct s_PXENV_FILE_EXEC *fx;
+
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
+    q = (char *)(fx + 1);
+
+    fx->Status = 1;
+    fx->Command.offs = OFFS(q);
+    fx->Command.seg = SEG(q);
+
+    while (*args) {
+	q = stpcpy(q, *args);
+	*q++ = ' ';
+	args++;
+    }
+    *--q = '\0';
+
+    pxe_call(PXENV_FILE_EXEC, fx);
+
+    /* This should not return... */
+}
+
+int main(int argc, const char *argv[])
+{
+    if (argc < 2) {
+	printf("Usage: gpxecmd command...\n");
+	return 1;
+    }
+
+    if (!is_gpxe()) {
+	printf("gpxecmd: gPXE API not detected\n");
+	return 1;
+    }
+
+    gpxecmd(argv + 1);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,245 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <console.h>
+#include <errno.h>
+#include <syslinux/loadfile.h>
+
+/* Macros */
+#define ROWS_PER_PAGE 24
+#define COLS_PER_ROW 16
+#define BYTES_PER_PAGE (ROWS_PER_PAGE * COLS_PER_ROW)
+
+/* Functions declarations */
+static int usage(void);
+static void eat_stdin(void);
+static int do_page(void);
+static void hexdump(const void *memory, size_t bytes);
+
+/* Objects */
+static const char *prog_name;
+static int opt_page;
+static int opt_no_buffer;
+static int opt_extended_ascii;
+
+int main(int argc, char **argv)
+{
+    int rc;
+    const char *filename;
+    int i;
+    void *file_data;
+    size_t file_sz;
+    FILE *f;
+    size_t len;
+    const char *cur_pos;
+
+    /* Assume failure */
+    rc = EXIT_FAILURE;
+
+    /* Determine the program name, as invoked */
+    if (argc < 1 || !argv || !argv[0]) {
+	fprintf(stderr, "argc or argv failure!\n");
+	goto err_prog_name;
+    }
+    prog_name = argv[0];
+
+    /* Process arguments */
+    filename = NULL;
+    for (i = 1; i < argc; ++i) {
+	if (!argv[i]) {
+	    fprintf(stderr, "argc and argv mismatch!\n");
+	    goto err_argv;
+	}
+
+	if (!strncmp(argv[i], "--page", sizeof "--page") ||
+	    !strncmp(argv[i], "-p", sizeof "-p")) {
+	    opt_page = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--no-buffer", sizeof "--no-buffer")) {
+	    opt_no_buffer = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--extended-ascii", sizeof "--extended-ascii")) {
+	    opt_extended_ascii = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--help", sizeof "--help") ||
+	    !strncmp(argv[i], "-h", sizeof "-h") ||
+	    !strncmp(argv[i], "-?", sizeof "-?"))
+	    return usage();
+
+	/* Otherwise, interpret as a filename, but only accept one */
+	if (filename)
+	    return usage();
+	filename = argv[i];
+    }
+    if (!filename)
+	return usage();
+    fprintf(stdout, "Dumping file: %s\n", filename);
+
+    /* Either fetch the whole file, or just allocate a buffer */
+    f = NULL;
+    if (opt_no_buffer) {
+	errno = 0;
+	if (loadfile(filename, &file_data, &file_sz)) {
+	    fprintf(stderr, "Couldn't load file.  Error: %d\n", errno);
+	    goto err_file_data;
+	}
+    } else {
+	file_sz = BYTES_PER_PAGE;
+	file_data = malloc(file_sz);
+	if (!file_data) {
+	    fprintf(stderr, "Couldn't allocate file data buffer\n");
+	    goto err_file_data;
+	}
+	errno = 0;
+	f = fopen(filename, "r");
+	if (!f) {
+	    fprintf(stderr, "Couldn't open file.  Error: %d\n", errno);
+	    goto err_f;
+	}
+    }
+
+    /* Dump the data */
+    len = BYTES_PER_PAGE;
+    cur_pos = file_data;
+    do {
+	if (f) {
+	    /* Buffered */
+	    len = fread(file_data, 1, file_sz, f);
+	    cur_pos = file_data;
+	} else {
+	    /* Non-buffered */
+	    if (file_sz < len)
+		len = file_sz;
+	}
+	if (!len)
+	    break;
+
+	hexdump(cur_pos, len);
+
+	/* Pause, if requested */
+	if (opt_page) {
+	    /* The user might choose to quit */
+	    if (do_page())
+		break;
+	}
+
+	/* Reduce file_sz for non-buffered mode */
+	if (!f)
+	    file_sz -= len;
+    } while (cur_pos += len);
+
+    rc = EXIT_SUCCESS;
+
+    if (f)
+	fclose(f);
+    err_f:
+
+    free(file_data);
+    err_file_data:
+
+    err_argv:
+
+    err_prog_name:
+
+    return rc;
+}
+
+static int usage(void)
+{
+    static const char usage[] =
+	"Usage: %s [<option> [...]] <filename> [<option> [...]]\n"
+	"\n"
+	"Options: -p\n"
+	"         --page . . . . . . . Pause output every 24 lines\n"
+	"         --no-buffer . . . .  Load the entire file before dumping\n"
+	"         --extended-ascii . . Use extended ASCII chars in dump\n"
+	"         -?\n"
+	"         -h\n"
+	"         --help  . . . . . .  Display this help\n";
+
+    fprintf(stderr, usage, prog_name);
+    return EXIT_FAILURE;
+}
+
+static void eat_stdin(void)
+{
+    int i;
+
+    while (1) {
+	i = fgetc(stdin);
+	if (i == EOF || i == '\n')
+	    return;
+    }
+}
+static int do_page(void)
+{
+    int i;
+
+    while (1) {
+	fprintf(stdout, "Continue? [Y|n]: ");
+	i = fgetc(stdin);
+	switch (i) {
+	    case 'n':
+	    case 'N':
+	    eat_stdin();
+	    return 1;
+
+	    case EOF:
+	    fprintf(stderr, "No response.  Continuing...\n");
+	    /* Fall through to "yes" */
+
+	    case 'y':
+	    case 'Y':
+	    eat_stdin();
+	    case '\n':
+	    return 0;
+
+	    default:
+	    fprintf(stderr, "Invalid choice\n");
+	    eat_stdin();
+	}
+    }
+}
+
+static void hexdump(const void *memory, size_t bytes)
+{
+    const unsigned char *p, *q;
+    int i;
+ 
+    p = memory;
+    while (bytes) {
+        q = p;
+        printf("%p: ", (void *) p);
+        for (i = 0; i < 16 && bytes; ++i) {
+            printf("%02X ", *p);
+            ++p;
+            --bytes;
+          }
+        bytes += i;
+        while (i < 16) {
+            printf("XX ");
+            ++i;
+          }
+        printf("| ");
+        p = q;
+        for (i = 0; i < 16 && bytes; ++i) {
+            printf("%c", isprint(*p) && !isspace(*p) ? *p : ' ');
+            ++p;
+            --bytes;
+          }
+        while (i < 16) {
+            printf(" ");
+            ++i;
+          }
+        printf("\n");
+      }
+    return;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/host.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/host.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/host.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <netinet/in.h>
+#include <com32.h>
+#include <syslinux/pxe.h>
+
+static inline uint32_t dns_resolve(const char *hostname)
+{
+    return pxe_dns(hostname);
+}
+
+static inline void usage(const char *s)
+{
+    fprintf(stderr, "Usage: %s hostname [, hostname_1, hostname_2, ...]\n", s);
+}
+
+int main(int argc, char *argv[])
+{
+    int i;
+    uint32_t ip;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    if (argc < 2) {
+        usage(argv[0]);
+        return 1;
+    }
+
+    for (i = 1; i < argc; i++) {
+        ip = dns_resolve(argv[i]);
+        if (!ip) {
+            printf("%s not found.\n", argv[i]);
+        } else {
+            printf("%-39s %08X %u.%u.%u.%u\n", argv[i], ntohl(ip), ip & 0xFF,
+                   (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF);
+        }
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifcpu.c
+ *
+ */
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <cpuid.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+#include <com32.h>
+#include <consoles.h>
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+static void usage(void) 
+{
+ error("Run one command if system match some CPU features, another if it doesn't. \n"
+ "Usage: \n"
+ "   label ifcpu \n"
+ "       com32 ifcpu.c32 \n"
+ "       append <option> <cpu_features> -- boot_entry_1 -- boot_entry_2 \n"
+ "   label boot_entry_1 \n"
+ "   	  kernel vmlinuz_entry1 \n"
+ "	  append ... \n"
+ "   label boot_entry_2 \n"
+ "       kernel vmlinuz_entry2 \n"
+ "       append ... \n"
+ "\n"
+ "options could be :\n"
+ "   debug     : display some debugging messages \n"
+ "   dry-run   : just do the detection, don't boot \n"
+ "\n"
+ "cpu_features could be:\n"
+ "   64         : Processor is x86_64 compatible (lm cpu flag)\n"
+ "   hvm        : Processor features hardware virtualization (hvm or svm cpu flag)\n"
+ "   multicore  : Processor must be multi-core \n"
+ "   smp        : System must be multi-processor \n"
+ "   pae        : Processor features Physical Address Extension (PAE)\n"
+ "   hypervisor : Processor is running under an hypervisor\n"
+ "\n"
+ "if you want to match many cpu features, just separate them with a single space.\n");
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+#define show_bool(mybool) mybool ? "found":"not found"
+
+int main(int argc, char *argv[])
+{
+    char **args[3];
+    int i=0;
+    int n=0;
+    bool hardware_matches = true;
+    bool multicore = false;
+    bool dryrun = false;
+    bool debug = false;
+
+    s_cpu cpu;
+    console_ansi_raw();
+    detect_cpu(&cpu);
+
+    /* If no argument got passed, let's show the usage */
+    if (argc == 1) {
+	    usage();
+	    return -1;
+    }
+
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "--")) {
+	    argv[i] = NULL;
+	    args[n++] = &argv[i + 1];
+	} else if (!strcmp(argv[i], "64")) {
+	    if (debug)
+		printf(" 64bit      : %s on this system\n",
+		       show_bool(cpu.flags.lm));
+	    hardware_matches = cpu.flags.lm && hardware_matches;
+	} else if (!strcmp(argv[i], "pae")) {
+	    if (debug)
+		printf(" pae        : %s on this system\n",
+		       show_bool(cpu.flags.pae));
+	    hardware_matches = cpu.flags.pae && hardware_matches;
+	} else if (!strcmp(argv[i], "hvm")) {
+	    if (debug)
+		printf(" hvm        : %s on this system\n",
+		       show_bool((cpu.flags.vmx || cpu.flags.svm)));
+	    hardware_matches = (cpu.flags.vmx || cpu.flags.svm)
+		&& hardware_matches;
+	} else if (!strcmp(argv[i], "multicore")) {
+	    if (debug)
+		printf(" multicore  : %d cores on this system\n", cpu.num_cores);
+	    if (cpu.num_cores > 1)
+		multicore = true;
+	    hardware_matches = multicore && hardware_matches;
+	} else if (!strcmp(argv[i], "smp")) {
+	    if (debug)
+		printf(" smp        : %s on this system\n", show_bool(cpu.flags.smp));
+	    hardware_matches = cpu.flags.smp && hardware_matches;
+	} else if (!strcmp(argv[i], "hypervisor")) {
+	    if (debug)
+		printf(" hypervisor : %s on this system\n", show_bool(cpu.flags.hypervisor));
+	    hardware_matches = cpu.flags.hypervisor && hardware_matches;
+	} else if (!strcmp(argv[i], "dry-run")) {
+	    dryrun = true;
+	} else if (!strcmp(argv[i], "debug")) {
+	    debug = true;
+	}
+	if (n >= 2)
+	    break;
+    }
+    while (n < 2) {
+	args[n] = args[n - 1];
+	n++;
+    }
+    if (debug) {
+	printf("\nBooting labels are : '%s' or '%s'\n", *args[0], *args[1]);
+	printf("Hardware requirements%smatch this system, let's booting '%s'\n",
+	       hardware_matches ? " " : " doesn't ",
+	       hardware_matches ? *args[0] : *args[1]);
+	printf("Sleeping 5sec before booting\n");
+	if (!dryrun)
+	    sleep(5);
+    }
+
+    if (!dryrun)
+	boot_args(hardware_matches ? args[0] : args[1]);
+    else
+	printf("Dry-run mode, let's exiting\n");
+
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifcpu64.c
+ *
+ * Run one command if the CPU has 64-bit support, and another if it doesn't.
+ * Eventually this and other features should get folded into some kind
+ * of scripting engine.
+ *
+ * Usage:
+ *
+ *    label boot_kernel
+ *        com32 ifcpu64.c32
+ *        append boot_kernel_64 [-- boot_kernel_32pae] -- boot_kernel_32
+ *    label boot_kernel_32
+ *        kernel vmlinuz_32
+ *        append ...
+ *    label boot_kernel_64
+ *        kernel vmlinuz_64
+ *        append ...
+ */
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cpuid.h>
+#include <syslinux/boot.h>
+
+static bool __constfunc cpu_has_cpuid(void)
+{
+    return cpu_has_eflag(X86_EFLAGS_ID);
+}
+
+static bool __constfunc cpu_has_level(uint32_t level)
+{
+    uint32_t group;
+    uint32_t limit;
+
+    if (!cpu_has_cpuid())
+	return false;
+
+    group = level & 0xffff0000;
+    limit = cpuid_eax(group);
+
+    if ((limit & 0xffff0000) != group)
+	return false;
+
+    if (level > limit)
+	return false;
+
+    return true;
+}
+
+/* This only supports feature groups 0 and 1, corresponding to the
+   Intel and AMD EDX bit vectors.  We can add more later if need be. */
+static bool __constfunc cpu_has_feature(int x)
+{
+    uint32_t level = ((x & 1) << 31) | 1;
+
+    return cpu_has_level(level) && ((cpuid_edx(level) >> (x & 31) & 1));
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+int main(int argc, char *argv[])
+{
+    char **args[3];
+    int i;
+    int n;
+
+    args[0] = &argv[1];
+    n = 1;
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "--")) {
+	    argv[i] = NULL;
+	    args[n++] = &argv[i + 1];
+	}
+	if (n >= 3)
+	    break;
+    }
+    while (n < 3) {
+	args[n] = args[n - 1];
+	n++;
+    }
+
+    boot_args(cpu_has_feature(X86_FEATURE_LM) ? args[0] :
+	      cpu_has_feature(X86_FEATURE_PAE) ? args[1] : args[2]);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,392 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Shao Miller - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/****
+ * @file ifmemdsk.c
+ *
+ * This COM32 module detects if there are MEMDISKs established.
+ */
+
+static const char usage_text[] = "\
+Usage:\n\
+  ifmemdsk.c32 [<option> [...]] --info [<option> [...]]\n\
+  ifmemdsk.c32 [<option> [...]] [<detected_cmd>] -- [<not_detected_cmd>]\n\
+\n\
+Options:\n\
+  --info  . . . . . Displays info about MEMDISK(s)\n\
+  --safe-hooks . .  Will scan INT 13h \"safe hook\" chain\n\
+  --mbfts . . . . . Will scan memory for MEMDISK mBFTs\n\
+  --no-sequential   Suppresses probing all drive numbers\n\
+\n\
+If a MEMDISK is found, or if a particular MEMDISK is sought by the options\n\
+and is found, then the 'detected_cmd' action will be taken, else the\n\
+'not_detected_cmd' action will be taken.\n\
+\n";
+
+#include <stdio.h>
+#include <string.h>
+#include <alloca.h>
+#include <com32.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+/* Pull in MEMDISK common structures */
+#include "../../memdisk/mstructs.h"
+
+/*** Macros */
+#define M_GET_DRIVE_PARAMS (0x08)
+#define M_SEGOFFTOPTR(seg, off) (((seg) << 4) + (off))
+#define M_INT13H M_SEGOFFTOPTR(0x0000, 0x0013 * 4)
+#define M_FREEBASEMEM M_SEGOFFTOPTR(0x0040, 0x0013)
+#define M_TOP M_SEGOFFTOPTR(0x9FFF, 0x0000)
+
+/*** Object types */
+typedef struct mdi s_mdi;
+typedef real_addr_t u_segoff;
+typedef struct safe_hook s_safe_hook;
+typedef struct mBFT s_mbft;
+
+/*** Function types */
+typedef int f_find(void);
+
+/*** Function declarations */
+static const s_mdi * installation_check(int);
+static f_find scan_drives;
+static f_find walk_safe_hooks;
+static const s_safe_hook * is_safe_hook(const void *);
+static const s_mdi * is_memdisk_hook(const s_safe_hook *);
+static f_find scan_mbfts;
+static const s_mbft * is_mbft(const void *);
+static f_find do_nothing;
+static void memdisk_info(const s_mdi *);
+static void boot_args(char **);
+static const char * bootloadername(uint8_t);
+
+/*** Structure/union definitions */
+
+/*** Objects */
+static int show_info = 0;
+
+/*** Function definitions */
+
+int main(int argc, char ** argv) {
+    static f_find * do_scan_drives = scan_drives;
+    static f_find * do_walk_safe_hooks = do_nothing;
+    static f_find * do_scan_mbfts = do_nothing;
+    char ** detected_cmd;
+    char ** not_detected_cmd;
+    char ** cmd;
+    char ** cur_arg;
+    int show_usage;
+    int found;
+
+    (void) argc;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    detected_cmd = NULL;
+    not_detected_cmd = NULL;
+    show_usage = 1;
+    for (cur_arg = argv + 1; *cur_arg; ++cur_arg) {
+        /* Check for command divider */
+        if (!strcmp(*cur_arg, "--")) {
+            show_usage = 0;
+            *cur_arg = NULL;
+            not_detected_cmd = cur_arg + 1;
+            break;
+          }
+
+        /* Check for '--info' */
+        if (!strcmp(*cur_arg, "--info")) {
+            show_usage = 0;
+            show_info = 1;
+            continue;
+          }
+
+        /* Other options */
+        if (!strcmp(*cur_arg, "--no-sequential")) {
+            do_scan_drives = do_nothing;
+            continue;
+          }
+
+        if (!strcmp(*cur_arg, "--safe-hooks")) {
+            do_walk_safe_hooks = walk_safe_hooks;
+            continue;
+          }
+
+        if (!strcmp(*cur_arg, "--mbfts")) {
+            do_scan_mbfts = scan_mbfts;
+            continue;
+          }
+
+        /* Check for invalid option */
+        if (!memcmp(*cur_arg, "--", sizeof "--" - 1)) {
+            puts("Invalid option!");
+            show_usage = 1;
+            break;
+          }
+
+        /* Set 'detected_cmd' if it's null */
+        if (!detected_cmd)
+          detected_cmd = cur_arg;
+
+        continue;
+      }
+
+    if (show_usage) {
+        fprintf(stderr, usage_text);
+        return 1;
+      }
+
+    found = 0;
+    found += do_walk_safe_hooks();
+    found += do_scan_mbfts();
+    found += do_scan_drives();
+
+    cmd = found ? detected_cmd : not_detected_cmd;
+    if (cmd && *cmd)
+      boot_args(cmd);
+
+    return 0;
+  }
+
+static const s_mdi * installation_check(int drive) {
+    com32sys_t params, results;
+    int found;
+
+    /* Set parameters for INT 0x13 call */
+    memset(&params, 0, sizeof params);
+    params.eax.w[0] = M_GET_DRIVE_PARAMS << 8;
+    params.edx.w[0] = drive;
+    /* 'ME' 'MD' 'IS' 'K?' */
+    params.eax.w[1] = 0x454D;
+    params.ecx.w[1] = 0x444D;
+    params.edx.w[1] = 0x5349;
+    params.ebx.w[1] = 0x3F4B;
+
+    /* Perform the call */
+    __intcall(0x13, &params, &results);
+
+    /* Check result */
+    found = (
+        /* '!M' 'EM' 'DI' 'SK' */
+        results.eax.w[1] == 0x4D21 &&
+        results.ecx.w[1] == 0x4D45 &&
+        results.edx.w[1] == 0x4944 &&
+        results.ebx.w[1] == 0x4B53
+      );
+
+    if (found)
+      return MK_PTR(results.es, results.edi.w[0]);
+
+    return NULL;
+  }
+
+static int scan_drives(void) {
+    int found, drive;
+    const s_mdi * mdi;
+
+    for (found = drive = 0; drive <= 0xFF; ++drive) {
+        mdi = installation_check(drive);
+        if (!mdi)
+          continue;
+
+        memdisk_info(mdi);
+        ++found;
+        continue;
+      }
+
+    return found;
+  }
+
+static int walk_safe_hooks(void) {
+    static const u_segoff * const int13 = (void *) M_INT13H;
+    const void * addr;
+    int found;
+    const s_safe_hook * hook;
+    const s_mdi * mdi;
+
+    /* INT 0x13 vector */
+    addr = MK_PTR(int13->seg_off.segment, int13->seg_off.offset);
+    found = 0;
+    while (addr) {
+        hook = is_safe_hook(addr);
+        if (!hook)
+          break;
+
+        mdi = is_memdisk_hook(hook);
+        if (mdi) {
+            memdisk_info(mdi);
+            ++found;
+          }
+
+        addr = MK_PTR(
+            hook->old_hook.seg_off.segment,
+            hook->old_hook.seg_off.offset
+          );
+        continue;
+      }
+    return found;
+  }
+
+static const s_safe_hook * is_safe_hook(const void * addr) {
+    static const char magic[] = "$INT13SF";
+    const s_safe_hook * const test = addr;
+
+    if (memcmp(test->signature, magic, sizeof magic - 1))
+      return NULL;
+
+    return test;
+  }
+
+static const s_mdi * is_memdisk_hook(const s_safe_hook * hook) {
+    static const char magic[] = "MEMDISK";
+    const s_mbft * mbft;
+
+    if (memcmp(hook->vendor, magic, sizeof magic - 1))
+      return NULL;
+
+    /* An mBFT is always aligned */
+    mbft = MK_PTR(hook->mbft >> 4, 0);
+    return &mbft->mdi;
+  }
+
+static int scan_mbfts(void) {
+    static const uint16_t * const free_base_mem = (void *) M_FREEBASEMEM;
+    static const void * const top = (void *) M_TOP;
+    const void * addr;
+    const s_mbft * mbft;
+    int found;
+
+    found = 0;
+    for (addr = MK_PTR(*free_base_mem << 4, 0); addr < top; addr += 1 << 4) {
+        if (!(mbft = is_mbft(addr)))
+          continue;
+
+        memdisk_info(&mbft->mdi);
+        ++found;
+        continue;
+      }
+
+    return found;
+  }
+
+static const s_mbft * is_mbft(const void * addr) {
+    static const char magic[] = "mBFT";
+    const s_mbft * const test = addr;
+    const uint8_t * ptr, * end;
+    uint8_t chksum;
+
+    if (memcmp(test->acpi.signature, magic, sizeof magic - 1))
+      return NULL;
+
+    if (test->acpi.length != sizeof *test)
+      return NULL;
+
+    end = (void *) (test + 1);
+    chksum = 0;
+    for (ptr = addr; ptr < end; ++ptr)
+      chksum += *ptr;
+    if (chksum)
+      return NULL;
+
+    /* Looks like it's an mBFT! */
+    return test;
+  }
+
+static int do_nothing(void) {
+    return 0;
+  }
+
+static void memdisk_info(const s_mdi * mdi) {
+    const char * cmdline;
+
+    if (!show_info)
+      return;
+
+    cmdline = MK_PTR(
+        mdi->cmdline.seg_off.segment,
+        mdi->cmdline.seg_off.offset
+      );
+    printf(
+        "Found MEMDISK version %u.%02u:\n"
+        "  diskbuf == 0x%08X, disksize == %u sectors\n"
+        "  bootloaderid == 0x%02X (%s),\n"
+        "  cmdline: %s\n",
+        mdi->version_major,
+        mdi->version_minor,
+        mdi->diskbuf,
+        mdi->disksize,
+        mdi->bootloaderid,
+        bootloadername(mdi->bootloaderid),
+        cmdline
+      );
+    return;
+  }
+
+/* This function copyright H. Peter Anvin */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+/* This function copyright H. Peter Anvin */
+static const char *bootloadername(uint8_t id)
+{
+    static const struct {
+	uint8_t id, mask;
+	const char *name;
+    } *lp, list[] = {
+	{0x00, 0xf0, "LILO"}, 
+	{0x10, 0xf0, "LOADLIN"},
+	{0x31, 0xff, "SYSLINUX"},
+	{0x32, 0xff, "PXELINUX"},
+	{0x33, 0xff, "ISOLINUX"},
+	{0x34, 0xff, "EXTLINUX"},
+	{0x30, 0xf0, "Syslinux family"},
+	{0x40, 0xf0, "Etherboot"},
+	{0x50, 0xf0, "ELILO"},
+	{0x70, 0xf0, "GrUB"},
+	{0x80, 0xf0, "U-Boot"},
+	{0xA0, 0xf0, "Gujin"},
+	{0xB0, 0xf0, "Qemu"},
+	{0x00, 0x00, "unknown"}
+    };
+
+    for (lp = list;; lp++) {
+	if (((id ^ lp->id) & lp->mask) == 0)
+	    return lp->name;
+    }
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,168 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gert Hulselmans - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifplop.c
+ *
+ * This COM32 module detects if the PLoP Boot Manager was used to boot a CDROM
+ * drive or USB drive, by checking for the presence of the PLoP INT13h hook.
+ *
+ * Usage:    ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]
+ * Examples: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2
+ *              You need to remove the ".bin" extension of the plpbt.bin file
+ *              if you use it this way.
+ *           ifplop.c32 plop_detected -- plop_not_detected
+ *
+ * A possible config file could be:
+ *
+ * ===========================================================================
+ *  DEFAULT plopcheck
+ *
+ *  # Check for the presence of PLoP (run by default)
+ *  #   When PLoP INT13h hook is found, run the first command (plop_detected)
+ *  #   When PLoP INT13h hook isn't found, run the second command (plop_not_detected)
+ *  LABEL plopcheck
+ *      COM32 ifplop.c32
+ *      APPEND plop_detected -- plop_not_detected
+ *
+ *  # When PLoP INT13h hook was found, boot the menu system.
+ *  # PLoP can have added USB 2.0 speed, so the entries we want to boot
+ *  # will be read from disk much faster (supposing that we have a BIOS
+ *  # that only supports USB 1.1 speed, but a mobo with USB 2.0 controllers).
+ *  LABEL plop_detected
+ *      COM32 menu.c32
+ *      APPEND another.cfg
+ *
+ *  # PLoP INT13h hook wasn't found, so we boot PLoP, so it can add USB 2.0 support
+ *  # When using "LINUX plpbt.bin", you don't need to remove the .bin extension.
+ *  LABEL plop_not_detected
+ *      LINUX plpbt.bin
+ *      APPEND hiddenusb usb1=2
+ *
+ * ===========================================================================
+ *
+ * Why is/can this module be useful?
+ *
+ * You may want to boot PLoP by default from Syslinux when you boot from your
+ * USB stick/drive:
+ *   1. PLoP can upgrade USB 1.1 speed offered by the BIOS to USB 2.0 speed
+ *      if you have USB 2.0 controllers on your mobo.
+ *   2. Some BIOSes only can access the first 128GiB (137GB) on USB drives, while
+ *      internal hard drives don't necessarily suffer from this 128GiB problem.
+ *      Using PLoPs USB capabilities, you can access the whole drive.
+ *
+ * When you select the "USB" entry in PLoP, it will boot your USB stick/drive
+ * again and it will boot PLoP again when you have set booting PLoP as DEFAULT
+ * boot option in your Syslinux configuration file.
+ *
+ * By using ifplop.c32 you can specify which action you want to do the second
+ * time your USB stick/drive is booted. So you can load another config file or
+ * boot a large hard disk image or whatever you want.
+ *
+ * PLoP Boot Manager website: http://www.plop.at/en/bootmanager.html
+ */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <alloca.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+static bool plop_INT13h_check(void)
+{
+    com32sys_t inregs, outregs;
+
+    /* Prepare the register set */
+    memset(&inregs, 0, sizeof inregs);
+
+    /*
+     * Check if PLoP already has booted a CDROM or USB drive by checking
+     * for the presence of the PLoP INT13h hook.
+     *
+     * The following assembly code (NASM) can detect the PLoP INT13h hook:
+     *
+     *   mov eax,'PoLP'  ; Reverse of 'PLoP'
+     *   mov ebp,'DKHC'  ; Reverse of 'CHKD'
+     *   int 13h
+     *   cmp eax,' sey'  ; Reverse of 'yes '
+     *   jz plop_INT13h_active
+     */
+
+    inregs.eax.l = 0x504c6f50;	/* "PLoP" */
+    inregs.ebp.l = 0x43484b44;	/* "CHKD" */
+
+    __intcall(0x13, &inregs, &outregs);
+
+    /* eax will contain "yes " if PLoP INT13h hook is available */
+    if (outregs.eax.l == 0x79657320)
+	return true;
+
+    return false;
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+int main(int argc, char *argv[])
+{
+    char **args[2];
+    int arg = 0;
+
+    if (argc)
+	arg++;
+    args[0] = &argv[arg];
+    args[1] = NULL;
+    while (arg < argc) {
+	if (!strcmp(argv[arg], "--")) {
+	    argv[arg] = NULL;
+	    args[1] = &argv[arg + 1];
+	    break;
+	}
+	arg++;
+    }
+    if (args[1] != NULL) {
+	boot_args(plop_INT13h_check()? args[0] : args[1]);
+    } else {
+	fprintf(stderr,
+		"Usage:   ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]\n"
+		"Example: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2\n");
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/keyboard.h>
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int main(int argc, char *argv[])
+{
+    const struct syslinux_keyboard_map *const kmap = syslinux_keyboard_map();
+    size_t map_size;
+    void *kbdmap;
+
+    if (argc != 2) {
+	error("Usage: kbdmap mapfile\n");
+	return 1;
+    }
+
+    if (kmap->version != 1) {
+	error("Syslinux core version mismatch\n");
+	return 1;
+    }
+
+    if (loadfile(argv[1], &kbdmap, &map_size)) {
+	error("Keyboard map file load error\n");
+	return 1;
+    }
+
+    if (map_size != kmap->length) {
+	error("Keyboard map file format error\n");
+	return 1;
+    }
+
+    memcpy(kmap->map, kbdmap, map_size);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,414 @@
+/*
+ *  kempld_wdt.c - Kontron PLD watchdog driver
+ *
+ *  Copyright (c) 2010 Kontron Embedded Modules GmbH
+ *  Author: Michael Brunner <michael.brunner@kontron.com>
+ *  Author: Erwan Velu <erwan.velu@zodiacaerospace.com>
+ *
+ *  Note: From the PLD watchdog point of view timeout and pretimeout are
+ *        defined differently than in the kernel.
+ *        First the pretimeout stage runs out before the timeout stage gets
+ *        active. This has to be kept in mind.
+ *
+ *  Kernel/API:                     P-----| pretimeout
+ *                |-----------------------T timeout
+ *  Watchdog:     |-----------------P       pretimeout_stage
+ *                                  |-----T timeout_stage
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <string.h>
+#include <sys/io.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include "kontron_wdt.h"
+
+struct kempld_device_data  pld;
+struct kempld_watchdog_data wdt;
+uint8_t status;
+char default_label[255];
+
+/* Default Timeout is 60sec */
+#define TIMEOUT 60
+#define PRETIMEOUT 0
+
+#define do_div(n,base) ({ \
+		int __res; \
+		__res = ((unsigned long) n) % (unsigned) base; \
+		n = ((unsigned long) n) / (unsigned) base; \
+		__res; })
+
+
+/* Basic Wrappers to get code as less changed as possible */
+void iowrite8(uint8_t val, uint16_t addr) { outb(val,addr); }
+void iowrite16(uint16_t val, uint16_t addr) { outw(val,addr); }
+void iowrite32(uint32_t val, uint16_t addr) { outl(val,addr);}
+uint8_t ioread8(uint16_t addr)   { return inb(addr);}
+uint16_t ioread16(uint16_t addr) { return inw(addr);}
+uint32_t ioread32(uint32_t addr) { return inl(addr);}
+
+
+/**
+ * kempld_set_index -  change the current register index of the PLD
+ * @pld:   kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * This function changes the register index of the PLD.
+ */
+void kempld_set_index(struct kempld_device_data *pld, uint8_t index)
+{
+        if (pld->last_index != index) {
+                iowrite8(index, pld->io_index);
+                pld->last_index = index;
+        }
+}
+
+
+uint8_t kempld_read8(struct kempld_device_data *pld, uint8_t index) {
+        kempld_set_index(pld, index);
+        return ioread8(pld->io_data);
+}
+
+
+void kempld_write8(struct kempld_device_data *pld, uint8_t index, uint8_t data) {
+        kempld_set_index(pld, index);
+        iowrite8(data, pld->io_data);
+}
+
+
+uint16_t kempld_read16(struct kempld_device_data *pld, uint8_t index)
+{
+        return kempld_read8(pld, index) | kempld_read8(pld, index+1) << 8;
+}
+
+
+void kempld_write16(struct kempld_device_data *pld, uint8_t index, uint16_t data)
+{
+        kempld_write8(pld, index, (uint8_t)data);
+        kempld_write8(pld, index+1, (uint8_t)(data>>8));
+}
+
+uint32_t kempld_read32(struct kempld_device_data *pld, uint8_t index)
+{
+        return kempld_read16(pld, index) | kempld_read16(pld, index+2) << 16;
+}
+
+void kempld_write32(struct kempld_device_data *pld, uint8_t index, uint32_t data)
+{
+        kempld_write16(pld, index, (uint16_t)data);
+        kempld_write16(pld, index+2, (uint16_t)(data>>16));
+}
+
+static void kempld_release_mutex(struct kempld_device_data *pld)
+{
+        iowrite8(pld->last_index | KEMPLD_MUTEX_KEY, pld->io_index);
+}
+
+void init_structure(void) {
+	/* set default values for the case we start the watchdog or change
+	 * the configuration */
+	memset(&wdt,0,sizeof(wdt));
+	memset(&pld,0,sizeof(pld));
+	memset(&default_label,0,sizeof(default_label));
+        wdt.timeout = TIMEOUT;
+        wdt.pretimeout = PRETIMEOUT;
+        wdt.pld = &pld;
+
+	pld.io_base=KEMPLD_IOPORT;
+	pld.io_index=KEMPLD_IOPORT;
+	pld.io_data=KEMPLD_IODATA;
+	pld.pld_clock=33333333;
+}
+
+static int kempld_probe(void) {
+   /* Check for empty IO space */
+	int ret=0;
+	uint8_t  index_reg = ioread8(pld.io_index);
+        if ((index_reg == 0xff) && (ioread8(pld.io_data) == 0xff)) {
+                ret = 1;
+                goto err_empty_io;
+        }
+	printf("Kempld structure found at 0x%X (data @ 0x%X)\n",pld.io_base,pld.io_data);
+	return 0;
+
+err_empty_io:
+	printf("No IO Found !\n");
+	return ret;
+}
+
+static int kempld_wdt_probe_stages(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        int i, ret;
+        uint32_t timeout;
+        uint32_t timeout_mask;
+        struct kempld_watchdog_stage *stage;
+
+        wdt->stages = 0;
+        wdt->timeout_stage = NULL;
+        wdt->pretimeout_stage = NULL;
+
+        for (i = 0; i < KEMPLD_WDT_MAX_STAGES; i++) {
+
+		timeout = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+                kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), 0x00000000);
+                timeout_mask = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+                kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), timeout);
+
+                if (timeout_mask != 0xffffffff) {
+                        stage = malloc(sizeof(struct kempld_watchdog_stage));
+                        if (stage == NULL) {
+                                ret = -1;
+                                goto err_alloc_stages;
+                        }
+                        stage->num = i;
+                        stage->timeout_mask = ~timeout_mask;
+                        wdt->stage[i] = stage;
+                        wdt->stages++;
+
+                        /* assign available stages to timeout and pretimeout */
+                        if (wdt->stages == 1)
+                                wdt->timeout_stage = stage;
+                        else if (wdt->stages == 2) {
+                                wdt->pretimeout_stage = wdt->timeout_stage;
+                                wdt->timeout_stage = stage;
+                        }
+                } else {
+                        wdt->stage[i] = NULL;
+                }
+        }
+
+        return 0;
+err_alloc_stages:
+	kempld_release_mutex(pld);
+	printf("Cannot allocate stages\n");
+	return ret;
+}
+
+static int kempld_wdt_keepalive(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+
+	kempld_write8(pld, KEMPLD_WDT_KICK, 'K');
+
+        return 0;
+}
+
+static int kempld_wdt_setstageaction(struct kempld_watchdog_data *wdt,
+                                 struct kempld_watchdog_stage *stage,
+                                 int action)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t stage_cfg;
+
+        if (stage == NULL)
+                return -1;
+
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+        stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ACTION_MASK;
+        stage_cfg |= (action & KEMPLD_WDT_STAGE_CFG_ACTION_MASK);
+        if (action == KEMPLD_WDT_ACTION_RESET)
+                stage_cfg |= KEMPLD_WDT_STAGE_CFG_ASSERT;
+        else
+                stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ASSERT;
+
+        kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+
+        return 0;
+}
+
+static int kempld_wdt_setstagetimeout(struct kempld_watchdog_data *wdt,
+                                 struct kempld_watchdog_stage *stage,
+                                 int timeout)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t stage_cfg;
+        uint8_t prescaler;
+        uint64_t stage_timeout64;
+        uint32_t stage_timeout;
+
+        if (stage == NULL)
+                return -1;
+
+        prescaler = KEMPLD_WDT_PRESCALER_21BIT;
+
+        stage_timeout64 = ((uint64_t)timeout*pld->pld_clock);
+        do_div(stage_timeout64, KEMPLD_PRESCALER(prescaler));
+        stage_timeout = stage_timeout64 & stage->timeout_mask;
+
+        if (stage_timeout64 != (uint64_t)stage_timeout)
+                return -1;
+
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+        stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK;
+        stage_cfg |= KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(prescaler);
+        kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+        kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->num),
+                       stage_timeout);
+
+        return 0;
+}
+
+
+static int kempld_wdt_settimeout(struct kempld_watchdog_data *wdt)
+{
+        int stage_timeout;
+        int stage_pretimeout;
+        int ret;
+        if ((wdt->timeout <= 0) ||
+            (wdt->pretimeout < 0) ||
+            (wdt->pretimeout > wdt->timeout)) {
+                ret = -1;
+                goto err_check_values;
+        }
+
+        if ((wdt->pretimeout == 0) || (wdt->pretimeout_stage == NULL)) {
+                if (wdt->pretimeout != 0)
+                        printf("No pretimeout stage available, only enabling reset!\n");
+                stage_pretimeout = 0;
+                stage_timeout =  wdt->timeout;
+        } else {
+                stage_pretimeout = wdt->timeout - wdt->pretimeout;
+                stage_timeout =  wdt->pretimeout;
+        }
+
+        if (stage_pretimeout != 0) {
+                ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+                                                KEMPLD_WDT_ACTION_NMI);
+        } else if ((stage_pretimeout == 0)
+                   && (wdt->pretimeout_stage != NULL)) {
+                ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+                                                KEMPLD_WDT_ACTION_NONE);
+        } else
+                ret = 0;
+        if (ret)
+                goto err_setstage;
+
+        if (stage_pretimeout != 0) {
+                ret = kempld_wdt_setstagetimeout(wdt, wdt->pretimeout_stage,
+                                                 stage_pretimeout);
+                if (ret)
+                        goto err_setstage;
+        }
+
+        ret = kempld_wdt_setstageaction(wdt, wdt->timeout_stage,
+                                        KEMPLD_WDT_ACTION_RESET);
+        if (ret)
+                goto err_setstage;
+
+        ret = kempld_wdt_setstagetimeout(wdt, wdt->timeout_stage,
+                                         stage_timeout);
+        if (ret)
+                goto err_setstage;
+
+        return 0;
+err_setstage:
+err_check_values:
+        return ret;
+}
+
+static int kempld_wdt_start(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t status;
+
+        status = kempld_read8(pld, KEMPLD_WDT_CFG);
+        status |= KEMPLD_WDT_CFG_ENABLE;
+        kempld_write8(pld, KEMPLD_WDT_CFG, status);
+        status = kempld_read8(pld, KEMPLD_WDT_CFG);
+
+        /* check if the watchdog was enabled */
+        if (!(status & KEMPLD_WDT_CFG_ENABLE))
+                return -1;
+
+        return 0;
+}
+
+/* A regular configuration file looks like
+
+   LABEL WDT
+       COM32 wdt.c32
+       APPEND timeout=120 default_label=local
+*/
+void detect_parameters(const int argc, const char *argv[]) {
+	for (int i = 1; i < argc; i++) {
+		/* Override the timeout if specified on the cmdline */
+		if (!strncmp(argv[i], "timeout=", 8)) {
+			wdt.timeout=atoi(argv[i]+8);
+		} else
+		/* Define which boot entry shall be used */
+		if (!strncmp(argv[i], "default_label=", 14)) {
+			strlcpy(default_label, argv[i] + 14, sizeof(default_label));
+		}
+	}
+}
+
+int main(int argc, const char *argv[]) {
+	int ret=0;
+	openconsole(&dev_rawcon_r, &dev_stdcon_w);
+	init_structure();
+	detect_parameters(argc,argv);
+	kempld_probe();
+
+        /* probe how many usable stages we have */
+        if (kempld_wdt_probe_stages(&wdt)) {
+		printf("Cannot Probe Stages\n");
+		return -1;
+	}
+
+	/* Useless but who knows */
+	wdt.ident.firmware_version = KEMPLD_WDT_REV_GET(kempld_read8(&pld, KEMPLD_WDT_REV));
+
+        status = kempld_read8(&pld, KEMPLD_WDT_CFG);
+	/* kick the watchdog if it is already enabled, otherwise start it */
+        if (status & KEMPLD_WDT_CFG_ENABLE) {
+		/* Maybye the BIOS did setup a first timer
+		 * in this case, let's enforce the timeout
+		 * to be sure we do have the proper value */
+		kempld_wdt_settimeout(&wdt);
+                kempld_wdt_keepalive(&wdt);
+        } else {
+		ret = kempld_wdt_settimeout(&wdt);
+                if (ret) {
+			printf("Unable to setup timeout !\n");
+			goto booting;
+		}
+
+		ret = kempld_wdt_start(&wdt);
+                if (ret) {
+			printf("Unable to start watchdog !\n");
+			goto booting;
+		}
+
+        }
+
+	printf("Watchog armed ! Rebooting in %d seconds if no feed occurs !\n",wdt.timeout);
+
+booting:
+	/* Release Mutex to let Linux's Driver taking control */
+        kempld_release_mutex(&pld);
+
+	/* Let's boot the default entry if specified */
+	if (strlen(default_label)>0) {
+		printf("Executing default label = '%s'\n",default_label);
+		syslinux_run_command(default_label);
+	} else {
+		return ret;
+	}
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,117 @@
+/*
+ *  kempld_wdt.h - Kontron PLD watchdog driver definitions
+ *
+ *  Copyright (c) 2010 Kontron Embedded Modules GmbH
+ *  Author: Michael Brunner <michael.brunner@kontron.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _KEMPLD_WDT_H_
+#define _KEMPLD_WDT_H_
+#include <stdint.h>
+
+#define KEMPLD_IOPORT 0x0a80
+#define KEMPLD_IODATA (KEMPLD_IOPORT+1)
+
+#define KEMPLD_MUTEX_KEY	0x80
+
+/* watchdog register definitions */
+#define KEMPLD_WDT_KICK                 0x16
+#define KEMPLD_WDT_REV                  0x16
+#define         KEMPLD_WDT_REV_GET(x)                   (x & 0xf)
+#define KEMPLD_WDT_CFG                  0x17
+#define         KEMPLD_WDT_CFG_STAGE_TIMEOUT_OCCURED(x) (1<<x)
+#define         KEMPLD_WDT_CFG_ENABLE_LOCK              0x8
+#define         KEMPLD_WDT_CFG_ENABLE                   0x10
+#define         KEMPLD_WDT_CFG_AUTO_RELOAD              0x40
+#define         KEMPLD_WDT_CFG_GLOBAL_LOCK              0x80
+#define KEMPLD_WDT_STAGE_CFG(x)         (0x18+x)
+#define         KEMPLD_WDT_STAGE_CFG_ACTION_MASK        0x7
+#define         KEMPLD_WDT_STAGE_CFG_GET_ACTION(x)      (x & 0x7)
+#define         KEMPLD_WDT_STAGE_CFG_ASSERT             0x8
+#define         KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK     0x30
+#define         KEMPLD_WDT_STAGE_CFG_GET_PRESCALER(x)   ((x & 0x30)>>4)
+#define         KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(x)   ((x & 0x30)<<4)
+#define KEMPLD_WDT_STAGE_TIMEOUT(x)     (0x1b+x*4)
+#define KEMPLD_WDT_MAX_STAGES           3
+
+#define KEMPLD_WDT_ACTION_NONE          0x0
+#define KEMPLD_WDT_ACTION_RESET         0x1
+#define KEMPLD_WDT_ACTION_NMI           0x2
+#define KEMPLD_WDT_ACTION_SMI           0x3
+#define KEMPLD_WDT_ACTION_SCI           0x4
+#define KEMPLD_WDT_ACTION_DELAY         0x5
+
+#define KEMPLD_WDT_PRESCALER_21BIT      0x0
+#define KEMPLD_WDT_PRESCALER_17BIT      0x1
+#define KEMPLD_WDT_PRESCALER_12BIT      0x2
+
+const int kempld_prescaler_bits[] = { 21, 17, 12 };
+
+struct kempld_watchdog_stage {
+        int     num;
+        uint32_t     timeout_mask;
+};
+
+/**
+ * struct kempld_device_data - Internal representation of the PLD device
+ * @io_base:            Pointer to the IO memory
+ * @io_index:           Pointer to the IO index register
+ * @io_data:            Pointer to the IO data register
+ * @pld_clock:          PLD clock frequency
+ * @lock:               PLD spin-lock
+ * @lock_flags:         PLD spin-lock flags
+ * @have_mutex:         Bool value that indicates if mutex is aquired
+ * @last_index:         Last written index value
+ * @rscr:               Kernel resource structure
+ * @dev:                Pointer to kernel device structure
+ * @info:               KEMPLD info structure
+ */
+struct kempld_device_data {
+        uint16_t 	        io_base;
+        uint16_t		io_index;
+        uint16_t		io_data;
+        uint32_t		 pld_clock;
+/*        spinlock_t              lock;
+        unsigned long           lock_flags; */
+        int                     have_mutex;
+        uint8_t			last_index;
+/*        struct resource         rscr;
+        struct device           *dev;
+        struct kempld_info      info;*/
+};
+
+struct watchdog_info {
+	uint32_t options;          /* Options the card/driver supports */
+	uint32_t firmware_version; /* Firmware version of the card */
+	uint8_t  identity[32];     /* Identity of the board */
+};
+
+struct kempld_watchdog_data {
+        unsigned int                    revision;
+        int                             timeout;
+        int                             pretimeout;
+        unsigned long                   is_open;
+        unsigned long                   expect_close;
+        int                             stages;
+        struct kempld_watchdog_stage    *timeout_stage;
+        struct kempld_watchdog_stage    *pretimeout_stage;
+        struct kempld_device_data       *pld;
+        struct kempld_watchdog_stage    *stage[KEMPLD_WDT_MAX_STAGES];
+	struct watchdog_info		ident;
+};
+
+#endif /* _KEMPLD_WDT_H_ */
+#define KEMPLD_PRESCALER(x)     (0xffffffff>>(32-kempld_prescaler_bits[x]))
Index: bootcd/isolinux/syslinux-6.03/com32/modules/linux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,415 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2012 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * linux.c
+ *
+ * Sample module to load Linux kernels.  This module can also create
+ * a file out of the DHCP return data if running under PXELINUX.
+ *
+ * If -dhcpinfo is specified, the DHCP info is written into the file
+ * /dhcpinfo.dat in the initramfs.
+ *
+ * Usage: linux.c32 [-dhcpinfo] kernel arguments...
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+#include <syslinux/pxe.h>
+
+enum ldmode {
+    ldmode_raw,
+    ldmode_cpio,
+    ldmodes
+};
+
+typedef int f_ldinitramfs(struct initramfs *, char *);
+
+const char *progname = "linux.c32";
+
+/* Find the last instance of a particular command line argument
+   (which should include the final =; do not use for boolean arguments) */
+static char *find_argument(char **argv, const char *argument)
+{
+    int la = strlen(argument);
+    char **arg;
+    char *ptr = NULL;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strncmp(*arg, argument, la))
+	    ptr = *arg + la;
+    }
+
+    return ptr;
+}
+
+/* Find the next instance of a particular command line argument */
+static char **find_arguments(char **argv, char **ptr,
+			     const char *argument)
+{
+    int la = strlen(argument);
+    char **arg;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strncmp(*arg, argument, la)) {
+	    *ptr = *arg + la;
+	    break;
+	}
+    }
+
+    /* Exhausted all arguments */
+    if (!*arg)
+	return NULL;
+
+    return arg;
+}
+
+/* Search for a boolean argument; return its position, or 0 if not present */
+static int find_boolean(char **argv, const char *argument)
+{
+    char **arg;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strcmp(*arg, argument))
+	    return (arg - argv) + 1;
+    }
+
+    return 0;
+}
+
+/* Stitch together the command line from a set of argv's */
+static char *make_cmdline(char **argv)
+{
+    char **arg;
+    size_t bytes;
+    char *cmdline, *p;
+
+    bytes = 1;			/* Just in case we have a zero-entry cmdline */
+    for (arg = argv; *arg; arg++) {
+	bytes += strlen(*arg) + 1;
+    }
+
+    p = cmdline = malloc(bytes);
+    if (!cmdline)
+	return NULL;
+
+    for (arg = argv; *arg; arg++) {
+	int len = strlen(*arg);
+	memcpy(p, *arg, len);
+	p[len] = ' ';
+	p += len + 1;
+    }
+
+    if (p > cmdline)
+	p--;			/* Remove the last space */
+    *p = '\0';
+
+    return cmdline;
+}
+
+static f_ldinitramfs ldinitramfs_raw;
+static int ldinitramfs_raw(struct initramfs *initramfs, char *fname)
+{
+    return initramfs_load_archive(initramfs, fname);
+}
+
+static f_ldinitramfs ldinitramfs_cpio;
+static int ldinitramfs_cpio(struct initramfs *initramfs, char *fname)
+{
+    char *target_fname, *p;
+    int do_mkdir, unmangle, rc;
+
+    /* Choose target_fname based on presence of "@" syntax */
+    target_fname = strchr(fname, '@');
+    if (target_fname) {
+	/* Temporarily mangle */
+	unmangle = 1;
+	*target_fname++ = '\0';
+
+	/* Make parent directories? */
+	do_mkdir = !!strchr(target_fname, '/');
+    } else {
+	unmangle = 0;
+
+	/* Forget the source path */
+	target_fname = fname;
+	while ((p = strchr(target_fname, '/')))
+	    target_fname = p + 1;
+
+	/* The user didn't specify a desired path */
+	do_mkdir = 0;
+    }
+
+    /*
+     * Load the file, encapsulate it with the desired path, make the
+     * parent directories if the desired path contains them, add to initramfs
+     */
+    rc = initramfs_load_file(initramfs, fname, target_fname, do_mkdir, 0755);
+
+    /* Unmangle, if needed*/
+    if (unmangle)
+	*--target_fname = '@';
+
+    return rc;
+}
+
+/* It only makes sense to call this function from main */
+static int process_initramfs_args(char *arg, struct initramfs *initramfs,
+				  const char *kernel_name, enum ldmode mode,
+				  bool opt_quiet)
+{
+    const char *mode_msg;
+    f_ldinitramfs *ldinitramfs;
+    char *p;
+
+    switch (mode) {
+    case ldmode_raw:
+	mode_msg = "Loading";
+	ldinitramfs = ldinitramfs_raw;
+	break;
+    case ldmode_cpio:
+	mode_msg = "Encapsulating";
+	ldinitramfs = ldinitramfs_cpio;
+	break;
+    case ldmodes:
+    default:
+	return 1;
+    }
+
+    do {
+	p = strchr(arg, ',');
+	if (p)
+	    *p = '\0';
+
+	if (!opt_quiet)
+	    printf("%s %s... ", mode_msg, arg);
+	errno = 0;
+	if (ldinitramfs(initramfs, arg)) {
+	    if (opt_quiet)
+		printf("Loading %s ", kernel_name);
+	    printf("failed: ");
+	    return 1;
+	}
+	if (!opt_quiet)
+	    printf("ok\n");
+
+	if (p)
+	    *p++ = ',';
+    } while ((arg = p));
+
+    return 0;
+}
+
+static int setup_data_file(struct setup_data *setup_data,
+			   uint32_t type, const char *filename,
+			   bool opt_quiet)
+{
+    if (!opt_quiet)
+	printf("Loading %s... ", filename);
+
+    if (setup_data_load(setup_data, type, filename)) {
+	if (opt_quiet)
+	    printf("Loading %s ", filename);
+	printf("failed\n");
+	return -1;
+    }
+	    
+    if (!opt_quiet)
+	printf("ok\n");
+    
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    const char *kernel_name;
+    struct initramfs *initramfs;
+    struct setup_data *setup_data;
+    char *cmdline;
+    char *boot_image;
+    void *kernel_data;
+    size_t kernel_len;
+    bool opt_dhcpinfo = false;
+    bool opt_quiet = false;
+    void *dhcpdata;
+    size_t dhcplen;
+    char **argp, **argl, *arg;
+
+    (void)argc;
+    argp = argv + 1;
+
+    while ((arg = *argp) && arg[0] == '-') {
+	if (!strcmp("-dhcpinfo", arg)) {
+	    opt_dhcpinfo = true;
+	} else {
+	    fprintf(stderr, "%s: unknown option: %s\n", progname, arg);
+	    return 1;
+	}
+	argp++;
+    }
+
+    if (!arg) {
+	fprintf(stderr, "%s: missing kernel name\n", progname);
+	return 1;
+    }
+
+    kernel_name = arg;
+
+    errno = 0;
+    boot_image = malloc(strlen(kernel_name) + 12);
+    if (!boot_image) {
+	fprintf(stderr, "Error allocating BOOT_IMAGE string: ");
+	goto bail;
+    }
+    strcpy(boot_image, "BOOT_IMAGE=");
+    strcpy(boot_image + 11, kernel_name);
+    /* argp now points to the kernel name, and the command line follows.
+       Overwrite the kernel name with the BOOT_IMAGE= argument, and thus
+       we have the final argument. */
+    *argp = boot_image;
+
+    if (find_boolean(argp, "quiet"))
+	opt_quiet = true;
+
+    if (!opt_quiet)
+	printf("Loading %s... ", kernel_name);
+    errno = 0;
+    if (loadfile(kernel_name, &kernel_data, &kernel_len)) {
+	if (opt_quiet)
+	    printf("Loading %s ", kernel_name);
+	printf("failed: ");
+	goto bail;
+    }
+    if (!opt_quiet)
+	printf("ok\n");
+
+    errno = 0;
+    cmdline = make_cmdline(argp);
+    if (!cmdline) {
+	fprintf(stderr, "make_cmdline() failed: ");
+	goto bail;
+    }
+
+    /* Initialize the initramfs chain */
+    errno = 0;
+    initramfs = initramfs_init();
+    if (!initramfs) {
+	fprintf(stderr, "initramfs_init() failed: ");
+	goto bail;
+    }
+
+    /* Process initramfs arguments */
+    if ((arg = find_argument(argp, "initrd="))) {
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "initrd+="))) {
+	argl++;
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "initrdfile="))) {
+	argl++;
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_cpio,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    /* Append the DHCP info */
+    if (opt_dhcpinfo &&
+	!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	errno = 0;
+	if (initramfs_add_file(initramfs, dhcpdata, dhcplen, dhcplen,
+			       "/dhcpinfo.dat", 0, 0755)) {
+	    fprintf(stderr, "Unable to add DHCP info: ");
+	    goto bail;
+	}
+    }
+
+    /* Handle dtb and eventually other setup data */
+    setup_data = setup_data_init();
+    if (!setup_data)
+	goto bail;
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "dtb="))) {
+	argl++;
+	if (setup_data_file(setup_data, SETUP_DTB, arg, opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "blob."))) {
+	uint32_t type;
+	char *ep;
+
+	argl++;
+	type = strtoul(arg, &ep, 10);
+	if (ep[0] != '=' || !ep[1])
+	    continue;
+
+	if (!type)
+	    continue;
+
+	if (setup_data_file(setup_data, type, ep+1, opt_quiet))
+	    goto bail;
+    }
+
+    /* This should not return... */
+    errno = 0;
+    syslinux_boot_linux(kernel_data, kernel_len, initramfs,
+			setup_data, cmdline);
+    fprintf(stderr, "syslinux_boot_linux() failed: ");
+
+bail:
+    switch(errno) {
+    case ENOENT:
+	fprintf(stderr, "File not found\n");
+	break;
+    case ENOMEM:
+	fprintf(stderr, "Out of memory\n");
+	break;
+    default:
+	fprintf(stderr, "Error %d\n", errno);
+	break;
+    }
+    fprintf(stderr, "%s: Boot aborted!\n", progname);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ls.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ls.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ls.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <dirent.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <getkey.h>
+
+static int rows, cols;		/* Screen parameters */
+
+#define DIR_CHUNK	1024
+
+static const char *type_str(int type)
+{
+    switch (type) {
+    case DT_FIFO:
+	return "[fif]";
+    case DT_CHR:
+	return "[chr]";
+    case DT_DIR:
+	return "[dir]";
+    case DT_BLK:
+	return "[blk]";
+    case DT_UNKNOWN:
+    case DT_REG:
+	return "";
+    case DT_LNK:
+	return "[lnk]";
+    case DT_SOCK:
+	return "[sck]";
+    case DT_WHT:
+	return "[wht]";
+    default:
+	return "[???]";
+    }
+}
+
+static void free_dirents(struct dirent **dex, size_t n_de)
+{
+    size_t i;
+
+    for (i = 0; i < n_de; i++)
+	free(dex[i]);
+
+    free(dex);
+}
+
+static int compare_dirent(const void *p_de1, const void *p_de2)
+{
+    const struct dirent *de1 = *(const struct dirent **)p_de1;
+    const struct dirent *de2 = *(const struct dirent **)p_de2;
+    int ndir1, ndir2;
+
+    ndir1 = de1->d_type != DT_DIR;
+    ndir2 = de2->d_type != DT_DIR;
+
+    if (ndir1 != ndir2)
+	return ndir1 - ndir2;
+
+    return strcmp(de1->d_name, de2->d_name);
+}
+
+static int display_directory(const char *dirname)
+{
+    DIR *dir;
+    struct dirent *de;
+    struct dirent **dex = NULL;
+    size_t n_dex = 0, n_de = 0;
+    size_t i, j, k;
+    size_t nrows, ncols, perpage;
+    size_t endpage;
+    int maxlen = 0;
+    int pos, tpos, colwidth;
+
+    dir = opendir(dirname);
+    if (!dir) {
+	printf("Unable to read directory: %s\n", dirname);
+	return -1;
+    }
+
+    while ((de = readdir(dir)) != NULL) {
+	struct dirent *nde;
+
+	if (n_de >= n_dex) {
+	    struct dirent **ndex;
+
+	    ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
+	    if (!ndex)
+		goto nomem;
+
+	    dex = ndex;
+	    n_dex += DIR_CHUNK;
+	}
+
+	nde = malloc(de->d_reclen);
+	if (!nde)
+	    goto nomem;
+
+	memcpy(nde, de, de->d_reclen);
+	dex[n_de++] = nde;
+
+	maxlen = max(maxlen, de->d_reclen);
+    }
+
+    closedir(dir);
+
+    qsort(dex, n_de, sizeof *dex, compare_dirent);
+
+    maxlen -= offsetof(struct dirent, d_name) + 1;
+    ncols = (cols + 2)/(maxlen + 8);
+    ncols = min(ncols, n_de);
+    ncols = max(ncols, 1U);
+    colwidth = (cols + 2)/ncols;
+    perpage = ncols * (rows - 1);
+
+    for (i = 0; i < n_de; i += perpage) {
+	/* Rows on this page */
+	endpage = min(i+perpage, n_de);
+	nrows = ((endpage-i) + ncols - 1)/ncols;
+
+	for (j = 0; j < nrows; j++) {
+	    pos = tpos = 0;
+	    for (k = i+j; k < endpage; k += nrows) {
+		pos += printf("%*s%-5s %s",
+			      (tpos - pos), "",
+			      type_str(dex[k]->d_type),
+			      dex[k]->d_name);
+		tpos += colwidth;
+	    }
+	    printf("\n");
+	}
+
+	if (endpage >= n_de)
+	    break;
+
+	get_key(stdin, 0);
+    }
+
+    free_dirents(dex, n_de);
+    return 0;
+
+nomem:
+    closedir(dir);
+    printf("Out of memory error!\n");
+    free_dirents(dex, n_de);
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv;
+
+    if (getscreensize(1, &rows, &cols)) {
+	/* Unknown screen size? */
+	rows = 24;
+	cols = 80;
+    }
+
+    if (argc < 2)
+	rv = display_directory(".");
+    else if (argc == 2)
+	rv = display_directory(argv[1]);
+    else {
+	printf("Usage: %s directory\n", argv[0]);
+	rv = 1;
+    }
+
+    return rv ? 1 : 0;
+}
+ 
Index: bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * meminfo.c
+ *
+ * Dump the memory map of the system
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+
+struct e820_data {
+    uint64_t base;
+    uint64_t len;
+    uint32_t type;
+    uint32_t extattr;
+} __attribute__ ((packed));
+
+static const char *const e820_types[] = {
+    "usable",
+    "reserved",
+    "ACPI reclaim",
+    "ACPI NVS",
+    "unusable",
+};
+
+static void dump_e820(void)
+{
+    com32sys_t ireg, oreg;
+    struct e820_data ed;
+    uint32_t type;
+    void *low_ed;
+
+    low_ed = lmalloc(sizeof ed);
+    if (!low_ed)
+	return;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0xe820;
+    ireg.edx.l = 0x534d4150;
+    ireg.ecx.l = sizeof(struct e820_data);
+    ireg.edi.w[0] = OFFS(low_ed);
+    ireg.es = SEG(low_ed);
+
+    memset(&ed, 0, sizeof ed);
+    ed.extattr = 1;
+
+    do {
+	memcpy(low_ed, &ed, sizeof ed);
+
+	__intcall(0x15, &ireg, &oreg);
+	if (oreg.eflags.l & EFLAGS_CF ||
+	    oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
+	    break;
+
+	memcpy(&ed, low_ed, sizeof ed);
+
+	if (oreg.ecx.l >= 24) {
+	    /* ebx base length end type */
+	    printf("%8x %016llx %016llx %016llx %d [%x]",
+		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
+		   ed.extattr);
+	} else {
+	    /* ebx base length end */
+	    printf("%8x %016llx %016llx %016llx %d [-]",
+		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
+	    ed.extattr = 1;
+	}
+
+	type = ed.type - 1;
+	if (type < sizeof(e820_types) / sizeof(e820_types[0]))
+	    printf(" %s", e820_types[type]);
+
+	putchar('\n');
+
+	ireg.ebx.l = oreg.ebx.l;
+    } while (ireg.ebx.l);
+
+    lfree(low_ed);
+}
+
+static void dump_legacy(void)
+{
+    com32sys_t ireg, oreg;
+    uint16_t dosram = *(uint16_t *) 0x413;
+    struct {
+	uint16_t offs, seg;
+    } *const ivt = (void *)0;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    __intcall(0x12, &ireg, &oreg);
+
+    printf
+	("INT 15h = %04x:%04x  DOS RAM: %dK (0x%05x)  INT 12h: %dK (0x%05x)\n",
+	 ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0],
+	 oreg.eax.w[0] << 10);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[1] = 0x88;
+    __intcall(0x15, &ireg, &oreg);
+
+    printf("INT 15 88: 0x%04x (%uK)  ", oreg.eax.w[0], oreg.eax.w[0]);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0xe801;
+    __intcall(0x15, &ireg, &oreg);
+
+    printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
+	   oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
+}
+
+int main(int argc __unused, char **argv __unused)
+{
+    dump_legacy();
+    dump_e820();
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,151 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * pcitest.c
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <sys/pci.h>
+#include <stdbool.h>
+#include <dprintf.h>
+
+char display_line = 0;
+#define moreprintf(...)				\
+  do {						\
+    display_line++;				\
+    if (display_line == 24) {			\
+      char tempbuf[10];				\
+      display_line=0;				\
+      printf("Press Enter to continue\n");	\
+      fgets(tempbuf, sizeof tempbuf, stdin);	\
+    }						\
+    printf ( __VA_ARGS__);			\
+  } while (0);
+
+void display_pci_devices(struct pci_domain *pci_domain)
+{
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    for_each_pci_func(pci_device, pci_domain) {
+
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+/*	printf("PCI: found %d kernel modules for  %04x:%04x[%04x:%04x]\n",
+		  pci_device->dev_info->linux_kernel_module_count,
+		  pci_device->vendor, pci_device->product,
+		  pci_device->sub_vendor, pci_device->sub_product);
+*/
+	for (int i = 0; i < pci_device->dev_info->linux_kernel_module_count;
+	     i++) {
+	    if (i > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[i],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+
+	moreprintf("%04x:%04x[%04x:%04x]: %s\n",
+		   pci_device->vendor, pci_device->product,
+		   pci_device->sub_vendor, pci_device->sub_product,
+		   pci_device->dev_info->class_name);
+
+	moreprintf(" Vendor Name      : %s\n",
+		   pci_device->dev_info->vendor_name);
+	moreprintf(" Product Name     : %s\n",
+		   pci_device->dev_info->product_name);
+	moreprintf(" PCI bus position : %02x:%02x.%01x\n", __pci_bus,
+		   __pci_slot, __pci_func);
+	moreprintf(" Kernel modules   : %s\n\n", kernel_modules);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    struct pci_domain *pci_domain;
+    int return_code = 0;
+    int nb_pci_devices = 0;
+
+    (void)argc;
+    (void)argv;
+
+    /* Scanning to detect pci buses and devices */
+    printf("PCI: Scanning PCI BUS\n");
+    pci_domain = pci_scan();
+    if (!pci_domain) {
+	printf("PCI: no devices found!\n");
+	return 1;
+    }
+
+    struct pci_device *pci_device;
+    for_each_pci_func(pci_device, pci_domain) {
+	nb_pci_devices++;
+    }
+
+    printf("PCI: %d PCI devices found\n", nb_pci_devices);
+
+    printf("PCI: Looking for device name\n");
+    /* Assigning product & vendor name for each device */
+    return_code = get_name_from_pci_ids(pci_domain, "pci.ids");
+    if (return_code == -ENOPCIIDS) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open pci.ids file in current directory.\n");
+	printf("PCI: PCI Device names can't be computed.\n");
+    }
+
+    printf("PCI: Resolving class names\n");
+    /* Assigning class name for each device */
+    return_code = get_class_name_from_pci_ids(pci_domain, "pci.ids");
+    if (return_code == -ENOPCIIDS) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open pci.ids file in current directory.\n");
+	printf("PCI: PCI class names can't be computed.\n");
+    }
+
+    printf("PCI: Looking for Kernel modules\n");
+    /* Detecting which kernel module should match each device */
+    return_code = get_module_name_from_pcimap(pci_domain, "modules.pcimap");
+    if (return_code == -ENOMODULESPCIMAP) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open modules.pcimap file in current directory.\n");
+	printf("PCI: Kernel Module names can't be computed.\n");
+    }
+
+    /* display the pci devices we found */
+    display_pci_devices(pci_domain);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,216 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pmload.c
+ *
+ * Load a binary file and run it in protected mode.  We give it
+ * an ELF-style invocation record, becase, why not?
+ *
+ * Usage: pmload.c32 filename address [arguments...]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+/* If we don't have this much memory for the stack, signal failure */
+#define MIN_STACK	512
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int boot_raw(void *ptr, size_t len, addr_t where, char **argv)
+{
+    struct syslinux_movelist *ml = NULL;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_pm_regs regs;
+    int argc;
+    addr_t argsize;
+    char **argp;
+    addr_t lstart, llen;
+    char *stack_frame = NULL;
+    addr_t stack_frame_size;
+    addr_t stack_pointer;
+    uint32_t *spp;
+    char *sfp;
+    addr_t sfa;
+
+    memset(&regs, 0, sizeof regs);
+
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Segment at 0x%08x len 0x%08x\n", where, len);
+
+    if (syslinux_memmap_type(amap, where, len) != SMT_FREE) {
+	printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+	       where, len);
+	goto bail;		/* Memory region unavailable */
+    }
+
+    /* Mark this region as allocated in the available map */
+    if (syslinux_add_memmap(&amap, where, len, SMT_ALLOC))
+	goto bail;
+
+    /* Data present region.  Create a move entry for it. */
+    if (syslinux_add_movelist(&ml, where, (addr_t) ptr, len))
+	goto bail;
+
+    /* Create the invocation record (initial stack frame) */
+
+    argsize = argc = 0;
+    for (argp = argv; *argp; argp++) {
+	dprintf("argv[%2d] = \"%s\"\n", argc, *argp);
+	argc++;
+	argsize += strlen(*argp) + 1;
+    }
+
+    /* We need the argument strings, argument pointers,
+       argc, plus four zero-word terminators. */
+    stack_frame_size = argsize + argc * sizeof(char *) + 5 * sizeof(long);
+    stack_frame_size = (stack_frame_size + 15) & ~15;
+    stack_frame = calloc(stack_frame_size, 1);
+    if (!stack_frame)
+	goto bail;
+
+    dprintf("Right before syslinux_memmap_largest()...\n");
+    syslinux_dump_memmap(amap);
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen))
+	goto bail;		/* NO free memory?! */
+
+    if (llen < stack_frame_size + MIN_STACK + 16)
+	goto bail;		/* Insufficient memory  */
+
+    /* Initial stack pointer address */
+    stack_pointer = (lstart + llen - stack_frame_size) & ~15;
+
+    dprintf("Stack frame at 0x%08x len 0x%08x\n",
+	    stack_pointer, stack_frame_size);
+
+    /* Create the stack frame.  sfp is the pointer in current memory for
+       the next argument string, sfa is the address in its final resting place.
+       spp is the pointer into the argument array in current memory. */
+    spp = (uint32_t *) stack_frame;
+    sfp = stack_frame + argc * sizeof(char *) + 5 * sizeof(long);
+    sfa = stack_pointer + argc * sizeof(char *) + 5 * sizeof(long);
+
+    *spp++ = argc;
+    for (argp = argv; *argp; argp++) {
+	int bytes = strlen(*argp) + 1;	/* Including final null */
+	*spp++ = sfa;
+	memcpy(sfp, *argp, bytes);
+	sfp += bytes;
+	sfa += bytes;
+    }
+    /* Zero fields are aready taken care of by calloc() */
+
+    /* ... and we'll want to move it into the right place... */
+#if DEBUG
+    if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size)
+	!= SMT_FREE) {
+	dprintf("Stack frame area not free (how did that happen?)!\n");
+	goto bail;		/* Memory region unavailable */
+    }
+#endif
+
+    if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC))
+	goto bail;
+
+    if (syslinux_add_movelist(&ml, stack_pointer, (addr_t) stack_frame,
+			      stack_frame_size))
+	goto bail;
+
+    memset(&regs, 0, sizeof regs);
+    regs.eip = where;
+    regs.esp = stack_pointer;
+
+    dprintf("Final memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Final available map:\n");
+    syslinux_dump_memmap(amap);
+
+    dprintf("Movelist:\n");
+    syslinux_dump_movelist(ml);
+
+    /* This should not return... */
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_pm(ml, mmap, 0, &regs);
+
+bail:
+    if (stack_frame)
+	free(stack_frame);
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+    addr_t where;
+
+    if (argc < 3) {
+	error("Usage: pmload.c32 bin_file address arguments...\n");
+	return 1;
+    }
+
+    where = strtoul(argv[2], NULL, 0);
+
+    if (loadfile(argv[1], &data, &data_len)) {
+	error("Unable to load file\n");
+	return 1;
+    }
+
+    boot_raw(data, data_len, where, &argv[1]);
+    error("Failed to boot, probably insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2013 Sebastian Herbszt - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * poweroff.c
+ *
+ * APM poweroff module
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <com32.h>
+
+int main(int argc __unused, char *argv[] __unused)
+{
+	com32sys_t inregs, outregs;
+
+	memset(&inregs, 0, sizeof inregs);
+
+	inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
+		printf("Power management disabled.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM RM interface connect failed.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x5307; /* Set Power State (07h) */
+	inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
+	inregs.ecx.l = 3; /* Power state off */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("Power off failed.\n");
+		return 1;
+	}
+
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2011 Gene Cumm - All Rights Reserved
+ *
+ *   Portions from chain.c:
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Significant portions copyright (C) 2010 Shao Miller
+ *					[partition iteration, GPT, "fs"]
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * prdhcp.c
+ *
+ * Print the contents of the 3 DHCP packets
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+
+#define PRDHCP_DEBUG 0
+
+#define dprintf0(f, ...)		((void)0)
+
+#ifdef PRDHCP_DEBUG
+#  define dpressanykey			pressanykey
+#  define dprintf			printf
+#  define dprint_pxe_bootp_t		print_pxe_bootp_t
+#  define dprint_pxe_vendor_blk		print_pxe_vendor_blk
+#  define dprint_pxe_vendor_raw		print_pxe_vendor_raw
+#else
+#  define dpressanykey(void)		((void)0)
+#  define dprintf(f, ...)		((void)0)
+#  define dprint_pxe_bootp_t(p, l)	((void)0)
+#  define dprint_pxe_vendor_blk(p, l)	((void)0)
+#  define dprint_pxe_vendor_raw(p, l)	((void)0)
+#endif
+
+#define dprintf_opt_cp	dprintf0
+#define dprintf_opt_inj	dprintf
+
+
+const char app_name_str[] = "prdhcp.c32";
+
+
+int pressanykey(void) {
+    int inc;
+
+    printf("Press any key to continue. ");
+    inc = KEY_NONE;
+    while (inc == KEY_NONE)
+	inc = get_key(stdin, 6000);
+    puts("");
+    return inc;
+}
+
+void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen, oplen, j;
+    uint8_t *d;
+    uint32_t magic;
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    printf("  Vendor Data:    Len=%d", vlen);
+    d = p->vendor.d;
+    /* Print only 256 characters of the vendor/option data */
+    /*
+    print_pxe_vendor_raw(p, (len - vlen) + 256);
+    vlen = 0;
+    */
+    magic = ntohl(*((uint32_t *)d));
+    printf("    Magic: %08X", ntohl(*((uint32_t *)d)));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i])	/* Skip the padding */
+	    printf("\n    @%03X-%3d", i, d[i]);
+	if (d[i] == 255)	/* End of list */
+	    break;
+	if (d[i]) {
+	    oplen = d[++i];
+	    printf(" l=%3d:", oplen);
+	    for (j = (++i + oplen); i < vlen && i < j; i++) {
+		printf(" %02X", d[i]);
+	    }
+	    i--;
+	}
+    }
+    printf("\n");
+}
+
+void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
+{
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    printf("  op:%02X  hw:%02X  hl:%02X  gh:%02X  id:%08X se:%04X f:%04X"
+	"  cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
+	ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
+    printf("  yip:%08X  sip:%08X  gip:%08X",
+	ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
+    printf("  caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
+	p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
+    printf("  sName: '%s'\n", p->Sname);
+    printf("  bootfile: '%s'\n", p->bootfile);
+    print_pxe_vendor_blk(p, len);
+}
+
+void print_dhcp_pkt_all(void)
+{
+    pxe_bootp_t *p;
+    size_t len;
+    int i;
+    int ptype[3] = {PXENV_PACKET_TYPE_DHCP_DISCOVER, PXENV_PACKET_TYPE_DHCP_ACK, PXENV_PACKET_TYPE_CACHED_REPLY};
+
+    for (i = 0; i < 3; i++) {
+	if (!pxe_get_cached_info(ptype[i],
+		(void **)&(p), &(len))) {
+	    dprintf("Got packet #%d/%d\n", (i + 1), ptype[i]);
+	    print_pxe_bootp_t(p, len);
+	    pressanykey();
+	}
+    }
+}
+
+int main(void)
+{
+    int rv= -1;
+    const struct syslinux_version *sv;
+
+    console_ansi_raw();
+    sv = syslinux_version();
+    if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	printf("%s: May only run in PXELINUX\n", app_name_str);
+	return -2;
+    }
+    print_dhcp_pkt_all();
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gene Cumm - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Display present (current) working directory
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <console.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/* Size of path buffer string */
+#ifndef PATH_MAX
+#  ifdef NAME_MAX
+#    define PATH_MAX   NAME_MAX
+#  elif FILENAME_MAX
+#    define PATH_MAX   FILENAME_MAX
+#  else
+#    define PATH_MAX   256
+#  endif       /* NAME_MAX */
+#endif /* PATH_MAX */
+
+int main(void)
+{
+    int rv = 0;
+    char pwd[PATH_MAX], *pwdptr;
+
+    pwdptr = getcwd(pwd, PATH_MAX);
+    if (pwdptr) {
+       if (pwd[0] != 0)
+           puts(pwd);
+       else
+           puts(".");
+    } else {
+       rv = errno;
+       puts("ERROR: getcwd() returned NULL");
+    }
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1148 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2012 Gene Cumm - All Rights Reserved
+ *
+ *   Portions from chain.c:
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Significant portions copyright (C) 2010 Shao Miller
+ *					[partition iteration, GPT, "fs"]
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxechn.c
+ *
+ * PXE Chain Loader; Chain load to another PXE network boot program
+ * that may be on another host.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+#include <dhcp.h>
+#include <limits.h>
+
+
+#ifdef DEBUG
+#  define PXECHN_DEBUG 1
+#else
+#  define PXECHN_DEBUG 0
+#endif
+
+typedef union {
+    uint64_t q;
+    uint32_t l[2];
+    uint16_t w[4];
+    uint8_t b[8];
+} reg64_t;
+
+#define dprintf0(f, ...)		((void)0)
+
+#ifndef dprintf
+#  if (PXECHN_DEBUG > 0)
+#    define dprintf			printf
+#  else
+#    define dprintf(f, ...)		((void)0)
+#  endif
+#endif
+
+#if (PXECHN_DEBUG > 0)
+#  define dpressanykey			pressanykey
+#  define dprint_pxe_bootp_t		print_pxe_bootp_t
+#  define dprint_pxe_vendor_blk		print_pxe_vendor_blk
+#  define dprint_pxe_vendor_raw		print_pxe_vendor_raw
+#else
+#  define dpressanykey(tm)		((void)0)
+#  define dprint_pxe_bootp_t(p, l)	((void)0)
+#  define dprint_pxe_vendor_blk(p, l)	((void)0)
+#  define dprint_pxe_vendor_raw(p, l)	((void)0)
+#endif
+
+#define dprintf_opt_cp		dprintf0
+#define dprintf_opt_inj		dprintf0
+#define dprintf_pc_pa		dprintf
+#define dprintf_pc_so_s		dprintf0
+
+#define t_PXENV_RESTART_TFTP	t_PXENV_TFTP_READ_FILE
+
+#define STACK_SPLIT	11
+
+/* same as pxelinux.asm REBOOT_TIME */
+#define REBOOT_TIME	300
+
+#define NUM_DHCP_OPTS		256
+#define DHCP_OPT_LEN_MAX	256
+#define PXE_VENDOR_RAW_PRN_MAX	0x7F
+#define PXECHN_HOST_LEN		256	/* 63 bytes per label; 255 max total */
+
+#define PXECHN_NUM_PKT_TYPE	3
+#define PXECHN_NUM_PKT_AVAIL	2*PXECHN_NUM_PKT_TYPE
+#define PXECHN_PKT_TYPE_START	PXENV_PACKET_TYPE_DHCP_DISCOVER
+
+#define PXECHN_FORCE_PKT1	0x80000000
+#define PXECHN_FORCE_PKT2	0x40000000
+#define PXECHN_FORCE_ALL	(PXECHN_FORCE_PKT1 | PXECHN_FORCE_PKT2)
+#define PXECHN_FORCE_ALL_1	0
+#define STRASINT_str		('s' + (('t' + ('r' << 8)) << 8))
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+const char app_name_str[] = "pxechn.c32";
+
+struct pxelinux_opt {
+    char *fn;	/* Filename as passed to us */
+    in_addr_t fip;	/* fn's IP component */
+    char *fp;	/* fn's path component */
+    in_addr_t gip;	/* giaddr; Gateway/DHCP relay */
+    uint32_t force;
+    uint32_t wait;	/* Additional decision to wait before boot */
+    int32_t wds;	/* WDS option/level */
+    in_addr_t sip;	/* siaddr: Next Server IP Address */
+    struct dhcp_option p[PXECHN_NUM_PKT_AVAIL];
+	/* original _DHCP_DISCOVER, _DHCP_ACK, _CACHED_REPLY then modified packets */
+    char host[PXECHN_HOST_LEN];
+    struct dhcp_option opts[PXECHN_NUM_PKT_TYPE][NUM_DHCP_OPTS];
+    char p_unpacked[PXECHN_NUM_PKT_TYPE];
+};
+
+
+/* from chain.c */
+struct data_area {
+    void *data;
+    addr_t base;
+    addr_t size;
+};
+
+/* From chain.c */
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+/* From chain.c */
+static void do_boot(struct data_area *data, int ndata,
+		    struct syslinux_rm_regs *regs)
+{
+    uint16_t *const bios_fbm = (uint16_t *) 0x413;
+    addr_t dosmem = *bios_fbm << 10;	/* Technically a low bound */
+    struct syslinux_memmap *mmap;
+    struct syslinux_movelist *mlist = NULL;
+    addr_t endimage;
+    int i;
+
+    mmap = syslinux_memory_map();
+
+    if (!mmap) {
+	error("Cannot read system memory map\n");
+	return;
+    }
+
+    endimage = 0;
+    for (i = 0; i < ndata; i++) {
+	if (data[i].base + data[i].size > endimage)
+	    endimage = data[i].base + data[i].size;
+    }
+    if (endimage > dosmem)
+	goto too_big;
+
+    for (i = 0; i < ndata; i++) {
+	if (syslinux_add_movelist(&mlist, data[i].base,
+				  (addr_t) data[i].data, data[i].size))
+	    goto enomem;
+    }
+
+
+    /* Tell the shuffler not to muck with this area... */
+    syslinux_add_memmap(&mmap, endimage, 0xa0000 - endimage, SMT_RESERVED);
+
+    /* Force text mode */
+    syslinux_force_text_mode();
+
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_rm(mlist, mmap, 3, regs);
+    error("Chainboot failed!\n");
+    return;
+
+too_big:
+    error("Loader file too large\n");
+    return;
+
+enomem:
+    error("Out of memory\n");
+    return;
+}
+
+void usage(void)
+{
+    printf("USAGE:\n"
+        "    %s [OPTIONS]... _new-nbp_\n"
+	"    %s -r _new-nbp_    (calls PXE stack PXENV_RESTART_TFTP)\n"
+	"OPTIONS:\n"
+	"    [-c config] [-g gateway] [-p prefix] [-t reboot] [-u] [-w] [-W]"
+	" [-o opt.ty=val]\n\n",
+	app_name_str, app_name_str);
+}
+
+void pxe_error(int ierr, const char *evt, const char *msg)
+{
+    if (msg)
+	printf("%s", msg);
+    else if (evt)
+	printf("Error while %s: ", evt);
+    printf("%d:%s\n", ierr, strerror(ierr));
+}
+
+int pressanykey(clock_t tm) {
+    int inc;
+
+    printf("Press any key to continue. ");
+    inc = get_key(stdin, tm);
+    puts("");
+    return inc;
+}
+
+int dhcp_find_opt(pxe_bootp_t *p, size_t len, uint8_t opt)
+{
+    int rv = -1;
+    int i, vlen, oplen;
+    uint8_t *d;
+    uint32_t magic;
+
+    if (!p) {
+	dprintf("  packet pointer is null\n");
+	return rv;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    d = p->vendor.d;
+    magic = ntohl(*((uint32_t *)d));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i] == opt) {
+	    dprintf("\n    @%03X-%2d\n", i, d[i]);
+	    rv = i;
+	    break;
+	}
+	if (d[i] == ((NUM_DHCP_OPTS) - 1))	/* End of list */
+	    break;
+	if (d[i]) {		/* Skip padding */
+	    oplen = d[++i];
+	    i += oplen;
+	}
+    }
+    return rv;
+}
+
+void print_pxe_vendor_raw(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen;
+
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    if (vlen > PXE_VENDOR_RAW_PRN_MAX)
+	vlen = PXE_VENDOR_RAW_PRN_MAX;
+    dprintf("  rawLen = %d", vlen);
+    for (i = 0; i < vlen; i++) {
+	if ((i & 0xf) == 0)
+	    printf("\n  %04X:", i);
+	printf(" %02X", p->vendor.d[i]);
+    }
+    printf("\n");
+}
+
+void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen, oplen, j;
+    uint8_t *d;
+    uint32_t magic;
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    printf("  Vendor Data:    Len=%d", vlen);
+    d = p->vendor.d;
+    magic = ntohl(*((uint32_t *)d));
+    printf("    Magic: %08X", ntohl(*((uint32_t *)d)));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i])	/* Skip the padding */
+	    printf("\n    @%03X-%3d", i, d[i]);
+	if (d[i] == ((NUM_DHCP_OPTS) - 1))	/* End of list */
+	    break;
+	if (d[i]) {
+	    oplen = d[++i];
+	    printf(" l=%3d:", oplen);
+	    for (j = (++i + oplen); i < vlen && i < j; i++) {
+		printf(" %02X", d[i]);
+	    }
+	    i--;
+	}
+    }
+    printf("\n");
+}
+
+void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
+{
+    if (!p || len <= 0) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    printf("  op:%02X  hw:%02X  hl:%02X  gh:%02X  id:%08X se:%04X f:%04X"
+	"  cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
+	ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
+    printf("  yip:%08X  sip:%08X  gip:%08X",
+	ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
+    printf("  caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
+	p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
+    printf("  sName: '%s'\n", p->Sname);
+    printf("  bootfile: '%s'\n", p->bootfile);
+    dprint_pxe_vendor_blk(p, len);
+}
+
+void pxe_set_regs(struct syslinux_rm_regs *regs)
+{
+    const union syslinux_derivative_info *sdi;
+    const com32sys_t *pxe_regs;
+
+    sdi = syslinux_derivative_info();
+    pxe_regs = sdi->pxe.stack;	/* Original register values */
+
+    /* Just to be sure... */
+    memset(regs, 0, sizeof *regs);
+
+    regs->ip = 0x7C00;
+
+    /* Point to the original stack */
+    regs->ss    = sdi->pxe.stack_seg;
+    regs->esp.l = sdi->pxe.stack_offs + sizeof(com32sys_t);
+
+    /* Point to the PXENV+ address */
+    regs->es    = pxe_regs->es;
+    regs->ebx.l = pxe_regs->ebx.l;
+
+    dprintf("\nsp:%04x    ss:%04x    es:%04x    bx:%04x\n", regs->esp.w[0],
+	regs->ss, regs->es, regs->ebx.w[0]);
+}
+
+int hostlen_limit(int len)
+{
+    return min(len, ((PXECHN_HOST_LEN) - 1));
+}
+
+//FIXME: To a library
+/* Parse a filename into an IPv4 address and filename pointer
+ *	returns	Based on the interpretation of fn
+ *		0 regular file name
+ *		1 in format IP::FN
+ *		2 TFTP URL
+ *		3 HTTP URL
+ *		4 FTP URL
+ *		3 + 2^30 HTTPS URL
+ *		-1 if fn is another URL type
+ */
+int pxechn_parse_fn(char fn[], in_addr_t *fip, char *host, char *fp[])
+{
+    in_addr_t tip = 0;
+    char *csep, *ssep, *hsep;	/* Colon, Slash separator positions */
+    int hlen, plen;	/* Hostname, protocol length */
+    int rv = 0;
+
+    csep = strchr(fn, ':');
+    if (csep) {
+	if (csep[1] == ':') {	/* assume IP::FN */
+	    *fp = &csep[2];
+	    rv = 1;
+	    if (fn[0] != ':') {
+		hlen = hostlen_limit(csep - fn);
+		memcpy(host, fn, hlen);
+		host[hlen] = 0;
+	    }
+	} else if ((csep[1] == '/') && (csep[2] == '/')) {
+		/* URL: proto://host:port/path/file */
+		/* proto://[user[:passwd]@]host[:port]/path/file */
+	    ssep = strchr(csep + 3, '/');
+	    if (ssep) {
+		hlen = hostlen_limit(ssep - (csep + 3));
+		*fp = ssep + 1;
+	    } else {
+		hlen = hostlen_limit(strlen(csep + 3));
+	    }
+	    memcpy(host, (csep + 3), hlen);
+	    host[hlen] = 0;
+	    plen = csep - fn;
+	    if (strncmp(fn, "tftp", plen) == 0)
+		rv = 2;
+	    else if (strncmp(fn, "http", plen) == 0)
+		rv = 3;
+	    else if (strncmp(fn, "ftp", plen) == 0)
+		rv = 4;
+	    else if (strncmp(fn, "https", plen) == 0)
+		rv = 3 + ( 1 << 30 );
+	    else
+		rv = -1;
+	} else {
+	    csep = NULL;
+	}
+    }
+    if (!csep) {
+	*fp = fn;
+    }
+    if (host[0]) {
+	hsep = strchr(host, '@');
+	if (!hsep)
+	    hsep = host;
+	tip = pxe_dns(hsep);
+    }
+    if (tip != 0)
+	*fip = tip;
+    dprintf0("  host '%s'\n  fp   '%s'\n  fip  %08x\n", host, *fp, ntohl(*fip));
+    return rv;
+}
+
+void pxechn_opt_free(struct dhcp_option *opt)
+{
+    free(opt->data);
+    opt->len = -1;
+}
+
+void pxechn_fill_pkt(struct pxelinux_opt *pxe, int ptype)
+{
+    int rv = -1;
+    int p1, p2;
+    if ((ptype < 0) || (ptype > PXECHN_NUM_PKT_TYPE))
+	rv = -2;
+    p1 = ptype - PXECHN_PKT_TYPE_START;
+    p2 = p1 + PXECHN_NUM_PKT_TYPE;
+    if ((rv >= -1) && (!pxe_get_cached_info(ptype,
+	    (void **)&(pxe->p[p1].data), (size_t *)&(pxe->p[p1].len)))) {
+	pxe->p[p2].data = malloc(2048);
+	if (pxe->p[p2].data) {
+	    memcpy(pxe->p[p2].data, pxe->p[p1].data, pxe->p[p1].len);
+	    pxe->p[p2].len = pxe->p[p1].len;
+	    rv = 0;
+	    dprint_pxe_bootp_t((pxe_bootp_t *)(pxe->p[p1].data), pxe->p[p1].len);
+	    dpressanykey(INT_MAX);
+	} else {
+	    printf("%s: ERROR: Unable to malloc() for second packet\n", app_name_str);
+	}
+    } else {
+	printf("%s: ERROR: Unable to retrieve first packet\n", app_name_str);
+    }
+    if (rv <= -1) {
+	pxechn_opt_free(&pxe->p[p1]);
+    }
+}
+
+void pxechn_init(struct pxelinux_opt *pxe)
+{
+    /* Init for paranoia */
+    pxe->fn = NULL;
+    pxe->fp = NULL;
+    pxe->force = 0;
+    pxe->wait = 0;
+    pxe->gip = 0;
+    pxe->wds = 0;
+    pxe->sip = 0;
+    pxe->host[0] = 0;
+    pxe->host[((NUM_DHCP_OPTS) - 1)] = 0;
+    for (int j = 0; j < PXECHN_NUM_PKT_TYPE; j++){
+	for (int i = 0; i < NUM_DHCP_OPTS; i++) {
+	    pxe->opts[j][i].data = NULL;
+	    pxe->opts[j][i].len = -1;
+	}
+	pxe->p_unpacked[j] = 0;
+	pxe->p[j].data = NULL;
+	pxe->p[j+PXECHN_NUM_PKT_TYPE].data = NULL;
+	pxe->p[j].len = 0;
+	pxe->p[j+PXECHN_NUM_PKT_TYPE].len = 0;
+    }
+    pxechn_fill_pkt(pxe, PXENV_PACKET_TYPE_CACHED_REPLY);
+}
+
+int pxechn_to_hex(char i)
+{
+    if (i >= '0' && i <= '9')
+	return (i - '0');
+    if (i >= 'A' && i <= 'F')
+	return (i - 'A' + 10);
+    if (i >= 'a' && i <= 'f')
+	return (i - 'a' + 10);
+    if (i == 0)
+	return -1;
+    return -2;
+}
+
+int pxechn_parse_2bhex(char ins[])
+{
+    int ret = -2;
+    int n0 = -3, n1 = -3;
+    /* NULL pointer */
+    if (!ins) {
+	ret = -1;
+    /* pxechn_to_hex can handle the NULL character by returning -1 and
+       breaking the execution of the statement chain */
+    } else if (((n0 = pxechn_to_hex(ins[0])) >= 0)
+	    && ((n1 = pxechn_to_hex(ins[1])) >= 0)) {
+	ret = (n0 * 16) + n1;
+    } else if (n0 == -1) {	/* Leading NULL char */
+	ret = -1;
+    }
+    return ret;
+}
+
+int pxechn_optnum_ok(int optnum)
+{
+    if ((optnum > 0) && (optnum < ((NUM_DHCP_OPTS) - 1)))
+	return 1;
+    return 0;
+}
+
+int pxechn_optnum_ok_notres(int optnum)
+{
+    if ((optnum <= 0) && (optnum >= ((NUM_DHCP_OPTS) - 1)))
+	return 0;
+    switch(optnum){
+    case 66: case 67:
+	return 0;
+	break;
+    default:	return 1;
+    }
+}
+
+int pxechn_optlen_ok(int optlen)
+{
+    if ((optlen >= 0) && (optlen < ((DHCP_OPT_LEN_MAX) - 1)))
+	return 1;
+    return 0;
+}
+
+int pxechn_setopt(struct dhcp_option *opt, void *data, int len)
+{
+    void *p;
+    if (!opt || !data)
+	return -1;
+    if (len < 0) {
+	return -3;
+    }
+    p = realloc(opt->data, len);
+    if (!p && len) {	/* Allow for len=0 */
+	pxechn_opt_free(opt);
+	return -2;
+    }
+    opt->data = p;
+    memcpy(opt->data, data, len);
+    opt->len = len;
+    return len;
+}
+
+int pxechn_setopt_str(struct dhcp_option *opt, void *data)
+{
+    return pxechn_setopt(opt, data, strnlen(data, DHCP_OPT_LEN_MAX));
+}
+
+int pxechn_parse_int(char *data, char istr[], int tlen)
+{
+    int terr = errno;
+
+    if ((tlen == 1) || (tlen == 2) || (tlen == 4)) {
+	errno = 0;
+	uint32_t optval = strtoul(istr, NULL, 0);
+	if (errno)
+	    return -3;
+	errno = terr;
+	switch(tlen){
+	case  1:
+	    if (optval & 0xFFFFFF00)
+		return -4;
+	    break;
+	case  2:
+	    if (optval & 0xFFFF0000)
+		return -4;
+	    optval = htons(optval);
+	    break;
+	case  4:
+	    optval = htonl(optval);
+	    break;
+	}
+	memcpy(data, &optval, tlen);
+    } else if (tlen == 8) {
+	errno = 0;
+	uint64_t optval = strtoull(istr, NULL, 0);
+	if (errno)
+	    return -3;
+	errno = terr;
+	optval = htonq(optval);
+	memcpy(data, &optval, tlen);
+    } else {
+	return -2;
+    }
+    return tlen;
+}
+
+int pxechn_parse_hex_sep(char *data, char istr[], char sep)
+{
+    int len = 0;
+    int ipos = 0, ichar;
+    
+    if (!data || !istr)
+	return -1;
+    while ((istr[ipos]) && (len < DHCP_OPT_LEN_MAX)) {
+	dprintf(" %02X%02X", *((int *)(istr + ipos)) & 0xFF, *((int *)(istr + ipos +1)) & 0xFF);
+	ichar = pxechn_parse_2bhex(istr + ipos);
+	if (ichar >=0) {
+	    data[len++] = ichar;
+	} else {
+	    return -EINVAL;
+	}
+	if (!istr[ipos+2]){
+	    ipos += 2;
+	} else if (istr[ipos+2] != sep) {
+	    return -(EINVAL + 1);
+	} else {
+	    ipos += 3;
+	}
+    }
+    return len;
+}
+
+int pxechn_parse_opttype(char istr[], int optnum)
+{
+    char *pos;
+    int tlen, type, tmask;
+
+    if (!istr)
+	return -1;
+    pos = strchr(istr, '=');
+    if (!pos)
+	return -2;
+    if (istr[0] != '.') {
+	if (!pxechn_optnum_ok(optnum))
+	    return -3;
+	return -3;	/* do lookup here */
+    } else {
+	tlen = pos - istr - 1;
+	if ((tlen < 1) || (tlen > 4))
+	    return -4;
+	tmask = 0xFFFFFFFF >> (8 * (4 - tlen));
+	type = (*(int*)(istr + 1)) & tmask;
+    }
+    return type;
+}
+
+int pxechn_parse_setopt(struct dhcp_option opts[], struct dhcp_option *iopt,
+			char istr[])
+{
+    int rv = 0, optnum, opttype;
+    char *cpos = NULL, *pos;
+
+    if (!opts || !iopt || !(iopt->data))
+	return -1;
+    if (!istr || !istr[0])
+	return -2;
+    // -EINVAL;
+    optnum = strtoul(istr, &cpos, 0);
+    if (!pxechn_optnum_ok(optnum))
+	return -3;
+    pos = strchr(cpos, '=');
+    if (!pos)
+	return -4;
+    opttype = pxechn_parse_opttype(cpos, optnum);
+    pos++;
+    switch(opttype) {
+    case 'b':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 1);
+	break;
+    case 'l':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 4);
+	break;
+    case 'q':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 8);
+	break;
+    case 's':
+    case STRASINT_str:
+	iopt->len = strlen(pos);
+	if (iopt->len > DHCP_OPT_LEN_MAX)
+	    iopt->len = DHCP_OPT_LEN_MAX;
+	memcpy(iopt->data, pos, iopt->len);
+	dprintf_pc_so_s("s.len=%d\trv=%d\n", iopt->len, rv);
+	break;
+    case 'w':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 2);
+	break;
+    case 'x':
+	iopt->len = pxechn_parse_hex_sep(iopt->data, pos, ':');
+	break;
+    default:
+	return -6;
+	break;
+    }
+    if (pxechn_optlen_ok(iopt->len)) {
+	rv = pxechn_setopt(&(opts[optnum]), (void *)(iopt->data), iopt->len);
+    }
+    if((opttype == 's') || (opttype == STRASINT_str))
+	dprintf_pc_so_s("rv=%d\n", rv);
+    return rv;
+}
+
+int pxechn_parse_force(const char istr[])
+{
+    uint32_t rv = 0;
+    char *pos;
+    int terr = errno;
+
+    errno = 0;
+    rv = strtoul(istr, &pos, 0);
+    if ((istr == pos ) || ((rv == ULONG_MAX) && (errno)))
+	rv = 0;
+    errno = terr;
+    return rv;
+}
+
+int pxechn_uuid_set(struct pxelinux_opt *pxe)
+{
+    int ret = 0;
+
+    if (!pxe->p_unpacked[0])
+	ret = dhcp_unpack_packet((pxe_bootp_t *)(pxe->p[0].data),
+				 pxe->p[0].len, pxe->opts[0]);
+    if (ret) {
+	error("Could not unpack packet\n");
+	return -ret;	/* dhcp_unpack_packet always returns positive errors */
+    }
+
+    if (pxe->opts[0][97].len >= 0 )
+	pxechn_setopt(&(pxe->opts[2][97]), pxe->opts[0][97].data, pxe->opts[0][97].len);
+	return 1;
+    return 0;
+}
+
+int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe,
+			 struct dhcp_option opts[])
+{
+    int arg, optnum, rv = 0;
+    char *p = NULL;
+    const char optstr[] = "c:f:g:o:p:St:uwW";
+    struct dhcp_option iopt;
+
+    if (pxe->p[5].data)
+	pxe->fip = ( (pxe_bootp_t *)(pxe->p[5].data) )->sip;
+    else
+	pxe->fip = 0;
+    /* Fill */
+    pxe->fn = argv[0];
+    pxechn_parse_fn(pxe->fn, &(pxe->fip), pxe->host, &(pxe->fp));
+    pxechn_setopt_str(&(opts[67]), pxe->fp);
+    pxechn_setopt_str(&(opts[66]), pxe->host);
+    iopt.data = malloc(DHCP_OPT_LEN_MAX);
+    iopt.len = 0;
+    while ((rv >= 0) && (arg = getopt(argc, argv, optstr)) >= 0) {
+	dprintf_pc_pa("  Got arg '%c'/'%c' addr %08X val %s\n", arg == '?' ? optopt : arg, arg, (unsigned int)optarg, optarg ? optarg : "");
+	switch(arg) {
+	case 'c':	/* config */
+	    pxechn_setopt_str(&(opts[209]), optarg);
+	    break;
+	case 'f':	/* force */
+	    pxe->force = pxechn_parse_force(optarg);
+	    break;
+	case 'g':	/* gateway/DHCP relay */
+	    pxe->gip = pxe_dns(optarg);
+	    break;
+	case 'n':	/* native */
+	    break;
+	case 'o':	/* option */
+	    rv = pxechn_parse_setopt(opts, &iopt, optarg);
+	    break;
+	case 'p':	/* prefix */
+	    pxechn_setopt_str(&(opts[210]), optarg);
+	    break;
+	case 'S':	/* sip from sName */
+	    pxe->sip = 1;
+	    break;
+	case 't':	/* timeout */
+	    optnum = strtoul(optarg, &p, 0);
+	    if (p != optarg) {
+		optnum = htonl(optnum);
+		pxechn_setopt(&(opts[211]), (void *)(&optnum), 4);
+	    } else {
+		rv = -3;
+	    }
+	    break;
+	case 'u':	/* UUID: copy option 97 from packet 1 if present */
+	    pxechn_uuid_set(pxe);
+	    break;
+	case 'w':	/* wait */
+	    pxe->wait = 1;
+	    break;
+	case 'W':	/* WDS */
+	    pxe->wds = 1;
+	    break;
+	case '?':
+	    rv = -'?';
+	default:
+	    break;
+	}
+	if (rv >= 0)	/* Clear it since getopt() doesn't guarentee it */
+	    optarg = NULL;
+    }
+    if (iopt.data)
+	pxechn_opt_free(&iopt);
+/* FIXME: consider reordering the application of parsed command line options
+       such that the new nbp may be at the end */
+    if (rv >= 0) {
+	rv = 0;
+    } else if (arg != '?') {
+	printf("Invalid argument for -%c: %s\n", arg, optarg);
+    }
+    dprintf("pxechn_parse_args rv=%d\n", rv);
+    return rv;
+}
+
+int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe)
+{
+    pxe_bootp_t *bootp0, *bootp1;
+    int ret = 0;
+    struct dhcp_option *opts;
+    char *str;
+
+    opts = pxe->opts[2];
+    /* Start filling packet #1 */
+    bootp0 = (pxe_bootp_t *)(pxe->p[2].data);
+    bootp1 = (pxe_bootp_t *)(pxe->p[5].data);
+
+    ret = dhcp_unpack_packet(bootp0, pxe->p[2].len, opts);
+    if (ret) {
+	error("Could not unpack packet\n");
+	return -ret;
+    }
+    pxe->p_unpacked[2] = 1;
+    pxe->gip = bootp1->gip;
+
+    ret = pxechn_parse_args(argc, argv, pxe, opts);
+    if (ret)
+	return ret;
+    if (pxe->sip > 0xFFFFFF) {	/* a real IPv4 address */
+	bootp1->sip = pxe->sip;
+    } else if ((pxe->sip == 1)
+		&& (opts[66].len > 0)){
+	/* unterminated? */
+	if (strnlen(opts[66].data, opts[66].len) == (size_t)opts[66].len) {
+	    str = malloc(opts[66].len + 1);
+	    if (str) {
+		memcpy(str, opts[66].data, opts[66].len);
+		str[opts[66].len] = 0;
+	    }	
+	} else {
+	    str = opts[66].data;
+	}
+	if (str) {
+	    bootp1->sip = pxe_dns(str);
+	    if (str != opts[66].data)
+		free(str);
+	} else {
+	    bootp1->sip = pxe->fip;
+	}
+    } else {
+	bootp1->sip = pxe->fip;
+    }
+    bootp1->gip = pxe->gip;
+
+    ret = dhcp_pack_packet(bootp1, (size_t *)&(pxe->p[5].len), opts);
+    if (ret) {
+	error("Could not pack packet\n");
+	return -ret;	/* dhcp_pack_packet always returns positive errors */
+    }
+    return ret;
+}
+
+/* dhcp_pkt2pxe: Copy packet to PXE's BC data for a ptype packet
+ *	Input:
+ *	p	Packet data to copy
+ *	len	length of data to copy
+ *	ptype	Packet type to overwrite
+ */
+int dhcp_pkt2pxe(pxe_bootp_t *p, size_t len, int ptype)
+{
+    t_PXENV_GET_CACHED_INFO *ci;
+    void *cp;
+    int rv = -1;
+
+    if (!(ci = lzalloc(sizeof(t_PXENV_GET_CACHED_INFO)))){
+	dprintf("Unable to lzalloc() for PXE call structure\n");
+	rv = 1;
+	goto ret;
+    }
+    ci->Status = PXENV_STATUS_FAILURE;
+    ci->PacketType = ptype;
+    pxe_call(PXENV_GET_CACHED_INFO, ci);
+
+    if (ci->Status != PXENV_STATUS_SUCCESS) {
+	dprintf("PXE Get Cached Info failed: %d\n", ci->Status);
+	rv = 2;
+	goto ret;
+    }
+
+    cp = MK_PTR(ci->Buffer.seg, ci->Buffer.offs);
+    if (!(memcpy(cp, p, len))) {
+	dprintf("Failed to copy packet\n");
+	rv = 3;
+	goto ret;
+    }
+ret:
+    lfree(ci);
+   return rv;
+}
+
+int pxechn_mergeopt(struct pxelinux_opt *pxe, int d, int s)
+{
+    int ret = 0, i;
+
+    if ((d >= PXECHN_NUM_PKT_TYPE) || (s >= PXECHN_NUM_PKT_TYPE) 
+	    || (d < 0) || (s < 0)) {
+	return -2;
+    }
+    if (!pxe->p_unpacked[s])
+	ret = dhcp_unpack_packet(pxe->p[s].data, pxe->p[s].len, pxe->opts[s]);
+    if (ret) {
+	error("Could not unpack packet for merge\n");
+	printf("Error %d (%d)\n", ret, EINVAL);
+	if (ret == EINVAL) {
+	    if (pxe->p[s].len < 240)
+		printf("Packet %d is too short: %d (240)\n", s, pxe->p[s].len);
+	    else if (((const struct dhcp_packet *)(pxe->p[s].data))->magic != htonl(DHCP_VENDOR_MAGIC))
+		printf("Packet %d has no magic\n", s);
+	    else
+		error("Unknown EINVAL error\n");
+	} else {
+	    error("Unknown error\n");
+	}
+	return -ret;
+    }
+    for (i = 0; i < NUM_DHCP_OPTS; i++) {
+	if (pxe->opts[d][i].len <= -1) {
+	    if (pxe->opts[s][i].len >= 0)
+		pxechn_setopt(&(pxe->opts[d][i]), pxe->opts[s][i].data, pxe->opts[s][i].len);
+	}
+    }
+    return 0;
+}
+
+/* pxechn: Chainload to new PXE file ourselves
+ *	Input:
+ *	argc	Count of arguments passed
+ *	argv	Values of arguments passed
+ *	Returns	0 on success (which should never happen)
+ *		1 on loadfile() error
+ *		2 if DHCP Option 52 (Option Overload) used file field
+ *		-1 on usage error
+ */
+int pxechn(int argc, char *argv[])
+{
+    struct pxelinux_opt pxe;
+    pxe_bootp_t* p[(2 * PXECHN_NUM_PKT_TYPE)];
+    int rv = 0;
+    int i;
+    struct data_area file;
+    struct syslinux_rm_regs regs;
+
+    pxechn_init(&pxe);
+    for (i = 0; i < (2 * PXECHN_NUM_PKT_TYPE); i++) {
+	p[i] = (pxe_bootp_t *)(pxe.p[i].data);
+    }
+
+    /* Parse arguments and patch packet 1 */
+    rv = pxechn_args(argc, argv, &pxe);
+    dpressanykey(INT_MAX);
+    if (rv)
+	goto ret;
+    pxe_set_regs(&regs);
+    /* Load the file late; it's the most time-expensive operation */
+    printf("%s: Attempting to load '%s': ", app_name_str, pxe.fn);
+    if (loadfile(pxe.fn, &file.data, &file.size)) {
+	pxe_error(errno, NULL, NULL);
+	rv = -2;
+	goto ret;
+    }
+    puts("loaded.");
+    /* we'll be shuffling to the standard location of 7C00h */
+    file.base = 0x7C00;
+    if ((pxe.wds) || 
+	    ((pxe.force) && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0))) {
+	printf("Forcing behavior %08X\n", pxe.force);
+	// P2 is the same as P3 if no PXE server present.
+	if ((pxe.wds) ||
+		(pxe.force & PXECHN_FORCE_PKT2)) {
+	    pxechn_fill_pkt(&pxe, PXENV_PACKET_TYPE_DHCP_ACK);
+	    rv = pxechn_mergeopt(&pxe, 2, 1);
+	    if (rv) {
+		dprintf("Merge Option returned %d\n", rv);
+	    }
+	    rv = dhcp_pack_packet(p[5], (size_t *)&(pxe.p[5].len), pxe.opts[2]);
+	    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+	if (pxe.force & PXECHN_FORCE_PKT1) {
+	    puts("Unimplemented force option utilized");
+	}
+    }
+    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_CACHED_REPLY);
+    dprint_pxe_bootp_t(p[5], pxe.p[5].len);
+    if ((pxe.wds) ||
+	    ((pxe.force) && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0))) {
+	// printf("Forcing behavior %08X\n", pxe.force);
+	// P2 is the same as P3 if no PXE server present.
+	if ((pxe.wds) ||
+		(pxe.force & PXECHN_FORCE_PKT2)) {
+	    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+    } else if (pxe.force) {
+	printf("FORCE: bad argument %08X\n", pxe.force);
+    }
+    printf("\n...Ready to boot:\n");
+    if (pxe.wait) {
+	pressanykey(INT_MAX);
+    } else {
+	dpressanykey(INT_MAX);
+    }
+    if (true) {
+	puts("  Attempting to boot...");
+	do_boot(&file, 1, &regs);
+    }
+    /* If failed, copy backup back in and abort */
+    dhcp_pkt2pxe(p[2], pxe.p[2].len, PXENV_PACKET_TYPE_CACHED_REPLY);
+    if (pxe.force && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0)) {
+	if (pxe.force & PXECHN_FORCE_PKT2) {
+	    rv = dhcp_pkt2pxe(p[1], pxe.p[1].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+    }
+ret:
+    return rv;
+}
+
+/* pxe_restart: Restart the PXE environment with a new PXE file
+ *	Input:
+ *	ifn	Name of file to chainload to in a format PXELINUX understands
+ *		This must strictly be TFTP or relative file
+ */
+int pxe_restart(char *ifn)
+{
+    int rv = 0;
+    struct pxelinux_opt pxe;
+    t_PXENV_RESTART_TFTP *pxep;	/* PXENV callback Parameter */
+
+    pxe.fn = ifn;
+    pxechn_fill_pkt(&pxe, PXENV_PACKET_TYPE_CACHED_REPLY);
+    if (pxe.p[5].data)
+	pxe.fip = ( (pxe_bootp_t *)(pxe.p[5].data) )->sip;
+    else
+	pxe.fip = 0;
+    rv = pxechn_parse_fn(pxe.fn, &(pxe.fip), pxe.host, &(pxe.fp));
+    if ((rv > 2) || (rv < 0)) {
+	printf("%s: ERROR: Unparsable filename argument: '%s'\n\n", app_name_str, pxe.fn);
+	goto ret;
+    }
+    printf("  Attempting to boot '%s'...\n\n", pxe.fn);
+    if (!(pxep = lzalloc(sizeof(t_PXENV_RESTART_TFTP)))){
+	dprintf("Unable to lzalloc() for PXE call structure\n");
+	goto ret;
+    }
+    pxep->Status = PXENV_STATUS_SUCCESS;	/* PXENV_STATUS_FAILURE */
+    strcpy((char *)pxep->FileName, ifn);
+    pxep->BufferSize = 0x8000;
+    pxep->Buffer = (void *)0x7c00;
+    pxep->ServerIPAddress = pxe.fip;
+    dprintf("FN='%s'  %08X %08X %08X %08X\n\n", (char *)pxep->FileName,
+	pxep->ServerIPAddress, (unsigned int)pxep,
+	pxep->BufferSize, (unsigned int)pxep->Buffer);
+    dprintf("PXENV_RESTART_TFTP status %d\n", pxep->Status);
+
+    pxe_call(PXENV_RESTART_TFTP, pxep);
+
+    printf("PXENV_RESTART_TFTP returned %d\n", pxep->Status);
+    lfree(pxep);
+
+ret:
+    return rv;
+}
+
+/* pxechn_gpxe: Use gPXE to chainload a new NBP
+ *	Input:
+ *	argc	Count of arguments passed
+ *	argv	Values of arguments passed
+ *	Returns	0 on success (which should never happen)
+ *		1 on loadfile() error
+ *		-1 on usage error
+ */
+//FIXME:Implement
+int pxechn_gpxe(int argc, char *argv[])
+{
+    int rv = 0;
+    struct pxelinux_opt pxe;
+
+    if (argc) {
+	printf("%s\n", argv[0]);
+	pxechn_args(argc, argv, &pxe);
+    }
+    return rv;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv= -1;
+    int err;
+    const struct syslinux_version *sv;
+
+    /* Initialization */
+    err = errno;
+    console_ansi_raw();	/* sets errno = 9 (EBADF) */
+    /* printf("%d %d\n", err, errno); */
+    errno = err;
+    sv = syslinux_version();
+    if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	printf("%s: May only run in PXELINUX\n", app_name_str);
+	argc = 1;	/* prevents further processing to boot */
+    }
+    if (argc == 2) {
+	if ((strcasecmp(argv[1], "-h") == 0) || ((strcmp(argv[1], "-?") == 0))
+		|| (strcasecmp(argv[1], "--help") == 0)) {
+	    argc = 1;
+	} else {
+	    rv = pxechn(argc - 1, &argv[1]);
+	}
+    } else if (argc >= 3) {
+	if ((strcmp(argv[1], "-r") == 0)) {
+	    if (argc == 3)
+		rv = pxe_restart(argv[2]);
+	} else {
+	    rv = pxechn(argc - 1, &argv[1]);
+	}
+    }
+    if (rv <= -1 ) {
+	usage();
+	rv = 1;
+    }
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#include <syslinux/reboot.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+    int warm = 0;
+    int i;
+
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--warm"))
+	    warm = 1;
+    }
+
+    syslinux_reboot(warm);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sanboot.c
+ *
+ * Invoke the gPXE "sanboot" command, if available.
+ */
+
+#include <alloca.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <string.h>
+
+#include <sys/gpxe.h>
+#include <syslinux/pxe_api.h>
+
+struct segoff16 {
+    uint16_t offs, seg;
+};
+
+struct s_PXENV_FILE_EXEC {
+    uint16_t Status;
+    struct segoff16 Command;
+};
+
+static void sanboot(const char **args)
+{
+    char *q;
+    struct s_PXENV_FILE_EXEC *fx;
+
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
+    q = (char *)(fx + 1);
+
+    fx->Status = 1;
+    fx->Command.offs = OFFS(q);
+    fx->Command.seg = SEG(q);
+
+    q = stpcpy(q, "sanboot");
+
+    while (*args) {
+	*q++ = ' ';
+	q = stpcpy(q, *args);
+	args++;
+    }
+
+    pxe_call(PXENV_FILE_EXEC, fx);
+
+    /* This should not return... */
+}
+
+int main(int argc, const char *argv[])
+{
+    if (argc < 2) {
+	printf("Usage: sanboot rootpath\n");
+	return 1;
+    }
+
+    if (!is_gpxe()) {
+	printf("sanboot: gPXE API not detected\n");
+	return 1;
+    }
+
+    sanboot(argv + 1);
+
+    /* sanboot() should not return... */
+    printf("SAN boot failed.\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,185 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sdi.c
+ *
+ * Loader for the Microsoft System Deployment Image (SDI) format.
+ * Based on a historical patch by Remi Lefevre.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootrm.h>
+
+typedef uint8_t guid_t[16];
+
+struct SDIHeader {
+    uint32_t Signature;
+    char Version[4];
+    uint64_t MDBtype;
+    uint64_t BootCodeOffset;
+    uint64_t BootCodeSize;
+    uint64_t VendorID;
+    uint64_t DeviceID;
+    guid_t DeviceModel;
+    uint64_t DeviceRole;
+    uint64_t Reserved1;
+    guid_t RuntimeGUID;
+    uint64_t RuntimeOEMrev;
+    uint64_t Reserved2;
+    uint64_t PageAlignment;	/* BLOB alignment value in pages */
+    uint64_t Reserved3[48];
+    uint64_t Checksum;
+};
+
+#define SDI_LOAD_ADDR	(16 << 20)	/* 16 MB */
+#define SDI_SIGNATURE	('$' + ('S' << 8) + ('D' << 16) + ('I' << 24))
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+static int boot_sdi(void *ptr, size_t len)
+{
+    const struct SDIHeader *hdr = ptr;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_rm_regs regs;
+    struct syslinux_movelist *ml = NULL;
+
+    /* **** Basic sanity checking **** */
+    if (hdr->Signature != SDI_SIGNATURE) {
+	fputs("No $SDI signature in file\n", stdout);
+	goto bail;
+    }
+    if (memcmp(hdr->Version, "0001", 4)) {
+	int i;
+	fputs("Warning: unknown SDI version: ", stdout);
+	for (i = 0; i < 4; i++)
+	    putchar(hdr->Version[i]);
+	putchar('\n');
+	/* Then try anyway... */
+    }
+
+    /* **** Setup **** */
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    /* **** Map the BOOT BLOB to 0x7c00 **** */
+    if (!hdr->BootCodeOffset) {
+	fputs("No BOOT BLOB in image\n", stdout);
+	goto bail;
+    }
+    if (!hdr->BootCodeSize) {
+	fputs("BOOT BLOB is empty\n", stdout);
+	goto bail;
+    }
+    if (len < hdr->BootCodeOffset + hdr->BootCodeSize) {
+	fputs("BOOT BLOB extends beyond file\n", stdout);
+	goto bail;
+    }
+
+    if (syslinux_memmap_type(amap, 0x7c00, hdr->BootCodeSize) != SMT_FREE) {
+	fputs("BOOT BLOB too large for memory\n", stdout);
+	goto bail;
+    }
+    if (syslinux_add_memmap(&amap, 0x7c00, hdr->BootCodeSize, SMT_ALLOC))
+	goto bail;
+    if (syslinux_add_movelist(&ml, 0x7c00, (addr_t) ptr + hdr->BootCodeOffset,
+			      hdr->BootCodeSize))
+	goto bail;
+
+    /* **** Map the entire image to SDI_LOAD_ADDR **** */
+    if (syslinux_memmap_type(amap, SDI_LOAD_ADDR, len) != SMT_FREE) {
+	fputs("Image too large for memory\n", stdout);
+	goto bail;
+    }
+    if (syslinux_add_memmap(&amap, SDI_LOAD_ADDR, len, SMT_ALLOC))
+	goto bail;
+    if (syslinux_add_movelist(&ml, SDI_LOAD_ADDR, (addr_t) ptr, len))
+	goto bail;
+
+    /* **** Set up registers **** */
+    memset(&regs, 0, sizeof regs);
+    regs.ip = 0x7c00;
+    regs.esp.l = 0x7c00;
+    regs.edx.l = SDI_LOAD_ADDR | 0x41;
+
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_rm(ml, mmap, 0, &regs);
+
+bail:
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+    return -1;
+}
+
+/*
+ * Check that the sum of all bytes from first 512 bytes (SDI header)
+ * is 0 modulo 256.
+ */
+int has_valid_header(unsigned char *header)
+{
+    unsigned char checksum;
+    unsigned int i;
+
+    checksum = 0;
+    for (i = 0; i < sizeof(struct SDIHeader); i++)
+	checksum += header[i];
+    return (!checksum);
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+
+    if (argc != 2) {
+	error("Usage: sdi.c32 sdi_file\n");
+	return 1;
+    }
+
+    fputs("Loading ", stdout);
+    fputs(argv[1], stdout);
+    fputs("... ", stdout);
+    if (zloadfile(argv[1], &data, &data_len)) {
+	error("failed!\n");
+	return 1;
+    }
+    fputs("ok\n", stdout);
+
+    if (!has_valid_header(data)) {
+	error("SDI header is corrupted\n");
+	return 1;
+    }
+
+    boot_sdi(data, data_len);
+    error("Invalid SDI file or insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+		bits 16
+		rep movsd
+		mov si,0
+		mov di,0
+		mov ds,si
+		mov es,di
+		mov ecx,0
+		mov esi,0
+		mov edi,0
+		jmp 0:0
+		align 16
Index: bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+	bits 16
+swap:
+	push bx
+	movzx bx,dl
+	mov dl,[cs:bx+(table-$$)]
+	pop bx
+.jmp:	jmp 0:0
+	nop
+	nop
+install:
+	;; DS = CS, ES = 0
+	mov edi,[es:si+4*0x13]
+	mov [swap.jmp+1],edi
+	mov di,[es:0x413]
+	dec di
+	mov [es:0x413],di
+	shl edi,16+6
+	mov [es:si+4*0x13],edi
+	shr edi,16
+	mov es,di
+	xor di,di
+	rep movsd
+	mov si,0
+	mov di,0
+	mov ds,si
+	mov es,di
+	mov ecx,0
+	mov esi,0
+	mov edi,0
+	jmp 0:0
+
+	align 16
+table:
Index: bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,92 @@
+/*
+ * vesainfo.c
+ *
+ * Dump information about what VESA graphics modes are supported.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <inttypes.h>
+#include "../lib/sys/vesa/vesa.h"
+
+/* Wait for a keypress */
+static void wait_key(void)
+{
+    char ch;
+    while (fread(&ch, 1, 1, stdin) == 0) ;
+}
+
+static void print_modes(void)
+{
+	static com32sys_t rm;
+	struct vesa_general_info *gi;
+	struct vesa_mode_info *mi;
+	uint16_t mode, *mode_ptr;
+	int lines;
+
+	struct vesa_info *vesa;
+
+	vesa = lmalloc(sizeof(*vesa));
+	if (!vesa) {
+		printf("vesainfo.c32: fail in lmalloc\n");
+		return;
+	}
+	gi = &vesa->gi;
+	mi = &vesa->mi;
+
+        memset(&rm, 0, sizeof rm);
+	gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+	rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+	rm.edi.w[0] = OFFS(gi);
+	rm.es = SEG(gi);
+	__intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F) {
+	printf("No VESA BIOS detected\n");
+	goto exit;
+    } else if (gi->signature != VESA_MAGIC) {
+	printf("VESA information structure has bad magic, trying anyway...\n");
+    }
+
+    printf("VBE version %d.%d\n"
+	   "Mode   attrib h_res v_res bpp layout rpos gpos bpos\n",
+	   (gi->version >> 8) & 0xff, gi->version & 0xff);
+
+    lines = 1;
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	if (++lines >= 23) {
+	    wait_key();
+	    lines = 0;
+	}
+
+        memset(&rm, 0, sizeof rm);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mi);
+	rm.es = SEG(mi);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	printf("0x%04x 0x%04x %5u %5u %3u %6u %4u %4u %4u\n",
+	       mode, mi->mode_attr, mi->h_res, mi->v_res, mi->bpp,
+	       mi->memory_layout, mi->rpos, mi->gpos, mi->bpos);
+    }
+
+exit:
+	lfree(vesa);
+	return;
+}
+
+int main(int argc __unused, char **argv __unused)
+{
+    print_modes();
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * vpdtest.c
+ *
+ * VPD demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "vpd/vpd.h"
+
+int main(void)
+{
+    s_vpd vpd;
+
+    if (vpd_decode(&vpd) == -ENOVPDTABLE) {
+	printf("No VPD Structure found\n");
+	return -1;
+    } else {
+	printf("VPD present at address : 0x%s\n", vpd.base_address);
+    }
+    if (strlen(vpd.bios_build_id) > 0)
+	printf("Bios Build ID                 : %s\n", vpd.bios_build_id);
+    if (strlen(vpd.bios_release_date) > 0)
+	printf("Bios Release Date             : %s\n", vpd.bios_release_date);
+    if (strlen(vpd.bios_version) > 0)
+	printf("Bios Version                  : %s\n", vpd.bios_version);
+    if (strlen(vpd.default_flash_filename) > 0)
+	printf("Default Flash Filename        : %s\n",
+	       vpd.default_flash_filename);
+    if (strlen(vpd.box_serial_number) > 0)
+	printf("Box Serial Number             : %s\n", vpd.box_serial_number);
+    if (strlen(vpd.motherboard_serial_number) > 0)
+	printf("Motherboard Serial Number     : %s\n",
+	       vpd.motherboard_serial_number);
+    if (strlen(vpd.machine_type_model) > 0)
+	printf("Machine Type/Model            : %s\n", vpd.machine_type_model);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,126 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gert Hulselmans - 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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * whichsys.c
+ *
+ * Detemine which command to execute, based on the Syslinux bootloader variant
+ * from which you run it.
+ *
+ * Usage:    whichsys.c32 [-iso- command] [-pxe- command] [-sys- command]
+ * Examples: whichsys.c32 -iso- chain.c32 hd0 -sys- chain.c32 hd1 swap
+ *           whichsys.c32 -iso- config iso.cfg -pxe- config pxe.cfg
+ *
+ */
+
+#include <stdio.h>
+#include <alloca.h>
+#include <console.h>
+#include <string.h>
+#include <syslinux/boot.h>
+#include "syslinux/config.h"
+
+
+static struct syslinux_parameter {
+    char **arg[1];
+    bool option;
+} isolinux, pxelinux, syslinux;
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+static void usage(void)
+{
+    static const char usage[] = "\
+Usage:    whichsys.c32 [-iso- command] [-pxe- command] [-sys- command]\n\
+Examples: whichsys.c32 -iso- chain.c32 hd0 -sys- chain.c32 hd1 swap\n\
+          whichsys.c32 -iso- config iso.cfg -pxe- config pxe.cfg\n";
+    fprintf(stderr, usage);
+}
+
+int main(int argc, char *argv[])
+{
+    const union syslinux_derivative_info *sdi;
+
+    int arg = 0;
+
+    /* If no argument got passed, let's show the usage */
+    if (argc == 1) {
+	    usage();
+	    return 0;
+    }
+
+    arg++;
+
+    while (arg < argc) {
+	if (!strcmp(argv[arg], "-iso-")) {
+	    argv[arg] = NULL;
+	    isolinux.arg[0] = &argv[arg + 1];
+	    isolinux.option = true;
+	}
+	if (!strcmp(argv[arg], "-pxe-")) {
+	    argv[arg] = NULL;
+	    pxelinux.arg[0] = &argv[arg + 1];
+	    pxelinux.option = true;
+	}
+	if (!strcmp(argv[arg], "-sys-")) {
+	    argv[arg] = NULL;
+	    syslinux.arg[0] = &argv[arg + 1];
+	    syslinux.option = true;
+	}
+	arg++;
+    }
+
+    sdi = syslinux_derivative_info();
+
+    switch (sdi->c.filesystem) {
+	case SYSLINUX_FS_ISOLINUX:
+	    isolinux.option ? boot_args(isolinux.arg[0]) : fprintf(stderr, "No command specified for ISOLINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_PXELINUX:
+	    pxelinux.option ? boot_args(pxelinux.arg[0]) : fprintf(stderr, "No command specified for PXELINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_SYSLINUX:
+	    syslinux.option ? boot_args(syslinux.arg[0]) : fprintf(stderr, "No command specified for SYSLINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_UNKNOWN:
+	default:
+	    fprintf(stderr, "Unknown Syslinux filesystem\n\n");
+    }
+
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,107 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <zzjson/zzjson.h>
+#include <stdarg.h>
+
+static void myerror(void *ehandle, const char *format, ...) {
+    va_list ap;
+    fprintf(ehandle, "error: ");
+    va_start(ap, format);
+    vfprintf(ehandle, format, ap);
+    va_end(ap);
+    fputc('\n', ehandle);
+}
+
+
+int main(int argc, char *argv[])
+{
+#if 0
+	/* this hangs! */
+    openconsole(&dev_rawcon_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+    (void) argc;
+    (void) argv;
+    ZZJSON  *tmp;
+    ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+                             (int(*)(void*)) fgetc,
+                             NULL,
+                             malloc, calloc, free, realloc,
+                             stderr, myerror, stdout,
+                             (int(*)(void*,const char*,...)) fprintf,
+                             (int(*)(int,void*)) fputc };
+    
+    do {
+        ZZJSON *tmp2;
+
+        tmp = zzjson_create_array(&config,
+                zzjson_create_number_d(&config, 3.14),
+                zzjson_create_number_i(&config, 1234LL),
+                zzjson_create_number_i(&config, -4321LL),
+                zzjson_create_true(&config),
+                zzjson_create_false(&config),
+                zzjson_create_null(&config),
+                zzjson_create_string(&config, "hello, world"),
+                zzjson_create_object(&config,
+                    "picard", zzjson_create_string(&config, "jean-luc"),
+                    "riker",  zzjson_create_string(&config, "william t."),
+                    NULL),
+                zzjson_create_object(&config, NULL),
+                zzjson_create_array(&config, NULL),
+                NULL );
+
+        if (!tmp) {
+            fprintf(stderr, "error during creation of json tree\n");
+            break;
+        }
+
+        tmp2 = zzjson_array_prepend(&config, tmp,
+                    zzjson_create_string(&config, "prepended string"));
+
+        if (!tmp2) {
+            fprintf(stderr, "error during prepend\n");
+            break;
+        }
+        tmp = tmp2;
+
+        tmp2 = zzjson_array_append(&config, tmp,
+                    zzjson_create_string(&config, "appended string (slow)"));
+
+        if (!tmp2) {
+            fprintf(stderr, "error during append\n");
+            break;
+        }
+        tmp = tmp2;
+
+        zzjson_print(&config, tmp);
+    } while(0);
+    if (tmp) zzjson_free(&config, tmp);
+
+    {
+        tmp = zzjson_create_array(&config, NULL); /* empty array */
+        tmp = zzjson_array_prepend(&config, tmp, zzjson_create_true(&config));
+        zzjson_print(&config, tmp);
+        zzjson_free(&config, tmp);
+    }
+
+    {
+        tmp = zzjson_create_object(&config, NULL); /* empty object */
+        tmp = zzjson_object_prepend(&config, tmp, "hello",
+                                zzjson_create_string(&config, "world"));
+        tmp = zzjson_object_append(&config, tmp, "goodbye",
+                                zzjson_create_string(&config, "cruel world"));
+        zzjson_print(&config, tmp);
+        zzjson_free(&config, tmp);
+    }
+
+    return 0;
+}
+  
Index: bootcd/isolinux/syslinux-6.03/com32/rosh/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/rosh/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/rosh/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+##   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+##   Copyright 2008-2010 Gene Cumm - 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.
+##
+## -----------------------------------------------------------------------
+
+##
+## ROSH Read Only Shell
+##
+
+LIBS = $(objdir)/com32/libutil/libutil.c32 \
+	$(objdir)/com32/lib/libcom32.c32
+
+VPATH = $(SRC)
+include $(MAKEDIR)/rosh.mk
+
+# from com32/sysdump/Makefile
+# The DATE is set on the make command line when building binaries for
+# official release.  Otherwise, substitute a hex string that is pretty much
+# guaranteed to be unique to be unique from build to build.
+ifndef HEXDATE
+HEXDATE := $(shell $(PERL) $(topdir)/now.pl $(SRCS) $(wildcard *.h))
+endif
+ifndef DATE
+DATE    := $(shell sh $(topdir)/gen-id.sh $(VERSION) $(HEXDATE))
+endif
+
+CFLAGS		+= -DDATE='"$(DATE)"'
+LNXCFLAGS	+= -DDATE='"$(DATE)"'
+
+all:	rosh.c32
+
+rosh.o:	rosh.h
+
+rosh.lo:	rosh.h
+
+allgrc:	rosh.c32 rosh.lnx
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1363 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008-2011 Gene Cumm - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rosh.c
+ *
+ * Read-Only shell; Simple shell system designed for SYSLINUX-derivitives.
+ * Provides minimal commands utilizing the console via stdout/stderr as the
+ * sole output devices.  Designed to compile for Linux for testing/debugging.
+ */
+
+/*
+ * ToDos:
+ * prompt:	Allow left/right arrow, home/end and more?
+ * commands	Break into argv/argc-like array
+ * rosh_cfg:	allow -s <file> to change config
+ * rosh_ls():	sorted; then multiple columns
+ * prompt:	Possibly honor timeout on initial entry for usage as UI
+ *		Also possibly honor totaltimeout
+ */
+
+/*#define DO_DEBUG 1
+//*/
+/* Uncomment the above line for debugging output; Comment to remove */
+/*#define DO_DEBUG2 1
+//*/
+/* Uncomment the above line for super-debugging output; Must have regular
+ * debugging enabled; Comment to remove.
+ */
+#include "rosh.h"
+#include "version.h"
+
+#define APP_LONGNAME	"Read-Only Shell"
+#define APP_NAME	"rosh"
+#define APP_AUTHOR	"Gene Cumm"
+#define APP_YEAR	"2010"
+#define APP_VER		"beta-b090"
+
+/* Print version information to stdout
+ */
+void rosh_version(int vtype)
+{
+    char env[256];
+    env[0] = 0;
+    printf("%s v %s; (c) %s %s.\n\tFrom Syslinux %s, %s\n", APP_LONGNAME, APP_VER, APP_YEAR, APP_AUTHOR, VERSION_STR, DATE);
+    switch (vtype) {
+    case 1:
+	rosh_get_env_ver(env, 256);
+	printf("\tRunning on %s\n", env);
+    }
+}
+
+/* Print beta message and if DO_DEBUG/DO_DEBUG2 are active
+ */
+void print_beta(void)
+{
+    puts(rosh_beta_str);
+    ROSH_DEBUG("DO_DEBUG active\n");
+    ROSH_DEBUG2("DO_DEBUG2 active\n");
+}
+
+/* Search a string for first non-space (' ') character, starting at ipos
+ *	istr	input string to parse
+ *	ipos	input position to start at
+ */
+int rosh_search_nonsp(const char *istr, const int ipos)
+{
+    int curpos;
+    char c;
+
+    curpos = ipos;
+    c = istr[curpos];
+    while (c && isspace(c))
+	c = istr[++curpos];
+    return curpos;
+}
+
+/* Search a string for space (' '), returning the position of the next space
+ * or the '\0' at end of string
+ *	istr	input string to parse
+ *	ipos	input position to start at
+ */
+int rosh_search_sp(const char *istr, const int ipos)
+{
+    int curpos;
+    char c;
+
+    curpos = ipos;
+    c = istr[curpos];
+    while (c && !(isspace(c)))
+	c = istr[++curpos];
+    return curpos;
+}
+
+/* Parse a string for the first non-space string, returning the end position
+ * from src
+ *	dest	string to contain the first non-space string
+ *	src	string to parse
+ *	ipos	Position to start in src
+ */
+int rosh_parse_sp_1(char *dest, const char *src, const int ipos)
+{
+    int bpos, epos;		/* beginning and ending position of source string
+				   to copy to destination string */
+
+    bpos = 0;
+    epos = 0;
+/* //HERE-error condition checking */
+    bpos = rosh_search_nonsp(src, ipos);
+    epos = rosh_search_sp(src, bpos);
+    if (epos > bpos) {
+	memcpy(dest, src + bpos, epos - bpos);
+	if (dest[epos - bpos] != 0)
+	    dest[epos - bpos] = 0;
+    } else {
+	epos = strlen(src);
+	dest[0] = 0;
+    }
+    return epos;
+}
+
+/*
+ * parse_args1: Try 1 at parsing a string to an argc/argv pair.  use free_args1 to free memory malloc'd
+ *
+ * Derived from com32/lib/sys/argv.c:__parse_argv()
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ */
+int parse_args1(char ***iargv, const char *istr)
+{
+    int argc  = 0;
+    const char *p;
+    char *q, *r, *args, **arg;
+    int sp = 1;	//, qt = 0;		/* Was a space; inside a quote */
+
+    /* Scan 1: Length */
+    /* I could eliminate this if I knew a max length, like strncpy() */
+    int len = strlen(istr);
+
+    /* Scan 2: Copy, nullify and make argc */
+    if (!(args = malloc(len + 1)))
+	goto fail_args;
+    q = args;
+    for (p = istr;; p++) {
+	if (*p <= ' ') {
+	    if (!sp) {
+		sp = 1;
+		*q++ = '\0';
+	    }
+	} else {
+	    if (sp) {
+		argc++;
+		sp = 0;
+	    }
+	    *q++ = *p;
+	}
+	if (!*p)
+	    break;
+    }
+
+    q--;			/* Point q to final null */
+    /* Scan 3: Build array of pointers */
+    if (!(*iargv = malloc((argc + 1) * sizeof(char *))))
+	goto fail_args_ptr;
+    arg = *iargv;
+    arg[argc] = NULL;		/* Nullify the last pointer */
+    if (*args != '\0')
+	    *arg++ = args;
+    for (r = args; r < q ; r++) {
+	if (*r == '\0') {
+	    *arg++ = r + 1;
+	}
+    }
+
+fail_args:
+    return argc;
+fail_args_ptr:
+    free(args);
+    return 0;
+}
+
+/* Free argv created by parse_args1()
+ *	argv	Argument Values
+ */
+void free_args1(char ***argv)
+{
+    char *s;
+    s = **argv;
+    free(*argv);
+    free(s);
+}
+
+/* Convert a string to an argc/argv pair
+ *	str	String to parse
+ *	argv	Argument Values
+ *	returns	Argument Count
+ */
+int rosh_str2argv(char ***argv, const char *str)
+{
+    return parse_args1(argv, str);
+}
+
+/* Free an argv created by rosh_str2argv()
+ *	argv	Argument Values to free
+ */
+void rosh_free_argv(char ***argv)
+{
+     free_args1(argv);
+}
+
+/* Print the contents of an argc/argv pair
+ *	argc	Argument Count
+ *	argv	Argument Values
+ */
+void rosh_pr_argv(int argc, char *argv[])
+{
+    int i;
+    for (i = 0; i < argc; i++) {
+	printf("%s%s", argv[i], (i < argc)? " " : "");
+    }
+    puts("");
+}
+
+/* Print the contents of an argc/argv pair verbosely
+ *	argc	Argument Count
+ *	argv	Argument Values
+ */
+void rosh_pr_argv_v(int argc, char *argv[])
+{
+    int i;
+    for (i = 0; i < argc; i++) {
+	printf("%4d '%s'\n", i, argv[i]);
+    }
+}
+
+/* Reset the getopt() environment
+ */
+void rosh_getopt_reset(void)
+{
+    optind = 0;
+    optopt = 0;
+}
+
+/* Display help
+ *	type	Help type
+ *	cmdstr	Command for which help is requested
+ */
+void rosh_help(int type, const char *cmdstr)
+{
+    switch (type) {
+    case 2:
+	if ((cmdstr == NULL) || (strcmp(cmdstr, "") == 0)) {
+	    rosh_version(0);
+	    puts(rosh_help_str2);
+	} else {
+	    switch (cmdstr[0]) {
+	    case 'c':
+		puts(rosh_help_cd_str);
+		break;
+	    case 'l':
+		puts(rosh_help_ls_str);
+		break;
+	    default:
+		printf(rosh_help_str_adv, cmdstr);
+	    }
+	}
+	break;
+    case 1:
+    default:
+	if (cmdstr)
+	    printf("%s: %s: unknown command\n", APP_NAME, cmdstr);
+	rosh_version(0);
+	puts(rosh_help_str1);
+    }
+}
+
+/* Handle most/all errors
+ *	ierrno	Input Error number
+ *	cmdstr	Command being executed to cause error
+ *	filestr	File/parameter causing error
+ */
+void rosh_error(const int ierrno, const char *cmdstr, const char *filestr)
+{
+    printf("--ERROR: %s '%s': ", cmdstr, filestr);
+    switch (ierrno) {
+    case 0:
+	puts("NO ERROR");
+	break;
+    case ENOENT:
+	puts("not found");
+	/* SYSLinux-3.72 COM32 API returns this for a
+	   directory or empty file */
+	ROSH_COM32("  (COM32) could be a directory or empty file\n");
+	break;
+    case EIO:
+	puts("I/O Error");
+	break;
+    case EBADF:
+	puts("Bad File Descriptor");
+	break;
+    case EACCES:
+	puts("Access DENIED");
+	break;
+    case ENOTDIR:
+	puts("not a directory");
+	ROSH_COM32("  (COM32) could be directory\n");
+	break;
+    case EISDIR:
+	puts("IS a directory");
+	break;
+    case ENOSYS:
+	puts("not implemented");
+	break;
+    default:
+	printf("returns error; errno=%d\n", ierrno);
+    }
+}				/* rosh_error */
+
+/* Concatenate command line arguments into one string
+ *	cmdstr	Output command string
+ *	cmdlen	Length of cmdstr
+ *	argc	Argument Count
+ *	argv	Argument Values
+ *	barg	Beginning Argument
+ */
+int rosh_argcat(char *cmdstr, const int cmdlen, const int argc, char *argv[],
+		const int barg)
+{
+    int i, arglen, curpos;	/* index, argument length, current position
+				   in cmdstr */
+    curpos = 0;
+    cmdstr[0] = '\0';		/* Nullify string just to be sure */
+    for (i = barg; i < argc; i++) {
+	arglen = strlen(argv[i]);
+	/* Theoretically, this should never be met in SYSLINUX */
+	if ((curpos + arglen) > (cmdlen - 1))
+	    arglen = (cmdlen - 1) - curpos;
+	memcpy(cmdstr + curpos, argv[i], arglen);
+	curpos += arglen;
+	if (curpos >= (cmdlen - 1)) {
+	    /* Hopefully, curpos should not be greater than
+	       (cmdlen - 1) */
+	    /* Still need a '\0' at the last character */
+	    cmdstr[(cmdlen - 1)] = 0;
+	    break;		/* Escape out of the for() loop;
+				   We can no longer process anything more */
+	} else {
+	    cmdstr[curpos] = ' ';
+	    curpos += 1;
+	    cmdstr[curpos] = 0;
+	}
+    }
+    /* If there's a ' ' at the end, remove it.  This is normal unless
+       the maximum length is met/exceeded. */
+    if (cmdstr[curpos - 1] == ' ')
+	cmdstr[--curpos] = 0;
+    return curpos;
+}				/* rosh_argcat */
+
+/*
+ * Prints a lot of the data in a struct termios
+ */
+/*
+void rosh_print_tc(struct termios *tio)
+{
+	printf("  -- termios: ");
+	printf(".c_iflag=%04X ", tio->c_iflag);
+	printf(".c_oflag=%04X ", tio->c_oflag);
+	printf(".c_cflag=%04X ", tio->c_cflag);
+	printf(".c_lflag=%04X ", tio->c_lflag);
+	printf(".c_cc[VTIME]='%d' ", tio->c_cc[VTIME]);
+	printf(".c_cc[VMIN]='%d'", tio->c_cc[VMIN]);
+	printf("\n");
+}
+*/
+
+/*
+ * Attempts to get a single key from the console
+ *	returns	key pressed
+ */
+int rosh_getkey(void)
+{
+    int inc;
+
+    inc = KEY_NONE;
+    while (inc == KEY_NONE)
+	inc = get_key(stdin, 6000);
+    return inc;
+}				/* rosh_getkey */
+
+/*
+ * Qualifies a filename relative to the working directory
+ *	filestr	Filename to qualify
+ *	pwdstr	working directory
+ *	returns	qualified file name string
+ */
+void rosh_qualify_filestr(char *filestr, const char *ifilstr,
+			  const char *pwdstr)
+{
+    int filepos = 0;
+    if ((filestr) && (pwdstr) && (ifilstr)) {
+	if (ifilstr[0] != SEP) {
+	    strcpy(filestr, pwdstr);
+	    filepos = strlen(pwdstr);
+	    if (filestr[filepos - 1] != SEP)
+		filestr[filepos++] = SEP;
+	}
+	strcpy(filestr + filepos, ifilstr);
+	ROSH_DEBUG("--'%s'\n", filestr);
+    }
+}
+
+/* Concatenate multiple files to stdout
+ *	argc	Argument Count
+ *	argv	Argument Values
+ */
+void rosh_cat(int argc, char *argv[])
+{
+    FILE *f;
+    char buf[ROSH_BUF_SZ];
+    int i, numrd;
+
+    for (i = 0; i < argc; i++) {
+	printf("--File = '%s'\n", argv[i]);
+	errno = 0;
+	f = fopen(argv[i], "r");
+	if (f != NULL) {
+	    numrd = fread(buf, 1, ROSH_BUF_SZ, f);
+	    while (numrd > 0) {
+		fwrite(buf, 1, numrd, stdout);
+		numrd = fread(buf, 1, ROSH_BUF_SZ, f);
+	    }
+	    fclose(f);
+	} else {
+	    rosh_error(errno, "cat", argv[i]);
+	    errno = 0;
+	}
+    }
+}				/* rosh_cat */
+
+/* Change PWD (Present Working Directory)
+ *	argc	Argument count
+ *	argv	Argument values
+ *	ipwdstr	Initial PWD
+ */
+void rosh_cd(int argc, char *argv[], const char *ipwdstr)
+{
+    int rv = 0;
+#ifdef DO_DEBUG
+    char filestr[ROSH_PATH_SZ];
+#endif /* DO_DEBUG */
+    ROSH_DEBUG("CMD: \n");
+    ROSH_DEBUG_ARGV_V(argc, argv);
+    errno = 0;
+    if (argc == 2)
+	rv = chdir(argv[1]);
+    else if (argc == 1)
+	rv = chdir(ipwdstr);
+    else
+	rosh_help(2, argv[0]);
+    if (rv != 0) {
+	if (argc == 2)
+	    rosh_error(errno, "cd", argv[1]);
+	else
+	    rosh_error(errno, "cd", ipwdstr);
+	errno = 0;
+    } else {
+#ifdef DO_DEBUG
+	if (getcwd(filestr, ROSH_PATH_SZ))
+	    ROSH_DEBUG("  %s\n", filestr);
+#endif /* DO_DEBUG */
+    }
+}				/* rosh_cd */
+
+/* Print the syslinux config file name
+ */
+void rosh_cfg(void)
+{
+    printf("CFG:     '%s'\n", syslinux_config_file());
+}				/* rosh_cfg */
+
+/* Echo a string back to the screen
+ *	cmdstr	command string to process
+ */
+void rosh_echo(const char *cmdstr)
+{
+    int bpos = 0;
+    ROSH_DEBUG("CMD: '%s'\n", cmdstr);
+    bpos = rosh_search_nonsp(cmdstr, rosh_search_sp(cmdstr, 0));
+    if (bpos > 1) {
+	ROSH_DEBUG("  bpos=%d\n", bpos);
+	printf("'%s'\n", cmdstr + bpos);
+    } else {
+	puts("");
+    }
+}				/* rosh_echo */
+
+/* Process argc/argv to optarr
+ *	argc	Argument count
+ *	argv	Argument values
+ *	optarr	option array to populate
+ */
+void rosh_ls_arg_opt(int argc, char *argv[], int optarr[])
+{
+    int rv = 0;
+
+    optarr[0] = -1;
+    optarr[1] = -1;
+    optarr[2] = -1;
+    rosh_getopt_reset();
+    while (rv != -1) {
+	ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+	rv = getopt(argc, argv, rosh_ls_opt_str);
+	switch (rv) {
+	case 'l':
+	case 0:
+	    optarr[0] = 1;
+	    break;
+	case 'F':
+	case 1:
+	    optarr[1] = 1;
+	    break;
+	case 'i':
+	case 2:
+	    optarr[2] = 1;
+	    break;
+	case '?':
+	case -1:
+	default:
+	    ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+	    break;
+	}
+    }
+    ROSH_DEBUG2(" end getopt optind=%d rv=%d\n", optind, rv);
+    ROSH_DEBUG2("\tIn rosh_ls_arg_opt() opt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr[0], optarr[1],
+	       optarr[2]);
+}				/* rosh_ls_arg_opt */
+
+/* Retrieve the size of a file argument
+ *	filestr	directory name of directory entry
+ *	de	directory entry
+ */
+int rosh_ls_de_size(const char *filestr, struct dirent *de)
+{
+    int de_size;
+    char filestr2[ROSH_PATH_SZ];
+    int fd2, file2pos;
+    struct stat fdstat;
+
+    filestr2[0] = 0;
+    file2pos = -1;
+    if (filestr) {
+	file2pos = strlen(filestr);
+	memcpy(filestr2, filestr, file2pos);
+	filestr2[file2pos] = '/';
+    }
+    strcpy(filestr2 + file2pos + 1, de->d_name);
+    fd2 = open(filestr2, O_RDONLY);
+    fstat(fd2, &fdstat);
+    fd2 = close(fd2);
+    de_size = (int)fdstat.st_size;
+    return de_size;
+}				/* rosh_ls_de_size */
+
+/* Retrieve the size and mode of a file
+ *	filestr	directory name of directory entry
+ *	de	directory entry
+ */
+int rosh_ls_de_size_mode(const char *filestr, struct dirent *de, mode_t * st_mode)
+{
+    int de_size;
+    char filestr2[ROSH_PATH_SZ];
+    int file2pos;
+    struct stat fdstat;
+    int status;
+
+    filestr2[0] = 0;
+    file2pos = -1;
+    memset(&fdstat, 0, sizeof fdstat);
+    ROSH_DEBUG2("ls:dsm(%s, %s) ", filestr, de->d_name);
+    if (filestr) {
+	/* FIXME: prevent string overflow */
+	file2pos = strlen(filestr);
+	memcpy(filestr2, filestr, file2pos);
+	if (( filestr2[file2pos - 1] == SEP )) {
+	    file2pos--;
+	} else {
+	    filestr2[file2pos] = SEP;
+	}
+    }
+    strcpy(filestr2 + file2pos + 1, de->d_name);
+    errno = 0;
+    ROSH_DEBUG2("stat(%s) ", filestr2);
+    status = stat(filestr2, &fdstat);
+    (void)status;
+    ROSH_DEBUG2("\t--stat()=%d\terr=%d\n", status, errno);
+    if (errno) {
+	rosh_error(errno, "ls:szmd.stat", de->d_name);
+	errno = 0;
+    }
+    de_size = (int)fdstat.st_size;
+    *st_mode = fdstat.st_mode;
+    return de_size;
+}				/* rosh_ls_de_size_mode */
+
+/* Returns the Inode number if fdstat contains it
+ *	fdstat	struct to extract inode from if not COM32, for now
+ */
+long rosh_ls_d_ino(struct stat *fdstat)
+{
+    long de_ino;
+#ifdef __COM32__
+    if (fdstat)
+	de_ino = -1;
+    else
+	de_ino = 0;
+#else /* __COM32__ */
+    de_ino = fdstat->st_ino;
+#endif /* __COM32__ */
+    return de_ino;
+}
+
+/* Convert a d_type to a single char in human readable format
+ *	d_type	d_type to convert
+ *	returns human readable single character; a space if other
+ */
+char rosh_d_type2char_human(unsigned char d_type)
+{
+    char ret;
+    switch (d_type) {
+    case DT_UNKNOWN:
+	ret = 'U';
+	break;			/* Unknown */
+    case DT_FIFO:
+	ret = 'F';
+	break;			/* FIFO */
+    case DT_CHR:
+	ret = 'C';
+	break;			/* Char Dev */
+    case DT_DIR:
+	ret = 'D';
+	break;			/* Directory */
+    case DT_BLK:
+	ret = 'B';
+	break;			/* Block Dev */
+    case DT_REG:
+	ret = 'R';
+	break;			/* Regular File */
+    case DT_LNK:
+	ret = 'L';
+	break;			/* Link, Symbolic */
+    case DT_SOCK:
+	ret = 'S';
+	break;			/* Socket */
+    case DT_WHT:
+	ret = 'W';
+	break;			/* UnionFS Whiteout */
+    default:
+	ret = ' ';
+    }
+    return ret;
+}				/* rosh_d_type2char_human */
+
+/* Convert a d_type to a single char by ls's prefix standards for -l
+ *	d_type	d_type to convert
+ *	returns ls style single character; a space if other
+ */
+char rosh_d_type2char_lspre(unsigned char d_type)
+{
+    char ret;
+    switch (d_type) {
+    case DT_FIFO:
+	ret = 'p';
+	break;
+    case DT_CHR:
+	ret = 'c';
+	break;
+    case DT_DIR:
+	ret = 'd';
+	break;
+    case DT_BLK:
+	ret = 'b';
+	break;
+    case DT_REG:
+	ret = '-';
+	break;
+    case DT_LNK:
+	ret = 'l';
+	break;
+    case DT_SOCK:
+	ret = 's';
+	break;
+    default:
+	ret = '?';
+    }
+    return ret;
+}				/* rosh_d_type2char_lspre */
+
+/* Convert a d_type to a single char by ls's classify (-F) suffix standards
+ *	d_type	d_type to convert
+ *	returns ls style single character; a space if other
+ */
+char rosh_d_type2char_lssuf(unsigned char d_type)
+{
+    char ret;
+    switch (d_type) {
+    case DT_FIFO:
+	ret = '|';
+	break;
+    case DT_DIR:
+	ret = '/';
+	break;
+    case DT_LNK:
+	ret = '@';
+	break;
+    case DT_SOCK:
+	ret = '=';
+	break;
+    default:
+	ret = ' ';
+    }
+    return ret;
+}				/* rosh_d_type2char_lssuf */
+
+/* Converts data in the "other" place of st_mode to a ls-style string
+ *	st_mode	Mode in other to analyze
+ *	st_mode_str	string to hold converted string
+ */
+void rosh_st_mode_am2str(mode_t st_mode, char *st_mode_str)
+{
+    st_mode_str[0] = ((st_mode & S_IROTH) ? 'r' : '-');
+    st_mode_str[1] = ((st_mode & S_IWOTH) ? 'w' : '-');
+    st_mode_str[2] = ((st_mode & S_IXOTH) ? 'x' : '-');
+}
+
+/* Converts st_mode to an ls-style string
+ *	st_mode	mode to convert
+ *	st_mode_str	string to hold converted string
+ */
+void rosh_st_mode2str(mode_t st_mode, char *st_mode_str)
+{
+    st_mode_str[0] = rosh_d_type2char_lspre(IFTODT(st_mode));
+    rosh_st_mode_am2str((st_mode & S_IRWXU) >> 6, st_mode_str + 1);
+    rosh_st_mode_am2str((st_mode & S_IRWXG) >> 3, st_mode_str + 4);
+    rosh_st_mode_am2str(st_mode & S_IRWXO, st_mode_str + 7);
+    st_mode_str[10] = 0;
+}				/* rosh_st_mode2str */
+
+/* Output a single entry
+ *	filestr	directory name to list
+ *	de	directory entry
+ *	optarr	Array of options
+ */
+void rosh_ls_arg_dir_de(const char *filestr, struct dirent *de, const int *optarr)
+{
+    int de_size;
+    mode_t st_mode;
+    char st_mode_str[11];
+    st_mode = 0;
+    ROSH_DEBUG2("+");
+    if (optarr[2] > -1)
+	printf("%10d ", (int)(de->d_ino));
+    if (optarr[0] > -1) {
+	de_size = rosh_ls_de_size_mode(filestr, de, &st_mode);
+	rosh_st_mode2str(st_mode, st_mode_str);
+	ROSH_DEBUG2("%04X ", st_mode);
+	printf("%s %10d ", st_mode_str, de_size);
+    }
+    ROSH_DEBUG("'");
+    printf("%s", de->d_name);
+    ROSH_DEBUG("'");
+    if (optarr[1] > -1)
+	printf("%c", rosh_d_type2char_lssuf(de->d_type));
+    printf("\n");
+}				/* rosh_ls_arg_dir_de */
+
+/* Output listing of a regular directory
+ *	filestr	directory name to list
+ *	d	the open DIR
+ *	optarr	Array of options
+	NOTE:This is where I could use qsort
+ */
+void rosh_ls_arg_dir(const char *filestr, DIR * d, const int *optarr)
+{
+    struct dirent *de;
+    int filepos;
+
+    filepos = 0;
+    errno = 0;
+    while ((de = readdir(d))) {
+	filepos++;
+	rosh_ls_arg_dir_de(filestr, de, optarr);
+    }
+    if (errno) {
+	rosh_error(errno, "ls:arg_dir", filestr);
+	errno = 0;
+    } else { if (filepos == 0)
+	ROSH_DEBUG("0 files found");
+    }
+}				/* rosh_ls_arg_dir */
+
+/* Simple directory listing for one argument (file/directory) based on
+ * filestr and pwdstr
+ *	ifilstr	input filename/directory name to list
+ *	pwdstr	Present Working Directory string
+ *	optarr	Option Array
+ */
+void rosh_ls_arg(const char *filestr, const int *optarr)
+{
+    struct stat fdstat;
+    int status;
+//     char filestr[ROSH_PATH_SZ];
+//     int filepos;
+    DIR *d;
+    struct dirent de;
+
+    /* Initialization; make filestr based on leading character of ifilstr
+       and pwdstr */
+//     rosh_qualify_filestr(filestr, ifilstr, pwdstr);
+    fdstat.st_mode = 0;
+    fdstat.st_size = 0;
+    ROSH_DEBUG("\topt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr[0], optarr[1],
+	       optarr[2]);
+
+    /* Now, the real work */
+    errno = 0;
+    status = stat(filestr, &fdstat);
+    if (status == 0) {
+	if (S_ISDIR(fdstat.st_mode)) {
+	    ROSH_DEBUG("PATH '%s' is a directory\n", filestr);
+	    if ((d = opendir(filestr))) {
+		rosh_ls_arg_dir(filestr, d, optarr);
+		closedir(d);
+	    } else {
+		rosh_error(errno, "ls", filestr);
+		errno = 0;
+	    }
+	} else {
+	    de.d_ino = rosh_ls_d_ino(&fdstat);
+	    de.d_type = (IFTODT(fdstat.st_mode));
+	    strcpy(de.d_name, filestr);
+	    if (S_ISREG(fdstat.st_mode)) {
+		ROSH_DEBUG("PATH '%s' is a regular file\n", filestr);
+	    } else {
+		ROSH_DEBUG("PATH '%s' is some other file\n", filestr);
+	    }
+	    rosh_ls_arg_dir_de(NULL, &de, optarr);
+/*	    if (ifilstr[0] == SEP)
+		rosh_ls_arg_dir_de(NULL, &de, optarr);
+	    else
+		rosh_ls_arg_dir_de(pwdstr, &de, optarr);*/
+	}
+    } else {
+	rosh_error(errno, "ls", filestr);
+	errno = 0;
+    }
+    return;
+}				/* rosh_ls_arg */
+
+/* Parse options that may be present in the cmdstr
+ *	filestr	Possible option string to parse
+ *	optstr	Current options
+ *	returns 1 if filestr does not begin with '-' else 0
+ */
+int rosh_ls_parse_opt(const char *filestr, char *optstr)
+{
+    int ret;
+    if (filestr[0] == '-') {
+	ret = 0;
+	if (optstr)
+	    strcat(optstr, filestr + 1);
+    } else {
+	ret = 1;
+    }
+    ROSH_DEBUG("ParseOpt: '%s'\n\topt: '%s'\n\tret: %d\n", filestr, optstr,
+	       ret);
+    return ret;
+}				/* rosh_ls_parse_opt */
+
+/* List Directory
+ *	argc	Argument count
+ *	argv	Argument values
+ */
+void rosh_ls(int argc, char *argv[])
+{
+    int optarr[3];
+    int i;
+
+    rosh_ls_arg_opt(argc, argv, optarr);
+    ROSH_DEBUG2("In ls()\n");
+    ROSH_DEBUG2_ARGV_V(argc, argv);
+#ifdef DO_DEBUG
+    optarr[0] = 2;
+#endif /* DO_DEBUG */
+    ROSH_DEBUG2("  argc=%d; optind=%d\n", argc, optind);
+    if (optind >= argc)
+	rosh_ls_arg(".", optarr);
+    for (i = optind; i < argc; i++) {
+	rosh_ls_arg(argv[i], optarr);
+    }
+}				/* rosh_ls */
+
+/* Simple directory listing; calls rosh_ls()
+ *	argc	Argument count
+ *	argv	Argument values
+ */
+void rosh_dir(int argc, char *argv[])
+{
+    ROSH_DEBUG("  dir implemented as ls\n");
+    rosh_ls(argc, argv);
+}				/* rosh_dir */
+
+/* Page through a buffer string
+ *	buf	Buffer to page through
+ */
+void rosh_more_buf(char *buf, int buflen, int rows, int cols, char *scrbuf)
+{
+    char *bufp, *bufeol, *bufeol2;	/* Pointer to current and next
+					   end-of-line position in buffer */
+    int bufpos, bufcnt;		/* current position, count characters */
+    int inc;
+    int i, numln;		/* Index, Number of lines */
+    int elpl;		/* Extra lines per line read */
+
+    (void)cols;
+
+    bufpos = 0;
+    bufp = buf + bufpos;
+    bufeol = bufp;
+    numln = rows - 1;
+    ROSH_DEBUG("--(%d)\n", buflen);
+    while (bufpos < buflen) {
+	for (i = 0; i < numln; i++) {
+	    bufeol2 = strchr(bufeol, '\n');
+	    if (bufeol2 == NULL) {
+		bufeol = buf + buflen;
+		i = numln;
+	    } else {
+		elpl = ((bufeol2 - bufeol - 1) / cols);
+		if (elpl < 0)
+		    elpl = 0;
+		i += elpl;
+		ROSH_DEBUG2("  %d/%d  ", elpl, i+1);
+		/* If this will not push too much, use it */
+		/* but if it's the first line, use it */
+		/* //HERE: We should probably snip the line off */
+		if ((i < numln) || (i == elpl))
+		    bufeol = bufeol2 + 1;
+	    }
+	}
+	ROSH_DEBUG2("\n");
+	bufcnt = bufeol - bufp;
+	printf("--(%d/%d @%d)\n", bufcnt, buflen, bufpos);
+	memcpy(scrbuf, bufp, bufcnt);
+	scrbuf[bufcnt] = 0;
+	printf("%s", scrbuf);
+	bufp = bufeol;
+	bufpos += bufcnt;
+	if (bufpos == buflen)
+	    break;
+	inc = rosh_getkey();
+	numln = 1;
+	switch (inc) {
+	case KEY_CTRL('c'):
+	case 'q':
+	case 'Q':
+	    bufpos = buflen;
+	    break;
+	case ' ':
+	    numln = rows - 1;
+	}
+    }
+}				/* rosh_more_buf */
+
+/* Page through a single file using the open file stream
+ *	fd	File Descriptor
+ */
+void rosh_more_fd(int fd, int rows, int cols, char *scrbuf)
+{
+    struct stat fdstat;
+    char *buf;
+    int bufpos;
+    int numrd;
+    FILE *f;
+
+    fstat(fd, &fdstat);
+    if (S_ISREG(fdstat.st_mode)) {
+	buf = malloc((int)fdstat.st_size);
+	if (buf != NULL) {
+	    f = fdopen(fd, "r");
+	    bufpos = 0;
+	    numrd = fread(buf, 1, (int)fdstat.st_size, f);
+	    while (numrd > 0) {
+		bufpos += numrd;
+		numrd = fread(buf + bufpos, 1,
+			      ((int)fdstat.st_size - bufpos), f);
+	    }
+	    fclose(f);
+	    rosh_more_buf(buf, bufpos, rows, cols, scrbuf);
+	}
+    } else {
+    }
+
+}				/* rosh_more_fd */
+
+/* Page through a file like the more command
+ *	argc	Argument Count
+ *	argv	Argument Values
+ */
+void rosh_more(int argc, char *argv[])
+{
+    int fd, i;
+/*    char filestr[ROSH_PATH_SZ];
+    int cmdpos;*/
+    int rows, cols;
+    char *scrbuf;
+    int ret;
+
+    ROSH_DEBUG_ARGV_V(argc, argv);
+    ret = getscreensize(1, &rows, &cols);
+    if (ret) {
+	ROSH_DEBUG("getscreensize() fail(%d); fall back\n", ret);
+	ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows, cols);
+	/* If either fail, go under normal size, just in case */
+	if (!rows)
+	    rows = 20;
+	if (!cols)
+	    cols = 75;
+    }
+    ROSH_DEBUG("\tUSE ROWS='%d'\tCOLS='%d'\n", rows, cols);
+    /* 32 bit align beginning of row and over allocate */
+    scrbuf = malloc(rows * ((cols+3)&(INT_MAX - 3)));
+    if (!scrbuf)
+	return;
+
+    if (argc) {
+	/* There is no need to mess up the console if we don't have a
+	   file */
+	rosh_console_raw();
+	for (i = 0; i < argc; i++) {
+	    printf("--File = '%s'\n", argv[i]);
+	    errno = 0;
+	    fd = open(argv[i], O_RDONLY);
+	    if (fd != -1) {
+		rosh_more_fd(fd, rows, cols, scrbuf);
+		close(fd);
+	    } else {
+		rosh_error(errno, "more", argv[i]);
+		errno = 0;
+	    }
+	}
+	rosh_console_std();
+    }
+    free(scrbuf);
+}				/* rosh_more */
+
+/* Page a file with rewind
+ *	argc	Argument Count
+ *	argv	Argument Values
+ */
+void rosh_less(int argc, char *argv[])
+{
+    printf("  less implemented as more (for now)\n");
+    rosh_more(argc, argv);
+}				/* rosh_less */
+
+/* Show PWD
+ */
+void rosh_pwd(void)
+{
+    char pwdstr[ROSH_PATH_SZ];
+    errno = 0;
+    if (getcwd(pwdstr, ROSH_PATH_SZ)) {
+	printf("%s\n", pwdstr);
+    } else {
+	rosh_error(errno, "pwd", "");
+	errno = 0;
+    }
+}				/* rosh_pwd */
+
+/* Reboot; use warm reboot if one of certain options set
+ *	argc	Argument count
+ *	argv	Argument values
+ */
+void rosh_reboot(int argc, char *argv[])
+{
+    int rtype = 0;
+    if (argc) {
+	/* For now, just use the first */
+	switch (argv[0][0]) {
+	case '1':
+	case 's':
+	case 'w':
+	    rtype = 1;
+	    break;
+	case '-':
+	    switch (argv[0][1]) {
+	    case '1':
+	    case 's':
+	    case 'w':
+		rtype = 1;
+		break;
+	    }
+	    break;
+	}
+    }
+    syslinux_reboot(rtype);
+}				/* rosh_reboot */
+
+/* Run a boot string, calling syslinux_run_command
+ *	argc	Argument count
+ *	argv	Argument values
+ */
+void rosh_run(int argc, char *argv[])
+{
+    char cmdstr[ROSH_CMD_SZ];
+    int len;
+
+    len = rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 0);
+    if (len) {
+	printf("--run: '%s'\n", cmdstr);
+	syslinux_run_command(cmdstr);
+    } else {
+	printf(APP_NAME ":run: No arguments\n");
+    }
+}				/* rosh_run */
+
+/* Process an argc/argv pair and call handling function
+ *	argc	Argument count
+ *	argv	Argument values
+ *	ipwdstr	Initial Present Working Directory string
+ *	returns	Whether to exit prompt
+ */
+char rosh_command(int argc, char *argv[], const char *ipwdstr)
+{
+    char do_exit = false;
+    int tlen;
+    tlen = strlen(argv[0]);
+    ROSH_DEBUG_ARGV_V(argc, argv);
+    switch (argv[0][0]) {
+    case 'e':
+    case 'E':
+    case 'q':
+    case 'Q':
+	switch (argv[0][1]) {
+	case 0:
+	case 'x':
+	case 'X':
+	case 'u':
+	case 'U':
+	    if ((strncasecmp("exit", argv[0], tlen) == 0) ||
+		(strncasecmp("quit", argv[0], tlen) == 0))
+		do_exit = true;
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'c':
+	case 'C':
+	    if (strncasecmp("echo", argv[0], tlen) == 0)
+		rosh_pr_argv(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	default:
+	    rosh_help(1, argv[0]);
+	}
+	break;
+    case 'c':
+    case 'C':			/* run 'cd' 'cat' 'cfg' */
+	switch (argv[0][1]) {
+	case 'a':
+	case 'A':
+	    if (strncasecmp("cat", argv[0], tlen) == 0)
+		rosh_cat(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'd':
+	case 'D':
+	    if (strncasecmp("cd", argv[0], tlen) == 0)
+		rosh_cd(argc, argv, ipwdstr);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'f':
+	case 'F':
+	    if (strncasecmp("cfg", argv[0], tlen) == 0)
+		rosh_cfg();
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	default:
+	    rosh_help(1, argv[0]);
+	}
+	break;
+    case 'd':
+    case 'D':			/* run 'dir' */
+	if (strncasecmp("dir", argv[0], tlen) == 0)
+	    rosh_dir(argc - 1, &argv[1]);
+	else
+	    rosh_help(1, argv[0]);
+	break;
+    case 'h':
+    case 'H':
+    case '?':
+	if ((strncasecmp("help", argv[0], tlen) == 0) || (tlen == 1))
+	    rosh_help(2, argv[1]);
+	else
+	    rosh_help(1, NULL);
+	break;
+    case 'l':
+    case 'L':			/* run 'ls' 'less' */
+	switch (argv[0][1]) {
+	case 0:
+	case 's':
+	case 'S':
+	    if (strncasecmp("ls", argv[0], tlen) == 0)
+		rosh_ls(argc, argv);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'e':
+	case 'E':
+	    if (strncasecmp("less", argv[0], tlen) == 0)
+		rosh_less(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	default:
+	    rosh_help(1, argv[0]);
+	}
+	break;
+    case 'm':
+    case 'M':
+	switch (argv[0][1]) {
+	case 'a':
+	case 'A':
+	    if (strncasecmp("man", argv[0], tlen) == 0)
+		rosh_help(2, argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'o':
+	case 'O':
+	    if (strncasecmp("more", argv[0], tlen) == 0)
+		rosh_more(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	default:
+	    rosh_help(1, argv[0]);
+	}
+	break;
+    case 'p':
+    case 'P':			/* run 'pwd' */
+	if (strncasecmp("pwd", argv[0], tlen) == 0)
+	    rosh_pwd();
+	else
+	    rosh_help(1, argv[0]);
+	break;
+    case 'r':
+    case 'R':			/* run 'run' */
+	switch (argv[0][1]) {
+	case 0:
+	case 'e':
+	case 'E':
+	    if (strncasecmp("reboot", argv[0], tlen) == 0)
+		rosh_reboot(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	case 'u':
+	case 'U':
+	    if (strncasecmp("run", argv[0], tlen) == 0)
+		rosh_run(argc - 1, &argv[1]);
+	    else
+		rosh_help(1, argv[0]);
+	    break;
+	default:
+	    rosh_help(1, argv[0]);
+	}
+	break;
+    case 'v':
+    case 'V':
+	if (strncasecmp("version", argv[0], tlen) == 0)
+	    rosh_version(1);
+	else
+	    rosh_help(1, argv[0]);
+	break;
+    case 0:
+    case '\n':
+	break;
+    default:
+	rosh_help(1, argv[0]);
+    }				/* switch(argv[0][0]) */
+    return do_exit;
+}				/* rosh_command */
+
+/* Process the prompt for commands as read from stdin and call rosh_command
+ * to process command line string
+ *	icmdstr	Initial command line string
+ *	returns	Exit status
+ */
+int rosh_prompt(int iargc, char *iargv[])
+{
+    int rv;
+    char cmdstr[ROSH_CMD_SZ];
+    char ipwdstr[ROSH_PATH_SZ];
+    char do_exit;
+    char **argv;
+    int argc;
+
+    rv = 0;
+    do_exit = false;
+    if (!getcwd(ipwdstr, ROSH_PATH_SZ))
+	strcpy(ipwdstr, "./");
+    if (iargc > 1)
+	do_exit = rosh_command(iargc - 1, &iargv[1], ipwdstr);
+    while (!(do_exit)) {
+	/* Extra preceeding newline */
+	printf("\nrosh: ");
+	/* Read a line from console */
+	if (fgets(cmdstr, ROSH_CMD_SZ, stdin)) {
+	    argc = rosh_str2argv(&argv, cmdstr);
+	    do_exit = rosh_command(argc, argv, ipwdstr);
+	    rosh_free_argv(&argv);
+	} else {
+	    do_exit = false;
+	}
+    }
+    return rv;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv;
+
+    /* Initialization */
+    rv = 0;
+    rosh_console_std();
+    if (argc == 1) {
+	rosh_version(0);
+	print_beta();
+    } else {
+#ifdef DO_DEBUG
+	char cmdstr[ROSH_CMD_SZ];
+	rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 1);
+	ROSH_DEBUG("arg='%s'\n", cmdstr);
+#endif
+    }
+    rv = rosh_prompt(argc, argv);
+    printf("--Exiting '" APP_NAME "'\n");
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/rosh/rosh.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,282 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008-2009 Gene Cumm - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rosh.h
+ *
+ * Read-Only shell; Header
+ */
+
+/*
+ * History
+ * b034	Improve debug functions to simpler code
+ * b021	Move much PreProcessing stuff to rosh.h
+ * b018	Create rosh_debug() macro
+ * b012	Version of rosh.c at time of creating this file.
+ */
+
+#ifndef ROSH_H
+#define ROSH_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>		/* macro: true false */
+#include <string.h>		/* strcpy() strlen() memcpy() strchr() */
+#include <sys/types.h>
+#include <limits.h>
+#include <sys/stat.h>		/* fstat() */
+#include <fcntl.h>		/* open(); open mode macros */
+#include <dirent.h>		/* fdopendir() opendir() readdir() closedir() DIR */
+#include <unistd.h>		/* getcwd() getopt() */
+#include <errno.h>		/* errno; error macros */
+#include <netinet/in.h>		/* For htonl/ntohl/htons/ntohs */
+#include <ctype.h>		/* isspace() */
+
+#include <getkey.h>
+#include <consoles.h>		/* console_ansi_raw() console_ansi_std() */
+// #include <getopt.h>		/* getopt_long() */
+
+#ifdef DO_DEBUG
+# define ROSH_DEBUG	printf
+# define ROSH_DEBUG_ARGV_V	rosh_pr_argv_v
+/* define ROSH_DEBUG(f, ...)	printf (f, ## __VA_ARGS__) */
+# ifdef DO_DEBUG2
+#  define ROSH_DEBUG2	printf
+#  define ROSH_DEBUG2_ARGV_V	rosh_pr_argv_v
+# else /* DO_DEBUG2 */
+	/* This forces a format argument into the function call */
+#  define ROSH_DEBUG2(f, ...)	((void)0)
+#  define ROSH_DEBUG2_ARGV_V(argc, argv)	((void)0)
+# endif	/* DO_DEBUG2 */
+#else /* DO_DEBUG */
+# define ROSH_DEBUG(f, ...)	((void)0)
+# define ROSH_DEBUG_ARGV_V(argc, argv)	((void)0)
+# define ROSH_DEBUG2(f, ...)	((void)0)
+# define ROSH_DEBUG2_ARGV_V(argc, argv)	((void)0)
+#endif /* DO_DEBUG */
+#define ROSH_DEBUG2_STAT(f, ...)	((void)0)
+// #define ROSH_DEBUG2_STAT	ROSH_DEBUG2
+
+#ifdef __COM32__
+#define ROSH_IS_COM32	1
+#include <console.h>		/* openconsole() */
+#include <syslinux/config.h>	/* Has info on the SYSLINUX variant */
+#include <syslinux/boot.h>	/* syslinux_run_command() */
+#include <syslinux/reboot.h>
+#define ROSH_COM32(f, ...)	printf (f, ## __VA_ARGS__)
+#define rosh_console_std()		console_ansi_std()
+#define rosh_console_raw()		console_ansi_raw()
+
+int stat(const char *pathname, struct stat *buf)
+{
+    int fd, status, ret = -1;
+    DIR *d;
+
+    ROSH_DEBUG2_STAT("stat:opendir(%s) ", pathname);
+    d = opendir(pathname);
+    if (d != NULL) {
+	ROSH_DEBUG2_STAT("stat:closedir() ");
+	closedir(d);
+	ret = 0;
+	buf->st_mode = S_IFDIR | 0555;
+	buf->st_size = 0;
+    } else if ((errno == 0) || (errno == ENOENT) || (errno == ENOTDIR)) {
+	ROSH_DEBUG2_STAT("(%d)stat:open() ", errno);
+	fd = open(pathname, O_RDONLY);
+	if (fd != -1) {
+	    ROSH_DEBUG2_STAT("(%d)stat:fstat() ", fd);
+	    status = fstat(fd, buf);
+	    (void)status;
+	    ROSH_DEBUG2_STAT("stat:close() ");
+	    close(fd);
+	    ret = 0;
+	}
+    }
+    return ret;
+}
+
+int rosh_get_env_ver(char *dest, size_t n)
+{
+    const struct syslinux_version *slv = syslinux_version();
+    strncpy(dest, slv->version_string, n);
+    return 0;
+}
+
+#else
+#  include <termios.h>
+#  include <sys/ioctl.h>
+#  include <sys/utsname.h>
+#  define ROSH_IS_COM32	0
+
+static inline char *syslinux_config_file(void)
+{
+    return "";
+}
+
+int rosh_get_env_ver(char *dest, size_t n)
+{
+    int ret, len;
+    struct utsname env;
+    ret= uname(&env);
+    if (ret >= 0) {
+	strncpy(dest, env.sysname, n);
+	len = strlen(dest);
+	strncpy(dest + len, " ", (n - len));
+	len = strlen(dest);
+	strncpy(dest + len, env.release, (n - len));
+    }
+    return ret;
+}
+
+static inline int getscreensize(int fd, int *rows, int *cols)
+{
+    char *str;
+    int rv;
+    struct winsize ws;
+    if (rows)
+	*rows = 0;
+    if (cols)
+	*cols = 0;
+    str = NULL;
+    if (fd == 1) {
+	ioctl(0, TIOCGWINSZ, &ws);
+	if (rows)
+	    *rows = ws.ws_row;
+	if (cols)
+	    *cols = ws.ws_col;
+	if (rows && !*rows) {
+	    str = getenv("LINES");
+	    if (str)
+		*rows = atoi(str);
+	}
+	if (cols && !*cols) {
+	    str = getenv("COLUMNS");
+	    if (str)
+		*cols = atoi(str);
+	}
+    }
+    if (!rows || !cols)
+	rv = -1;
+    else if (!*rows || !*cols)
+	rv = -2;
+    else
+	rv = 0;
+    return rv;
+}
+
+/*
+ * Switches console over to raw input mode.  Allows get_key to get just
+ * 1 key sequence (without delay or display)
+ */
+void rosh_console_raw(void)
+{
+    struct termios tio;
+
+    console_ansi_raw();		/* Allows get_key to get just 1 key sequence
+				   (w/o delay or display */
+    /* Deal with the changes that haven't been replicated to ansiraw.c */
+    tcgetattr(0, &tio);
+    tio.c_iflag &= ~IGNCR;
+    tcsetattr(0, TCSAFLUSH, &tio);
+}
+
+/*
+ * Switches back to standard getline mode.
+ */
+void rosh_console_std(void)
+{
+    struct termios tio;
+
+    console_ansi_std();
+    tcgetattr(0, &tio);
+    tio.c_iflag |= ICRNL;
+    tio.c_iflag &= ~IGNCR;
+    tcsetattr(0, TCSANOW, &tio);
+}
+
+void syslinux_reboot(int warm)
+{
+    printf("Test Reboot(%d)\n", warm);
+}
+
+#define ROSH_COM32(f, ...)	((void)0)
+#define syslinux_run_command(f)	((void)0)
+#endif /* __COM32__ */
+
+#define SEP	'/'
+
+/* Size of buffer string */
+#define ROSH_BUF_SZ	16384
+/* Size of screen output buffer (80*40) //HERE */
+#define ROSH_SBUF_SZ	((80 + 2) * 40)
+
+/* Size of command buffer string */
+#ifdef MAX_CMDLINE_LEN
+#  define ROSH_CMD_SZ		MAX_CMDLINE_LEN
+#elif COMMAND_LINE_SIZE
+#  define ROSH_CMD_SZ		COMMAND_LINE_SIZE
+#else
+#  define ROSH_CMD_SZ_LG2	12
+#  define ROSH_CMD_SZ		(1 << ROSH_CMD_SZ_LG2)
+#endif /* MAX_CMDLINE_LEN */
+
+/* Size of path buffer string */
+#ifdef PATH_MAX
+#  define ROSH_PATH_SZ		PATH_MAX
+#elif NAME_MAX
+#  define ROSH_PATH_SZ		NAME_MAX
+#elif FILENAME_MAX
+#  define ROSH_PATH_SZ		FILENAME_MAX
+#else
+#  define ROSH_PATH_SZ_LG2	8
+#  define ROSH_PATH_SZ		(1 << ROSH_PATH_SZ_LG2)
+#endif /* PATH_MAX */
+
+#define ROSH_OPT_SZ	8
+
+const char rosh_beta_str[] =
+    "  ROSH is currently beta.  Constructive feedback is appreciated";
+
+const char rosh_cd_norun_str[] =
+    " -- cd (Change Directory) not implemented for use with run and exit.\n";
+
+const char rosh_help_cd_str[] = "cd    Change directory\n\
+   with no argument, return to original directory from entry to rosh\n\
+   with one argument, change to that directory";
+
+const char rosh_help_ls_str[] = "ls    List contents of current directory\n\
+  -l  Long format\n\
+  -i  Inode; print Inode of file\n\
+  -F  Classify; Add a 1-character suffix to classify files";
+
+const char rosh_help_str1[] =
+    "Commands: ? cat cd cfg dir exit help less ls man more pwd run quit ver";
+
+const char rosh_help_str2[] =
+    "Commands: (short generally non-ambiguous abreviations are also allowed)\n\
+  h     HELP\n     ALSO ? help man\n     ALSO help <command>\n\
+  cat   Concatenate file to console\n    cat <file>\n\
+  cd    Change to directory <dir>\n    cd <dir>\n\
+  less  Page a file with rewind\n\
+  ls    List contents of current directory\n    ls <dir>\n\
+    ALSO l dir\n\
+  more  Page a file\n\
+  pwd   display Present Working Directory\n\
+  run   Run a program/kernel with options\n\
+  r     Reboot (if COM32)\n        Also reboot\n\
+  exit  Exit to previous environment\n    ALSO quit";
+
+const char rosh_help_str_adv[] = "No additional help available for '%s'";
+
+const char rosh_ls_opt_str[] = "lFi";
+
+#endif /* Not ROSH_H */
Index: bootcd/isolinux/syslinux-6.03/com32/samples/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,40 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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.
+##
+## -----------------------------------------------------------------------
+
+##
+## samples for syslinux users
+##
+
+LIBS = $(objdir)/com32/libutil/libutil.c32
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+all:	hello.c32 resolv.c32 serialinfo.c32 \
+		localboot.c32 \
+		fancyhello.c32 fancyhello.lnx \
+		keytest.c32 keytest.lnx \
+		advdump.c32 entrydump.c32
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:	# Don't install samples
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/samples/advdump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/advdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/advdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * advdump.c
+ *
+ * Dump the contents of the syslinux ADV
+ */
+
+#include <stdio.h>
+#include <console.h>
+#include <syslinux/adv.h>
+#include <string.h>
+
+int main(void)
+{
+    uint8_t *p, *ep;
+    size_t s = syslinux_adv_size();
+    char buf[256];
+
+#if 0
+	/* this hangs! */
+    openconsole(&dev_stdcon_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+
+    p = syslinux_adv_ptr();
+
+    printf("ADV size: %zd bytes at %p\n", s, p);
+
+    ep = p + s;			/* Need at least opcode+len */
+    while (p < ep - 1 && *p) {
+	int t = *p++;
+	int l = *p++;
+
+	if (p + l > ep)
+	    break;
+
+	memcpy(buf, p, l);
+	buf[l] = '\0';
+
+	printf("ADV %3d: \"%s\"\n", t, buf);
+
+	p += l;
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/entrydump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/entrydump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/entrydump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,66 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * entry.c
+ *
+ * Dump the entry point registers
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <console.h>
+#include <syslinux/config.h>
+
+struct stack_frame {
+    uint16_t gs, fs, es, ds;
+    uint32_t edi, esi, ebp, esp;
+    uint32_t ebx, edx, ecx, eax;
+    uint32_t eflags;
+    uint16_t ret_ip, ret_cs;
+    uint16_t pxe_ip, pxe_cs;
+};
+
+int main(void)
+{
+    const union syslinux_derivative_info *di;
+    const struct stack_frame *sf;
+
+#if 0
+	/* this hangs! */
+    openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+
+    di = syslinux_derivative_info();
+
+    if (di->c.filesystem != SYSLINUX_FS_PXELINUX) {
+	printf("Not running under PXELINUX (fs = %02x)\n", di->c.filesystem);
+	return 1;
+    }
+
+    sf = (const struct stack_frame *)di->pxe.stack;
+
+    printf("EAX: %08x  EBX: %08x  ECX: %08x  EDX: %08x\n"
+	   "ESP: %08x  EBP: %08x  ESI: %08x  EDI: %08x\n"
+	   "SS: %04x   DS: %04x   ES: %04x   FS: %04x   GS:  %04x\n"
+	   "EFLAGS: %08x   RET: %04x:%04x   PXE: %04x:%04x\n",
+	   sf->eax, sf->ebx, sf->ecx, sf->edx,
+	   sf->esp + 4, sf->ebp, sf->esi, sf->edi,
+	   di->rr.r.fs, sf->ds, sf->es, sf->fs, sf->gs,
+	   sf->eflags, sf->ret_cs, sf->ret_ip, sf->pxe_cs, sf->pxe_ip);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/fancyhello.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/fancyhello.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/fancyhello.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fancyhello.c
+ *
+ * Hello, World! using libcom32 and ANSI console; also possible to compile
+ * as a Linux application for testing.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <consoles.h>		/* Provided by libutil */
+
+int main(void)
+{
+    char buffer[1024];
+
+    console_ansi_std();
+
+    printf("\033[1;33;44m *** \033[37mHello, World!\033[33m *** \033[0m\n");
+
+    for (;;) {
+	printf("\033[1;36m>\033[0m ");
+	fgets(buffer, sizeof buffer, stdin);
+	if (!strncmp(buffer, "exit", 4))
+	    break;
+	printf("\033[1m:\033[0m %s", buffer);
+    }
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/hello.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/hello.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/hello.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/*
+ * hello.c - A simple ELF module that sorts a couple of numbers
+ *
+ *  Created on: Aug 11, 2008
+ *      Author: Stefan Bucur <stefanb@zytor.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sort.h"
+
+#define NUM_COUNT		10
+#define MAX_NUM			100
+
+int main(int argc __unused, char **argv __unused)
+{
+    int *nums = NULL;
+
+    nums = malloc(NUM_COUNT * sizeof(int));
+    printf("Hello, world, from 0x%08X! malloc return %p\n", (unsigned int)&main, nums);
+
+    free(nums);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/keytest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/keytest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/keytest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * keytest.c
+ *
+ * Test the key parsing library
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/times.h>
+
+#include <consoles.h>		/* Provided by libutil */
+#include <getkey.h>
+
+static void cooked_keys(void)
+{
+    int key;
+
+    printf("[cooked]");
+
+    for (;;) {
+	key = get_key(stdin, 0);
+
+	if (key == 0x03) {
+	    printf("[done]\n");
+	    exit(0);
+	} else if (key == '!')
+	    return;
+
+	if (key >= 0x20 && key < 0x100) {
+	    putchar(key);
+	} else {
+	    printf("[%s,%04x]", key_code_to_name(key), key);
+	}
+    }
+}
+
+static void raw_keys(void)
+{
+    int key;
+
+    printf("[raw]");
+
+    for (;;) {
+	key = getc(stdin);
+
+	if (key == 0x03) {
+	    printf("[done]\n");
+	    exit(0);
+	} else if (key == '!')
+	    return;
+
+	if (key != EOF)
+	    printf("<%02x>", key);
+    }
+}
+
+int main(void)
+{
+    console_ansi_raw();
+
+    printf("CLK_TCK = %d\n", (int)CLK_TCK);
+    printf("Press keys, end with Ctrl-C, ! changes from cooked to raw\n");
+
+    for (;;) {
+	cooked_keys();
+	raw_keys();
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/localboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/localboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/localboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,9 @@
+#include <syslinux/boot.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+    syslinux_local_boot(argc > 1 ? atoi(argv[1]) : 0);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/resolv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/resolv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/resolv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * resolv.c
+ *
+ * Resolve an IP address
+ */
+
+#include <syslinux/pxe_api.h>
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include <stdlib.h>
+#include <com32.h>
+
+uint32_t resolv(const char *name)
+{
+    return dns_resolv(name);
+}
+
+int main(int argc, char *argv[])
+{
+    uint32_t ip;
+
+#if 0
+	/* this hangs! */
+    openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+
+    if (argc < 2) {
+	fputs("Usage: resolv hostname\n", stderr);
+	exit(1);
+    }
+
+    ip = resolv(argv[1]);
+
+    if (ip) {
+	printf("%s = %u.%u.%u.%u\n", argv[1],
+	       (ip & 0xff), (ip >> 8) & 0xff,
+	       (ip >> 16) & 0xff, (ip >> 24) & 0xff);
+    } else {
+	printf("%s not found\n", argv[1]);
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/samples/serialinfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/samples/serialinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/samples/serialinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * serialinfo.c
+ *
+ * Print serial port info
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include <syslinux/config.h>
+
+int main(void)
+{
+    const struct syslinux_serial_console_info *si;
+
+#if 0
+	/* this hangs! */
+    openconsole(&dev_null_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+
+    si = syslinux_serial_console_info();
+
+    printf("Serial port base:    %#06x\n", si->iobase);
+    printf("Serial port divisor:  %5d", si->divisor);
+    if (si->divisor)
+	printf(" (%d baud)", 115200 / si->divisor);
+    printf("\n" "Flow control bits:    %#05x\n", si->flowctl);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Simple menu system
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+-include $(topdir)/version.mk
+
+LIBS	   = $(objdir)/com32/libupload/libcom32upload.a
+LNXLIBS	   = $(objdir)/com32/libutil/libutil_lnx.a
+
+CFLAGS += -I$(com32) -I$(topdir)
+
+MODULES	  = sysdump.c32
+TESTFILES =
+
+SRCS = $(wildcard $(SRC)/*.c)
+OBJS = $(subst $(SRC)/,,$(patsubst %.c,%.o,$(SRCS)))
+
+# The DATE is set on the make command line when building binaries for
+# official release.  Otherwise, substitute a hex string that is pretty much
+# guaranteed to be unique to be unique from build to build.
+ifndef HEXDATE
+HEXDATE := $(shell $(PERL) $(topdir)/now.pl $(SRCS) $(wildcard *.h))
+endif
+ifndef DATE
+DATE    := $(shell sh $(topdir)/gen-id.sh $(VERSION) $(HEXDATE))
+endif
+
+CFLAGS    += -DDATE='"$(DATE)"'
+
+all: $(MODULES) $(TESTFILES)
+
+sysdump.elf : $(OBJS) $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,258 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Dump ACPI information
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sysdump.h"
+#include "rbtree.h"
+
+struct acpi_rsdp {
+    uint8_t  magic[8];		/* "RSD PTR " */
+    uint8_t  csum;
+    char     oemid[6];
+    uint8_t  rev;
+    uint32_t rsdt_addr;
+    uint32_t len;
+    uint64_t xsdt_addr;
+    uint8_t  xcsum;
+    uint8_t  rsvd[3];
+};
+
+struct acpi_hdr {
+    char     sig[4];		/* Signature */
+    uint32_t len;
+    uint8_t  rev;
+    uint8_t  csum;
+    char     oemid[6];
+    char     oemtblid[16];
+    uint32_t oemrev;
+    uint32_t creatorid;
+    uint32_t creatorrev;
+};
+
+struct acpi_rsdt {
+    struct acpi_hdr hdr;
+    uint32_t entry[0];
+};
+
+struct acpi_xsdt {
+    struct acpi_hdr hdr;
+    uint64_t entry[0];
+};
+
+static struct rbtree *rb_types, *rb_addrs;
+
+static bool rb_has(struct rbtree **tree, uint64_t key)
+{
+    struct rbtree *node;
+
+    node = rb_search(*tree, key);
+    if (node && node->key == key)
+	return true;
+
+    node = malloc(sizeof *node);
+    if (node) {
+	node->key = key;
+	*tree = rb_insert(*tree, node);
+    }
+    return false;
+}
+
+static inline bool addr_ok(uint64_t addr)
+{
+    /* We can only handle 32-bit addresses for now... */
+    return addr <= 0xffffffff;
+}
+
+enum tbl_errs {
+    ERR_NONE,			/* No errors */
+    ERR_CSUM,			/* Invalid checksum */
+    ERR_SIZE,			/* Impossibly large table */
+    ERR_NOSIG			/* No signature */
+};
+
+static uint8_t checksum_range(const void *start, uint32_t size)
+{
+    const uint8_t *p = start;
+    uint8_t csum = 0;
+
+    while (size--)
+	csum += *p++;
+
+    return csum;
+}
+
+static enum tbl_errs is_valid_table(const void *ptr)
+{
+    const struct acpi_hdr *hdr = ptr;
+
+    if (hdr->sig[0] == 0)
+	return ERR_NOSIG;
+
+    if (hdr->len < 10 || hdr->len > (1 << 20)) {
+	/* Either insane or too large to dump */
+	return ERR_SIZE;
+    }
+
+    return checksum_range(hdr, hdr->len) == 0 ? ERR_NONE : ERR_CSUM;
+}
+
+static const struct acpi_rsdp *scan_for_rsdp(uint32_t base, uint32_t end)
+{
+    for (base &= ~15; base < end-20; base += 16) {
+	const struct acpi_rsdp *rsdp = (const struct acpi_rsdp *)base;
+
+	if (memcmp(rsdp->magic, "RSD PTR ", 8))
+	    continue;
+
+	if (checksum_range(rsdp, 20))
+	    continue;
+
+	if (rsdp->rev > 0) {
+	    if (base + rsdp->len >= end ||
+		checksum_range(rsdp, rsdp->len))
+		continue;
+	}
+
+	return rsdp;
+    }
+
+    return NULL;
+}
+
+static const struct acpi_rsdp *find_rsdp(void)
+{
+    uint32_t ebda;
+    const struct acpi_rsdp *rsdp;
+
+    ebda = (*(uint16_t *)0x40e) << 4;
+    if (ebda >= 0x70000 && ebda < 0xa0000) {
+	rsdp = scan_for_rsdp(ebda, ebda+1024);
+
+	if (rsdp)
+	    return rsdp;
+    }
+
+    return scan_for_rsdp(0xe0000, 0x100000);
+}
+
+static void dump_table(struct upload_backend *be,
+		       const char name[], const void *ptr, uint32_t len)
+{
+    char namebuf[64];
+    uint32_t name_key = *(uint32_t *)name;
+
+    if (rb_has(&rb_addrs, (size_t)ptr))
+	return;			/* Already dumped this table */
+
+    if (!rb_has(&rb_types, name_key)) {
+	snprintf(namebuf, sizeof namebuf, "acpi/%4.4s", name);
+	cpio_mkdir(be, namebuf);
+    }
+
+    snprintf(namebuf, sizeof namebuf, "acpi/%4.4s/%08x", name, (uint32_t)ptr);
+    cpio_hdr(be, MODE_FILE, len, namebuf);
+
+    write_data(be, ptr, len);
+}
+
+static void dump_rsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp)
+{
+    const struct acpi_rsdt *rsdt;
+    uint32_t i, n;
+
+    rsdt = (const struct acpi_rsdt *)rsdp->rsdt_addr;
+
+    if (memcmp(rsdt->hdr.sig, "RSDT", 4) || is_valid_table(rsdt) > ERR_CSUM)
+	return;
+
+    dump_table(be, rsdt->hdr.sig, rsdt, rsdt->hdr.len);
+
+    if (rsdt->hdr.len < 36)
+	return;
+
+    n = (rsdt->hdr.len - 36) >> 2;
+
+    for (i = 0; i < n; i++) {
+	const struct acpi_hdr *hdr = (const struct acpi_hdr *)(rsdt->entry[i]);
+
+	if (is_valid_table(hdr) <= ERR_CSUM)
+	    dump_table(be, hdr->sig, hdr, hdr->len);
+    }
+}
+
+static void dump_xsdt(struct upload_backend *be, const struct acpi_rsdp *rsdp)
+{
+    const struct acpi_xsdt *xsdt;
+    uint32_t rsdp_len = rsdp->rev > 0 ? rsdp->len : 20;
+    uint32_t i, n;
+
+    if (rsdp_len < 34)
+	return;
+
+    if (!addr_ok(rsdp->xsdt_addr))
+	return;
+
+    xsdt = (const struct acpi_xsdt *)(size_t)rsdp->xsdt_addr;
+
+    if (memcmp(xsdt->hdr.sig, "XSDT", 4) || is_valid_table(xsdt) > ERR_CSUM)
+	return;
+
+    dump_table(be, xsdt->hdr.sig, xsdt, xsdt->hdr.len);
+
+    if (xsdt->hdr.len < 36)
+	return;
+
+    n = (xsdt->hdr.len - 36) >> 3;
+
+    for (i = 0; i < n; i++) {
+	const struct acpi_hdr *hdr;
+	if (addr_ok(xsdt->entry[i])) {
+	    hdr = (const struct acpi_hdr *)(size_t)(xsdt->entry[i]);
+
+	    if (is_valid_table(hdr) <= ERR_CSUM)
+		dump_table(be, hdr->sig, hdr, hdr->len);
+	}
+    }
+}
+
+void dump_acpi(struct upload_backend *be)
+{
+    const struct acpi_rsdp *rsdp;
+    uint32_t rsdp_len;
+
+    rsdp = find_rsdp();
+
+    printf("Dumping ACPI... ");
+
+    if (!rsdp)
+	return;			/* No ACPI information found */
+
+    cpio_mkdir(be, "acpi");
+
+    rsdp_len = rsdp->rev > 0 ? rsdp->len : 20;
+
+    dump_table(be, "RSDP", rsdp, rsdp_len);
+
+    dump_rsdt(be, rsdp);
+    dump_xsdt(be, rsdp);
+
+    rb_destroy(rb_types);
+    rb_destroy(rb_addrs);
+
+    printf("done.\n");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/cpuid.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,101 @@
+/*
+ * Dump CPUID information
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <com32.h>
+#include <sys/cpu.h>
+#include "sysdump.h"
+
+struct cpuid_data {
+    uint32_t eax, ebx, ecx, edx;
+};
+
+struct cpuid_info {
+    uint32_t eax, ecx;
+    struct cpuid_data data;
+};
+
+static void get_cpuid(uint32_t eax, uint32_t ecx, struct cpuid_data *data)
+{
+#if __SIZEOF_POINTER__ == 4
+    asm("pushl %%ebx ; cpuid ; movl %%ebx,%1 ; popl %%ebx"
+	: "=a" (data->eax), "=r" (data->ebx),
+	  "=c" (data->ecx), "=d" (data->edx)
+	: "a" (eax), "c" (ecx));
+#elif __SIZEOF_POINTER__ == 8
+        asm volatile("push %%rbx; cpuid; movl %%ebx, %1; pop %%rbx"
+            : "=a" (data->eax),
+              "=b" (data->ebx),
+              "=c" (data->ecx),
+              "=d" (data->edx)
+            : "a" (eax), "c" (ecx));
+#else
+#error "unsupported architecture"
+#endif
+}
+
+#define CPUID_CHUNK 128
+
+void dump_cpuid(struct upload_backend *be)
+{
+    struct cpuid_info *buf = NULL;
+    int nentry, nalloc;
+    uint32_t region;
+    struct cpuid_data base_leaf;
+    uint32_t base, leaf, count;
+    struct cpuid_data invalid_leaf;
+    struct cpuid_data data;
+
+    if (!cpu_has_eflag(EFLAGS_ID))
+	return;
+
+    printf("Dumping CPUID... ");
+
+    nentry = nalloc = 0;
+
+    /* Find out what the CPU returns for invalid leaves */
+    get_cpuid(0, 0, &base_leaf);
+    get_cpuid(base_leaf.eax+1, 0, &invalid_leaf);
+
+    for (region = 0 ; region <= 0xffff ; region++) {
+	base = region << 16;
+
+	get_cpuid(base, 0, &base_leaf);
+	if (region && !memcmp(&base_leaf, &invalid_leaf, sizeof base_leaf))
+	    continue;
+
+	if ((base_leaf.eax ^ base) & 0xffff0000)
+	    continue;
+
+	for (leaf = base ; leaf <= base_leaf.eax ; leaf++) {
+	    get_cpuid(leaf, 0, &data);
+	    count = 0;
+
+	    do {
+		if (nentry >= nalloc) {
+		    nalloc += CPUID_CHUNK;
+		    buf = realloc(buf, nalloc*sizeof *buf);
+		    if (!buf)
+			return;		/* FAILED */
+		}
+		buf[nentry].eax = leaf;
+		buf[nentry].ecx = count;
+		buf[nentry].data = data;
+		nentry++;
+		count++;
+
+		get_cpuid(leaf, count, &data);
+	    } while (memcmp(&data, &buf[nentry-1].data, sizeof data) &&
+		     (data.eax | data.ebx | data.ecx | data.edx));
+	}
+    }
+
+    if (nentry)
+	cpio_writefile(be, "cpuid", buf, nentry*sizeof *buf);
+    free(buf);
+
+    printf("done.\n");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,125 @@
+/*
+ * Dump DMI information in a way hopefully compatible with dmidecode
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sysdump.h"
+
+struct dmi_header {
+    char signature[5];
+    uint8_t csum;
+    uint16_t tbllen;
+    uint32_t tbladdr;
+    uint16_t nstruc;
+    uint8_t revision;
+    uint8_t reserved;
+};
+
+struct smbios_header {
+    char signature[4];
+    uint8_t csum;
+    uint8_t len;
+    uint8_t major;
+    uint8_t minor;
+    uint16_t maxsize;
+    uint8_t revision;
+    uint8_t fmt[5];
+
+    struct dmi_header dmi;
+};
+
+static uint8_t checksum(const void *buf, size_t len)
+{
+    const uint8_t *p = buf;
+    uint8_t csum = 0;
+
+    while (len--)
+	csum += *p++;
+
+    return csum;
+}
+
+static bool is_old_dmi(size_t dptr)
+{
+    const struct dmi_header *dmi = (void *)dptr;
+
+    return !memcmp(dmi->signature, "_DMI_", 5) &&
+	!checksum(dmi, 0x0f);
+    return false;
+}
+
+static bool is_smbios(size_t dptr)
+{
+    const struct smbios_header *smb = (void *)dptr;
+
+    return !memcmp(smb->signature, "_SM_", 4) &&
+	!checksum(smb, smb->len) &&
+	is_old_dmi(dptr+16);
+}
+
+static void dump_smbios(struct upload_backend *be, size_t dptr)
+{
+    const struct smbios_header *smb = (void *)dptr;
+    struct smbios_header smx = *smb;
+    char filename[32];
+
+    snprintf(filename, sizeof filename, "dmi/%05x.%08x",
+	     dptr, smb->dmi.tbladdr);
+    cpio_hdr(be, MODE_FILE, smb->dmi.tbllen + 32, filename);
+
+    /*
+     * Adjust the address of the smbios table to be 32, to
+     * make dmidecode happy.  The checksum on the smbios table is unchanged,
+     * since it includes the checksum on the dmi table.
+     */
+    smx.dmi.tbladdr = sizeof smx;
+    smx.dmi.csum -= checksum(&smx.dmi, 0x0f);
+
+    write_data(be, &smx, sizeof smx);
+    write_data(be, (const void *)smb->dmi.tbladdr, smb->dmi.tbllen);
+}
+
+static void dump_old_dmi(struct upload_backend *be, size_t dptr)
+{
+    const struct dmi_header *dmi = (void *)dptr;
+    struct fake {
+	struct dmi_header dmi;
+	char pad[16];
+    } fake;
+    char filename[32];
+
+    snprintf(filename, sizeof filename, "dmi/%05x.%08x",
+	     dptr, dmi->tbladdr);
+    cpio_hdr(be, MODE_FILE, dmi->tbllen + 32, filename);
+
+    /*
+     * Adjust the address of the smbios table to be 32, to
+     * make dmidecode happy.
+     */
+    fake.dmi = *dmi;
+    memset(&fake.pad, 0, sizeof fake.pad);
+    fake.dmi.tbladdr = sizeof fake;
+    fake.dmi.csum -= checksum(&fake.dmi, 0x0f);
+
+    write_data(be, &fake, sizeof fake);
+    write_data(be, (const void *)dmi->tbladdr, dmi->tbllen);
+}
+
+void dump_dmi(struct upload_backend *be)
+{
+    size_t dptr;
+
+    cpio_mkdir(be, "dmi");
+
+    /* Search for _SM_ or _DMI_ structure */
+    for (dptr = 0xf0000 ; dptr < 0x100000 ; dptr += 16) {
+	if (is_smbios(dptr)) {
+	    dump_smbios(be, dptr);
+	    dptr += 16;		/* Skip the subsequent DMI header */
+	} else if (is_old_dmi(dptr)) {
+	    dump_old_dmi(be, dptr);
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/main.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/main.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <dprintf.h>
+#include <console.h>
+#include <sys/cpu.h>
+#include <version.h>
+#include "sysdump.h"
+
+const char program[] = "sysdump";
+const char version[] = "SYSDUMP " VERSION_STR " " DATE "\n";
+
+__noreturn die(const char *msg)
+{
+    printf("%s: %s\n", program, msg);
+    exit(1);
+}
+
+static void dump_all(struct upload_backend *be, const char *argv[])
+{
+    cpio_init(be, argv);
+
+    cpio_writefile(be, "sysdump", version, sizeof version-1);
+
+    dump_memory_map(be);
+    dump_memory(be);
+    dump_dmi(be);
+    dump_acpi(be);
+    dump_cpuid(be);
+    dump_pci(be);
+    dump_vesa_tables(be);
+
+    cpio_close(be);
+    flush_data(be);
+}
+
+static struct upload_backend *upload_backends[] =
+{
+    &upload_tftp,
+    &upload_ymodem,
+    &upload_srec,
+    NULL
+};
+
+__noreturn usage(void)
+{
+    struct upload_backend **bep, *be;
+
+    printf("Usage:\n");
+    for (bep = upload_backends ; (be = *bep) ; bep++)
+	printf("    %s %s %s\n", program, be->name, be->helpmsg);
+
+    exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+    struct upload_backend **bep, *be;
+
+    fputs(version, stdout);
+
+    if (argc < 2)
+	usage();
+
+    for (bep = upload_backends ; (be = *bep) ; bep++) {
+	if (!strcmp(be->name, argv[1]))
+	    break;
+    }
+
+    if (!be || argc < be->minargs + 2)
+	usage();
+
+    /* Do this as early as possible */
+    snapshot_lowmem();
+
+    printf("Backend: %s\n", be->name);
+
+    /* Do the actual data dump */
+    dump_all(be, (const char **)argv + 2);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/memmap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/memmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/memmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,86 @@
+/*
+ * Dump memory map information
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <com32.h>
+#include "sysdump.h"
+
+#define E820_CHUNK 128
+struct e820_info {
+    uint32_t ebx;
+    uint32_t len;
+    uint8_t  data[24];
+};
+
+static void dump_e820(struct upload_backend *be)
+{
+    com32sys_t ireg, oreg;
+    struct e820_info *curr;
+    struct e820_info *buf, *p;
+    int nentry, nalloc;
+
+    curr = lmalloc(sizeof *curr);
+
+    buf = p = NULL;
+    nentry = nalloc = 0;
+    memset(&ireg, 0, sizeof ireg);
+    memset(&curr, 0, sizeof curr);
+
+    ireg.eax.l = 0xe820;
+    ireg.edx.l = 0x534d4150;
+    ireg.ecx.l = sizeof curr->data;
+    ireg.es = SEG(curr->data);
+    ireg.edi.w[0] = OFFS(curr->data);
+
+    do {
+	__intcall(0x15, &ireg, &oreg);
+	if ((oreg.eflags.l & EFLAGS_CF) ||
+	    oreg.eax.l != 0x534d4150)
+	    break;
+
+	if (nentry >= nalloc) {
+	    nalloc += E820_CHUNK;
+	    buf = realloc(buf, nalloc*sizeof *buf);
+	    if (!buf)
+		return;		/* FAILED */
+	}
+	memcpy(buf[nentry].data, curr->data, sizeof curr->data);
+	buf[nentry].ebx = ireg.ebx.l;
+	buf[nentry].len = oreg.ecx.l;
+	nentry++;
+
+	ireg.ebx.l = oreg.ebx.l;
+    } while (ireg.ebx.l);
+
+    if (nentry)
+	cpio_writefile(be, "memmap/15e820", buf, nentry*sizeof *buf);
+
+    free(buf);
+    lfree(curr);
+}
+
+void dump_memory_map(struct upload_backend *be)
+{
+    com32sys_t ireg, oreg;
+
+    cpio_mkdir(be, "memmap");
+
+    memset(&ireg, 0, sizeof ireg);
+    __intcall(0x12, &ireg, &oreg);
+    cpio_writefile(be, "memmap/12", &oreg, sizeof oreg);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[1] = 0x88;
+    __intcall(0x15, &ireg, &oreg);
+    cpio_writefile(be, "memmap/1588", &oreg, sizeof oreg);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0xe801;
+    __intcall(0x15, &ireg, &oreg);
+    cpio_writefile(be, "memmap/15e801", &oreg, sizeof oreg);
+
+    dump_e820(be);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/*
+ * Dump memory
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include "sysdump.h"
+
+static char *lowmem;
+static size_t lowmem_len;
+
+void *zero_addr;		/* Hack to keep gcc from complaining */
+
+void snapshot_lowmem(void)
+{
+    extern void _start(void);
+
+    lowmem_len = (size_t)_start;
+    lowmem = malloc(lowmem_len);
+    if (lowmem) {
+	printf("Snapshotting lowmem... ");
+	cli();
+	memcpy(lowmem, zero_addr, lowmem_len);
+	sti();
+	printf("ok\n");
+    }
+}
+
+static void dump_memory_range(struct upload_backend *be, const void *where,
+			      const void *addr, size_t len)
+{
+    char filename[32];
+
+    sprintf(filename, "memory/%08zx", (size_t)addr);
+    cpio_writefile(be, filename, where, len);
+}
+
+void dump_memory(struct upload_backend *be)
+{
+    printf("Dumping memory... ");
+
+    cpio_mkdir(be, "memory");
+
+    if (lowmem)
+	dump_memory_range(be, lowmem, zero_addr, lowmem_len);
+
+    printf("done.\n");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,69 @@
+/*
+ * Dump PCI device headers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/pci.h>
+#include "sysdump.h"
+
+static void dump_pci_device(struct upload_backend *be, pciaddr_t a, uint8_t hdrtype)
+{
+    unsigned int bus  = pci_bus(a);
+    unsigned int dev  = pci_dev(a);
+    unsigned int func = pci_func(a);
+    uint8_t data[256];
+    unsigned int i;
+    char filename[32];
+
+    hdrtype &= 0x7f;
+
+    printf("Scanning PCI bus... %02x:%02x.%x\r", bus, dev, func);
+
+    /* Assume doing a full device dump is actually safe... */
+    for (i = 0; i < sizeof data; i += 4)
+	*(uint32_t *)(data+i) = pci_readl(a + i);
+
+    snprintf(filename, sizeof filename, "pci/%02x:%02x.%x",
+	     bus, dev, func);
+    cpio_writefile(be, filename, data, sizeof data);
+}
+
+void dump_pci(struct upload_backend *be)
+{
+    int cfgtype;
+    unsigned int nbus, ndev, nfunc, maxfunc;
+    pciaddr_t a;
+    uint32_t did;
+    uint8_t hdrtype;
+
+    cfgtype = pci_set_config_type(PCI_CFG_AUTO);
+    if (cfgtype == PCI_CFG_NONE)
+	return;
+
+    cpio_mkdir(be, "pci");
+
+    for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) {
+	for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) {
+	    maxfunc = 1;	/* Assume a single-function device */
+
+	    for (nfunc = 0; nfunc < maxfunc; nfunc++) {
+		a = pci_mkaddr(nbus, ndev, nfunc, 0);
+		did = pci_readl(a);
+
+		if (did == 0xffffffff || did == 0xffff0000 ||
+		    did == 0x0000ffff || did == 0x00000000)
+		    continue;
+
+		hdrtype = pci_readb(a + 0x0e);
+		if (hdrtype & 0x80)
+		    maxfunc = MAX_PCI_FUNC;	/* Multifunction device */
+
+		dump_pci_device(be, a, hdrtype);
+	    }
+	}
+    }
+
+    printf("Scanning PCI bus... done.  \n");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *     
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rbtree.c
+ *
+ * Simple implementation of a left-leaning red-black tree with 64-bit
+ * integer keys.  The search operation will return the highest node <=
+ * the key; only search and insert are supported, but additional
+ * standard llrbtree operations can be coded up at will.
+ *
+ * See http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf for
+ * information about left-leaning red-black trees.
+ */
+
+#include <stdlib.h>
+#include "rbtree.h"
+
+struct rbtree *rb_search(struct rbtree *tree, uint64_t key)
+{
+    struct rbtree *best = NULL;
+
+    while (tree) {
+	if (tree->key == key)
+	    return tree;
+	else if (tree->key > key)
+	    tree = tree->left;
+	else {
+	    best = tree;
+	    tree = tree->right;
+	}
+    }
+    return best;
+}
+
+static bool is_red(struct rbtree *h)
+{
+    return h && h->red;
+}
+
+static struct rbtree *rotate_left(struct rbtree *h)
+{
+    struct rbtree *x = h->right;
+    h->right = x->left;
+    x->left = h;
+    x->red = x->left->red;
+    x->left->red = true;
+    return x;
+}
+
+static struct rbtree *rotate_right(struct rbtree *h)
+{
+    struct rbtree *x = h->left;
+    h->left = x->right;
+    x->right = h;
+    x->red = x->right->red;
+    x->right->red = true;
+    return x;
+}
+
+static void color_flip(struct rbtree *h)
+{
+    h->red = !h->red;
+    h->left->red = !h->left->red;
+    h->right->red = !h->right->red;
+}
+
+struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node)
+{
+    node->left = node->right = NULL;
+    node->red = false;
+
+    if (!tree) {
+	node->red = true;
+	return node;
+    }
+
+    if (is_red(tree->left) && is_red(tree->right))
+	color_flip(tree);
+
+    if (node->key < tree->key)
+	tree->left = rb_insert(tree->left, node);
+    else
+	tree->right = rb_insert(tree->right, node);
+
+    if (is_red(tree->right))
+	tree = rotate_left(tree);
+
+    if (is_red(tree->left) && is_red(tree->left->left))
+	tree = rotate_right(tree);
+
+    return tree;
+}
+
+void rb_destroy(struct rbtree *tree)
+{
+    if (tree->left)
+	rb_destroy(tree->left);
+    if (tree->right)
+	rb_destroy(tree->right);
+    free(tree);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/rbtree.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *     
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef NASM_RBTREE_H
+#define NASM_RBTREE_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+/* This structure should be embedded in a larger data structure;
+   the final output from rb_search() can then be converted back
+   to the larger data structure via container_of(). */
+struct rbtree {
+    uint64_t key;
+    struct rbtree *left, *right;
+    bool red;
+};
+
+struct rbtree *rb_insert(struct rbtree *, struct rbtree *);
+struct rbtree *rb_search(struct rbtree *, uint64_t);
+void rb_destroy(struct rbtree *);
+
+#endif /* NASM_RBTREE_H */
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/sysdump.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/sysdump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/sysdump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#ifndef SYSDUMP_H
+#define SYSDUMP_H
+
+#include <libupload/upload_backend.h>
+
+void dump_memory_map(struct upload_backend *);
+void snapshot_lowmem(void);
+void dump_memory(struct upload_backend *);
+void dump_dmi(struct upload_backend *);
+void dump_acpi(struct upload_backend *);
+void dump_cpuid(struct upload_backend *);
+void dump_pci(struct upload_backend *);
+void dump_vesa_tables(struct upload_backend *);
+
+#endif /* SYSDUMP_H */
Index: bootcd/isolinux/syslinux-6.03/com32/sysdump/vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/sysdump/vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/sysdump/vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+#include <string.h>
+#include <stdio.h>
+#include <lib/sys/vesa/vesa.h>
+#include "sysdump.h"
+
+void dump_vesa_tables(struct upload_backend *be)
+{
+    com32sys_t rm;
+    struct vesa_info *vip;
+    struct vesa_general_info *gip, gi;
+    struct vesa_mode_info *mip, mi;
+    uint16_t mode, *mode_ptr;
+    char modefile[64];
+
+    printf("Scanning VESA BIOS... ");
+
+    /* Allocate space in the bounce buffer for these structures */
+    vip = lmalloc(sizeof *vip);
+    gip = &vip->gi;
+    mip = &vip->mi;
+
+    memset(&rm, 0, sizeof rm);
+    memset(gip, 0, sizeof *gip);
+
+    gip->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    rm.eax.w[0] = 0x4F00;		/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gip);
+    rm.es = SEG(gip);
+    __intcall(0x10, &rm, &rm);
+    memcpy(&gi, gip, sizeof gi);
+
+    if (rm.eax.w[0] != 0x004F)
+	return;		/* Function call failed */
+    if (gi.signature != VESA_MAGIC)
+	return;		/* No magic */
+
+    cpio_mkdir(be, "vesa");
+
+    cpio_writefile(be, "vesa/global.bin", &gi, sizeof gi);
+
+    mode_ptr = GET_PTR(gi.video_mode_ptr);
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	memset(mip, 0, sizeof *mip);
+        memset(&rm, 0, sizeof rm);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mip);
+	rm.es = SEG(mip);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	memcpy(&mi, mip, sizeof mi);
+
+	sprintf(modefile, "vesa/mode%04x.bin", mode);
+	cpio_writefile(be, modefile, &mi, sizeof mi);
+    }
+
+    lfree(vip);
+    printf("done.\n");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/tools/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/tools/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/tools/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,32 @@
+## -*- makefile -*- ------------------------------------------------------
+##
+##   Copyright 2001-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.
+##
+## -----------------------------------------------------------------------
+
+VPATH = $(SRC)
+include $(MAKEDIR)/build.mk
+
+BINS    = relocs
+
+INCLUDES += -I$(SRC)/include
+
+all : $(BINS)
+
+relocs : relocs.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+tidy dist clean spotless:
+	rm -f $(BINS)
+	rm -f *.o *.a .*.d
+	rm -f */*.o */*.a */.*.d
+
+install installer:
+
+-include .*.d */.*.d
Index: bootcd/isolinux/syslinux-6.03/com32/tools/include/tools/le_byteshift.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/tools/include/tools/le_byteshift.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/tools/include/tools/le_byteshift.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,70 @@
+#ifndef _TOOLS_LE_BYTESHIFT_H
+#define _TOOLS_LE_BYTESHIFT_H
+
+#include <linux/types.h>
+
+static inline __u16 __get_unaligned_le16(const __u8 *p)
+{
+	return p[0] | p[1] << 8;
+}
+
+static inline __u32 __get_unaligned_le32(const __u8 *p)
+{
+	return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
+}
+
+static inline __u64 __get_unaligned_le64(const __u8 *p)
+{
+	return (__u64)__get_unaligned_le32(p + 4) << 32 |
+	       __get_unaligned_le32(p);
+}
+
+static inline void __put_unaligned_le16(__u16 val, __u8 *p)
+{
+	*p++ = val;
+	*p++ = val >> 8;
+}
+
+static inline void __put_unaligned_le32(__u32 val, __u8 *p)
+{
+	__put_unaligned_le16(val >> 16, p + 2);
+	__put_unaligned_le16(val, p);
+}
+
+static inline void __put_unaligned_le64(__u64 val, __u8 *p)
+{
+	__put_unaligned_le32(val >> 32, p + 4);
+	__put_unaligned_le32(val, p);
+}
+
+static inline __u16 get_unaligned_le16(const void *p)
+{
+	return __get_unaligned_le16((const __u8 *)p);
+}
+
+static inline __u32 get_unaligned_le32(const void *p)
+{
+	return __get_unaligned_le32((const __u8 *)p);
+}
+
+static inline __u64 get_unaligned_le64(const void *p)
+{
+	return __get_unaligned_le64((const __u8 *)p);
+}
+
+static inline void put_unaligned_le16(__u16 val, void *p)
+{
+	__put_unaligned_le16(val, p);
+}
+
+static inline void put_unaligned_le32(__u32 val, void *p)
+{
+	__put_unaligned_le32(val, p);
+}
+
+static inline void put_unaligned_le64(__u64 val, void *p)
+{
+	__put_unaligned_le64(val, p);
+}
+
+#endif /* _TOOLS_LE_BYTESHIFT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/tools/relocs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/tools/relocs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/tools/relocs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,808 @@
+/*
+ * This file is taken from the Linux kernel and is distributed under GPL v2.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <elf.h>
+#include <byteswap.h>
+#define USE_BSD
+#include <endian.h>
+#include <regex.h>
+#include <tools/le_byteshift.h>
+
+static void die(char *fmt, ...);
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+static Elf32_Ehdr ehdr;
+static unsigned long reloc_count, reloc_idx;
+static unsigned long *relocs;
+static unsigned long reloc16_count, reloc16_idx;
+static unsigned long *relocs16;
+
+struct section {
+	Elf32_Shdr     shdr;
+	struct section *link;
+	Elf32_Sym      *symtab;
+	Elf32_Rel      *reltab;
+	char           *strtab;
+};
+static struct section *secs;
+
+enum symtype {
+	S_ABS,
+	S_REL,
+	S_SEG,
+	S_LIN,
+	S_NSYMTYPES
+};
+
+static const char * const sym_regex_kernel[S_NSYMTYPES] = {
+/*
+ * Following symbols have been audited.  Don't warn user about
+ * absolute relocations present w.r.t these symbols.
+ */
+	[S_ABS] =
+	"^(__.*_len|__.*_dwords)$",
+
+/*
+ * These symbols are known to be relative, even if the linker marks them
+ * as absolute (typically defined outside any section in the linker script.)
+ */
+	[S_REL] =
+	"^(__.*_start|__.*_end|_end|_[se](text|data))$",
+};
+
+
+static const char * const sym_regex_realmode[S_NSYMTYPES] = {
+/*
+ * These are 16-bit segment symbols when compiling 16-bit code.
+ */
+	[S_SEG] =
+	"^real_mode_seg$",
+
+/*
+ * These are offsets belonging to segments, as opposed to linear addresses,
+ * when compiling 16-bit code.
+ */
+	[S_LIN] =
+	"^pa_",
+};
+
+static const char * const *sym_regex;
+
+static regex_t sym_regex_c[S_NSYMTYPES];
+static int is_reloc(enum symtype type, const char *sym_name)
+{
+	return sym_regex[type] &&
+		!regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
+}
+
+static void regex_init(int use_real_mode)
+{
+        char errbuf[128];
+        int err;
+	int i;
+
+	if (use_real_mode)
+		sym_regex = sym_regex_realmode;
+	else
+		sym_regex = sym_regex_kernel;
+
+	for (i = 0; i < S_NSYMTYPES; i++) {
+		if (!sym_regex[i])
+			continue;
+
+		err = regcomp(&sym_regex_c[i], sym_regex[i],
+			      REG_EXTENDED|REG_NOSUB);
+
+		if (err) {
+			regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf);
+			die("%s", errbuf);
+		}
+        }
+}
+
+static void die(char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	exit(1);
+}
+
+static const char *sym_type(unsigned type)
+{
+	static const char *type_name[] = {
+#define SYM_TYPE(X) [X] = #X
+		SYM_TYPE(STT_NOTYPE),
+		SYM_TYPE(STT_OBJECT),
+		SYM_TYPE(STT_FUNC),
+		SYM_TYPE(STT_SECTION),
+		SYM_TYPE(STT_FILE),
+		SYM_TYPE(STT_COMMON),
+		SYM_TYPE(STT_TLS),
+#undef SYM_TYPE
+	};
+	const char *name = "unknown sym type name";
+	if (type < ARRAY_SIZE(type_name)) {
+		name = type_name[type];
+	}
+	return name;
+}
+
+static const char *sym_bind(unsigned bind)
+{
+	static const char *bind_name[] = {
+#define SYM_BIND(X) [X] = #X
+		SYM_BIND(STB_LOCAL),
+		SYM_BIND(STB_GLOBAL),
+		SYM_BIND(STB_WEAK),
+#undef SYM_BIND
+	};
+	const char *name = "unknown sym bind name";
+	if (bind < ARRAY_SIZE(bind_name)) {
+		name = bind_name[bind];
+	}
+	return name;
+}
+
+static const char *sym_visibility(unsigned visibility)
+{
+	static const char *visibility_name[] = {
+#define SYM_VISIBILITY(X) [X] = #X
+		SYM_VISIBILITY(STV_DEFAULT),
+		SYM_VISIBILITY(STV_INTERNAL),
+		SYM_VISIBILITY(STV_HIDDEN),
+		SYM_VISIBILITY(STV_PROTECTED),
+#undef SYM_VISIBILITY
+	};
+	const char *name = "unknown sym visibility name";
+	if (visibility < ARRAY_SIZE(visibility_name)) {
+		name = visibility_name[visibility];
+	}
+	return name;
+}
+
+static const char *rel_type(unsigned type)
+{
+	static const char *type_name[] = {
+#define REL_TYPE(X) [X] = #X
+		REL_TYPE(R_386_NONE),
+		REL_TYPE(R_386_32),
+		REL_TYPE(R_386_PC32),
+		REL_TYPE(R_386_GOT32),
+		REL_TYPE(R_386_PLT32),
+		REL_TYPE(R_386_COPY),
+		REL_TYPE(R_386_GLOB_DAT),
+		REL_TYPE(R_386_JMP_SLOT),
+		REL_TYPE(R_386_RELATIVE),
+		REL_TYPE(R_386_GOTOFF),
+		REL_TYPE(R_386_GOTPC),
+		REL_TYPE(R_386_8),
+		REL_TYPE(R_386_PC8),
+		REL_TYPE(R_386_16),
+		REL_TYPE(R_386_PC16),
+#undef REL_TYPE
+	};
+	const char *name = "unknown type rel type name";
+	if (type < ARRAY_SIZE(type_name) && type_name[type]) {
+		name = type_name[type];
+	}
+	return name;
+}
+
+static const char *sec_name(unsigned shndx)
+{
+	const char *sec_strtab;
+	const char *name;
+	sec_strtab = secs[ehdr.e_shstrndx].strtab;
+	name = "<noname>";
+	if (shndx < ehdr.e_shnum) {
+		name = sec_strtab + secs[shndx].shdr.sh_name;
+	}
+	else if (shndx == SHN_ABS) {
+		name = "ABSOLUTE";
+	}
+	else if (shndx == SHN_COMMON) {
+		name = "COMMON";
+	}
+	return name;
+}
+
+static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym)
+{
+	const char *name;
+	name = "<noname>";
+	if (sym->st_name) {
+		name = sym_strtab + sym->st_name;
+	}
+	else {
+		name = sec_name(sym->st_shndx);
+	}
+	return name;
+}
+
+
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define le16_to_cpu(val) (val)
+#define le32_to_cpu(val) (val)
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+#define le16_to_cpu(val) bswap_16(val)
+#define le32_to_cpu(val) bswap_32(val)
+#endif
+
+static uint16_t elf16_to_cpu(uint16_t val)
+{
+	return le16_to_cpu(val);
+}
+
+static uint32_t elf32_to_cpu(uint32_t val)
+{
+	return le32_to_cpu(val);
+}
+
+static void read_ehdr(FILE *fp)
+{
+	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
+		die("Cannot read ELF header: %s\n",
+			strerror(errno));
+	}
+	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
+		die("No ELF magic\n");
+	}
+	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) {
+		die("Not a 32 bit executable\n");
+	}
+	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
+		die("Not a LSB ELF executable\n");
+	}
+	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
+		die("Unknown ELF version\n");
+	}
+	/* Convert the fields to native endian */
+	ehdr.e_type      = elf16_to_cpu(ehdr.e_type);
+	ehdr.e_machine   = elf16_to_cpu(ehdr.e_machine);
+	ehdr.e_version   = elf32_to_cpu(ehdr.e_version);
+	ehdr.e_entry     = elf32_to_cpu(ehdr.e_entry);
+	ehdr.e_phoff     = elf32_to_cpu(ehdr.e_phoff);
+	ehdr.e_shoff     = elf32_to_cpu(ehdr.e_shoff);
+	ehdr.e_flags     = elf32_to_cpu(ehdr.e_flags);
+	ehdr.e_ehsize    = elf16_to_cpu(ehdr.e_ehsize);
+	ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize);
+	ehdr.e_phnum     = elf16_to_cpu(ehdr.e_phnum);
+	ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize);
+	ehdr.e_shnum     = elf16_to_cpu(ehdr.e_shnum);
+	ehdr.e_shstrndx  = elf16_to_cpu(ehdr.e_shstrndx);
+
+	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
+		die("Unsupported ELF header type\n");
+	}
+	if (ehdr.e_machine != EM_386) {
+		die("Not for x86\n");
+	}
+	if (ehdr.e_version != EV_CURRENT) {
+		die("Unknown ELF version\n");
+	}
+	if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) {
+		die("Bad Elf header size\n");
+	}
+	if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) {
+		die("Bad program header entry\n");
+	}
+	if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) {
+		die("Bad section header entry\n");
+	}
+	if (ehdr.e_shstrndx >= ehdr.e_shnum) {
+		die("String table index out of bounds\n");
+	}
+}
+
+static void read_shdrs(FILE *fp)
+{
+	int i;
+	Elf32_Shdr shdr;
+
+	secs = calloc(ehdr.e_shnum, sizeof(struct section));
+	if (!secs) {
+		die("Unable to allocate %d section headers\n",
+		    ehdr.e_shnum);
+	}
+	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
+		die("Seek to %d failed: %s\n",
+			ehdr.e_shoff, strerror(errno));
+	}
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		if (fread(&shdr, sizeof shdr, 1, fp) != 1)
+			die("Cannot read ELF section headers %d/%d: %s\n",
+			    i, ehdr.e_shnum, strerror(errno));
+		sec->shdr.sh_name      = elf32_to_cpu(shdr.sh_name);
+		sec->shdr.sh_type      = elf32_to_cpu(shdr.sh_type);
+		sec->shdr.sh_flags     = elf32_to_cpu(shdr.sh_flags);
+		sec->shdr.sh_addr      = elf32_to_cpu(shdr.sh_addr);
+		sec->shdr.sh_offset    = elf32_to_cpu(shdr.sh_offset);
+		sec->shdr.sh_size      = elf32_to_cpu(shdr.sh_size);
+		sec->shdr.sh_link      = elf32_to_cpu(shdr.sh_link);
+		sec->shdr.sh_info      = elf32_to_cpu(shdr.sh_info);
+		sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign);
+		sec->shdr.sh_entsize   = elf32_to_cpu(shdr.sh_entsize);
+		if (sec->shdr.sh_link < ehdr.e_shnum)
+			sec->link = &secs[sec->shdr.sh_link];
+	}
+
+}
+
+static void read_strtabs(FILE *fp)
+{
+	int i;
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		if (sec->shdr.sh_type != SHT_STRTAB) {
+			continue;
+		}
+		sec->strtab = malloc(sec->shdr.sh_size);
+		if (!sec->strtab) {
+			die("malloc of %d bytes for strtab failed\n",
+				sec->shdr.sh_size);
+		}
+		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				sec->shdr.sh_offset, strerror(errno));
+		}
+		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
+		    != sec->shdr.sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+	}
+}
+
+static void read_symtabs(FILE *fp)
+{
+	int i,j;
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		if (sec->shdr.sh_type != SHT_SYMTAB) {
+			continue;
+		}
+		sec->symtab = malloc(sec->shdr.sh_size);
+		if (!sec->symtab) {
+			die("malloc of %d bytes for symtab failed\n",
+				sec->shdr.sh_size);
+		}
+		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				sec->shdr.sh_offset, strerror(errno));
+		}
+		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
+		    != sec->shdr.sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
+			Elf32_Sym *sym = &sec->symtab[j];
+			sym->st_name  = elf32_to_cpu(sym->st_name);
+			sym->st_value = elf32_to_cpu(sym->st_value);
+			sym->st_size  = elf32_to_cpu(sym->st_size);
+			sym->st_shndx = elf16_to_cpu(sym->st_shndx);
+		}
+	}
+}
+
+
+static void read_relocs(FILE *fp)
+{
+	int i,j;
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		if (sec->shdr.sh_type != SHT_REL) {
+			continue;
+		}
+		sec->reltab = malloc(sec->shdr.sh_size);
+		if (!sec->reltab) {
+			die("malloc of %d bytes for relocs failed\n",
+				sec->shdr.sh_size);
+		}
+		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
+			die("Seek to %d failed: %s\n",
+				sec->shdr.sh_offset, strerror(errno));
+		}
+		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
+		    != sec->shdr.sh_size) {
+			die("Cannot read symbol table: %s\n",
+				strerror(errno));
+		}
+		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+			Elf32_Rel *rel = &sec->reltab[j];
+			rel->r_offset = elf32_to_cpu(rel->r_offset);
+			rel->r_info   = elf32_to_cpu(rel->r_info);
+		}
+	}
+}
+
+
+static void print_absolute_symbols(void)
+{
+	int i;
+	printf("Absolute symbols\n");
+	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		char *sym_strtab;
+		int j;
+
+		if (sec->shdr.sh_type != SHT_SYMTAB) {
+			continue;
+		}
+		sym_strtab = sec->link->strtab;
+		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
+			Elf32_Sym *sym;
+			const char *name;
+			sym = &sec->symtab[j];
+			name = sym_name(sym_strtab, sym);
+			if (sym->st_shndx != SHN_ABS) {
+				continue;
+			}
+			printf("%5d %08x %5d %10s %10s %12s %s\n",
+				j, sym->st_value, sym->st_size,
+				sym_type(ELF32_ST_TYPE(sym->st_info)),
+				sym_bind(ELF32_ST_BIND(sym->st_info)),
+				sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)),
+				name);
+		}
+	}
+	printf("\n");
+}
+
+static void print_absolute_relocs(void)
+{
+	int i, printed = 0;
+
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		struct section *sec = &secs[i];
+		struct section *sec_applies, *sec_symtab;
+		char *sym_strtab;
+		Elf32_Sym *sh_symtab;
+		int j;
+		if (sec->shdr.sh_type != SHT_REL) {
+			continue;
+		}
+		sec_symtab  = sec->link;
+		sec_applies = &secs[sec->shdr.sh_info];
+		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+			continue;
+		}
+		sh_symtab  = sec_symtab->symtab;
+		sym_strtab = sec_symtab->link->strtab;
+		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+			Elf32_Rel *rel;
+			Elf32_Sym *sym;
+			const char *name;
+			rel = &sec->reltab[j];
+			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
+			name = sym_name(sym_strtab, sym);
+			if (sym->st_shndx != SHN_ABS) {
+				continue;
+			}
+
+			/* Absolute symbols are not relocated if bzImage is
+			 * loaded at a non-compiled address. Display a warning
+			 * to user at compile time about the absolute
+			 * relocations present.
+			 *
+			 * User need to audit the code to make sure
+			 * some symbols which should have been section
+			 * relative have not become absolute because of some
+			 * linker optimization or wrong programming usage.
+			 *
+			 * Before warning check if this absolute symbol
+			 * relocation is harmless.
+			 */
+			if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
+				continue;
+
+			if (!printed) {
+				printf("WARNING: Absolute relocations"
+					" present\n");
+				printf("Offset     Info     Type     Sym.Value "
+					"Sym.Name\n");
+				printed = 1;
+			}
+
+			printf("%08x %08x %10s %08x  %s\n",
+				rel->r_offset,
+				rel->r_info,
+				rel_type(ELF32_R_TYPE(rel->r_info)),
+				sym->st_value,
+				name);
+		}
+	}
+
+	if (printed)
+		printf("\n");
+}
+
+static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym),
+			int use_real_mode)
+{
+	int i;
+	/* Walk through the relocations */
+	for (i = 0; i < ehdr.e_shnum; i++) {
+		char *sym_strtab;
+		Elf32_Sym *sh_symtab;
+		struct section *sec_applies, *sec_symtab;
+		int j;
+		struct section *sec = &secs[i];
+
+		if (sec->shdr.sh_type != SHT_REL) {
+			continue;
+		}
+		sec_symtab  = sec->link;
+		sec_applies = &secs[sec->shdr.sh_info];
+		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+			continue;
+		}
+		sh_symtab = sec_symtab->symtab;
+		sym_strtab = sec_symtab->link->strtab;
+		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
+			Elf32_Rel *rel;
+			Elf32_Sym *sym;
+			unsigned r_type;
+			const char *symname;
+			int shn_abs;
+
+			rel = &sec->reltab[j];
+			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
+			r_type = ELF32_R_TYPE(rel->r_info);
+
+			shn_abs = sym->st_shndx == SHN_ABS;
+
+			switch (r_type) {
+			case R_386_NONE:
+			case R_386_PC32:
+			case R_386_PC16:
+			case R_386_PC8:
+			case R_386_GOTPC:
+			case R_386_GOTOFF:
+			case R_386_GOT32:
+			case R_386_PLT32:
+				/*
+				 * NONE can be ignored and and PC relative
+				 * relocations don't need to be adjusted.
+				 */
+				break;
+
+			case R_386_16:
+				symname = sym_name(sym_strtab, sym);
+				if (!use_real_mode)
+					goto bad;
+				if (shn_abs) {
+					if (is_reloc(S_ABS, symname))
+						break;
+					else if (!is_reloc(S_SEG, symname))
+						goto bad;
+				} else {
+					if (is_reloc(S_LIN, symname))
+						goto bad;
+					else
+						break;
+				}
+				visit(rel, sym);
+				break;
+
+			case R_386_32:
+				symname = sym_name(sym_strtab, sym);
+				if (shn_abs) {
+					if (is_reloc(S_ABS, symname))
+						break;
+					else if (!is_reloc(S_REL, symname))
+						goto bad;
+				} else {
+					if (use_real_mode &&
+					    !is_reloc(S_LIN, symname))
+						break;
+				}
+				visit(rel, sym);
+				break;
+			default:
+				die("Unsupported relocation type: %s (%d)\n",
+				    rel_type(r_type), r_type);
+				break;
+			bad:
+				symname = sym_name(sym_strtab, sym);
+				die("Invalid %s %s relocation: %s\n",
+				    shn_abs ? "absolute" : "relative",
+				    rel_type(r_type), symname);
+			}
+		}
+	}
+}
+
+static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
+{
+	(void)sym;
+
+	if (ELF32_R_TYPE(rel->r_info) == R_386_16)
+		reloc16_count++;
+	else
+		reloc_count++;
+}
+
+static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym)
+{
+	(void)sym;
+
+	/* Remember the address that needs to be adjusted. */
+	if (ELF32_R_TYPE(rel->r_info) == R_386_16)
+		relocs16[reloc16_idx++] = rel->r_offset;
+	else
+		relocs[reloc_idx++] = rel->r_offset;
+}
+
+static int cmp_relocs(const void *va, const void *vb)
+{
+	const unsigned long *a, *b;
+	a = va; b = vb;
+	return (*a == *b)? 0 : (*a > *b)? 1 : -1;
+}
+
+static int write32(unsigned int v, FILE *f)
+{
+	unsigned char buf[4];
+
+	put_unaligned_le32(v, buf);
+	return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
+}
+
+static void emit_relocs(int as_text, int use_real_mode)
+{
+	int i;
+	/* Count how many relocations I have and allocate space for them. */
+	reloc_count = 0;
+	walk_relocs(count_reloc, use_real_mode);
+	relocs = malloc(reloc_count * sizeof(relocs[0]));
+	if (!relocs) {
+		die("malloc of %d entries for relocs failed\n",
+			reloc_count);
+	}
+
+	relocs16 = malloc(reloc16_count * sizeof(relocs[0]));
+	if (!relocs16) {
+		die("malloc of %d entries for relocs16 failed\n",
+			reloc16_count);
+	}
+	/* Collect up the relocations */
+	reloc_idx = 0;
+	walk_relocs(collect_reloc, use_real_mode);
+
+	if (reloc16_count && !use_real_mode)
+		die("Segment relocations found but --realmode not specified\n");
+
+	/* Order the relocations for more efficient processing */
+	qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs);
+	qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs);
+
+	/* Print the relocations */
+	if (as_text) {
+		/* Print the relocations in a form suitable that
+		 * gas will like.
+		 */
+		printf(".section \".data.reloc\",\"a\"\n");
+		printf(".balign 4\n");
+		if (use_real_mode) {
+			printf("\t.long %lu\n", reloc16_count);
+			for (i = 0; i < reloc16_count; i++)
+				printf("\t.long 0x%08lx\n", relocs16[i]);
+			printf("\t.long %lu\n", reloc_count);
+			for (i = 0; i < reloc_count; i++) {
+				printf("\t.long 0x%08lx\n", relocs[i]);
+			}
+		} else {
+			for (i = 0; i < reloc_count; i++) {
+				printf("\t.long 0x%08lx\n", relocs[i]);
+			}
+			/* Print a stop */
+			printf("\t.long 0x%08lx\n", (unsigned long)0);
+		}
+
+		printf("\n");
+	}
+	else {
+		if (use_real_mode) {
+			write32(reloc16_count, stdout);
+			for (i = 0; i < reloc16_count; i++)
+				write32(relocs16[i], stdout);
+			write32(reloc_count, stdout);
+
+			/* Now print each relocation */
+			for (i = 0; i < reloc_count; i++)
+				write32(relocs[i], stdout);
+		} else {
+			/* Now print each relocation */
+			for (i = 0; i < reloc_count; i++) {
+				write32(relocs[i], stdout);
+			}
+
+			/* Print a stop */
+			write32(0, stdout);
+		}
+	}
+}
+
+static void usage(void)
+{
+	die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
+}
+
+int main(int argc, char **argv)
+{
+	int show_absolute_syms, show_absolute_relocs;
+	int as_text, use_real_mode;
+	const char *fname;
+	FILE *fp;
+	int i;
+
+	show_absolute_syms = 0;
+	show_absolute_relocs = 0;
+	as_text = 0;
+	use_real_mode = 0;
+	fname = NULL;
+	for (i = 1; i < argc; i++) {
+		char *arg = argv[i];
+		if (*arg == '-') {
+			if (strcmp(arg, "--abs-syms") == 0) {
+				show_absolute_syms = 1;
+				continue;
+			}
+			if (strcmp(arg, "--abs-relocs") == 0) {
+				show_absolute_relocs = 1;
+				continue;
+			}
+			if (strcmp(arg, "--text") == 0) {
+				as_text = 1;
+				continue;
+			}
+			if (strcmp(arg, "--realmode") == 0) {
+				use_real_mode = 1;
+				continue;
+			}
+		}
+		else if (!fname) {
+			fname = arg;
+			continue;
+		}
+		usage();
+	}
+	if (!fname) {
+		usage();
+	}
+	regex_init(use_real_mode);
+	fp = fopen(fname, "r");
+	if (!fp) {
+		die("Cannot open %s: %s\n",
+			fname, strerror(errno));
+	}
+	read_ehdr(fp);
+	read_shdrs(fp);
+	read_strtabs(fp);
+	read_symtabs(fp);
+	read_relocs(fp);
+	if (show_absolute_syms) {
+		print_absolute_symbols();
+		return 0;
+	}
+	if (show_absolute_relocs) {
+		print_absolute_relocs();
+		return 0;
+	}
+	emit_relocs(as_text, use_real_mode);
+	return 0;
+}
