Cover V05, I05
Article
Listing 1
Listing 2
Listing 3
Listing 4
Listing 5
Listing 6
Listing 7
Listing 8

may96.tar


Listing 1: Complete perl program of UUCP hosts

#!/usr/local/bin/perl

#
# Maintain network configuration
#
# Program can be called as maintsite.uucp for UUCP maintenance
# Program can be called as maintsite.lan for LAN maintenance
#
# This program is copyright 1995,1996 Arthur Donkers
#
#    Le Reseau netwerksystemen BV
#    Burg. F. v. Ankenweg 5
#    NL-9991 AM Middelstum
#    The Netherlands
#    arthur@reseau.nl
#
# DISCLAIMER : user this program at your own risk, any loss of data is your
# problem, not mine !!
#

#$trigger  = "/etc/maintsite.";
#$newsconf = "/usr/local/lib/news/sys";
#$passwd   = "/etc/passwd";
#$group    = "/etc/group";
$trigger = "testsite.";
$newsconf = "newssys";
$passwd   = "passwd";
$group    = "group";

# UUCP related config files
#$pending = "/etc/pending.uucp";
#$uuconf  = "/usr/local/lib/uucp/conf/sys";
#$nwsbat  = "/usr/local/lib/news/batchparms";
#$mailnam = "/etc/mail/sendmail.uunames";
$pending = "pending.uucp";
$uuconf  = "uucpsys";
$nwsbat  = "batchparms";
$mailnam = "sendmail.uunames";
$uustat  = "/usr/bin/uustat";

# LAN related config files
$newsnntp = "/usr/local/lib/news/nntp_access";
$namedfwd = "/etc/inet/named.reseau.data";
$namedrev = "/etc/inet/named.rev.data";

# Globals
$config = "";

# List of systems to add and delete
%add    = ();
%delete = ();

# Program starts executing here
die "Must be called as LAN or UUCP" if( &callconfig() eq "");

# See how we are called and behave appropriately
if( $config eq 'uucp' ) {
&dopending( $pending ) if( -e pending);
&douucp( "$trigger" . "$config" ) if( -e "$trigger" . "$config"
);
}
else {
&dolan( "$trigger" . "$config" ) if( -e "$trigger" . "$config"
);
}
exit 0;

# End of execution
#
# Subroutines are listed below

# What are we called ?
sub	callconfig
{
$config = "";
if ($0 =~ /.*\maintsite.uucp$/) {$config = 'uucp';}
elsif ($0 =~ /.*\maintsite.lan$/) {$config = 'lan';}
return $config;
} # callconfig

# The UUCP main entry point
sub	douucp
{
local( $trigger ) = @_;
local( $busy, $sysnam );

$busy = $trigger . ".busy";
link $trigger, $busy || warn "Cannot rename $trigger, $!\n" && return;
unlink $trigger;
open TRIGGER, "$busy" || warn "Cannot open $trigger, $!\n" && unlink $busy
&& return;

while( <TRIGGER> ) {
chomp;
if( /^\+.*/ ) {
$sysnam = substr $_, 1;
$add{$sysnam} = 1;
}
if( /^\-.*/ ) {
$sysnam = substr $_, 1;
$delete{$sysnam} = 1;
}
}
close TRIGGER;
unlink $busy;

# We got a list of hosts to be added and hosts to be deleted
# First delete all hosts
&deluucpmailnews( );
foreach $sysnam (keys %delete) {
if( !&uucpbatch( $sysnam ) ) {
&deluucp( $sysnam );
}
else {
if( -e $pendfile ) { open PENDING, ">>$pendfile"; }
else { open PENDING, ">$pendfile"; }
print PENDING "$sysnam\t24\n";
close PENDING;
}
}
@_ = keys %delete;
if( $#_ > 0 ) {
&notifyuucp( "deleted", keys %delete );
}

# Now add new hosts
&adduucp( );
&adduucpmailnews( );
@_ = keys %add;
if( $#_ > 0 ) {
&notifyuucp( "added", keys %add );
}
} # douucp

