#!/afs/athena/contrib/perl/perl

# "message-id-to-newsrc.pl"
# 
# Copyright (c) 1991 by Jonathan Kamens (jik@athena.mit.edu).
# 
# This file may be freely redistributed as long as this entire
# comment (up to the first blank line below) stays on it, and as long
# as you don't try to make any money distributing it.
# 
# Furthermore, if you make any changes to it and then redistribute
# it, please mark in some ways the changes you have made my version,
# and, if possible, forward the changes back to me.
# 
# $Id: message-id-to-newsrc.pl,v 1.9 1992/11/15 04:35:05 jik Exp $

# This script reads the output of the 'newsrc-to-message-id.pl'
# script and turns it back into a .newsrc file.
# 
# The server to use to convert Message-ID's back into article numbers
# can be specified using $NNTPSERVER or the '-server' command line
# flag.

# $opt_D = 1;
# $find_debug = 1;

# Defaults

$opt_D = 0;
$ticks = 1;
$unbuffered = 0;
undef $outfile;
$server = $ENV{"NNTPSERVER"};
$upto = 0;

push(@INC, '/afs/athena.mit.edu/user/j/i/jik/lib/perl');

require 'nntp.pl';

while ($_ = $ARGV[0], /^[-+]/) {
    shift;
    if (/^-server$/) {
	die "Missing argument to \"$_\".\n" if (@ARGV == 0);
	$server = shift;
	next;
    }
    if (/^-out$/) {
	die "Missing argument to \"$_\".\n" if (@ARGV == 0);
	$outfile = shift;
	next;
    }
    if (/^(\+|-)buffered$/) {
	$unbuffered = ($1 eq "+") ? 0 : 1;
	next;
    }
    if (/^(\+|-)ticks$/) {
	$ticks = ($1 eq "+") ? 1 : 0;
	next;
    }
    if (/^(\+|-)nntp_debug/) {
	$opt_D = ($1 eq "+") ? 1 : 0;
	next;
    }
    if (/^(\+|-)upto/) {
	$upto = ($1 eq "+") ? 1 : 0;
	next;
    }
    die "Unknown argument \"$_\".\n";
}

if ($outfile) {
    close(STDOUT);
    open(STDOUT, ">$outfile") || die "Opening $outfile for write: $!.\n";
    select(STDOUT);
}

if ($unbuffered) {
    $| = 1;
}

die "No NNTP server specified!\n" if (! $server);

&news_open($server);

%byid = ();
$newsgroup = undef;
$subbed = undef;
@articles = ();
@stats = ();
%xref = ();
$in_xhdr = 0;

while (<>) {
    if (/^(.*)([:!])$/) {

	# This is a new group.
	# If there's an old current group, deal with it.

	&output() if $newsgroup;
	if ($in_xhdr) {
	    while ((($xhdr_tag, $xhdr_val) = &news_xhdr_next()) == 2) {
		# Empty.
	    }
	}
	undef $in_xhdr;
	$newsgroup = $1;
	$subbed = $2;
	($newsgroup_regex = $newsgroup) =~ s/(\W)/\\$1/g;
	@articles = ();
	%byid = ();
	undef @stats;

	next;
    }

    if (! defined(@stats)) {
	@stats = &news_select_ng($newsgroup);
    }
    next if (@stats == ());

    chop;

    if (defined($byid{$_})) {
	print STDERR "Found $_ in table.\n" if ($find_debug);
	push(@articles, $byid{$_});
	next;
    }
    elsif (! defined($in_xhdr) &&
	   (&news_xhdr_init('xref', $_)) &&
	   ((($xhdr_tag, $xhdr_val) = &news_xhdr_next()) == 2)) {
	&news_xhdr_next();	# Flush the dot at the end.
	if ($xhdr_val =~ / $newsgroup_regex:([^ ]+)/) {
	    print STDERR "Found xref in $_.\n" if ($find_debug);
	    push(@articles, $1);
	    next;
	}
    }
    else {
	next if (! ($in_xhdr || 
		    (! defined($in_xhdr) &&
		     ++$in_xhdr &&
		     &news_xhdr_init('message-id', "$stats[0]-$stats[1]"))));
	print STDERR "Building table to find $_.\n" if ($find_debug);
	while ((($xhdr_tag, $xhdr_val) = &news_xhdr_next()) == 2) {
	    $byid{$xhdr_val} = $xhdr_tag;
	    if ($xhdr_val eq $_) {
		print STDERR "Found $_ in built table.\n" if ($find_debug);
		push(@articles, $xhdr_tag);
		last;
	    }
	}
	$in_xhdr = 0 if ($xhdr_val ne $_);
    }
}

&output() if $newsgroup;

print STDERR "\n" if ($ticks);

sub output {
    local($i);

    print "$newsgroup$subbed ";
    if (@articles) {
	local($first, $last, $new);
	@articles = sort byval @articles;
	$first = $last = shift @articles;
	if ($upto) {
	    for ($i = $first; $i > 1; $i--) {
		unshift(@articles, $i);
	    }
	    $first = $last = 1;
	}
	while ($new = shift @articles) {
	    if ($new > $last + 1) {
		if ($last > $first) {
		    print "$first-$last,";
		}
		else {
		    print "$first,";
		}
		$first = $last = $new;
		next;
	    }
	    else {
		$last = $new;
		next;
	    }
	}
	if ($last > $first) {
	    print "$first-$last\n";
	}
	else {
	    print "$first\n";
	}
    }
    else {
	print "\n";
    }
    if ($ticks) {
	if (++$counter % 10 == 0) {
	    print STDERR $counter;
	}
	else {
	    print STDERR ".";
	}
    }
}
    
sub byval { $a <=> $b; }
