#!/usr/bin/perl use strict; $|++; use Net::NNTP; use News::Newsrc; use IO::File; ## config my $DST_MAX = 500; my $SRC_MAX = $DST_MAX * 3; my $OLD = "news.old-isp.comm"; my $NEW = "news.big-mega-isp.comm"; my $VIA = "shell.old-isp.comm"; my $VIA_OLD_PORT = 42001; my $VIA_NEW_PORT = 42002; my $VERBOSE = 2; # 0 quiet, 1 expected errors, 2 noisy ## end config system join " ", "ssh -f -q", "-L $VIA_OLD_PORT:$OLD:119", "-L $VIA_NEW_PORT:$NEW:119", "$VIA", "exec sleep 60", "&", "sleep 5" if $VIA; my $SRC_NNTP = $VIA ? "localhost:$VIA_OLD_PORT" : $OLD; my $DST_NNTP = $VIA ? "localhost:$VIA_NEW_PORT" : $NEW; my $src = Net::NNTP->new($SRC_NNTP) or die "src: $!"; my $dst = Net::NNTP->new($DST_NNTP) or die "dst: $!"; my $src_rc = News::Newsrc->new or die "Cannot new newsrc for src"; my $dst_rc = News::Newsrc->new or die "Cannot new newsrc for dst"; my @extra_lines = (); { my $newsrc = IO::File->new("$ENV{HOME}/.newsrc", "r") or die "Cannot open .newsrc: $!"; my @all = <$newsrc>; @extra_lines = grep !/^\S+[:!]\s/, @all; $src_rc->_scan(join "", grep /^\S+[:!]\s/, @all); # dies if fail } for my $group ($src_rc->groups) { eval { if ($src_rc->subscribed($group)) { print "subscribed to $group\n" if $VERBOSE > 1; $dst_rc->subscribe($group); (undef, my $src_low, my $src_high) = $src->group($group) or die "Cannot get info for src $group\n"; $src_low = $src_high - $SRC_MAX if $src_low < $src_high - $SRC_MAX; my %src_msgid_to_art = reverse %{$src->xhdr("Message-Id", "$src_low-$src_high")}; (undef, my $dst_low, my $dst_high) = $dst->group($group) or die "Cannot get info for dst $group\n"; $dst_low = $dst_high - $DST_MAX if $dst_low < $dst_high - $DST_MAX; my %dst_art_to_msgid = %{$dst->xhdr("Message-Id", "$dst_low-$dst_high")}; for my $dst_art ($dst_low..$dst_high) { eval { my $msgid = $dst_art_to_msgid{$dst_art} or die "no msgid for $dst_art in $group at dst\n"; ## next; my $src_art = $src_msgid_to_art{$msgid} or die "no art for $msgid in $group at src\n"; ## next; next unless $src_rc->marked($group,$src_art); print "mapping $msgid from $src_art to $dst_art\n" if $VERBOSE > 1; $dst_rc->mark($group, $dst_art); }; warn $@ if $@ and $VERBOSE; } $dst_rc->mark_range($group, 1, $dst_low - 1); } else { print "unsubscribed to $group\n" if $VERBOSE > 1; $dst_rc->unsubscribe($group); (undef, my $dst_low, my $dst_high) = $dst->group($group) or die "Cannot get info for dst $group\n"; $dst_rc->mark_range($group, 1, $dst_low - 1) if $dst_low; } }; warn $@ if $@ and $VERBOSE; } print "==== RESULT ====\n"; print @extra_lines, $dst_rc->_dump;