# The LAN main entry point
sub	dolan
{
local( $trigger ) = @_;
local( $busy, $sysnam, $address );

$busy = $trigger . ".busy";
link $trigger, $busy || warn "Cannot rename $trigger, $!\n" && return;
unlink $trigger;
open TRIGGER, "$busy" || warn "Cannot open $trigger, $!\n" && unlink $busy
&& return;

while( <TRIGGER> ) {
chomp;
if( /^\+.*/ ) {
($sysnam, $address) = split /\s/;
$sysnam = substr $sysnam, 1;
$add{$sysnam} = $address;
}
if( /^\-.*/ ) {
$sysnam = substr $_, 1;
$delete{$sysnam} = 1;
}
}
close TRIGGER;
unlink $busy;

# We got a list of hosts to be added and hosts to be deleted
# First delete all hosts
&delnewslan( );
&delnamed( );
@_ = keys %delete;
if( $#_ > 0 ) {
&notifylan( "deleted", keys %delete );
}

# Now add new hosts
&addnamed( );
&addnewslan( );
@_ = keys %add;
if( $#_ > 0 ) {
&notifylan( "added", keys %add );
}

# Kick the named
&kicknamed( );
} # dolan

# Check the pending file for pending UUCP systems applicable for deletion
sub	dopending
{
local( $pendfile ) = @_;
local( $oldpendfile, $sysnam, $retry, $total, @deleted );

$oldpendfile = $pendfile . ".old";
link $pendfile, $oldpendfile;
unlink $pendfile;
$total = 0;

# There is a pending file, read it
open PENDING, "$oldpendfile" || warn "Cannot open file $oldpendfile, $!\n"
&& return;
open NEWPENDING, ">$pendfile" || warn "Cannot create file $pendfile, $!\n"
&& link $oldpendfile, $pendfile && unlink $oldpendfile;

# Read host names from pending file
while( <PENDING> ) {
($sysnam, $retry) = split /\s/;
$retry--;
if( $retry == 0 ) {
&deluucp( $sysnam );
push @deleted, $sysnam;
}
else {
if( &uucpbatch( $sysnam ) ) {
print NEWPENDING "$sysnam\t$retry\n";
$total++;
}
else {
&deluucp( $sysnam );
push @deleted, $sysnam;
}
}
}
close PENDING;
close NEWPENDING;
unlink $oldpendfile;

unlink $pendfile if( $total == 0 );
&notifyuucp( "deleted", @deleted );
} # dopending

# Check system for pending batches
sub	uucpbatch
{
local( $sysnam ) = @_;

open UUSTAT, "$uustat -s $sysnam|" || warn "Cannot start $uustat, $!\n" &&
return 1;

while( <UUSTAT> ) {
close UUSTAT;
return 1;
}
close UUSTAT;
return 0;
} # uucpbatch

# Delete one UUCP host from uucp configuration
sub	deluucp
{
local( $deleteme ) = @_;
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $uuconf );
$backup = $uuconf . ".o";

open ORIGINAL, "$backup" || warn "Cannot open $uuconf, $!\n" && link
$backup, $uuconf
&& return;     open NEW, ">$uuconf" || warn "Cannot
creat $uuconf, $!\n" && link $backup,
$uuconf && return;

while( <ORIGINAL> ) {
if( /^\#START .*$/ ) {
chomp;
$sysnam = $_;
$sysnam =~ s/^\#START //;
if( $sysnam eq $deleteme ) {
while( <ORIGINAL> ) {
last if (/^\#END .*$/);
}
}
else {
print NEW;
while( <ORIGINAL> ) {
print NEW;
last if ( /^\#END .*$/);
}
}
}
else {print NEW;}
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $uuconf );
&deluser( $deleteme );
} # deluucp

# Add UUCP host to uucp configuration
sub	adduucp
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $uuconf );
$backup = $uuconf . ".o";

open ORIGINAL, "$backup" || warn "Cannot open $uuconf, $!\n" && link
$backup, $uuconf && return;
open NEW, ">$uuconf" || warn "Cannot creat $uuconf, $!\n" && link
$backup, $uuconf && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW <<EOF

