perl 3.0: (no announcement message available)
[p5sagit/p5-mst-13.2.git] / eg / g / gsh
1 #!/bin/perl
2
3 # $Header: gsh,v 3.0 89/10/18 15:14:36 lwall Locked $
4
5 # Do rsh globally--see man page
6
7 $SIG{'QUIT'} = 'quit';                  # install signal handler for SIGQUIT
8
9 sub getswitches {
10     while ($ARGV[0] =~ /^-/) {          # parse switches
11         $ARGV[0] =~ /^-h/ && ($showhost++,$silent++,shift,next);
12         $ARGV[0] =~ /^-s/ && ($silent++,shift,next);
13         $ARGV[0] =~ /^-d/ && ($dodist++,shift,next);
14         $ARGV[0] =~ /^-n/ && ($n=' -n',shift,next);
15         $ARGV[0] =~ /^-l/ && ($l=' -l ' . $ARGV[1],shift,shift,next);
16         last;
17     }
18 }
19
20 do getswitches();                       # get any switches before class
21 $systype = shift;                       # get name representing set of hosts
22 do getswitches();                       # same switches allowed after class
23
24 if ($dodist) {                          # distribute input over all rshes?
25     `cat >/tmp/gsh$$`;                  #  get input into a handy place
26     $dist = " </tmp/gsh$$";             #  each rsh takes input from there
27 }
28
29 $cmd = join(' ',@ARGV);                 # remaining args constitute the command
30 $cmd =~ s/'/'"'"'/g;                    # quote any embedded single quotes
31
32 $one_of_these = ":$systype:";           # prepare to expand "macros"
33 $one_of_these =~ s/\+/:/g;              # we hope to end up with list of
34 $one_of_these =~ s/-/:-/g;              #  colon separated attributes
35
36 @ARGV = ();
37 push(@ARGV,'.grem') if -f '.grem';
38 push(@ARGV,'.ghosts') if -f '.ghosts';
39 push(@ARGV,'/etc/ghosts');
40
41 $remainder = '';
42
43 line: while (<>) {              # for each line of ghosts
44
45     s/[ \t]*\n//;                       # trim trailing whitespace
46     if (!$_ || /^#/) {                  # skip blank line or comment
47         next line;
48     }
49
50     if (/^(\w+)=(.+)/) {                # a macro line?
51         $name = $1; $repl = $2;
52         $repl =~ s/\+/:/g;
53         $repl =~ s/-/:-/g;
54         $one_of_these =~ s/:$name:/:$repl:/;    # do expansion in "wanted" list
55         $repl =~ s/:/:-/g;
56         $one_of_these =~ s/:-$name:/:-$repl:/;
57         next line;
58     }
59
60     # we have a normal line
61
62     @attr = split(' ');                 # a list of attributes to match against
63                                         #   which we put into an array
64     $host = $attr[0];                   # the first attribute is the host name
65     if ($showhost) {
66         $showhost = "$host:\t";
67     }
68
69     $wanted = 0;
70     foreach $attr (@attr) {             # iterate over attribute array
71         $wanted++ if index($one_of_these,":$attr:") >= 0;
72         $wanted = -9999 if index($one_of_these,":-$attr:") >= 0;
73     }
74     if ($wanted > 0) {
75         print "rsh $host$l$n '$cmd'\n" unless $silent;
76         $SIG{'INT'} = 'DEFAULT';
77         if (open(pipe,"rsh $host$l$n '$cmd'$dist 2>&1|")) {     # start an rsh
78             $SIG{'INT'} = 'cont';
79             for ($iter=0; <pipe>; $iter++) {
80                 unless ($iter) {
81                     $remainder .= "$host+"
82                         if /Connection timed out|Permission denied/;
83                 }
84                 print $showhost,$_;
85             }
86             close(pipe);
87         } else {
88             print "(Can't execute rsh: $!)\n";
89             $SIG{'INT'} = 'cont';
90         }
91     }
92 }
93
94 unlink "/tmp/gsh$$" if $dodist;
95
96 if ($remainder) {
97     chop($remainder);
98     open(grem,">.grem") || (printf stderr "Can't make a .grem file: $!\n");
99     print grem 'rem=', $remainder, "\n";
100     close(grem);
101     print 'rem=', $remainder, "\n";
102 }
103
104 # here are a couple of subroutines that serve as signal handlers
105
106 sub cont {
107     print "\rContinuing...\n";
108     $remainder .= "$host+";
109 }
110
111 sub quit {
112     $| = 1;
113     print "\r";
114     $SIG{'INT'} = '';
115     kill 2, $$;
116 }