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