#!/usr/local/bin/perl

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

$debug = 0;
$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, "");

foreach $article (@ARGV) {
	print "*** Article $article\n" if $morethanone;

	($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;
	read(R, $buf, $size);
	$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;
}
