diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-05-29 15:11:38 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-05-29 15:11:38 -0700 |
commit | b536209dfb7bd50c37061735fe10d2c19a97d26d (patch) | |
tree | 9d8ca6882fc5d9721fb0efea1abfd6dc09886814 /utils | |
parent | 3ec40a0119587f63411475c76c69f9db24c7598e (diff) | |
download | syslinux-b536209dfb7bd50c37061735fe10d2c19a97d26d.tar.gz |
Move files out of root into core, dos, and utils
Move source files out of the root directory; the root is a mess and
has become virtually unmaintainable. The Syslinux core now lives in
core/; the Linux and generic utilities has moved into utils/, and
copybs.com has moved into dos/; it had to go somewhere, and it seemed
as good a place as any.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/Makefile | 58 | ||||
-rw-r--r-- | utils/bin2hex.pl | 44 | ||||
-rw-r--r-- | utils/gethostip.c | 131 | ||||
-rwxr-xr-x | utils/keytab-lilo | 111 | ||||
-rwxr-xr-x | utils/lss16toppm | 111 | ||||
-rwxr-xr-x | utils/md5pass | 34 | ||||
-rw-r--r-- | utils/mkdiskimage.in | 310 | ||||
-rwxr-xr-x | utils/ppmtolss16 | 393 | ||||
-rwxr-xr-x | utils/sha1pass | 34 | ||||
-rwxr-xr-x | utils/syslinux2ansi | 53 |
10 files changed, 1279 insertions, 0 deletions
diff --git a/utils/Makefile b/utils/Makefile new file mode 100644 index 00000000..0c5a3636 --- /dev/null +++ b/utils/Makefile @@ -0,0 +1,58 @@ +## ----------------------------------------------------------------------- +## +## 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 +# +# No builtin rules +MAKEFLAGS += -r +MAKE += -r + +TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) + +CC = gcc + +gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) dummy.c -o $$tmpf 2>/dev/null; \ + then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf) + +comma := , +LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,) + +CFLAGS = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 +LDFLAGS = -O2 -s $(LDHASH) +LD = ld +PERL = perl + +TARGETS = mkdiskimage gethostip +ASIS = keytab-lilo lss16toppm md5pass ppmtolss16 sha1pass syslinux2ansi + +all: mkdiskimage gethostip + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +mkdiskimage: mkdiskimage.in ../mbr/mbr.bin bin2hex.pl + $(PERL) bin2hex.pl < ../mbr/mbr.bin | cat mkdiskimage.in - > $@ + chmod a+x $@ + +gethostip: gethostip.o + $(CC) $(LDFLAGS) -o $@ $^ + +tidy dist: + rm -f *.o + +clean: tidy + rm -f $(TARGETS) + +spotless: clean + +installer: all diff --git a/utils/bin2hex.pl b/utils/bin2hex.pl new file mode 100644 index 00000000..3c86ec27 --- /dev/null +++ b/utils/bin2hex.pl @@ -0,0 +1,44 @@ +#!/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); + $len += printf ("%x", $cc); + if ( $len > 72 ) { + print "\n"; + $len = 0; + } else { + print " "; + $len++; + } +} +print "\n" if ( $len ); +exit 0; diff --git a/utils/gethostip.c b/utils/gethostip.c new file mode 100644 index 00000000..2a1e6e65 --- /dev/null +++ b/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/utils/keytab-lilo b/utils/keytab-lilo new file mode 100755 index 00000000..867be7e2 --- /dev/null +++ b/utils/keytab-lilo @@ -0,0 +1,111 @@ +#!/usr/bin/perl +# -------------------------------------------------------------------------- +# This program was taken from the LILO-20 distribution; only this header +# was added. +# +# LILO program code, documentation and auxiliary programs are +# Copyright 1992-1997 Werner Almesberger. +# All rights reserved. +# +# Redistribution and use in source and binary forms of parts of or the +# whole original or derived work are permitted provided that the +# original work is properly attributed to the author. The name of the +# author may not be used to endorse or promote products derived from +# this software without specific prior written permission. This work +# is provided "as is" and without any express or implied warranties. +# -------------------------------------------------------------------------- + +eval { use bytes; }; eval { binmode STDOUT; }; + +$DEFAULT_PATH = "/usr/lib/kbd/keytables"; +$DEFAULT_MAP = "us"; +$DEFAULT_EXT = ".map"; + +sub usage +{ + print STDERR + "usage: $0 [ -p old_code=new_code ] ...\n". + (" "x(8+length $0))."[path]default_layout[.map] ] ". + "[path]kbd_layout[.map]\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_PATH."/".$map unless $map =~ m|/|; + $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 (/^u_short\s+(\S+)_map\[\S+\]\s+=\s+{\s*$/) { + die "active at beginning of map" if defined $current; + $current = $pfx.":".$1; + 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/utils/lss16toppm b/utils/lss16toppm new file mode 100755 index 00000000..18b7f642 --- /dev/null +++ b/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/utils/md5pass b/utils/md5pass new file mode 100755 index 00000000..3404f1d6 --- /dev/null +++ b/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/utils/mkdiskimage.in b/utils/mkdiskimage.in new file mode 100644 index 00000000..f66ad7cf --- /dev/null +++ b/utils/mkdiskimage.in @@ -0,0 +1,310 @@ +#!/usr/bin/perl +## ----------------------------------------------------------------------- +## +## Copyright 2002-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. +## +## ----------------------------------------------------------------------- + +# +# 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 (sysopen($rfd, '/dev/urandom', O_RDONLY) && + sysread($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; +} + +$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"; + 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 = ''; +while ( $line = <DATA> ) { + chomp $line; + foreach $byte ( split(/\s+/, $line) ) { + $mbr .= chr(hex($byte)); + } +} +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; + +$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/utils/ppmtolss16 b/utils/ppmtolss16 new file mode 100755 index 00000000..5af90831 --- /dev/null +++ b/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/utils/sha1pass b/utils/sha1pass new file mode 100755 index 00000000..3be2dbc1 --- /dev/null +++ b/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/utils/syslinux2ansi b/utils/syslinux2ansi new file mode 100755 index 00000000..085f6c97 --- /dev/null +++ b/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 ); + } +} |