#!/usr/local/bin/perl

# usage: $0 rawpart:offset [rawpart:offset ...]

$debug = 1;
$bigendian = &am_i_big_endian;

$truezottf = $bigendian ? 0x00001234 : 0x34120000;
$rawartheaderfmt = "l N a64";
$morethanone = 1 if $#ARGV > 0;

&read_config("/var/news/rawpart.config");
$buf = pack($rawartheaderfmt, 0, 0, "");

($article, $xref) = @ARGV;

($rawpart, $offset) = split(/:/, $article);

$offset = hex($offset);
die "No such rawpart: $rawpart" if ! defined $path{$rawpart};
die "Offset $offset illegal" if $offset < 0 || $offset >= $length{$rawpart};

open(R, $path{$rawpart}) || die "open $path{$rawpart}: $!";
print "seek(R, $start{$rawpart}, 0)\n" if $debug;
seek(R, $start{$rawpart}, 0) || die "seek 1 ($start{$rawpart}, 0): $!";
print "seek(R, $offset, 1)\n" if $debug;
seek(R, $offset, 1) || die "seek 2 ($offset, 1): $!";
($r = read(R, $buf, length $buf)) || die "read: $!";
($zottf, $size, $messageid) = unpack($rawartheaderfmt, $buf);
die "Leading zottf does not exist, sorry!\n" if $zottf != $truezottf;
$messageid =~ s/\000.*//;
print "Size: $size\nMessage-ID: $messageid\n\n" if $debug;

$bl = length($buf);
seek(R, $xref -$bl , 1);
read(R, $buf, $size - $xref + $bl);
$buf =~ tr/\r//d;		# parsecontrol dislikes \r
print $buf;

exit 0;

sub read_config {
    my($file) = @_;

    open(F, $file) || die "open $file: $!";
    while (<F>) {
	next if /^#/ || /^\s*$/;
	chop;
	while (/\\$/) {
	    my $extra;
	    chop;
	    $extra = <F>;
	    $_ .= $extra;
	}
	@a = split(/:/, $_);
	next if $a[0] ne "rawpart";
	$path{$a[1]} = $a[2];
	$length{$a[1]} = hex($a[3]);
    }
    close(F);
}

sub am_i_big_endian {
    local($orig, $netfmt, $new);

    $orig = 1;
    $netfmt = pack("N", $orig);
    $new = unpack("L", $netfmt);
    return $orig == $new;
}