#START $sysnam
system $sysnam
time Never
baud 38400
port Direct
phone ""
called-login uu$sysnam
send-request yes
receive-request yes
called-transfer yes
remote-send /usr/spool/uucppublic /usr/spool/news
local-receive /
remote-receive /usr/spool/uucppublic /usr/spool/news
commands /bin/rmail /usr/local/lib/news/bin/rnews
myname lrngate
#END $sysnam
EOF
;
&adduser( $sysnam );
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $uuconf );
} # adduucp

# Notify root of succesful action for UUCP
sub	notifyuucp
{
local( $action, @hostlist ) = @_;

open MAILTO, "|mail root" || warn "Cannot start mail program, $!\n" &&
return;
print MAILTO <<EOF
Subject: UUCP hosts $action.

The following UUCP hosts have been $action :

@hostlist

EOF
;
} # notifyuucp

# Notify root of succesful action for LAN
sub	notifylan
{
local( $action, @hostlist ) = @_;

open MAILTO, "|mail root" || warn "Cannot start mail program, $!\n" &&
return;
print MAILTO <<EOF
Subject: LAN hosts $action.

The following LAN hosts have been $action :

@hostlist
EOF
;
} # notifylan

# Delete host from news config for LAN
sub	delnewslan
{
# First the nntp access
&delnntp( );
# secondly the sys file
&delnews( );
} # delnewslan

# Add host to news config for LAN
sub	addnewslan
{
# First the nntp access
&addnntp( );
# secondly the sys file
&addnews( );
} # addnewslan

# Delete host from news and news config for UUCP
sub	deluucpmailnews
{
# First the batch params
&delbatch( );
# Secondly the mail setup
&delmail( );
# Lastly the sys file
&delnews( );
} # deluucpmailnews

# Add host to news config for UUCP
sub	adduucpmailnews
{
# First the batch params
&addbatch( );
# Secondly the mail setup
&addmail( );
# Lastly the sys file
&addnews( );
} # adduucpmailnews

# Backup a file
sub	backupfile
{
local( $file ) = @_;
local( $backup );

# Back up older versions
$backup = "$file" . ".ooo";
unlink $backup if( -e $backup );
$backup = "$file" . ".oo";
rename $backup, "$backup" . "o" if( -e $backup );
$backup = "$file" . ".o";
rename $backup, "$backup" . "o" if( -e $backup );
rename $file, $backup;
} # backupfile

# Set permissions on new file as they were on the old one
sub	setperm
{
local( $new, $old );

($dummy, $dummy, $mode, $dummy, $uid, $gid, $dummy) = stat $old;
chown $uid, $gid, $new;
chmod $mode, $new;
} # setperm

# Delete all hosts from newsconfig
sub	delnews
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $newsconf );
$backup = $newsconf . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $newsconf, $!\n" && link
$backup, $newsconf && return;
open NEW, ">$newsconf" || warn "Cannot creat $newsconf, $!\n" && link
$backup, $newsconf && return;

while( <ORIGINAL> ) {
($sysnam, $dummy) = split /:/, $_, 2;
if (!exists $delete{$sysnam}) {
print NEW;
}
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $newsconf );
} # delnews

# Delete all hosts from nntpconfig
sub	delnntp
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $newsnntp );
$backup = $newsconf . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $newsnntp, $!\n" && link
$backup, $newsnntp && return;
open NEW, ">$newsnntp" || warn "Cannot creat $newsnntp, $!\n" && link
$backup, $newsnntp && return;

while( <ORIGINAL> ) {
if( /^#/ || /^\s*$/ ) {
print NEW;
next;
}
$sysnam = $_;
$sysnam =~ s/^([^\.]+)\..*/\1/;
chomp $sysnam;
print NEW if (!exists $delete{$sysnam});
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $newsnntp );
} # delnntp

# Delete all hosts from named
sub	delnamed
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# First the forward mapping
# Back up older versions
&backupfile( $namedfwd );
$backup = $namedfwd . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $namedfwd, $!\n" && link
$backup, $namedfwd && return;
open NEW, ">$namedfwd" || warn "Cannot creat $namedfwd, $!\n" && link
$backup, $namedfwd && return;

while( <ORIGINAL> ) {
if( /^;/ ) {
print NEW;
next;
}
($sysnam, $dummy) = split /\s/;
print NEW if( !exists $delete{$sysnam} );
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $namedfwd );

