home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-convex / here < prev    next >
Encoding:
Text File  |  1990-03-02  |  5.3 KB  |  213 lines

  1. #!/usr/local/bin/perl 
  2.  
  3. # process command line var settings
  4. $idle = -1;
  5. $dot = 60;
  6. $colon = 10;
  7. ($me = $0) =~ s%.*/%%;
  8. sub another { print stderr "Interrupted!\n"; exit 1;} 
  9. $SIG{'INT'} = 'another';
  10.  
  11. eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;
  12.  
  13. # parse switches
  14. while ($ARGV[0] =~ /^-/) {      
  15.     $ARGV[0] =~ /^-a/ && ($all++,shift,next);
  16.     $ARGV[0] =~ /^-d/ && ($debug++,shift,next);
  17.     $ARGV[0] =~ /^-n/ && ($idle = 0,shift,next);
  18.     $ARGV[0] =~ /^-w/ && ($window++,shift,next);
  19.     $ARGV[0] =~ /^-l/ && ($long++,shift,next);
  20.     $ARGV[0] =~ /^-b/ && ($broadcast++,shift,next);
  21.     $ARGV[0] =~ /^-m/ && ($multicast++,shift,next);
  22.     $ARGV[0] =~ /^-s/ && ($slumber++,shift,next);
  23.     $ARGV[0] =~ /^-i/ && (shift,$idle=$ARGV[0],shift,next);
  24.     last;
  25. }
  26.  
  27. $hosts && $multicast++;
  28.  
  29. if ($idle =~ /[:h]/) {
  30.         $hours = $minutes = 0;
  31.         ($hours = $idle)   =~ s/[:h].*$//;
  32.         ($minutes = $idle) =~ s/.*[:h]//;
  33.         $idle = $hours * 60 + $minutes;
  34.         if ($debug) { print "you said $idle m idle\n"; }
  35. } elsif ($idle < 0) {
  36.     $idle = $dot;
  37.  
  38. $sleep = 60 unless $sleep;
  39. $idle = 999E10 if $all;
  40.  
  41. if ( $ARGV[0] =~ /^-/ ) {
  42.     select (stderr);
  43.     printf "usage: %s [vars] [-b | -m] [-a] [-n] [-l] [-w] [-s] [target ...]\n",
  44.             $me;
  45.     printf "\t-b to broadcast to the ruserd\n";
  46.     printf "\t-m to multicast to the ruserd\n";
  47.     printf "\t-a for ALL, even very idle people\n";
  48.     printf "\t-n for people active NOW short idles\n";
  49.     printf "\t-l for LONG listing\n";
  50.     printf "\t-w to dynamically compute WINDOW size\n";
  51.     printf "\t-s to sleep and repeat until all targets found\n";
  52.     printf "\tvars \$idle ($idle) and \$sleep ($sleep) can be set with var=value\n";
  53.     printf "\t     as can \$hosts, \$dot ($dot), and \$colon ($colon)\n";
  54.     exit 1;
  55. }
  56.  
  57. # compute width according to window size
  58.  
  59. $ENV{"TERMCAP"} =~ /:co#(\d+):/ && ($cols = int($1/25));
  60.  
  61. if ( $window ) {
  62.     open(win,"(stty all > /dev/tty ) 2>&1 |") || die "can't run stty";
  63.     while (<win>) {
  64.         chop; split;
  65.         $cols = int($_[7]/ 25);
  66.         last;
  67.     } 
  68.     close win;
  69. }
  70.  
  71. $cols = 3 unless $cols;
  72.  
  73. if ($multicast && !$hosts) {
  74.     $machines = '/usr/adm/MACHINES';
  75.     open machines || die "$me: can't open $machines: $!\n";
  76.     open(saveout, ">&stdout"); # much cheaper than invoking sh
  77.     close(stdout);
  78.  
  79.     while (<machines>) {
  80.     next if /norpc/;
  81.     chop;
  82.     s/\s.*//;
  83.     if (do ping($_)) { # no sh here!
  84.         #print stderr $_, " ok\n";
  85.         push(@hosts,$_); 
  86.     } else {
  87.         #printf stderr "%s is down!\n", $_;
  88.     } 
  89.     } 
  90.     open(stdout, ">&saveout");
  91.     close machines;
  92.     close saveout;
  93.     $debug && print "hosts are: ", join(' ',@hosts),"\n";
  94.  
  95. restart:
  96.  
  97. $count = $#ARGV + 1;
  98.  
  99. $PIPE = "/usr/ucb/rwho";
  100. if ($broadcast || $multicast) {
  101.     $PIPE = "/usr/ucb/rusers -l ";
  102.     $multicast && $PIPE .= $hosts ? $hosts : join(' ',@hosts);
  103. }
  104. $PIPE .= "|sort|";
  105. $debug && printf "PIPE is %s", $PIPE;
  106. open PIPE || die "$me: can't popen \"$PIPE\": $!\n";
  107.  
  108. PIPEline: while (<PIPE>) {
  109.     s/-ex0//;
  110.     $matched = 0;
  111.     if ( $count ) {
  112.         matchcheck: for ( $i = 0; $i < $count; $i++ ) {
  113.             $str = $ARGV[$i];
  114.             $matched = /$str/;
  115.             if ( $matched ) {
  116.                 if ($debug) { printf "YES: `%s' MATCH <%s>\n", $str, $_ ; }
  117.                 last matchcheck; # break
  118.             } else { 
  119.                 if ($debug) { printf "NO: `%s' DIDN'T <%s>\n", $str, $_ ; }
  120.             }
  121.         }
  122.         if ( ! $matched ) {
  123.             next PIPEline;
  124.         }
  125.     }
  126.  
  127.     $_[5] = "";
  128.     split; 
  129.  
  130.     $myidle = 0;
  131.     if ( $_[5] =~ /^[:0-9]*$/  ) {
  132.         $hours = $minutes = 0;
  133.         if ( $_[5] =~ /[0-9]:/ ) {
  134.             $hours = $_[5];
  135.             $hours =~ s/:.*$//;
  136.         }
  137.         $minutes = $_[5];
  138.         $minutes =~ s/^.*://;
  139.         $myidle = $hours * 60 + $minutes;
  140.     } 
  141.  
  142.     next PIPEline if $myidle > $idle;
  143.  
  144.     $found{$str}++ if ($slumber);
  145.  
  146.     if ( $long ) {
  147.         print;
  148.     } else {
  149.         if ($debug) { printf "%s@%s is %d\n", $_[0],$_[1],$myidle; }
  150.         if ($myidle < $dot && $myidle > $colon) {
  151.             $_[1] =~ s/:/./;
  152.         }  elsif ($myidle > $dot) {
  153.             $_[1] =~ s/:/ /;
  154.         } 
  155.         push(users,sprintf("%-9s%15s", $_[0], $_[1]));
  156.     }
  157. }
  158. exit if $long && ! $slumber;
  159.  
  160. $rows = int(($#users+$cols) / $cols);
  161.  
  162. # { printf "found %d matches\n", $#users+1; }
  163. # { printf "rows are %s, cols are %s\n", $rows, $cols; }
  164.  
  165. if ($slumber && $restarted && $#users >= $[) {
  166.     printf "\n%s: bingo! at %s%c\n", $me, `date`, 7;
  167.  
  168. for ($elt = 0; $elt < $rows * $cols; $elt++) {
  169.     $targ =  ($elt%$cols) * $rows + int(($elt/$cols));
  170.     printf "%s ", $targ < ($#users+1) ? $users[$targ] : "";
  171.     #if ($debug) { #printf "%d ", $targ < ($#users+1) ? $targ : -1; }
  172.     
  173.     print "\n" if (($elt+1) % $cols) == 0;
  174. }
  175.  
  176. print "\n" if ($elt+1) % $cols == 0;
  177.  
  178. close PIPE;
  179.  
  180. if ($slumber) {
  181.     @nargv = ();
  182.     @users = ();
  183.     for ($i = 0; $i < $count; $i++) {
  184.         ! $found{$ARGV[$i]} && push(@nargv,$ARGV[$i]); 
  185.     } 
  186.     @ARGV = @nargv;
  187.  
  188.     if ($#ARGV >= $[) {
  189.         exit if ($forked++ == 0 && fork);
  190.         sleep $sleep;
  191.         $restarted = 1;
  192.         ($whoami = `who am i`) =~ s/.*!([^ ]*).*/$1/;
  193.         exit if $whoami != $ENV{"USER"};
  194.         goto restart;
  195.     }
  196.  
  197.  
  198. sub ping {
  199.     local($host) = @_;
  200.  
  201.     if (fork) {
  202.     wait;
  203.     exit if $? & 0xff; # interrupted  
  204.     return $? == 0;
  205.     }  else {
  206.     exec 'pong', $host, 1;
  207.     } 
  208.