#!/usr/bin/perl -w # Copyright (c) 2001 Leigh Brown. Released under the GNU GPL. No warranty. # You know the drill. require 5.005; use strict; use vars qw(@fields); sub err_exit($) { print STDERR $_[0], "\n"; exit 1 } sub usage { err_exit "Usage: $0 <-s\"command line\" | -q> "; } sub open_image($) { my $fh; open $fh, "+<$_[0]" or err_exit "cannot open $_[0]: $!"; return $fh; } sub file_length($) { my $pos = sysseek($_[0], 0, 1); my $len = sysseek($_[0], 0, 2); sysseek($_[0], $pos, 0); return $len; } sub read_header($) { if (sysseek($_[0], 0x200, 0) != 0x200) { err_exit "$0: seek failed: $!" } my $data; if (sysread($_[0], $data, 0x400) != 0x400) { err_exit "$0: sysread failed" } return unpack "VVCCA32x470Z256", $data; } sub read_and_verify_header($) { # my @stat = stat $_[0]; # err_exit "$0: file is too short: $stat[7]" # if $stat[7] < 0x504; @fields = read_header $_[0]; err_exit "$0: offset incorrect: $fields[0]" if $fields[0] != 0x500; err_exit "$0: length too small: $fields[1]" if $fields[1] < 0x504; # err_exit "$0: length too large: $fields[1]" # if $fields[1] > $stat[7]; } sub query_image() { my $fh = open_image $ARGV[1]; read_and_verify_header $fh; print "$ARGV[1]\n", "-" x length $ARGV[1], "\n"; printf "Entry point offset = 0x%08x\n", $fields[0]; printf "Load image length = 0x%08x\n", $fields[1]; printf "Load image Flags = 0x%02x\n", $fields[2]; printf "Operating system id = 0x%02x\n", $fields[3]; print "Partition name = [$fields[4]]\n"; if (length $fields[5] > 40) { print "Command line:\n$fields[5]\n"; } else { print "Command line = [$fields[5]]\n"; } } sub set_command_line($) { my $fh = open_image $ARGV[1]; read_and_verify_header $fh; if (sysseek($fh, 0x400, 0) != 0x400) { err_exit "$0: seek failed: $!" } my $data = pack "Z256", $_[0]; if (syswrite($fh, $data) != 0x100) { err_exit "$0: syswrite failed: $1" } } usage unless scalar @ARGV == 2; foreach ($ARGV[0]) { /^-q$/ and query_image, last; /^-s(.*)$/ and set_command_line($1), last; usage; }