#! /usr/bin/perl # fixscript will replace this line with require innshellvars.pl # batch-active-update # Author: David Lawrence # Reads a series of ctlinnd newgroup/rmgroup/changegroup commands, such as # is output by checkgroups and actsync, and efficiently handles them all at # once. Input can come from command line files or stdin, a la awk/sed. $oldact = $inn::active; # active file location $oldact = $inn::active; # active file location (same; shut up, perl -w) $newact = "$oldact.new$$"; # temporary name for new active file $actime = "$oldact.times"; # active.times file $pausemsg = 'batch active update, ok'; # message to be used for pausing? $diff_flags = ''; # Flags for diff(1); default chosen if null. $0 =~ s#^.*/##; die "$0: must run as $inn::newsuser user" unless $> == (getpwnam($inn::newsuser))[2]; $debug = -t STDOUT ? 1 : 0; $| = 1; # show output as it happens (for an rsh/ssh pipe) # Guess at best flags for a condensed diff listing. The # checks for alternative operating systems is incomplete. unless ($diff_flags) { if (`diff -v 2>&1` =~ /GNU/) { $diff_flags = '-U0'; } elsif ($^O =~ /^(dec_osf|solaris)$/) { $diff_flags = '-C0'; } elsif ($^O eq 'nextstep') { $diff_flags = '-c0'; } else { $diff_flags = '-c'; } } print "reading list of groups to update\n" if $debug; $eval = "while () {\n"; $eval .= " \$group = (split)[0];\n"; while (<>) { if (/^\s*\S*ctlinnd newgroup (\S+) (\S)/) { $toadd{$1} = $2; } elsif (/^\s*\S*ctlinnd rmgroup (\S+)/) { $eval .= " next if \$group eq '$1';\n"; } elsif (/^\s*\S*ctlinnd changegroup (\S+) (\S)/) { $eval .= " s/ \\S+\$/ $2/ if \$group eq '$1';\n"; } } $eval .= " delete \$toadd{\$group};\n"; $eval .= " if (!print(NEWACT \$_)) {\n"; $eval .= " die \"\$0: writing \$newact failed (\$!), aborting\\n\";\n"; $eval .= " }\n"; $eval .= "}\n"; &ctlinnd("pause $pausemsg"); open(OLDACT, "< $oldact") || die "$0: open $oldact: $!\n"; open(NEWACT, "> $newact") || die "$0: open $newact: $!\n"; print "rewriting active file\n" if $debug; eval $eval; for (sort keys %toadd) { $add = "$_ 0000000000 0000000001 $toadd{$_}\n"; if (!print( NEWACT $add)) { &ctlinnd("go $pausemsg"); die "$0: writing $newact failed ($!), aborting\n"; } } close(OLDACT) || warn "$0: close $oldact: $!\n"; close(NEWACT) || warn "$0: close $newact: $!\n"; if (!rename("$oldact", "$oldact.old")) { warn "$0: rename $oldact $oldact.old: $!\n"; } if (!rename("$newact", "$oldact")) { die "$0: rename $newact $oldact: $!\n"; } &ctlinnd("reload active 'updated from checkgroups'"); system("diff $diff_flags $oldact.old $oldact"); &ctlinnd("go $pausemsg"); print "updating $actime\n" if $debug; if (open(TIMES, ">> $actime")) { $time = time; for (sort keys %toadd) { print TIMES "$_ $time checkgroups-update\n" || last; } close(TIMES) || warn "$0: close $actime: $!\n"; } else { warn "$0: $actime not updated: $!\n"; } exit 0; sub ctlinnd { local($command) = @_; print "ctlinnd $command\n" if $debug; if (system("$inn::newsbin/ctlinnd -s $command")) { die "$0: \"$command\" failed, aborting\n"; } }