# Secondly the reverse mapping
# Back up older versions
&backupfile( $namedrev );
$backup = $namedrev . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $namedrev, $!\n" && link
$backup, $namedrev && return;
open NEW, ">$namedrev" || warn "Cannot creat $namedrev, $!\n" && link
$backup, $namedrev && return;

while( <ORIGINAL> ) {
if( /^;/ ) {
print NEW;
next;
}
($dummy, $dummy, $sysnam) = split /\s+/;
$sysnam =~ s/^([^\.]*).*/\1/;
print NEW if( !exists $delete{$sysnam} );
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $namedrev );
} # delnamed

# Add all hosts to newsconfig
sub	addnews
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $newsconf );
$backup = $newsconf . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $newsconf, $!\n" && link
$backup, $newsconf && return;
open NEW, ">$newsconf" || warn "Cannot creat $newsconf, $!\n" && link
$backup, $newsconf && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW <<EOF
$sysnam:news,misc,comp,eunet,hacktic,nl,nlnet,reseau,to.$sysnam/all,!general:f:$sysnam/togo
EOF
;
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $newsconf );
} # addnews

# Add all hosts to nntpconfig
sub	addnntp
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $newsnntp );
$backup = $newsnntp . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $newsnntp, $!\n" && link
$backup, $newsnntp && return;
open NEW, ">$newsnntp" || warn "Cannot creat $newsnntp, $!\n" && link
$backup, $newsnntp && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW <<EOF
$sysnam.reseau.nl        both            post
EOF
;
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $newsnntp );
} # addnntp

# Add all hosts to named
sub	addnamed
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# First the forward mapping
# Back up older versions
&backupfile( $namedfwd );
$backup = $namedfwd . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $namedfwd, $!\n" && link
$backup, $namedfwd && return;
open NEW, ">$namedfwd" || warn "Cannot creat $namedfwd, $!\n" && link
$backup, $namedfwd && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW <<EOF
$sysnam	IN	A	$add{$sysnam}
EOF
;
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $namedfwd );

# Secondly the reverse mapping
# Back up older versions
&backupfile( $namedrev );
$backup = $namedrev . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $namedrev, $!\n" && link
$backup, $namedrev && return;
open NEW, ">$namedrev" || warn "Cannot creat $namedrev, $!\n" && link
$backup, $namedrev && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
local( $hostnum, $fullname);

$fullname = $sysnam . ".reseau.nl.";
$hostnum = $add{$sysnam};
$hostnum =~ s/^.*\.([0-9]+)$/\1/;
print NEW <<EOF
$hostnum	PTR	$fullname
EOF
;
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $namedrev );
} # addnamed

sub	kicknamed
{
open PID, "/etc/named.pid";
$pid = <PID>;
kill SIGHUP, $pid;
} # kicknamed

# Delete all hosts from batchparms
sub	delbatch
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $nwsbat );
$backup = $nwsbat . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $nwsbat, $!\n" && link
$backup, $nwsbat && return;
open NEW, ">$nwsbat" || warn "Cannot creat $nwsbat, $!\n" && link
$backup, $nwsbat && return;

while( <ORIGINAL> ) {
if( /^#/ || /^\s*$/ ) {
print NEW;
next;
}
($sysnam, $dummy) = split /\s/;
print NEW if (!exists $delete{$sysnam});
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $nwsbat );
} # delbatch

# Add all hosts to batchparms
sub	addbatch
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $nwsbat );
$backup = $nwsbat . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $nwsbat, $!\n" && link
$backup, $nwsbat && return;
open NEW, ">$nwsbat" || warn "Cannot creat $nwsbat, $!\n" && link
$backup, $nwsbat && return;

while( <ORIGINAL> ) {print NEW;}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW <<EOF
$sysnam	u	100000	20	batcher
| compcun | viauux
EOF
;
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $nwsbat );
} # addbatch

# Delete all hosts from sendmail.uunames
sub	delmail
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $mailnam );
$backup = $mailnam . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $mailnam, $!\n" && link
$backup, $mailnam && return;
open NEW, ">$mailnam" || warn "Cannot creat $mailnam, $!\n" && link
$backup, $mailnam && return;

