--- /dev/null
+#!/usr/bin/perl
+
+$minreaddays= 21;
+$maxperuser= 250;
+$fetchdir= "/var/lib/news/fetch";
+chdir("/etc/news") || die $!;
+
+open(CONF,"nntp-merge.conf") || die $!;
+while(<CONF>) {
+ next if m/^\#/ || !m/^\S/;
+ next if m/^(myfqdn|xref|server|server-nosearch|fetch|read|post|permit|believe|minreaddays)\s/;
+ if (m/^maxperuser\s+(\d+)\s+$/) {
+ $maxperuser= $1;
+ } elsif (m/^extrarc\s+(\S+)\s+$/) {
+ push(@extrarc,$1);
+ } else {
+ die "$_ ?";
+ }
+}
+
+open IGN,"</etc/news/newsrc-ignoredusers" or die $!;
+while (<IGN>) {
+ chomp;
+ next if m/^\#/;
+ s/\s*$//;
+ $ign{$_}= 1;
+}
+close IGN or die $!;
+
+open PASS,"</etc/userlist" or die $!;
+while (<PASS>) {
+ chomp;
+ next if m/^\#/;
+ $user= $_;
+ next if $ign{$user};
+ open GL,"userv -t 30 $user newsrc-listgroups |" or die $!;
+ scan("user $user",1);
+ close GL; $? and warn "getgroups: error getting groups for $user (code $?)";
+}
+close PASS or die $!;
+
+for $f (@extrarc) {
+ open GL,"< $f" or die $!;
+ scan("file $f",0);
+ close GL or die $!;
+}
+
+chdir($fetchdir) || die $!;
+open(NG,">all-read-groups.new") || die $!;
+print(NG join("\n",sort keys %yes)."\n") || die $!;
+close(NG) || die $!;
+rename("all-read-groups.new","all-read-groups") || die $!;
+
+printf "total %d groups\n",scalar(keys %yes);
+exit(0);
+
+sub scan ($) {
+ my ($where,$toomanyenf) = @_;
+ @g= ();
+ while (<GL>) {
+ die "bad group in $where" unless m/^[-a-z0-9+]+\.[-a-z0-9+._]+$/i;
+ push @g, $&;
+ }
+ warn("too many from $where"), return if $toomanyenf && @g > $maxperuser;
+ map { $yes{$_}=1; } @g;
+ printf "%-20s - %4d groups\n",$where,scalar(@g);
+}