Commit | Line | Data |
---|---|---|
378cc40b LW |
1 | #!/bin/perl |
2 | ||
3 | # $Header: gsh,v 2.0 88/06/05 00:17:20 root Exp $ | |
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 | $SIG{'INT'} = 'cont'; | |
89 | print "(Can't execute rsh.)\n"; | |
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 | } |