while( <ORIGINAL> ) {
if( /^#/ || /^\s*$/ ) {
print NEW;
next;
}
chomp;
print NEW if (!exists $delete{$_});
}
close ORIGINAL;
close NEW;
# Set ownership and permissions
&setperm( $backup, $mailnam );
} # delmail

# Add all hosts to sendmail.uunames
sub	addmail
{
local( $sysnam, $backup, $dummy );
local( $uid, $gid, $mode );

# Back up older versions
&backupfile( $mailnam );
$backup = $mailnam . ".o";
open ORIGINAL, "$backup" || warn "Cannot open $mailnam, $!\n" && link
$backup, $mailnam && return;
open NEW, ">$mailnam" || warn "Cannot creat $mailnam, $!\n" && link
$backup, $mailnam && return;

while( <ORIGINAL> ) {print NEW "$_\n";}
close ORIGINAL;

foreach $sysnam (keys %add) {
print NEW "$sysnam\n";
}
close NEW;
# Set ownership and permissions
&setperm( $backup, $mailnam );
} # addmail

# Delete a user from the passwd and group file
sub	deluser
{
local( $usrnam ) = @_;
local( $nwfile );

$usrnam = "uu" . $usrnam;

# from the group file
$nwfile  = $group . ".new";
open OLD, "$group" || warn "Cannot open $group, $!\n" && return;
open NEW, ">$nwfile" || warn "Cannot creat $nwfile, $!\n" && close OLD
&& return;
while( <OLD> ) {
if( /^uucp/ ) {
s/,$usrnam//;
}
print NEW;
}
close OLD;
close NEW;
rename $group, $group . ".old";
rename $nwfile, $group;
&setperm( $group . ".old", $nwfile );

# from the passwd file
$nwfile  = $passwd . ".new";
open OLD, "$passwd" || warn "Cannot open $passwd, $!\n" && return;
open NEW, ">$nwfile" || warn "Cannot creat $nwfile, $!\n" && close OLD
&& return;
while( <OLD> ) {
if( /^$usrnam/ ) {
next;
}
print NEW;
}
close OLD;
close NEW;
rename $passwd, $passwd . ".old";
rename $nwfile, $passwd;
&setperm( $passwd . ".old", $nwfile );
} # deluser

# Add a user to the passwd and group file
sub	adduser
{
local( $usrnam ) = @_;
local( $gid, $uid, $nuid, $dummy, @uids );

$usrnam = "uu" . $usrnam;

# to the group file
$nwfile  = $group . ".new";
open OLD, "$group" || warn "Cannot open $group, $!\n" && return;
open NEW, ">$nwfile" || warn "Cannot creat $nwfile, $!\n" && close OLD
&& return;
while( <OLD> ) {
if( /^uucp/ ) {
chomp;
$_ .= ",$usrnam\n";
}
print NEW;
}
close OLD;
close NEW;
rename $group, $group . ".old";
rename $nwfile, $group;
&setperm( $group . ".old", $nwfile );

# to the passwd file
# find the gid of uucp
($dummy, $dummy, $gid, $dummy) = getgrnam( "uucp" );

# find a free uid
setpwent;
while( ($dummy, $dummy, $uid, $dummy) = getpwent ) {
push @uids, $uid;
}
endpwent;
@uids = sort numeric @uids;
$uid = shift @uids;
while( $#uids ) {
$nuid = shift @uids;
if( $nuid != $uid + 1 ) {
$uid++;
last;
}
$uid = $nuid;
}

$nwfile  = $passwd . ".new";
open OLD, "$passwd" || warn "Cannot open $passwd, $!\n" && return;
open NEW, ">$nwfile" || warn "Cannot creat $nwfile, $!\n" && close OLD
&& return;
while( <OLD> ) {
print NEW;
}
close OLD;
print NEW "$usrnam:*:$uid:$gid:Dial in UUCP account for
$sysnam:/usr/spool/uucppublic:/usr/local/lib/uucp/uucico\n";
close NEW;
rename $passwd, $passwd . ".old";
rename $nwfile, $passwd;
&setperm( $passwd . ".old", $nwfile );

} # adduser

sub	numeric
{
$a <=> $b;
}
# End of program