home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
-
- # process command line var settings
- $idle = -1;
- $dot = 60;
- $colon = 10;
- ($me = $0) =~ s%.*/%%;
- sub another { print stderr "Interrupted!\n"; exit 1;}
- $SIG{'INT'} = 'another';
-
- eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;
-
- # parse switches
- while ($ARGV[0] =~ /^-/) {
- $ARGV[0] =~ /^-a/ && ($all++,shift,next);
- $ARGV[0] =~ /^-d/ && ($debug++,shift,next);
- $ARGV[0] =~ /^-n/ && ($idle = 0,shift,next);
- $ARGV[0] =~ /^-w/ && ($window++,shift,next);
- $ARGV[0] =~ /^-l/ && ($long++,shift,next);
- $ARGV[0] =~ /^-b/ && ($broadcast++,shift,next);
- $ARGV[0] =~ /^-m/ && ($multicast++,shift,next);
- $ARGV[0] =~ /^-s/ && ($slumber++,shift,next);
- $ARGV[0] =~ /^-i/ && (shift,$idle=$ARGV[0],shift,next);
- last;
- }
-
- $hosts && $multicast++;
-
- if ($idle =~ /[:h]/) {
- $hours = $minutes = 0;
- ($hours = $idle) =~ s/[:h].*$//;
- ($minutes = $idle) =~ s/.*[:h]//;
- $idle = $hours * 60 + $minutes;
- if ($debug) { print "you said $idle m idle\n"; }
- } elsif ($idle < 0) {
- $idle = $dot;
- }
-
- $sleep = 60 unless $sleep;
- $idle = 999E10 if $all;
-
- if ( $ARGV[0] =~ /^-/ ) {
- select (stderr);
- printf "usage: %s [vars] [-b | -m] [-a] [-n] [-l] [-w] [-s] [target ...]\n",
- $me;
- printf "\t-b to broadcast to the ruserd\n";
- printf "\t-m to multicast to the ruserd\n";
- printf "\t-a for ALL, even very idle people\n";
- printf "\t-n for people active NOW short idles\n";
- printf "\t-l for LONG listing\n";
- printf "\t-w to dynamically compute WINDOW size\n";
- printf "\t-s to sleep and repeat until all targets found\n";
- printf "\tvars \$idle ($idle) and \$sleep ($sleep) can be set with var=value\n";
- printf "\t as can \$hosts, \$dot ($dot), and \$colon ($colon)\n";
- exit 1;
- }
-
- # compute width according to window size
-
- $ENV{"TERMCAP"} =~ /:co#(\d+):/ && ($cols = int($1/25));
-
- if ( $window ) {
- open(win,"(stty all > /dev/tty ) 2>&1 |") || die "can't run stty";
- while (<win>) {
- chop; split;
- $cols = int($_[7]/ 25);
- last;
- }
- close win;
- }
-
- $cols = 3 unless $cols;
-
- if ($multicast && !$hosts) {
- $machines = '/usr/adm/MACHINES';
- open machines || die "$me: can't open $machines: $!\n";
- open(saveout, ">&stdout"); # much cheaper than invoking sh
- close(stdout);
-
- while (<machines>) {
- next if /norpc/;
- chop;
- s/\s.*//;
- if (do ping($_)) { # no sh here!
- #print stderr $_, " ok\n";
- push(@hosts,$_);
- } else {
- #printf stderr "%s is down!\n", $_;
- }
- }
- open(stdout, ">&saveout");
- close machines;
- close saveout;
- $debug && print "hosts are: ", join(' ',@hosts),"\n";
- }
-
- restart:
-
- $count = $#ARGV + 1;
-
- $PIPE = "/usr/ucb/rwho";
- if ($broadcast || $multicast) {
- $PIPE = "/usr/ucb/rusers -l ";
- $multicast && $PIPE .= $hosts ? $hosts : join(' ',@hosts);
- }
- $PIPE .= "|sort|";
- $debug && printf "PIPE is %s", $PIPE;
- open PIPE || die "$me: can't popen \"$PIPE\": $!\n";
-
- PIPEline: while (<PIPE>) {
- s/-ex0//;
- $matched = 0;
- if ( $count ) {
- matchcheck: for ( $i = 0; $i < $count; $i++ ) {
- $str = $ARGV[$i];
- $matched = /$str/;
- if ( $matched ) {
- if ($debug) { printf "YES: `%s' MATCH <%s>\n", $str, $_ ; }
- last matchcheck; # break
- } else {
- if ($debug) { printf "NO: `%s' DIDN'T <%s>\n", $str, $_ ; }
- }
- }
- if ( ! $matched ) {
- next PIPEline;
- }
- }
-
- $_[5] = "";
- split;
-
- $myidle = 0;
- if ( $_[5] =~ /^[:0-9]*$/ ) {
- $hours = $minutes = 0;
- if ( $_[5] =~ /[0-9]:/ ) {
- $hours = $_[5];
- $hours =~ s/:.*$//;
- }
- $minutes = $_[5];
- $minutes =~ s/^.*://;
- $myidle = $hours * 60 + $minutes;
- }
-
- next PIPEline if $myidle > $idle;
-
- $found{$str}++ if ($slumber);
-
- if ( $long ) {
- print;
- } else {
- if ($debug) { printf "%s@%s is %d\n", $_[0],$_[1],$myidle; }
- if ($myidle < $dot && $myidle > $colon) {
- $_[1] =~ s/:/./;
- } elsif ($myidle > $dot) {
- $_[1] =~ s/:/ /;
- }
- push(users,sprintf("%-9s%15s", $_[0], $_[1]));
- }
- }
- exit if $long && ! $slumber;
-
- $rows = int(($#users+$cols) / $cols);
-
- # { printf "found %d matches\n", $#users+1; }
- # { printf "rows are %s, cols are %s\n", $rows, $cols; }
-
- if ($slumber && $restarted && $#users >= $[) {
- printf "\n%s: bingo! at %s%c\n", $me, `date`, 7;
- }
-
- for ($elt = 0; $elt < $rows * $cols; $elt++) {
- $targ = ($elt%$cols) * $rows + int(($elt/$cols));
- printf "%s ", $targ < ($#users+1) ? $users[$targ] : "";
- #if ($debug) { #printf "%d ", $targ < ($#users+1) ? $targ : -1; }
-
- print "\n" if (($elt+1) % $cols) == 0;
- }
-
- print "\n" if ($elt+1) % $cols == 0;
-
- close PIPE;
-
- if ($slumber) {
- @nargv = ();
- @users = ();
- for ($i = 0; $i < $count; $i++) {
- ! $found{$ARGV[$i]} && push(@nargv,$ARGV[$i]);
- }
- @ARGV = @nargv;
-
- if ($#ARGV >= $[) {
- exit if ($forked++ == 0 && fork);
- sleep $sleep;
- $restarted = 1;
- ($whoami = `who am i`) =~ s/.*!([^ ]*).*/$1/;
- exit if $whoami != $ENV{"USER"};
- goto restart;
- }
- }
-
-
- sub ping {
- local($host) = @_;
-
- if (fork) {
- wait;
- exit if $? & 0xff; # interrupted
- return $? == 0;
- } else {
- exec 'pong', $host, 1;
- }
- }
-