Commit | Line | Data |
378cc40b |
1 | #!/bin/perl |
2 | |
a687059c |
3 | # $Header: gsh,v 3.0 89/10/18 15:14:36 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 |
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 { |
a687059c |
88 | print "(Can't execute rsh: $!)\n"; |
378cc40b |
89 | $SIG{'INT'} = 'cont'; |
378cc40b |
90 | } |
91 | } |
92 | } |
93 | |
94 | unlink "/tmp/gsh$$" if $dodist; |
95 | |
96 | if ($remainder) { |
97 | chop($remainder); |
a687059c |
98 | open(grem,">.grem") || (printf stderr "Can't make a .grem file: $!\n"); |
378cc40b |
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 | } |