#!/afs/sipb/project/perldev/p -w

use FileHandle;
use strict;

autoflush STDERR 1;

use vars qw( @PING @HES );
@PING = qw( NO_PING PINGS  );
@HES  = qw( NO_HES  HESIOD );

use vars qw( $subnet $hosts $debug $status $max_children );
$debug = 1;
$status = 1;

$max_children = 64;

$subnet = @ARGV ? shift(@ARGV) : '18.177';
$subnet .= '.' unless $subnet =~ /\.$/;

$hosts = @ARGV ? shift(@ARGV) : '/afs/net/admin/hosts/hosts';

print STDERR "making a list of hosts...\n" if $status;
use vars qw( $H @hostlist $host );

$H = new FileHandle $hosts, 'r';
while (<$H>) {
  next unless /^\Q$subnet\E/;
  $host = (split(/\s+/))[1];
  $host =~ s/\Q.mit.edu\E$//i;
  push @hostlist, $host;
}


print STDERR "looking up Hesiod data...\n" if $status;
use vars qw( %pidmap $queue $pid );
use vars qw( %hesiod );

%pidmap = ();
$queue = 0;
while (($queue <= $#hostlist) && ($queue < $max_children)) {
  print STDERR 'H' if $status;
  $pidmap{run('hesinfo', $hostlist[$queue], 'cluster')} = $hostlist[$queue];
  $queue++;
}
while (($pid = wait) >= 0) {
  print STDERR 'h' if $status;
  die "unknown pid $pid" unless exists $pidmap{$pid};
  $hesiod{$pidmap{$pid}} = ($? == 0);
  delete $pidmap{$pid};

  if ($queue <= $#hostlist) {
    print STDERR 'H' if $status;
    $pidmap{run('hesinfo', $hostlist[$queue], 'cluster')} = $hostlist[$queue];
    $queue++;
  }
}
print STDERR "\n" if $status;
warn "unclaimed PIDs @{[keys %pidmap]}" if %pidmap;


print STDERR "checking pings...\n" if $status;
use vars qw( %pings );

%pidmap = ();
$queue = 0;
while (($queue <= $#hostlist) && ($queue < $max_children)) {
  print STDERR 'P' if $status;
  $pidmap{run('ping', $hostlist[$queue])} = $hostlist[$queue];
  $queue++;
}
while (($pid = wait) >= 0) {
  print STDERR 'p' if $status;
  die "unknown pid $pid" unless exists $pidmap{$pid};
  $pings{$pidmap{$pid}} = ($? == 0);
  delete $pidmap{$pid};

  if ($queue <= $#hostlist) {
    print STDERR 'P' if $status;
    $pidmap{run('ping', $hostlist[$queue])} = $hostlist[$queue];
    $queue++;
  }
}
print STDERR "\n" if $status;
warn "unclaimed PIDs @{[keys %pidmap]}" if %pidmap;


print STDERR "writing data...\n" if $status;

foreach $host (@hostlist) {
  printf "%-7s %-7s %s\n", $PING[$pings{$host}], $HES[$hesiod{$host}], $host;
}

sub run {
  my @cmd = @_;
  my $pid = fork;
  die "fork: $!" unless defined $pid;
  return $pid if $pid;
  open(STDIN,   "/dev/null");
  open(STDOUT, ">/dev/null");
  open(STDERR, ">/dev/null");
  exec @cmd;
  die "exec(@cmd): $!";
}
