Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / perl5 / eg / g / gsh
1 #! /usr/bin/perl
2
3 # $RCSfile: gsh,v $$Revision: 4.1 $$Date: 92/08/07 17:20:20 $
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(@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);
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';
78         if (open(PIPE,"rsh $host$l$n '$cmd'$dist 2>&1|")) {     # start an rsh
79             $SIG{'INT'} = 'cont';
80             for ($iter=0; <PIPE>; $iter++) {
81                 unless ($iter) {
82                     $remainder .= "$host+"
83                         if /Connection timed out|Permission denied/;
84                 }
85                 print $showhost,$_;
86             }
87             close(PIPE);
88         } else {
89             print "(Can't execute rsh: $!)\n";
90             $SIG{'INT'} = 'cont';
91         }
92     }
93 }
94
95 unlink "/tmp/gsh$$" if $dodist;
96
97 if ($remainder) {
98     chop($remainder);
99     open(grem,">.grem") || (printf stderr "Can't make a .grem file: $!\n");
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 }