diff options
author | Sebastian Schmelzer | 2010-10-25 16:53:54 +0200 |
---|---|---|
committer | Sebastian Schmelzer | 2010-10-25 16:53:54 +0200 |
commit | 3050a9253437f4a4b5ad4bf3b3efdc3c660a5137 (patch) | |
tree | 91ac22153e416aac7ca20916b314b5e2ffa871b1 /contrib/syslinux-4.02/utils | |
download | preboot-master.tar.gz preboot-master.tar.xz preboot-master.zip |
Diffstat (limited to 'contrib/syslinux-4.02/utils')
-rw-r--r-- | contrib/syslinux-4.02/utils/Makefile | 72 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/bin2hex.pl | 48 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/gethostip.c | 131 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/isohdpfxarray.pl | 57 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/isohybrid.c | 561 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/isohybrid.h | 27 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/isohybrid.in | 258 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/keytab-lilo | 95 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/lss16toppm | 111 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/md5pass | 34 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/memdiskfind.c | 158 | ||||
-rw-r--r-- | contrib/syslinux-4.02/utils/mkdiskimage.in | 321 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/ppmtolss16 | 393 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/pxelinux-options | 499 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/sha1pass | 34 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/utils/syslinux2ansi | 53 |
16 files changed, 2852 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/utils/Makefile b/contrib/syslinux-4.02/utils/Makefile new file mode 100644 index 0000000..455eb82 --- /dev/null +++ b/contrib/syslinux-4.02/utils/Makefile @@ -0,0 +1,72 @@ +## ----------------------------------------------------------------------- +## +## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, Inc., 53 Temple Place Ste 330, +## Boston MA 02111-1307, USA; either version 2 of the License, or +## (at your option) any later version; incorporated herein by reference. +## +## ----------------------------------------------------------------------- + +# +# SYSLINUX utilities +# + +topdir = .. +include $(topdir)/MCONFIG + +CFLAGS = $(GCCWARN) -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 +LDFLAGS = -O2 -s + +TARGETS = mkdiskimage isohybrid gethostip memdiskfind +TARGETS += isohybrid.pl # about to be obsoleted +ASIS = keytab-lilo lss16toppm md5pass ppmtolss16 sha1pass syslinux2ansi \ + pxelinux-options + +ISOHDPFX = ../mbr/isohdpfx.bin ../mbr/isohdpfx_f.bin ../mbr/isohdpfx_c.bin \ + ../mbr/isohdppx.bin ../mbr/isohdppx_f.bin ../mbr/isohdppx_c.bin + +all: $(TARGETS) + +%.o: %.c + $(CC) $(UMAKEDEPS) $(CFLAGS) -c -o $@ $< + +mkdiskimage: mkdiskimage.in ../mbr/mbr.bin bin2hex.pl + $(PERL) bin2hex.pl < ../mbr/mbr.bin | cat mkdiskimage.in - > $@ + chmod a+x $@ + +# Works on anything with a Perl interpreter... +isohybrid.pl: isohybrid.in $(ISOHDPFX) bin2hex.pl + cp -f isohybrid.in $@ + for f in $(ISOHDPFX) ; do $(PERL) bin2hex.pl < $$f >> $@ ; done + chmod a+x $@ + +isohdpfx.c: $(ISOHDPFX) isohdpfxarray.pl + $(PERL) isohdpfxarray.pl $(ISOHDPFX) > $@ + +isohybrid: isohybrid.o isohdpfx.o + $(CC) $(LDFLAGS) -o $@ $^ + +gethostip: gethostip.o + $(CC) $(LDFLAGS) -o $@ $^ + +memdiskfind: memdiskfind.o + $(CC) $(LDFLAGS) -o $@ $^ + +tidy dist: + rm -f *.o .*.d isohdpfx.c + +clean: tidy + rm -f $(TARGETS) + +spotless: clean + +installer: all + +install: installer + mkdir -m 755 -p $(INSTALLROOT)$(BINDIR) + install -m 755 $(TARGETS) $(ASIS) $(INSTALLROOT)$(BINDIR) + +-include .*.d diff --git a/contrib/syslinux-4.02/utils/bin2hex.pl b/contrib/syslinux-4.02/utils/bin2hex.pl new file mode 100644 index 0000000..778b699 --- /dev/null +++ b/contrib/syslinux-4.02/utils/bin2hex.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## 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. +## +## ----------------------------------------------------------------------- + +eval { use bytes; }; +eval { binmode STDIN; }; + +$len = 0; +while ( read(STDIN,$ch,1) ) { + $cc = ord($ch); + $s = sprintf("%x", $cc); + print $s; + $len += length($s); + if ( $len > 72 ) { + print "\n"; + $len = 0; + } else { + print " "; + $len++; + } +} +print "\n" if ( $len ); +print "*\n"; +exit 0; diff --git a/contrib/syslinux-4.02/utils/gethostip.c b/contrib/syslinux-4.02/utils/gethostip.c new file mode 100644 index 0000000..f3f8757 --- /dev/null +++ b/contrib/syslinux-4.02/utils/gethostip.c @@ -0,0 +1,131 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * gethostip.c + * + * Small program to use gethostbyname() to print out a hostname in + * hex and/or dotted-quad notation + */ + +#include <stdio.h> +#include <stdlib.h> +#include <netdb.h> +#include <sys/socket.h> +#include <unistd.h> +#include <sysexits.h> +#define _GNU_SOURCE /* For getopt_long */ +#include <getopt.h> + +const struct option options[] = { + {"hexadecimal", 0, NULL, 'x'}, + {"decimal", 0, NULL, 'd'}, + {"dotted-quad", 0, NULL, 'd'}, + {"full-output", 0, NULL, 'f'}, + {"name", 0, NULL, 'n'}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0} +}; + +const char *program; + +void usage(int exit_code) +{ + fprintf(stderr, "Usage: %s [-dxnf] hostname/ip...\n", program); + exit(exit_code); +} + +int main(int argc, char *argv[]) +{ + int opt; + int output = 0; + int i; + char *sep; + int err = 0; + + struct hostent *host; + + program = argv[0]; + + while ((opt = getopt_long(argc, argv, "dxfnh", options, NULL)) != -1) { + switch (opt) { + case 'd': + output |= 2; /* Decimal output */ + break; + case 'x': + output |= 4; /* Hexadecimal output */ + break; + case 'n': + output |= 1; /* Canonical name output */ + break; + case 'f': + output = 7; /* Full output */ + break; + case 'h': + usage(0); + break; + default: + usage(EX_USAGE); + break; + } + } + + if (optind == argc) + usage(EX_USAGE); + + if (output == 0) + output = 7; /* Default output */ + + for (i = optind; i < argc; i++) { + sep = ""; + host = gethostbyname(argv[i]); + if (!host) { + herror(argv[i]); + err = 1; + continue; + } + + if (host->h_addrtype != AF_INET || host->h_length != 4) { + fprintf(stderr, "%s: No IPv4 address associated with name\n", + argv[i]); + err = 1; + continue; + } + + if (output & 1) { + printf("%s%s", sep, host->h_name); + sep = " "; + } + + if (output & 2) { + printf("%s%u.%u.%u.%u", sep, + ((unsigned char *)host->h_addr)[0], + ((unsigned char *)host->h_addr)[1], + ((unsigned char *)host->h_addr)[2], + ((unsigned char *)host->h_addr)[3]); + sep = " "; + } + + if (output & 4) { + printf("%s%02X%02X%02X%02X", sep, + ((unsigned char *)host->h_addr)[0], + ((unsigned char *)host->h_addr)[1], + ((unsigned char *)host->h_addr)[2], + ((unsigned char *)host->h_addr)[3]); + sep = " "; + } + + putchar('\n'); + } + + return err; +} diff --git a/contrib/syslinux-4.02/utils/isohdpfxarray.pl b/contrib/syslinux-4.02/utils/isohdpfxarray.pl new file mode 100644 index 0000000..06c71bf --- /dev/null +++ b/contrib/syslinux-4.02/utils/isohdpfxarray.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## Copyright (C) 2010 P J P <pj.pandit@yahoo.co.in> +## +## 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. +## +## ----------------------------------------------------------------------- + +use strict; +use warnings; + +binmode STDIN; + +print "#include <inttypes.h>\n"; +print "#include \"isohybrid.h\"\n"; +print "\n"; +print "uint8_t isohdpfx[][MBRSIZE] =\n"; +print "{\n"; + +foreach my $file (@ARGV) { + my $len = 0; + my $ch; + + open(IN, '<', $file) or die "$0: $file: $!\n"; + printf(" {\n"); + while (read(IN, $ch, 1)) + { + printf("\t/* 0x%03x */ ", $len) if (!($len % 8)); + printf("0x%02x,", ord($ch)); + $len++; + + print("\n") if (!($len % 8)); + } + print " },\n"; + close(IN); +} +print "};\n"; diff --git a/contrib/syslinux-4.02/utils/isohybrid.c b/contrib/syslinux-4.02/utils/isohybrid.c new file mode 100644 index 0000000..57c1015 --- /dev/null +++ b/contrib/syslinux-4.02/utils/isohybrid.c @@ -0,0 +1,561 @@ +/* + * isohybrid.c: Post process an ISO 9660 image generated with mkisofs or + * genisoimage to allow - hybrid booting - as a CD-ROM or as a hard + * disk. + * + * This is based on the original Perl script written by H. Peter Anvin. The + * rewrite in C is to avoid dependency on Perl on a system under installation. + * + * Copyright (C) 2010 P J P <pj.pandit@yahoo.co.in> + * + * isohybrid is a free software; you can redistribute it and/or modify it + * under the terms of GNU General Public License as published by Free Software + * Foundation; either version 2 of the license, or (at your option) any later + * version. + * + * isohybrid 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 isohybrid; if not, see: <http://www.gnu.org/licenses>. + * + */ + +#include <err.h> +#include <time.h> +#include <ctype.h> +#include <fcntl.h> +#include <stdio.h> +#include <alloca.h> +#include <getopt.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <inttypes.h> + +#include "isohybrid.h" + +char *prog = NULL; +extern int opterr, optind; + +uint8_t mode = 0; +enum { VERBOSE = 1 }; + +/* user options */ +uint16_t head = 64; /* 1 <= head <= 256 */ +uint8_t sector = 32; /* 1 <= sector <= 63 */ + +uint8_t entry = 1; /* partition number: 1 <= entry <= 4 */ +uint8_t offset = 0; /* partition offset: 0 <= offset <= 64 */ +uint16_t type = 0x17; /* partition type: 0 <= type <= 255 */ +uint32_t id = 0; /* MBR: 0 <= id <= 0xFFFFFFFF(4294967296) */ + +uint8_t hd0 = 0; /* 0 <= hd0 <= 2 */ +uint8_t partok = 0; /* 0 <= partok <= 1 */ + +uint16_t ve[16]; +uint32_t catoffset = 0; +uint32_t c = 0, cc = 0, cs = 0; + +/* boot catalogue parameters */ +uint32_t de_lba = 0; +uint16_t de_seg = 0, de_count = 0, de_mbz2 = 0; +uint8_t de_boot = 0, de_media = 0, de_sys = 0, de_mbz1 = 0; + + +void +usage(void) +{ + printf("Usage: %s [OPTIONS] <boot.iso>\n", prog); +} + + +void +printh(void) +{ +#define FMT "%-18s %s\n" + + usage(); + + printf("\n"); + printf("Options:\n"); + printf(FMT, " -h <X>", "Number of default geometry heads"); + printf(FMT, " -s <X>", "Number of default geometry sectors"); + printf(FMT, " -e --entry", "Specify partition entry number (1-4)"); + printf(FMT, " -o --offset", "Specify partition offset (default 0)"); + printf(FMT, " -t --type", "Specify partition type (default 0x17)"); + printf(FMT, " -i --id", "Specify MBR ID (default random)"); + + printf("\n"); + printf(FMT, " --forcehd0", "Assume we are loaded as disk ID 0"); + printf(FMT, " --ctrlhd0", "Assume disk ID 0 if the Ctrl key is pressed"); + printf(FMT, " --partok", "Allow booting from within a partition"); + + printf("\n"); + printf(FMT, " -? --help", "Display this help"); + printf(FMT, " -v --verbose", "Display verbose output"); + printf(FMT, " -V --version", "Display version information"); + + printf("\n"); + printf("Report bugs to <pj.pandit@yahoo.co.in>\n"); +} + + +int +check_option(int argc, char *argv[]) +{ + int n = 0, ind = 0; + + const char optstr[] = ":h:s:e:o:t:i:fcp?vV"; + struct option lopt[] = \ + { + { "entry", required_argument, NULL, 'e' }, + { "offset", required_argument, NULL, 'o' }, + { "type", required_argument, NULL, 't' }, + { "id", required_argument, NULL, 'i' }, + + { "forcehd0", no_argument, NULL, 'f' }, + { "ctrlhd0", no_argument, NULL, 'c' }, + { "partok", no_argument, NULL, 'p'}, + + { "help", no_argument, NULL, '?' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + + { 0, 0, 0, 0 } + }; + + opterr = mode = 0; + while ((n = getopt_long_only(argc, argv, optstr, lopt, &ind)) != -1) + { + switch (n) + { + case 'h': + if (!sscanf(optarg, "%hu", &head) || head < 1 || head > 256) + errx(1, "invalid head: `%s', 1 <= head <= 256", optarg); + break; + + case 's': + if (!sscanf(optarg, "%hhu", §or) || sector < 1 || sector > 63) + errx(1, "invalid sector: `%s', 1 <= sector <= 63", optarg); + break; + + case 'e': + if (!sscanf(optarg, "%hhu", &entry) || entry < 1 || entry > 4) + errx(1, "invalid entry: `%s', 1 <= entry <= 4", optarg); + break; + + case 'o': + if (!sscanf(optarg, "%hhu", &offset) || offset > 64) + errx(1, "invalid offset: `%s', 0 <= offset <= 64", optarg); + break; + + case 't': + if (!sscanf(optarg, "%hu", &type) || type > 255) + errx(1, "invalid type: `%s', 0 <= type <= 255", optarg); + break; + + case 'i': + if (!sscanf(optarg, "%u", &id)) + errx(1, "invalid id: `%s'", optarg); + break; + + case 'f': + hd0 = 1; + break; + + case 'c': + hd0 = 2; + break; + + case 'p': + partok = 1; + break; + + case 'v': + mode |= VERBOSE; + break; + + case 'V': + printf("%s version %s\n", prog, VERSION); + exit(0); + + case ':': + errx(1, "option `-%c' takes an argument", optopt); + + default: + case '?': + if (optopt) + errx(1, "invalid option `-%c', see --help", optopt); + + printh(); + exit(0); + } + } + + return optind; +} + + +uint16_t +lendian_short(const uint16_t s) +{ + uint16_t r = 1; + + if (*(uint8_t *)&r) + return s; + + r = (s & 0x00FF) << 8 | (s & 0xFF00) >> 8; + + return r; +} + + +uint32_t +lendian_int(const uint32_t s) +{ + uint32_t r = 1; + + if (*(uint8_t *)&r) + return s; + + r = (s & 0x000000FF) << 24 | (s & 0xFF000000) >> 24 + | (s & 0x0000FF00) << 8 | (s & 0x00FF0000) >> 8; + + return r; +} + + +int +check_banner(const uint8_t *buf) +{ + static const char banner[] = "\0CD001\1EL TORITO SPECIFICATION\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"; + + if (!buf || memcmp(buf, banner, sizeof(banner) - 1)) + return 1; + + buf += sizeof(banner) - 1; + memcpy(&catoffset, buf, sizeof(catoffset)); + + catoffset = lendian_int(catoffset); + + return 0; +} + + +int +check_catalogue(const uint8_t *buf) +{ + int i = 0; + + for (i = 0, cs = 0; i < 16; i++) + { + ve[i] = 0; + memcpy(&ve[i], buf, sizeof(ve[i])); + + ve[i] = lendian_short(ve[i]); + + buf += 2; + cs += ve[i]; + + if (mode & VERBOSE) + printf("ve[%d]: %d, cs: %d\n", i, ve[i], cs); + } + if ((ve[0] != 0x0001) || (ve[15] != 0xAA55) || (cs & 0xFFFF)) + return 1; + + return 0; +} + + +int +read_catalogue(const uint8_t *buf) +{ + memcpy(&de_boot, buf++, 1); + memcpy(&de_media, buf++, 1); + + memcpy(&de_seg, buf, 2); + de_seg = lendian_short(de_seg); + buf += 2; + + memcpy(&de_sys, buf++, 1); + memcpy(&de_mbz1, buf++, 1); + + memcpy(&de_count, buf, 2); + de_count = lendian_short(de_count); + buf += 2; + + memcpy(&de_lba, buf, 4); + de_lba = lendian_int(de_lba); + buf += 4; + + memcpy(&de_mbz2, buf, 2); + de_mbz2 = lendian_short(de_mbz2); + buf += 2; + + if (de_boot != 0x88 || de_media != 0 + || (de_seg != 0 && de_seg != 0x7C0) || de_count != 4) + return 1; + + return 0; +} + + +void +display_catalogue(void) +{ + printf("de_boot: %hhu\n", de_boot); + printf("de_media: %hhu\n", de_media); + printf("de_seg: %hu\n", de_seg); + printf("de_sys: %hhu\n", de_sys); + printf("de_mbz1: %hhu\n", de_mbz1); + printf("de_count: %hu\n", de_count); + printf("de_lba: %u\n", de_lba); + printf("de_mbz2: %hu\n", de_mbz2); +} + + +int +initialise_mbr(uint8_t *mbr) +{ + int i = 0; + uint32_t psize = 0, tmp = 0; + uint8_t ptype = 0, *rbm = mbr; + uint8_t bhead = 0, bsect = 0, bcyle = 0; + uint8_t ehead = 0, esect = 0, ecyle = 0; + + extern unsigned char isohdpfx[][MBRSIZE]; + + memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE); + mbr += MBRSIZE; /* offset 432 */ + + tmp = lendian_int(de_lba * 4); + memcpy(mbr, &tmp, sizeof(tmp)); + mbr += sizeof(tmp); /* offset 436 */ + + tmp = 0; + memcpy(mbr, &tmp, sizeof(tmp)); + mbr += sizeof(tmp); /* offset 440 */ + + tmp = lendian_int(id); + memcpy(mbr, &tmp, sizeof(tmp)); + mbr += sizeof(tmp); /* offset 444 */ + + mbr[0] = '\0'; + mbr[1] = '\0'; + mbr += 2; /* offset 446 */ + + ptype = type; + psize = c * head * sector - offset; + + bhead = (offset / sector) % head; + bsect = (offset % sector) + 1; + bcyle = offset / (head * sector); + + bsect += (bcyle & 0x300) >> 2; + bcyle &= 0xFF; + + ehead = head - 1; + esect = sector + (((cc - 1) & 0x300) >> 2); + ecyle = (cc - 1) & 0xFF; + + for (i = 1; i <= 4; i++) + { + memset(mbr, 0, 16); + if (i == entry) + { + mbr[0] = 0x80; + mbr[1] = bhead; + mbr[2] = bsect; + mbr[3] = bcyle; + mbr[4] = ptype; + mbr[5] = ehead; + mbr[6] = esect; + mbr[7] = ecyle; + + tmp = lendian_int(offset); + memcpy(&mbr[8], &tmp, sizeof(tmp)); + + tmp = lendian_int(psize); + memcpy(&mbr[12], &tmp, sizeof(tmp)); + } + mbr += 16; + } + mbr[0] = 0x55; + mbr[1] = 0xAA; + mbr += 2; + + return mbr - rbm; +} + + +void +display_mbr(const uint8_t *mbr, size_t len) +{ + unsigned char c = 0; + unsigned int i = 0, j = 0; + + printf("sizeof(MBR): %zu bytes\n", len); + for (i = 0; i < len; i++) + { + if (!(i % 16)) + printf("%04d ", i); + + if (!(i % 8)) + printf(" "); + + c = mbr[i]; + printf("%02x ", c); + + if (!((i + 1) % 16)) + { + printf(" |"); + for (; j <= i; j++) + printf("%c", isprint(mbr[j]) ? mbr[j] : '.'); + printf("|\n"); + } + } +} + + +int +main(int argc, char *argv[]) +{ + int i = 0; + FILE *fp = NULL; + struct stat isostat; + uint8_t *buf = NULL, *bufz = NULL; + int cylsize = 0, frac = 0, padding = 0; + + prog = strcpy(alloca(strlen(argv[0]) + 1), argv[0]); + i = check_option(argc, argv); + argc -= i; + argv += i; + + if (!argc) + { + usage(); + return 1; + } + srand(time(NULL) << (getppid() << getpid())); + + if (!(fp = fopen(argv[0], "r+"))) + err(1, "could not open file `%s'", argv[0]); + if (fseek(fp, 17 * 2048, SEEK_SET)) + err(1, "%s: seek error - 1", argv[0]); + + bufz = buf = calloc(BUFSIZE, sizeof(char)); + if (fread(buf, sizeof(char), BUFSIZE, fp) != BUFSIZE) + err(1, "%s", argv[0]); + + if (check_banner(buf)) + errx(1, "%s: could not find boot record", argv[0]); + + if (mode & VERBOSE) + printf("catalogue offset: %d\n", catoffset); + + if (fseek(fp, catoffset * 2048, SEEK_SET)) + err(1, "%s: seek error - 2", argv[0]); + + buf = bufz; + memset(buf, 0, BUFSIZE); + if (fread(buf, sizeof(char), BUFSIZE, fp) != BUFSIZE) + err(1, "%s", argv[0]); + + if (check_catalogue(buf)) + errx(1, "%s: invalid boot catalogue", argv[0]); + + buf += sizeof(ve); + if (read_catalogue(buf)) + errx(1, "%s: unexpected boot catalogue parameters", argv[0]); + + if (mode & VERBOSE) + display_catalogue(); + + if (fseek(fp, (de_lba * 2048 + 0x40), SEEK_SET)) + err(1, "%s: seek error - 3", argv[0]); + + buf = bufz; + memset(buf, 0, BUFSIZE); + if (fread(buf, sizeof(char), 4, fp) != 4) + err(1, "%s", argv[0]); + + if (memcmp(buf, "\xFB\xC0\x78\x70", 4)) + errx(1, "%s: boot loader does not have an isolinux.bin hybrid " \ + "signature. Note that isolinux-debug.bin does not support " \ + "hybrid booting", argv[0]); + + if (stat(argv[0], &isostat)) + err(1, "%s", argv[0]); + + cylsize = head * sector * 512; + frac = isostat.st_size % cylsize; + padding = (frac > 0) ? cylsize - frac : 0; + + if (mode & VERBOSE) + printf("imgsize: %zu, padding: %d\n", (size_t)isostat.st_size, padding); + + cc = c = (isostat.st_size + padding) / cylsize; + if (c > 1024) + { + warnx("Warning: more than 1024 cylinders: %d", c); + warnx("Not all BIOSes will be able to boot this device"); + cc = 1024; + } + + if (!id) + { + if (fseek(fp, 440, SEEK_SET)) + err(1, "%s: seek error - 4", argv[0]); + + if (fread(&id, 1, 4, fp) != 4) + err(1, "%s: read error", argv[0]); + + id = lendian_int(id); + if (!id) + { + if (mode & VERBOSE) + printf("random "); + id = rand(); + } + } + if (mode & VERBOSE) + printf("id: %u\n", id); + + buf = bufz; + memset(buf, 0, BUFSIZE); + i = initialise_mbr(buf); + + if (mode & VERBOSE) + display_mbr(buf, i); + + if (fseek(fp, 0, SEEK_SET)) + err(1, "%s: seek error - 5", argv[0]); + + if (fwrite(buf, sizeof(char), i, fp) != (size_t)i) + err(1, "%s: write error - 1", argv[0]); + + if (padding) + { + if (!(buf = realloc(buf, padding))) + err(1, "%s: could not re-size buffer", argv[0]); + + if (fseek(fp, isostat.st_size, SEEK_SET)) + err(1, "%s: seek error - 6", argv[0]); + + memset(buf, 0, padding); + if (fwrite(buf, sizeof(char), padding, fp) != (size_t)padding) + err(1, "%s: write error - 2", argv[0]); + } + + free(buf); + fclose(fp); + + return 0; +} diff --git a/contrib/syslinux-4.02/utils/isohybrid.h b/contrib/syslinux-4.02/utils/isohybrid.h new file mode 100644 index 0000000..826e90c --- /dev/null +++ b/contrib/syslinux-4.02/utils/isohybrid.h @@ -0,0 +1,27 @@ +/* + * isohybrid.h: header file for isohybrid.c: Post process an ISO 9660 image + * generated with mkisofs or genisoimage to allow - hybrid booting - as a + * CD-ROM or as a hard disk. + * + * Copyright (C) 2010 Geert Stappers <stappers@stappers.nl> + * + * isohybrid is a free software; you can redistribute it and/or modify it + * under the terms of GNU General Public License as published by Free Software + * Foundation; either version 2 of the license, or (at your option) any later + * version. + * + * isohybrid 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 isohybrid; if not, see: <http://www.gnu.org/licenses>. + * + */ + +#define VERSION "0.11" +#define BUFSIZE 2048 +#define MBRSIZE 432 + +/* End of header file */ diff --git a/contrib/syslinux-4.02/utils/isohybrid.in b/contrib/syslinux-4.02/utils/isohybrid.in new file mode 100644 index 0000000..a127784 --- /dev/null +++ b/contrib/syslinux-4.02/utils/isohybrid.in @@ -0,0 +1,258 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## Copyright 2002-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., 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. +## +## ----------------------------------------------------------------------- + +# +# Post-process an ISO 9660 image generated with mkisofs/genisoimage +# to allow "hybrid booting" as a CD-ROM or as a hard disk. +# + +use bytes; +use Fcntl; + +# User-specifyable options +%opt = ( + # Fake geometry (zipdrive-style...) + 'h' => 64, + 's' => 32, + # Partition number + 'entry' => 1, + # Partition offset + 'offset' => 0, + # Partition type + 'type' => 0x17, # "Windows hidden IFS" + # MBR ID + 'id' => undef, +); + +%valid_range = ( + 'h' => [1, 256], + 's' => [1, 63], + 'entry' => [1, 4], + 'offset' => [0, 64], + 'type' => [0, 255], + 'id' => [0, 0xffffffff], + 'hd0' => [0, 2], + 'partok' => [0, 1], +); + +# Boolean options just set other options +%bool_opt = ( + 'nohd0' => ['hd0', 0], + 'forcehd0' => ['hd0', 1], + 'ctrlhd0' => ['hd0', 2], + 'nopartok' => ['partok', 0], + 'partok' => ['partok', 1], +); + +sub usage() { + print STDERR "Usage: $0 [options] filename.iso\n", + "Options:\n", + " -h Number of default geometry heads\n", + " -s Number of default geometry sectors\n", + " -entry Specify partition entry number (1-4)\n", + " -offset Specify partition offset (default 0)\n", + " -type Specify partition type (default 0x17)\n", + " -id Specify MBR ID (default random)\n", + " -forcehd0 Always assume we are loaded as disk ID 0\n", + " -ctrlhd0 Assume disk ID 0 if the Ctrl key is pressed\n", + " -partok Allow booting from within a partition\n"; + exit 1; +} + +# Parse a C-style integer (decimal/octal/hex) +sub doh($) { + my($n) = @_; + return ($n =~ /^0/) ? oct $n : $n+0; +} + +sub get_random() { + # Get a 32-bit random number + my $rfd, $rnd; + my $rid; + + if (open($rfd, "< /dev/urandom\0") && read($rfd, $rnd, 4) == 4) { + $rid = unpack("V", $rnd); + } + + close($rfd) if (defined($rfd)); + return $rid if (defined($rid)); + + # This sucks but is better than nothing... + return ($$+time()) & 0xffffffff; +} + +sub get_hex_data() { + my $mbr = ''; + my $line, $byte; + while ( $line = <DATA> ) { + chomp $line; + last if ($line eq '*'); + foreach $byte ( split(/\s+/, $line) ) { + $mbr .= chr(hex($byte)); + } + } + return $mbr; +} + +while ($ARGV[0] =~ /^\-(.*)$/) { + $o = $1; + shift @ARGV; + if (defined($bool_opt{$o})) { + ($o, $v) = @{$bool_opt{$o}}; + $opt{$o} = $v; + } elsif (exists($opt{$o})) { + $opt{$o} = doh(shift @ARGV); + if (defined($valid_range{$o})) { + ($l, $h) = @{$valid_range{$o}}; + if ($opt{$o} < $l || $opt{$o} > $h) { + die "$0: valid values for the -$o parameter are $l to $h\n"; + } + } + } else { + usage(); + } +} + +($file) = @ARGV; + +if (!defined($file)) { + usage(); +} + +open(FILE, "+< $file\0") or die "$0: cannot open $file: $!\n"; +binmode FILE; + +# +# First, actually figure out where mkisofs hid isolinux.bin +# +seek(FILE, 17*2048, SEEK_SET) or die "$0: $file: $!\n"; +read(FILE, $boot_record, 2048) == 2048 or die "$0: $file: read error\n"; +($br_sign, $br_cat_offset) = unpack("a71V", $boot_record); +if ($br_sign ne ("\0CD001\1EL TORITO SPECIFICATION" . ("\0" x 41))) { + die "$0: $file: no boot record found\n"; +} +seek(FILE, $br_cat_offset*2048, SEEK_SET) or die "$0: $file: $!\n"; +read(FILE, $boot_cat, 2048) == 2048 or die "$0: $file: read error\n"; + +# We must have a Validation Entry followed by a Default Entry... +# no fanciness allowed for the Hybrid mode [XXX: might relax this later] +@ve = unpack("v16", $boot_cat); +$cs = 0; +for ($i = 0; $i < 16; $i++) { + $cs += $ve[$i]; +} +if ($ve[0] != 0x0001 || $ve[15] != 0xaa55 || $cs & 0xffff) { + die "$0: $file: invalid boot catalog\n"; +} +($de_boot, $de_media, $de_seg, $de_sys, $de_mbz1, $de_count, + $de_lba, $de_mbz2) = unpack("CCvCCvVv", substr($boot_cat, 32, 32)); +if ($de_boot != 0x88 || $de_media != 0 || + ($de_segment != 0 && $de_segment != 0x7c0) || $de_count != 4) { + die "$0: $file: unexpected boot catalog parameters\n"; +} + +# Now $de_lba should contain the CD sector number for isolinux.bin +seek(FILE, $de_lba*2048+0x40, SEEK_SET) or die "$0: $file: $!\n"; +read(FILE, $ibsig, 4); +if ($ibsig ne "\xfb\xc0\x78\x70") { + die "$0: $file: bootloader does not have a isolinux.bin hybrid signature.". + "Note that isolinux-debug.bin does not support hybrid booting.\n"; +} + +# Get the total size of the image +(@imgstat = stat(FILE)) or die "$0: $file: $!\n"; +$imgsize = $imgstat[7]; +if (!$imgsize) { + die "$0: $file: cannot determine length of file\n"; +} +# Target image size: round up to a multiple of $h*$s*512 +$h = $opt{'h'}; +$s = $opt{'s'}; +$cylsize = $h*$s*512; +$frac = $imgsize % $cylsize; +$padding = ($frac > 0) ? $cylsize - $frac : 0; +$imgsize += $padding; +$c = int($imgsize/$cylsize); +if ($c > 1024) { + print STDERR "Warning: more than 1024 cylinders ($c).\n"; + print STDERR "Not all BIOSes will be able to boot this device.\n"; + $cc = 1024; +} else { + $cc = $c; +} + +# Preserve id when run again +if (defined($opt{'id'})) { + $id = pack("V", doh($opt{'id'})); +} else { + seek(FILE, 440, SEEK_SET) or die "$0: $file: $!\n"; + read(FILE, $id, 4); + if ($id eq "\x00\x00\x00\x00") { + $id = pack("V", get_random()); + } +} + +# Print the MBR and partition table +seek(FILE, 0, SEEK_SET) or die "$0: $file: $!\n"; + +for ($i = 0; $i <= $opt{'hd0'}+3*$opt{'partok'}; $i++) { + $mbr = get_hex_data(); +} +if ( length($mbr) > 432 ) { + die "$0: Bad MBR code\n"; +} + +$mbr .= "\0" x (432 - length($mbr)); + +$mbr .= pack("VV", $de_lba*4, 0); # Offset 432: LBA of isolinux.bin +$mbr .= $id; # Offset 440: MBR ID +$mbr .= "\0\0"; # Offset 446: actual partition table + +# Print partition table +$offset = $opt{'offset'}; +$psize = $c*$h*$s - $offset; +$bhead = int($offset/$s) % $h; +$bsect = ($offset % $s) + 1; +$bcyl = int($offset/($h*$s)); +$bsect += ($bcyl & 0x300) >> 2; +$bcyl &= 0xff; +$ehead = $h-1; +$esect = $s + ((($cc-1) & 0x300) >> 2); +$ecyl = ($cc-1) & 0xff; +$fstype = $opt{'type'}; # Partition type +$pentry = $opt{'entry'}; # Partition slot + +for ( $i = 1 ; $i <= 4 ; $i++ ) { + if ( $i == $pentry ) { + $mbr .= pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, + $ehead, $esect, $ecyl, $offset, $psize); + } else { + $mbr .= "\0" x 16; + } +} +$mbr .= "\x55\xaa"; + +print FILE $mbr; + +# Pad the image to a fake cylinder boundary +seek(FILE, $imgstat[7], SEEK_SET) or die "$0: $file: $!\n"; +if ($padding) { + print FILE "\0" x $padding; +} + +# Done... +close(FILE); + +exit 0; +__END__ diff --git a/contrib/syslinux-4.02/utils/keytab-lilo b/contrib/syslinux-4.02/utils/keytab-lilo new file mode 100755 index 0000000..9e34160 --- /dev/null +++ b/contrib/syslinux-4.02/utils/keytab-lilo @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +eval { use bytes; }; +eval { binmode STDOUT; }; + +$DEFAULT_MAP = "us"; +$DEFAULT_EXT = ".kmap"; + +sub usage +{ + print STDERR + "usage: $0 [ -p old_code=new_code ] ...\n". + (" "x(8+length $0))."[path]default_layout[.kmap] ] ". + "[path]kbd_layout[.kmap]\n"; + exit 1; +} + + +while ($ARGV[0] eq "-p") { + shift(@ARGV); + &usage unless $ARGV[0] =~ /=/; + $table[eval($`)] = eval($'); + shift(@ARGV); +} +&usage unless defined $ARGV[0]; +load_map("def",defined $ARGV[1] ? $ARGV[0] : undef); +load_map("kbd",defined $ARGV[1] ? $ARGV[1] : $ARGV[0]); +&build_table("plain","shift","ctrl","altgr","shift_ctrl", + "altgr_ctrl","alt","shift_alt","ctrl_alt"); +for ($i = 0; $i < 256; $i++) { + printf("%c",$table[$i] ? $table[$i] : $i) || die "print: $!"; +} +close STDOUT || die "close: $!"; + + +sub load_map +{ + local ($pfx,$map) = @_; + local ($empty,$current); + + $map = $DEFAULT_MAP unless defined $map; + $map .= $DEFAULT_EXT unless $map =~ m|/[^/]+\.[^/]+$|; + if (!open(FILE,"loadkeys -m $map |")) { + print STDERR "loadkeys -m $map: $!\n"; + exit 1; + } + undef $current; + $empty = 1; + while (<FILE>) { + chop; + if (/^(static\s+)?u_short\s+(\S+)_map\[\S*\]\s+=\s+{\s*$/) { + die "active at beginning of map" if defined $current; + $current = $pfx.":".$2; + next; + } + undef $current if /^};\s*$/; + next unless defined $current; + s/\s//g; + $map{$current} .= $_; + $empty = 0; + } + close FILE; + return unless $empty; + print STDERR "Keymap is empty\n"; + exit 1; +} + + +sub build_table +{ + local (@maps) = @_; + local (@tmp); + + $set = 0; + for $map (@maps) { + $code = $set; + for (split(",",$map{"def:".$map})) { + die "bad map entry $_ (def, map $map)" unless /^0x\S\S(\S\S)$/; + $tmp[$code] = hex $1 unless $tmp[$code]; + $code++; + } + $set += 256; + } + $set = 0; + for $map (@maps) { + $code = $set; + for (split(",",$map{"kbd:".$map})) { + die "bad map entry $_ (kbd, map $map)" unless /^0x\S\S(\S\S)$/; + $table[$tmp[$code]] = hex $1 unless $table[$tmp[$code]]; + $code++; + } + $set += 256; + } + $table[0] = 0; +} diff --git a/contrib/syslinux-4.02/utils/lss16toppm b/contrib/syslinux-4.02/utils/lss16toppm new file mode 100755 index 0000000..18b7f64 --- /dev/null +++ b/contrib/syslinux-4.02/utils/lss16toppm @@ -0,0 +1,111 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## 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. +## +## ----------------------------------------------------------------------- + +## +## lss16toppm: +## Convert an LSS-16 image to PPM +## +## Usage: +## +## lss16toppm [-map] < file.lss > file.ppm +## +## The -map causes the color map to be output on stderr. +## + +eval { use bytes; }; +eval { binmode STDIN; }; +eval { binmode STDOUT; }; + +$map = 0; +foreach $arg ( @ARGV ) { + if ( $arg eq '-map' ) { + $map = 1; + } else { + print STDERR "$0: Unknown option: $arg\n"; + exit 127; + } +} + +if ( read(STDIN, $header, 56) != 56 ) { + print STDERR "$0: Short file\n"; + exit 1; +} + +($magic, $xsize, $ysize, @colorset) = unpack("Vvvc48", $header); + +if ( $magic != 0x1413f33d ) { + print STDERR "$0: Invalid file format\n"; + exit 1; +} + +%color = (); +for ( $i = 0 ; $i < 16 ; $i++ ) { + $r = int((shift @colorset) * 255 / 63 + 0.5); + $g = int((shift @colorset) * 255 / 63 + 0.5); + $b = int((shift @colorset) * 255 / 63 + 0.5); + + $color{$i} = pack("ccc", $r, $g, $b); + + if ( $map ) { + printf STDERR "#%02x%02x%02x=%d\n", $r, $g, $b, $i; + } +} + +sub get_nybble() { + my($ch,$n); + if ( defined($nybble_buf) ) { + $n = $nybble_buf; + undef $nybble_buf; + } else { + if ( read(STDIN, $ch, 1) != 1 ) { + print STDERR "$0: Short read on input (file corrupt)\n"; + exit 1; + } + $ch = ord($ch); + $nybble_buf = $ch >> 4; + $n = $ch & 0xF; + } + return $n; +} + +print "P6\n"; +print "$xsize $ysize\n"; +print "255\n"; + +for ( $y = 0 ; $y < $ysize ; $y++ ) { + $x = 0; + $last = 0; + undef $nybble_buf; # Nybble buffer starts clear on each line + while ( $x < $xsize ) { + $n = get_nybble(); + + if ( $n != $last ) { + print $color{$n}; + $last = $n; + $x++; + } else { + $c = get_nybble(); + if ( $c == 0 ) { + # Double-nybble run + $c = get_nybble(); + $c += get_nybble() << 4; + $c += 16; + } + # Truncate overlong runs + $c = $xsize-$x if ( $c > $xsize-$x ); + # Output run + print $color{$n} x $c; + $x += $c; + } + } +} diff --git a/contrib/syslinux-4.02/utils/md5pass b/contrib/syslinux-4.02/utils/md5pass new file mode 100755 index 0000000..3404f1d --- /dev/null +++ b/contrib/syslinux-4.02/utils/md5pass @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +use bytes; +use Crypt::PasswdMD5; +use MIME::Base64; + +sub random_bytes($) { + my($n) = @_; + my($v, $i); + + if ( open(RANDOM, '<', '/dev/random') || + open(RANDOM, '<', '/dev/urandom') ) { + read(RANDOM, $v, $n); + } else { + # No real RNG available... + srand($$ ^ time); + $v = ''; + for ( $i = 0 ; $i < $n ; $i++ ) { + $v .= ord(int(rand() * 256)); + } + } + + return $v; +} + + +($pass, $salt) = @ARGV; + +unless (defined($salt)) { + $salt = MIME::Base64::encode(random_bytes(6), ''); + $salt =~ tr/\+/./; # . not + +} + +print unix_md5_crypt($pass, $salt), "\n"; diff --git a/contrib/syslinux-4.02/utils/memdiskfind.c b/contrib/syslinux-4.02/utils/memdiskfind.c new file mode 100644 index 0000000..decc788 --- /dev/null +++ b/contrib/syslinux-4.02/utils/memdiskfind.c @@ -0,0 +1,158 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * memdiskfind.c + * + * Simple utility to search for a MEMDISK instance and output the parameters + * needed to use the "phram" driver in Linux to map it. + */ + +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include "../memdisk/mstructs.h" + +#define MBFT_MIN_LENGTH (36+4+26) + +static bool valid_mbft(const struct mBFT *mbft, size_t space) +{ + uint8_t csum; + size_t i; + + if (memcmp(mbft->acpi.signature, "mBFT", 4)) + return false; + + if (mbft->acpi.length < MBFT_MIN_LENGTH) + return false; + + if (mbft->acpi.length > space) + return false; + + if ((size_t)mbft->acpi.length != (size_t)mbft->mdi.bytes + 36+4) + return false; + + csum = 0; + for (i = 0; i < mbft->acpi.length; i++) + csum += ((const uint8_t *)mbft)[i]; + + if (csum) + return false; + + return true; +} + +static void output_params(const struct mBFT *mbft) +{ + int sector_shift = mbft->mdi.sector_shift; + + if (!sector_shift) + sector_shift = 9; + + printf("%#x,%#x\n", + mbft->mdi.diskbuf, mbft->mdi.disksize << sector_shift); +} + +static size_t memlimit(void) +{ + char txtline[256], user[256]; + size_t maxram = 0; + unsigned long long start, end; + FILE *iomem; + + iomem = fopen("/proc/iomem", "r"); + if (!iomem) + return 0; + + while (fgets(txtline, sizeof txtline, iomem) != NULL) { + if (sscanf(txtline, "%llx-%llx : %[^\n]", &start, &end, user) != 3) + continue; + if (strcmp(user, "System RAM")) + continue; + if (start >= 0xa0000) + continue; + maxram = (end >= 0xa0000) ? 0xa0000 : end+1; + } + fclose(iomem); + + return maxram; +} + +int main(int argc, char *argv[]) +{ + const char *map; + int memfd; + size_t fbm; + const char *ptr, *end; + size_t page = sysconf(_SC_PAGESIZE); + size_t mapbase, maplen; + int err = 1; + + (void)argc; + + mapbase = memlimit() & ~(page - 1); + if (!mapbase) + return 2; + + memfd = open("/dev/mem", O_RDONLY); + if (memfd < 0) { + fprintf(stderr, "%s: cannot open /dev/mem: %s\n", + argv[0], strerror(errno)); + return 2; + } + + map = mmap(NULL, page, PROT_READ, MAP_SHARED, memfd, 0); + if (map == MAP_FAILED) { + fprintf(stderr, "%s: cannot map page 0: %s\n", + argv[0], strerror(errno)); + return 2; + } + + fbm = *(uint16_t *)(map + 0x413) << 10; + if (fbm < mapbase) + fbm = mapbase; + + munmap((void *)map, page); + + if (fbm < 64*1024 || fbm >= 640*1024) + return 1; + + maplen = 0xa0000 - mapbase; + map = mmap(NULL, maplen, PROT_READ, MAP_SHARED, memfd, mapbase); + if (map == MAP_FAILED) { + fprintf(stderr, "%s: cannot map base memory: %s\n", + argv[0], strerror(errno)); + return 2; + } + + ptr = map + (fbm - mapbase); + end = map + (0xa0000 - mapbase); + while (ptr < end) { + if (valid_mbft((const struct mBFT *)ptr, end-ptr)) { + output_params((const struct mBFT *)ptr); + err = 0; + break; + } + ptr += 16; + } + + munmap((void *)map, maplen); + + return err; +} diff --git a/contrib/syslinux-4.02/utils/mkdiskimage.in b/contrib/syslinux-4.02/utils/mkdiskimage.in new file mode 100644 index 0000000..533193a --- /dev/null +++ b/contrib/syslinux-4.02/utils/mkdiskimage.in @@ -0,0 +1,321 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## Copyright 2002-2008 H. Peter Anvin - All Rights Reserved +## Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, Inc., 53 Temple Place Ste 330, +## Boston MA 02111-1307, USA; either version 2 of the License, or +## (at your option) any later version; incorporated herein by reference. +## +## ----------------------------------------------------------------------- + +# +# Creates a blank MS-DOS formatted hard disk image +# + +use bytes; +use integer; +use Fcntl; +use Errno; +use Cwd; +use IO::Handle; # For flush() + +sub absolute_path($) { + my($f) = @_; + my($c); + + return $f if ( $f =~ /^\// ); + $c = cwd(); + $c = '' if ( $c eq '/' ); + return $c.'/'.$f; +} + +sub is_linux() { + return !!eval '{ '. + 'use POSIX; '. + '($sysname, $nodename, $release, $version, $machine) = POSIX::uname(); '. + "return \$sysname eq \'Linux\'; }"; +} + +sub get_random() { + # Get a 32-bit random number + my $rfd, $rnd; + my $rid; + + if (open($rfd, "< /dev/urandom\0") && read($rfd, $rnd, 4) == 4) { + $rid = unpack("V", $rnd); + } + + close($rfd) if (defined($rfd)); + return $rid if (defined($rid)); + + # This sucks but is better than nothing... + return ($$+time()) & 0xffffffff; +} + +sub get_hex_data() { + my $mbr = ''; + my $line, $byte; + while ( $line = <DATA> ) { + chomp $line; + last if ($line eq '*'); + foreach $byte ( split(/\s+/, $line) ) { + $mbr .= chr(hex($byte)); + } + } + return $mbr; +} + +$is_linux = is_linux(); +if ( $is_linux ) { + # IOCTL numbers + $BLKRRPART = 0x125f; + $BLKGETSIZE = 0x1260; +} + +%opt = (); +@args = (); + +while (defined($a = shift(@ARGV))) { + if ( $a =~ /^\-/ ) { + foreach $o ( split(//, substr($a,1)) ) { + $opt{$o} = 1; + if ($o eq 'i') { + $id = shift(@ARGV); + } + } + } else { + push(@args, $a); + } +} + +($file,$c,$h,$s) = @args; +$c += 0; $h += 0; $s += 0; + +$pentry = 1; +$pentry = 2 if ( $opt{'2'} ); +$pentry = 3 if ( $opt{'3'} ); +$pentry = 4 if ( $opt{'4'} ); + +if ( $opt{'z'} ) { + $h = $h || 64; + $s = $s || 32; +} + +if ( $opt{'M'} && $h && $s ) { + # Specify size in megabytes, not in cylinders + $c = ($c*1024*2)/($h*$s); +} + +$is_open = 0; + +if ( $c == 0 && $file ne '' ) { + $len = 0; + if ( sysopen(OUTPUT, $file, O_RDWR, 0666) ) { + $is_open = 1; + + if ( (@filestat = stat(OUTPUT)) && S_ISREG($filestat[2]) ) { + $len = $filestat[7] >> 9; + } elsif ( $is_linux && S_ISBLK($filestat[2]) ) { + $blksize = pack("L!", 0); + if ( ioctl(OUTPUT, $BLKGETSIZE, $blksize) == 0 ) { + $len = unpack("L!", $blksize); # In 512-byte sectors! + } + } + } + + if ( !$len ) { + print STDERR "$0: $file: don't know how to determine the size of this device\n"; + exit 1; + } + + $c = $len/($h*$s); +} + +if ( $file eq '' || $c < 1 || $h < 1 || $h > 256 || $s < 1 || $s > 63 ) { + print STDERR "Usage: $0 [-doFMz4][-i id] file c h s (max: 1024 256 63)\n"; + print STDERR " -d add DOSEMU header\n"; + print STDERR " -o print filesystem offset to stdout\n"; + print STDERR " -F format partition as FAT32\n"; + print STDERR " -M \"c\" argument is megabytes, calculate cylinders\n"; + print STDERR " -z use zipdisk geometry (h=64 s=32)\n"; + print STDERR " -4 use partition entry 4 (standard for zipdisks)\n"; + print STDERR " -i specify the MBR ID\n"; + print STDERR " -s output a sparse file (don't allocate all blocks)\n"; + exit 1; +} + +if ($c > 1024) { + print STDERR "Warning: more than 1024 cylinders ($c).\n"; + print STDERR "Not all BIOSes will be able to boot this device.\n"; + $cc = 1024; +} else { + $cc = $c; +} + +$cylsize = $h*$s*512; + +if ( !$is_open ) { + sysopen(OUTPUT, $file, O_CREAT|O_RDWR|O_TRUNC, 0666) + or die "$0: Cannot open: $file\n"; +} +binmode OUTPUT; + +# Print out DOSEMU header, if requested +if ( $opt{'d'} ) { + $emuhdr = "DOSEMU\0" . pack("VVVV", $h, $s, $c, 128); + $emuhdr .= "\0" x (128 - length($emuhdr)); + print OUTPUT $emuhdr; +} + +# Print the MBR and partition table +$mbr = get_hex_data(); +if ( length($mbr) > 440 ) { + die "$0: Bad MBR code\n"; +} + +$mbr .= "\0" x (440 - length($mbr)); +if (defined($id)) { + $id = to_int($id); +} else { + $id = get_random(); +} +$mbr .= pack("V", $id); # Offset 440: MBR ID +$mbr .= "\0\0"; # Offset 446: actual partition table + +print OUTPUT $mbr; + +# Print partition table +$psize = $c*$h*$s-$s; +$bhead = ($h > 1) ? 1 : 0; +$bsect = 1; +$bcyl = ($h > 1) ? 0 : 1; +$ehead = $h-1; +$esect = $s + ((($cc-1) & 0x300) >> 2); +$ecyl = ($cc-1) & 0xff; +if ( $c > 1024 ) { + $fstype = 0x0e; +} elsif ( $psize > 65536 ) { + $fstype = 0x06; +} else { + $fstype = 0x04; +} +for ( $i = 1 ; $i <= 4 ; $i++ ) { + if ( $i == $pentry ) { + print OUTPUT pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, + $ehead, $esect, $ecyl, $s, $psize); + } else { + print OUTPUT "\0" x 16; + } +} +print OUTPUT "\x55\xaa"; + +# Output blank file +$totalsize = $c*$h*$s; +$tracks = $c*$h; + +# If -s is given, try to simply use truncate... +unless ($opt{'s'} && truncate(OUTPUT, $totalsize)) { + $track = "\0" x (512*$s); + + # Print fractional track + print OUTPUT "\0" x (512 * ($s-1)); + + for ( $i = 1 ; $i < $tracks ; $i++ ) { + print OUTPUT $track; + } +} + +# Print mtools temp file +$n = 0; +while ( !defined($tmpdir) ) { + $tmpdir = "/tmp/mkdiskimage.$$.".($n++); + if ( !mkdir($tmpdir, 0700) ) { + die "$0: Failed to make temp directory: $tmpdir\n" + if ( $! != EEXIST ); + undef $tmpdir; + } +} + +$cfgfile = $tmpdir.'/mtools.conf'; +$imglink = $tmpdir.'/disk.img'; +die "$0: Failed to create symlink $imglink\n" + if ( !symlink(absolute_path($file), $imglink) ); + +$header_size = ($opt{'d'} ? 128 : 0); + +# Start of filesystem +$offset = $s*512 + $header_size; + +# Start of partition table entry +$pstart = $header_size + 446 + 16*($pentry-1); + +open(MCONFIG, "> ${cfgfile}") or die "$0: Cannot make mtools config\n"; +print MCONFIG "drive z:\n"; +print MCONFIG "file=\"${imglink}\"\n"; +print MCONFIG "cylinders=${c}\n"; +print MCONFIG "heads=${h}\n"; +print MCONFIG "sectors=${s}\n"; +print MCONFIG "offset=${offset}\n"; +print MCONFIG "mformat_only\n"; +close(MCONFIG); + +# Output the filesystem offset to stdout if appropriate +if ( $opt{'o'} ) { + print $offset, "\n"; +} + +$ENV{'MTOOLSRC'} = $cfgfile; +if ( $opt{'F'} ) { + system('mformat', '-F', 'z:'); +} else { + system('mformat', 'z:'); +} + +# Clean up in /tmp +unlink($cfgfile); +unlink($imglink); +rmdir($tmpdir); + +# MTOOLS doesn't write the bsHiddenSecs field correctly +seek(OUTPUT, $offset + 0x1c, 0); +print OUTPUT pack("V", ($offset-$header_size)>>9); + +# Set the partition type +if ( $opt{'F'} ) { + if ( $c > 1024 ) { + $fstype = 0x0c; # FAT32 LBA + } else { + $fstype = 0x0b; + } +} else { + if ( $c > 1024 ) { + $fstype = 0x0e; # FAT16 LBA + } elsif ( $psize > 65536 ) { + $fstype = 0x06; # FAT16 > 32MB + } else { + $fstype = 0x04; # FAT16 <= 32MB + } + seek(OUTPUT, $offset + 0x36, 0); + read(OUTPUT, $fsname, 8); + + # FAT12: adjust partition type + if ( $fsname eq 'FAT12 ' ) { + $fstype = 0x01; # FAT12 + } +} +seek(OUTPUT, $pstart+4, 0); +print OUTPUT pack("C", $fstype); + +flush OUTPUT; + +# Just in case this is a block device, try to flush the partition table +if ( $is_linux ) { + ioctl(OUTPUT, $BLKRRPART, 0); +}; + +exit 0; +__END__ diff --git a/contrib/syslinux-4.02/utils/ppmtolss16 b/contrib/syslinux-4.02/utils/ppmtolss16 new file mode 100755 index 0000000..5af9083 --- /dev/null +++ b/contrib/syslinux-4.02/utils/ppmtolss16 @@ -0,0 +1,393 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## 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. +## +## ----------------------------------------------------------------------- + +## +## ppmtolss16 +## +## Convert a PNM file with max 16 colors to a simple RLE-based format: +## +## uint32 0x1413f33d ; magic (littleendian) +## uint16 xsize ; littleendian +## uint16 ysize ; littleendian +## 16 x uint8 r,g,b ; color map, in 6-bit format (each byte is 0..63) +## +## Then, a sequence of nybbles: +## +## N ... if N is != previous pixel, one pixel of color N +## ... otherwise run sequence follows ... +## M ... if M > 0 then run length is M +## ... otherwise run sequence is encoded in two nybbles, +## littleendian, +16 +## +## The nybble sequences are on a per-row basis; runs may not extend +## across rows and odd-nybble rows are zero-padded. +## +## At the start of row, the "previous pixel" is assumed to be zero. +## +## Usage: +## +## ppmtolss16 [#rrggbb=i ...] < input.ppm > output.rle +## +## Command line options of the form #rrggbb=i indicate that +## the color #rrggbb (hex) should be assigned index i (decimal) +## + +eval { use bytes; }; +eval { binmode STDIN; }; +eval { binmode STDOUT; }; + +$magic = 0x1413f33d; + +# Get a token from the PPM header. Ignore comments and leading +# and trailing whitespace, as is required by the spec. +# This routine eats exactly one character of trailing whitespace, +# unless it is a comment (in which case it eats the comment up +# to and including the end of line.) +sub get_token() { + my($token, $ch); + my($ch); + + do { + $ch = getc(STDIN); + return undef if ( !defined($ch) ); # EOF + if ( $ch eq '#' ) { + do { + $ch = getc(STDIN); + return undef if ( !defined($ch) ); + } while ( $ch ne "\n" ); + } + } while ( $ch =~ /^[ \t\n\v\f\r]$/ ); + + $token = $ch; + while ( 1 ) { + $ch = getc(STDIN); + last if ( $ch =~ /^[ \t\n\v\f\r\#]$/ ); + $token .= $ch; + } + if ( $ch eq '#' ) { + do { + $ch = getc(STDIN); + } while ( defined($ch) && $ch ne "\n" ); + } + return $token; +} + +# Get a token, and make sure it is numeric (and exists) +sub get_numeric_token() { + my($token) = get_token(); + + if ( $token !~ /^[0-9]+$/ ) { + print STDERR "Format error on input\n"; + exit 1; + } + + return $token + 0; +} + +# Must be called before each pixel row is read +sub start_new_row() { + $getrgb_leftover_bit_cnt = 0; + $getrgb_leftover_bit_val = 0; +} + +# Get a single RGB token depending on the PNM type +sub getrgb($) { + my($form) = @_; + my($rgb,$r,$g,$b); + + if ( $form == 6 ) { + # Raw PPM, most common + return undef unless ( read(STDIN,$rgb,3) == 3 ); + return unpack("CCC", $rgb); + } elsif ( $form == 3 ) { + # Plain PPM + $r = get_numeric_token(); + $g = get_numeric_token(); + $b = get_numeric_token(); + return ($r,$g,$b); + } elsif ( $form == 5 ) { + # Raw PGM + return undef unless ( read(STDIN,$rgb,1) == 1 ); + $r = unpack("C", $rgb); + return ($r,$r,$r); + } elsif ( $form == 2 ) { + # Plain PGM + $r = get_numeric_token(); + return ($r,$r,$r); + } elsif ( $form == 4 ) { + # Raw PBM + if ( !$getrgb_leftover_bit_cnt ) { + return undef unless ( read(STDIN,$rgb,1) == 1 ); + $getrgb_leftover_bit_val = unpack("C", $rgb); + $getrgb_leftover_bit_cnt = 8; + } + $r = ( $getrgb_leftover_bit_val & 0x80 ) ? 0x00 : 0xff; + $getrgb_leftover_bit_val <<= 1; + $getrgb_leftover_bit_cnt--; + + return ($r,$r,$r); + } elsif ( $form == 1 ) { + # Plain PBM + my($ch); + + do { + $ch = getc(STDIN); + return undef if ( !defined($ch) ); + return (255,255,255) if ( $ch eq '0' ); # White + return (0,0,0) if ( $ch eq '1'); # Black + if ( $ch eq '#' ) { + do { + $ch = getc(STDIN); + return undef if ( !defined($ch) ); + } while ( $ch ne "\n" ); + } + } while ( $ch =~ /^[ \t\n\v\f\r]$/ ); + return undef; + } else { + die "Internal error: unknown format: $form\n"; + } +} + +sub rgbconvert($$$$) { + my($r,$g,$b,$maxmult) = @_; + my($rgb); + + $r = int($r*$maxmult); + $g = int($g*$maxmult); + $b = int($b*$maxmult); + $rgb = pack("CCC", $r, $g, $b); + return $rgb; +} + +foreach $arg ( @ARGV ) { + if ( $arg =~ /^\#([0-9a-f])([0-9a-f])([0-9a-f])=([0-9]+)$/i ) { + $r = hex($1) << 4; + $g = hex($2) << 4; + $b = hex($3) << 4; + $i = $4 + 0; + } elsif ( $arg =~ /^\#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})=([0-9]+)$/i ) { + $r = hex($1); + $g = hex($2); + $b = hex($3); + $i = $4 + 0; + } elsif ( $arg =~ /^\#([0-9a-f]{3})([0-9a-f]{3})([0-9a-f]{3})=([0-9]+)$/i ) { + $r = hex($1) >> 4; + $g = hex($2) >> 4; + $b = hex($3) >> 4; + $i = $4 + 0; + } elsif ( $arg =~ /^\#([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})=([0-9]+)$/i ) { + $r = hex($1) >> 8; + $g = hex($2) >> 8; + $b = hex($3) >> 8; + $i = $4 + 0; + } else { + print STDERR "$0: Unknown argument: $arg\n"; + next; + } + + if ( $i > 15 ) { + print STDERR "$0: Color index out of range: $arg\n"; + next; + } + + $rgb = rgbconvert($r, $g, $b, 64/256); + + if ( defined($index_forced{$i}) ) { + print STDERR "$0: More than one color index $i\n"; + exit(1); + } + $index_forced{$i} = $rgb; + $force_index{$rgb} = $i; +} + +$form = get_token(); +die "$0: stdin is not a PNM file" if ( $form !~ /^P([1-6])$/ ); +$form = $1+0; + +$xsize = get_numeric_token(); +$ysize = get_numeric_token(); +if ( $form == 1 || $form == 4 ) { + $maxcol = 255; # Internal convention +} else { + $maxcol = get_numeric_token(); +} +$maxmult = 64/($maxcol+1); # Equal buckets conversion + +@data = (); + +for ( $y = 0 ; $y < $ysize ; $y++ ) { + start_new_row(); + for ( $x = 0 ; $x < $xsize ; $x++ ) { + die "$0: Premature EOF at ($x,$y) of ($xsize,$ysize)\n" + if ( !defined(@pnmrgb = getrgb($form)) ); + # Convert to 6-bit representation + $rgb = rgbconvert($pnmrgb[0], $pnmrgb[1], $pnmrgb[2], $maxmult); + $color_count{$rgb}++; + push(@data, $rgb); + } +} + +# Sort list of colors according to freqency +@colors = sort { $color_count{$b} <=> $color_count{$a} } keys(%color_count); + +# Now we have our pick of colors. Sort according to intensity; +# this is more or less an ugly hack to cover for the fact that +# using PPM as input doesn't let the user set the color map, +# which the user really needs to be able to do. + +sub by_intensity() { + my($ra,$ga,$ba) = unpack("CCC", $a); + my($rb,$gb,$bb) = unpack("CCC", $b); + + my($ia) = $ra*0.299 + $ga*0.587 + $ba*0.114; + my($ib) = $rb*0.299 + $gb*0.587 + $bb*0.114; + + return ( $ia <=> $ib ) if ( $ia != $ib ); + + # If same, sort based on RGB components, + # with highest priority given to G, then R, then B. + + return ( $ga <=> $gb ) if ( $ga != $gb ); + return ( $ra <=> $rb ) if ( $ra != $rb ); + return ( $ba <=> $bb ); +} + +@icolors = sort by_intensity @colors; + +# Insert forced colors into "final" array +@colors = (undef) x 16; +foreach $rgb ( keys(%force_index) ) { + $i = $force_index{$rgb}; + $colors[$i] = $rgb; + $color_index{$rgb} = $i; +} + +undef %force_index; + +# Insert remaining colors in the remaining slots, +# in luminosity-sorted order +$nix = 0; +while ( scalar(@icolors) ) { + # Advance to the next free slot + $nix++ while ( defined($colors[$nix]) && $nix < 16 ); + last if ( $nix >= 16 ); + $rgb = shift @icolors; + if ( !defined($color_index{$rgb}) ) { + $colors[$nix] = $rgb; + $color_index{$rgb} = $nix; + } +} + +while ( scalar(@icolors) ) { + $rgb = shift @icolors; + $lost++ if ( !defined($color_index{$rgb}) ); +} + +if ( $lost ) { + printf STDERR + "$0: Warning: color palette truncated (%d colors ignored)\n", $lost; +} + +undef @icolors; + +# Output header +print pack("Vvv", $magic, $xsize, $ysize); + +# Output color map +for ( $i = 0 ; $i < 16 ; $i++ ) { + if ( defined($colors[$i]) ) { + print $colors[$i]; + } else { + # Padding for unused color entries + print pack("CCC", 63*$i/15, 63*$i/15, 63*$i/15); + } +} + +sub output_nybble($) { + my($ny) = @_; + + if ( !defined($ny) ) { + if ( defined($nybble_tmp) ) { + $ny = 0; # Force the last byte out + } else { + return; + } + } + + $ny = $ny & 0x0F; + + if ( defined($nybble_tmp) ) { + $ny = ($ny << 4) | $nybble_tmp; + print chr($ny); + $bytes++; + undef $nybble_tmp; + } else { + $nybble_tmp = $ny; + } +} + +sub output_run($$$) { + my($last,$this,$run) = @_; + + if ( $this != $last ) { + output_nybble($this); + $run--; + } + while ( $run ) { + if ( $run >= 16 ) { + output_nybble($this); + output_nybble(0); + if ( $run > 271 ) { + $erun = 255; + $run -= 271; + } else { + $erun = $run-16; + $run = 0; + } + output_nybble($erun); + output_nybble($erun >> 4); + } else { + output_nybble($this); + output_nybble($run); + $run = 0; + } + } +} + +$bytes = 0; +undef $nybble_tmp; + +for ( $y = 0 ; $y < $ysize ; $y++ ) { + $last = $prev = 0; + $run = 0; + for ( $x = 0 ; $x < $xsize ; $x++ ) { + $rgb = shift(@data); + $i = $color_index{$rgb} + 0; + if ( $i == $last ) { + $run++; + } else { + output_run($prev, $last, $run); + $prev = $last; + $last = $i; + $run = 1; + } + } + # Output final datum for row; we're always at least one pixel behind + output_run($prev, $last, $run); + output_nybble(undef); # Flush row +} + +$pixels = $xsize * $ysize; +$size = ($pixels+1)/2; +printf STDERR "%d pixels, %d bytes, (%2.2f%% compression)\n", + $pixels, $bytes, 100*($size-$bytes)/$size; diff --git a/contrib/syslinux-4.02/utils/pxelinux-options b/contrib/syslinux-4.02/utils/pxelinux-options new file mode 100755 index 0000000..ab7075b --- /dev/null +++ b/contrib/syslinux-4.02/utils/pxelinux-options @@ -0,0 +1,499 @@ +#!/usr/bin/perl +# +# Set PXELINUX hard-coded options +# + +use Socket; # For gethostbyname +use Fcntl; +use bytes; + +%option_names = ( + 6 => 'domain-name-servers', + 15 => 'domain-name', + 54 => 'next-server', + 209 => 'config-file', + 210 => 'path-prefix', + 211 => 'reboottime' + ); + +@fmt_oneip = ("ip-address", \&parse_oneip, \&show_ip); +@fmt_multiip = ("ip-address-list", \&parse_multiip, \&show_ip); +@fmt_string = ("string", \&parse_string, \&show_string); +@fmt_uint32 = ("uint32", \&parse_uint32, \&show_uint32); + +%option_format = ( + 6 => \@fmt_multiip, + 15 => \@fmt_string, + 54 => \@fmt_oneip, + 67 => \@fmt_string, + 209 => \@fmt_string, + 210 => \@fmt_string, + 211 => \@fmt_uint32 + ); + +sub parse_oneip($) +{ + my($s) = @_; + my($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($s); + + return ($addrtype == AF_INET) ? $addrs[0] : undef; +} + +sub parse_multiip($) +{ + my($l) = @_; + my $s; + my @a = (); + my $addr; + my $d = ''; + + foreach $s (split(/,/, $l)) { + my($name,$aliases,$addrtype,$length,@addrs) + = gethostbyname($s); + if ($addrtype == AF_INET) { + foreach $addr (@addrs) { + $d .= $addr; + } + } + } + + return $d ne '' ? $d : undef; +} + +sub show_ip($) +{ + my($l) = @_; + + if (length($l) & 3) { + return undef; + } else { + my @h = (); + my $i; + + for ($i = 0; $i < length($l); $i += 4) { + push(@h, inet_ntoa(substr($l, $i, 4))); + } + + return join(',', @h); + } +} + +sub parse_string($) +{ + return $_[0]; +} + +sub show_string($) +{ + my($s) = @_; + my $o, $i, $c; + + $o = "\'"; + for ($i = 0; $i < length($s); $i++) { + $c = substr($s, $i, 1); + if ($c eq "\'" || $c eq '!') { + $o .= "\'\\$c\'"; + } else { + $o .= $c; + } + } + $o .= "\'"; + + return $o; +} + +sub parse_uint32($) +{ + my($s) = @_; + + if ($s =~ /^[0-9]+$/) { + return pack("N", $s); + } else { + return undef; + } +} + +sub show_uint32($) +{ + my($l) = @_; + + if (length($l) == 4) { + return unpack("N", $l); + } else { + return undef; + } +} + +sub parse_generic($) +{ + my($s) = @_; + + if ($s =~ /^[0-9a-f]{1,2}(:[0-9a-f]{1,2})*$/) { + my $h; + my @b = (); + + foreach $h (split(/\:/, $s)) { + push(@b, hex $h); + } + + return pack("C", @b); + } else { + return undef; + } +} + +sub show_generic($) +{ + my($l) = @_; + my $i; + my @h; + + for ($i = 0; $i < length($l); $i++) { + push(@h, sprintf("%02x", unpack("C", substr($l, $i, $1)))); + } + + return join(':', @h); +} + +sub parse_option($$) +{ + my($opt, $arg) = @_; + my $v; + + if (defined($option_format{$opt})) { + $v = $option_format{$opt}[1]($arg); + return $v if (defined($v)); + } + + return parse_generic($arg); +} + +sub show_option($$) +{ + my($opt, $arg) = @_; + my $v; + + if (defined($option_format{$opt})) { + $v = $option_format{$opt}[2]($arg); + return $v if (defined($v)); + } + + return show_generic($arg); +} + +sub option_number($) +{ + my($n) = @_; + + if (defined($option_rnames{$n})) { + return $option_rnames{$n}; + } elsif ($n =~ /^[0-9]+$/ && $n >= 1 && $n <= 254) { + return $n+0; + } else { + return undef; + } +} + +sub read_optsets($) +{ + my($file) = @_; + my $data, $bdata, $adata; + my $patch_start = (stat($file))[7]; + + return undef unless (seek($file, 8, SEEK_SET)); + return undef unless (read($file, $data, 7*4) == 7*4); + + my($magic, $len, $flags, $boff, $blen, $aoff, $alen) + = unpack("VVVVVVV", $data); + return undef if ($magic != 0x2983c8ac); + return undef if ($len < 7*4); + + if ($blen == 0) { + $bdata = ''; + } else { + return undef unless (seek($file, $boff, SEEK_SET)); + return undef unless (read($file, $bdata, $blen) == $blen); + $patch_start = $boff if ($boff < $patch_start); + } + + if ($alen == 0) { + $adata = ''; + } else { + return undef unless (seek($file, $aoff, SEEK_SET)); + return undef unless (read($file, $adata, $alen) == $alen); + $patch_start = $aoff if ($aoff < $patch_start); + } + + return ($patch_start, $bdata, $adata); +} + +sub write_optsets($$@) +{ + my($file, $patch_start, $bdata, $adata) = @_; + my $boff = 0; + my $aoff = 0; + + if (length($bdata) > 0) { + $bdata .= "\xff"; + $boff = $patch_start; + return undef unless (seek($file, $boff, SEEK_SET)); + return undef unless (print $file $bdata); + $patch_start += length($bdata); + } + + if (length($adata) > 0) { + $adata .= "\xff"; + $aoff = $patch_start; + return undef unless (seek($file, $aoff, SEEK_SET)); + return undef unless (print $file $adata); + $patch_start += length($adata); + } + + my $hdr = pack("VVVV", $boff, length($bdata), $aoff, length($adata)); + + return undef unless (seek($file, 8+3*4, SEEK_SET)); + return undef unless (print $file $hdr); + + truncate($file, $patch_start); + return 1; +} + +sub delete_option($$) +{ + my ($num, $block) = @_; + my $o, $l, $c, $x; + + $x = 0; + while ($x < length($block)) { + ($o, $l) = unpack("CC", substr($block, $x, 2)); + if ($o == $num) { + # Delete this option + substr($block, $x, $l+2) = ''; + } elsif ($o == 0) { + # Delete a null option + substr($block, $x, 1) = ''; + } elsif ($o == 255) { + # End marker - truncate block + $block = substr($block, 0, $x); + last; + } else { + # Skip to the next option + $x += $l+2; + } + } + + return $block; +} + +sub add_option($$$) +{ + my ($num, $data, $block) = @_; + + $block = delete_option($num, $block); + + if (length($data) == 0) { + return $block; + } elsif (length($data) > 255) { + die "$0: option $num has too much data (max 255 bytes)\n"; + } else { + return $block . pack("CC", $num, length($data)) . $data; + } +} + +sub list_options($$) +{ + my($pfx, $data) = @_; + my $x, $o, $l; + + while ($x < length($data)) { + ($o, $l) = unpack("CC", substr($data, $x, 2)); + + if ($o == 0) { + $x++; + } elsif ($o == 255) { + last; + } else { + my $odata = substr($data, $x+2, $l); + last if (length($odata) != $l); # Incomplete option + + printf "%s%-20s %s\n", $pfx, + $option_names{$o} || sprintf("%d", $o), + show_option($o, $odata); + + $x += $l+2; + } + } +} + +sub usage() +{ + my $i; + + print STDERR "Usage: $0 options pxelinux.0\n"; + print STDERR "Options:\n"; + print STDERR "--before option value -b Add an option before DHCP data\n"; + print STDERR "--after option value -a Add an option after DHCP data\n"; + print STDERR "--delete option -d Delete an option\n"; + print STDERR "--list -l List set options\n"; + print STDERR "--dry-run -n Don't modify the target file\n"; + print STDERR "--help -h Display this help text\n"; + print STDERR "\n"; + print STDERR "The following DHCP options are currently recognized:\n"; + printf STDERR "%-23s %-3s %s\n", 'Name', 'Num', 'Value Format'; + + foreach $i (sort { $a <=> $b } keys(%option_names)) { + printf STDERR "%-23s %3d %s\n", + $option_names{$i}, $i, $option_format{$i}[0]; + } +} + +%option_rnames = (); +foreach $opt (keys(%option_names)) { + $option_rnames{$option_names{$opt}} = $opt; +} + +%before = (); +%after = (); +@clear = (); +$usage = 0; +$err = 0; +$list = 0; +$no_write = 0; +undef $file; + +while (defined($opt = shift(@ARGV))) { + if ($opt !~ /^-/) { + if (defined($file)) { + $err = $usage = 1; + last; + } + $file = $opt; + } elsif ($opt eq '-b' || $opt eq '--before') { + $oname = shift(@ARGV); + $odata = shift(@ARGV); + + if (!defined($odata)) { + $err = $usage = 1; + last; + } + + $onum = option_number($oname); + if (!defined($onum)) { + print STDERR "$0: unknown option name: $oname\n"; + $err = 1; + next; + } + + $odata = parse_option($onum, $odata); + if (!defined($odata)) { + print STDERR "$0: unable to parse data for option $oname\n"; + $err = 1; + next; + } + + delete $after{$onum}; + $before{$onum} = $odata; + push(@clear, $onum); + } elsif ($opt eq '-a' || $opt eq '--after') { + $oname = shift(@ARGV); + $odata = shift(@ARGV); + + if (!defined($odata)) { + $err = $usage = 1; + last; + } + + $onum = option_number($oname); + if (!defined($onum)) { + print STDERR "$0: unknown option name: $oname\n"; + $err = 1; + next; + } + + $odata = parse_option($onum, $odata); + if (!defined($odata)) { + print STDERR "$0: unable to parse data for option $oname\n"; + $err = 1; + next; + } + + delete $before{$onum}; + $after{$onum} = $odata; + push(@clear, $onum); + } elsif ($opt eq '-d' || $opt eq '--delete') { + $oname = shift(@ARGV); + + if (!defined($oname)) { + $err = $usage = 1; + last; + } + + $onum = option_number($oname); + if (!defined($onum)) { + print STDERR "$0: unknown option name: $oname\n"; + $err = 1; + next; + } + + push(@clear, $onum); + delete $before{$onum}; + delete $after{$onum}; + } elsif ($opt eq '-n' || $opt eq '--no-write' || $opt eq '--dry-run') { + $no_write = 1; + } elsif ($opt eq '-l' || $opt eq '--list') { + $list = 1; + } elsif ($opt eq '-h' || $opt eq '--help') { + $usage = 1; + } else { + print STDERR "Invalid option: $opt\n"; + $err = $usage = 1; + } +} + +if (!defined($file) && !$usage) { + $err = $usage = 1; +} +if ($usage) { + usage(); +} +if ($err || $usage) { + exit($err); +} + +if (!scalar(@clear)) { + $no_write = 1; # No modifications requested +} + +$mode = $no_write ? '<' : '+<'; + +open(FILE, $mode, $file) + or die "$0: cannot open: $file: $!\n"; +($patch_start, @data) = read_optsets(\*FILE); +if (!defined($patch_start)) { + die "$0: $file: patch block not found or file corrupt\n"; +} + +foreach $o (@clear) { + $data[0] = delete_option($o, $data[0]); + $data[1] = delete_option($o, $data[1]); +} +foreach $o (keys(%before)) { + $data[0] = add_option($o, $before{$o}, $data[0]); +} +foreach $o (keys(%after)) { + $data[1] = add_option($o, $after{$o}, $data[1]); +} + +if ($list) { + list_options('-b ', $data[0]); + list_options('-a ', $data[1]); +} + +if (!$no_write) { + if (!write_optsets(\*FILE, $patch_start, @data)) { + die "$0: $file: failed to write options: $!\n"; + } +} + +close(FILE); +exit 0; diff --git a/contrib/syslinux-4.02/utils/sha1pass b/contrib/syslinux-4.02/utils/sha1pass new file mode 100755 index 0000000..3be2dbc --- /dev/null +++ b/contrib/syslinux-4.02/utils/sha1pass @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +use bytes; +use Digest::SHA1; +use MIME::Base64; + +sub random_bytes($) { + my($n) = @_; + my($v, $i); + + if ( open(RANDOM, '<', '/dev/random') || + open(RANDOM, '<', '/dev/urandom') ) { + read(RANDOM, $v, $n); + } else { + # No real RNG available... + srand($$ ^ time); + $v = ''; + for ( $i = 0 ; $i < $n ; $i++ ) { + $v .= ord(int(rand() * 256)); + } + } + + return $v; +} + + +($pass, $salt) = @ARGV; + +unless (defined($salt)) { + $salt = MIME::Base64::encode(random_bytes(6), ''); +} +$pass = Digest::SHA1::sha1_base64($salt, $pass); + +print '$4$', $salt, '$', $pass, "\$\n"; diff --git a/contrib/syslinux-4.02/utils/syslinux2ansi b/contrib/syslinux-4.02/utils/syslinux2ansi new file mode 100755 index 0000000..085f6c9 --- /dev/null +++ b/contrib/syslinux-4.02/utils/syslinux2ansi @@ -0,0 +1,53 @@ +#!/usr/bin/perl +# +# Perl script to convert a Syslinux-format screen to PC-ANSI +# to display in a color xterm or on the Linux console +# + +@ansicol = (0,4,2,6,1,5,3,7); + +$getting_file = 0; +$enable = 1; + +while ( read(STDIN, $ch, 1) > 0 ) { + if ( $ch eq "\x1A" ) { # <SUB> <Ctrl-Z> EOF + last; + } elsif ( $ch eq "\x0C" ) { # <FF> <Ctrl-L> Clear screen + print "\x1b[2J" if ( $enable && !$getting_file ); + } elsif ( $ch eq "\x0F" ) { # <SI> <Ctrl-O> Attribute change + if ( !$getting_file ) { + if ( read(STDIN, $attr, 2) == 2 ) { + $attr = hex $attr; + if ( $enable ) { + print "\x1b[0;"; + if ( $attr & 0x80 ) { + print "5;"; + $attr &= ~0x80; + } + if ( $attr & 0x08 ) { + print "1;"; + $attr &= ~0x08; + } + printf "%d;%dm", + $ansicol[$attr >> 4] + 40, $ansicol[$attr & 7] + 30; + } + } + } + } elsif ( $ch eq "\x18" ) { # <CAN> <Ctrl-X> Display image + # We can't display an image; pretend to be a text screen + # Ignore all input until end of line + $getting_file = 1; + } elsif ( (ord($ch) & ~07) == 0x10 ) { # Mode controls + $enable = (ord($ch) & 0x01); # Emulate the text screen + } elsif ( $ch eq "\x0D" ) { # <CR> <Ctrl-M> Carriage return + # Ignore + } elsif ( $ch eq "\x0A" ) { # <LF> <Ctrl-J> Line feed + if ( $getting_file ) { + $getting_file = 0; + } else { + print $ch if ( $enable ); + } + } else { + print $ch if ( $enable && !$getting_file ); + } +} |