The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

# $RCSfile: scanner,v $$Revision: 4.1 $$Date: 92/08/07 17:20:44 $

# This runs all the scan_* routines on all the machines in /etc/ghosts.
# We run this every morning at about 6 am:

#	!/bin/sh
#	cd /usr/adm/private
#	decrypt scanner | perl >scan.out 2>&1
#	mail admin <scan.out

# Note that the scan_* files should be encrypted with the key "-inquire", and
# scanner should be encrypted somehow so that people can't find that key.
# I leave it up to you to figure out how to unencrypt it before executing.

$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/ucb:.';

$| = 1;		# command buffering on stdout

print "Subject: bizarre happenings\n\n";

(chdir '/usr/adm/private') || die "Can't cd to /usr/adm/private: $!\n";

if ($#ARGV >= 0) {
    @scanlist = @ARGV;
} else {
    @scanlist = split(/[ \t\n]+/,`echo scan_*`);
}

scan: while ($scan = shift(@scanlist)) {
    print "\n********** $scan **********\n";
    $showhost++;

    $systype = 'all';

    open(ghosts, '/etc/ghosts') || die 'No /etc/ghosts file';

    $one_of_these = ":$systype:";
    if ($systype =~ s/\+/[+]/g) {
	$one_of_these =~ s/\+/:/g;
    }

    line: while (<ghosts>) {
	s/[ \t]*\n//;
	if (!$_ || /^#/) {
	    next line;
	}
	if (/^([a-zA-Z_0-9]+)=(.+)/) {
	    $name = $1; $repl = $2;
	    $repl =~ s/\+/:/g;
	    $one_of_these =~ s/:$name:/:$repl:/;
	    next line;
	}
	@gh = split;
	$host = $gh[0];
	if ($showhost) { $showhost = "$host:\t"; }
	class: while ($class = pop(gh)) {
	    if (index($one_of_these,":$class:") >=0) {
		$iter = 0;
		`exec crypt -inquire <$scan >.x 2>/dev/null`;
		unless (open(scan,'.x')) {
		    print "Can't run $scan: $!\n";
		    next scan;
		}
		$cmd = <scan>;
		unless ($cmd =~ s/#!(.*)\n/$1/) {
		    $cmd = '/usr/bin/perl';
		}
		close(scan);
		if (open(PIPE,"exec rsh $host '$cmd' <.x|")) {
		    sleep(5);
		    unlink '.x';
		    while (<PIPE>) {
			last if $iter++ > 1000;		# must be looping
			next if /^[0-9.]+u [0-9.]+s/;
			print $showhost,$_;
		    }
		    close(PIPE);
		} else {
		    print "(Can't execute rsh: $!)\n";
		}
		last class;
	    }
	}
    }
}