diff options
Diffstat (limited to 'contrib/perl5/eg/g')
-rw-r--r-- | contrib/perl5/eg/g/gcp | 114 | ||||
-rw-r--r-- | contrib/perl5/eg/g/gcp.man | 77 | ||||
-rw-r--r-- | contrib/perl5/eg/g/ged | 21 | ||||
-rw-r--r-- | contrib/perl5/eg/g/ghosts | 33 | ||||
-rw-r--r-- | contrib/perl5/eg/g/gsh | 117 | ||||
-rw-r--r-- | contrib/perl5/eg/g/gsh.man | 80 |
6 files changed, 442 insertions, 0 deletions
diff --git a/contrib/perl5/eg/g/gcp b/contrib/perl5/eg/g/gcp new file mode 100644 index 0000000..d18b6f6 --- /dev/null +++ b/contrib/perl5/eg/g/gcp @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +# $RCSfile: gcp,v $$Revision: 4.1 $$Date: 92/08/07 17:20:15 $ + +# Here is a script to do global rcps. See man page. + +$#ARGV >= 1 || die "Not enough arguments.\n"; + +if ($ARGV[0] eq '-r') { + $rcp = 'rcp -r'; + shift; +} else { + $rcp = 'rcp'; +} +$args = $rcp; +$dest = $ARGV[$#ARGV]; + +$SIG{'QUIT'} = 'CLEANUP'; +$SIG{'INT'} = 'CONT'; + +while ($arg = shift) { + if ($arg =~ /^([-a-zA-Z0-9_+]+):/) { + if ($systype && $systype ne $1) { + die "Can't mix system type specifers ($systype vs $1).\n"; + } + $#ARGV < 0 || $arg !~ /:$/ || die "No source file specified.\n"; + $systype = $1; + $args .= " $arg"; + } else { + if ($#ARGV >= 0) { + if ($arg =~ /^[\/~]/) { + $arg =~ /^(.*)\// && ($dir = $1); + } else { + if (!$pwd) { + chop($pwd = `pwd`); + } + $dir = $pwd; + } + } + if ($olddir && $dir ne $olddir && $dest =~ /:$/) { + $args .= " $dest$olddir; $rcp"; + } + $olddir = $dir; + $args .= " $arg"; + } +} + +die "No system type specified.\n" unless $systype; + +$args =~ s/:$/:$olddir/; + +chop($thishost = `hostname`); + +$one_of_these = ":$systype:"; +if ($systype =~ s/\+/[+]/g) { + $one_of_these =~ s/\+/:/g; +} +$one_of_these =~ s/-/:-/g; + +@ARGV = (); +push(@ARGV,'.grem') if -f '.grem'; +push(@ARGV,'.ghosts') if -f '.ghosts'; +push(@ARGV,'/etc/ghosts'); + +$remainder = ''; + +line: while (<>) { + s/[ \t]*\n//; + if (!$_ || /^#/) { + next line; + } + if (/^([a-zA-Z_0-9]+)=(.+)/) { + $name = $1; $repl = $2; + $repl =~ s/\+/:/g; + $repl =~ s/-/:-/g; + $one_of_these =~ s/:$name:/:$repl:/; + $repl =~ s/:/:-/g; + $one_of_these =~ s/:-$name:/:-$repl:/g; + next line; + } + @gh = split(' '); + $host = $gh[0]; + next line if $host eq $thishost; # should handle aliases too + $wanted = 0; + foreach $class (@gh) { + $wanted++ if index($one_of_these,":$class:") >= 0; + $wanted = -9999 if index($one_of_these,":-$class:") >= 0; + } + if ($wanted > 0) { + ($cmd = $args) =~ s/[ \t]$systype:/ $host:/g; + print "$cmd\n"; + $result = `$cmd 2>&1`; + $remainder .= "$host+" if + $result =~ /Connection timed out|Permission denied/; + print $result; + } +} + +if ($remainder) { + chop($remainder); + open(grem,">.grem") || (printf stderr "Can't create .grem: $!\n"); + print grem 'rem=', $remainder, "\n"; + close(grem); + print 'rem=', $remainder, "\n"; +} + +sub CLEANUP { + exit; +} + +sub CONT { + print "Continuing...\n"; # Just ignore the signal that kills rcp + $remainder .= "$host+"; +} diff --git a/contrib/perl5/eg/g/gcp.man b/contrib/perl5/eg/g/gcp.man new file mode 100644 index 0000000..1198554 --- /dev/null +++ b/contrib/perl5/eg/g/gcp.man @@ -0,0 +1,77 @@ +.\" $RCSfile: gcp.man,v $$Revision: 4.1 $$Date: 92/08/07 17:20:17 $ +.TH GCP 1C "13 May 1988" +.SH NAME +gcp \- global file copy +.SH SYNOPSIS +.B gcp +file1 file2 +.br +.B gcp +[ +.B \-r +] file ... directory +.SH DESCRIPTION +.I gcp +works just like rcp(1C) except that you may specify a set of hosts to copy files +from or to. +The host sets are defined in the file /etc/ghosts. +(An individual host name can be used as a set containing one member.) +You can give a command like + + gcp /etc/motd sun: + +to copy your /etc/motd file to /etc/motd on all the Suns. +If, on the other hand, you say + + gcp /a/foo /b/bar sun:/tmp + +then your files will be copied to /tmp on all the Suns. +The general rule is that if you don't specify the destination directory, +files go to the same directory they are in currently. +.P +You may specify the union of two or more sets by using + as follows: + + gcp /a/foo /b/bar 750+mc: + +which will copy /a/foo to /a/foo on all 750's and Masscomps, and then copy +/b/bar to /b/bar on all 750's and Masscomps. +.P +Commonly used sets should be defined in /etc/ghosts. +For example, you could add a line that says + + pep=manny+moe+jack + +Another way to do that would be to add the word "pep" after each of the host +entries: + + manny sun3 pep +.br + moe sun3 pep +.br + jack sun3 pep + +Hosts and sets of host can also be excluded: + + foo=sun-sun2 + +Any host so excluded will never be included, even if a subsequent set on the +line includes it: + + foo=abc+def +.br + bar=xyz-abc+foo + +comes out to xyz+def. + +You can define private host sets by creating .ghosts in your current directory +with entries just like /etc/ghosts. +Also, if there is a file .grem, it defines "rem" to be the remaining hosts +from the last gsh or gcp that didn't succeed everywhere. +.PP +Interrupting with a SIGINT will cause the rcp to the current host to be skipped +and execution resumed with the next host. +To stop completely, send a SIGQUIT. +.SH SEE ALSO +rcp(1C) +.SH BUGS +All the bugs of rcp, since it calls rcp. diff --git a/contrib/perl5/eg/g/ged b/contrib/perl5/eg/g/ged new file mode 100644 index 0000000..07ac88f --- /dev/null +++ b/contrib/perl5/eg/g/ged @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +# $RCSfile: ged,v $$Revision: 4.1 $$Date: 92/08/07 17:20:18 $ + +# Does inplace edits on a set of files on a set of machines. +# +# Typical invokation: +# +# ged vax+sun /etc/passwd +# s/Freddy/Freddie/; +# ^D +# + +$class = shift; +$files = join(' ',@ARGV); + +die "Usage: ged class files <perlcmds\n" unless $files; + +exec "gsh", $class, "-d", "perl -pi.bak - $files"; + +die "Couldn't execute gsh for some reason, stopped"; diff --git a/contrib/perl5/eg/g/ghosts b/contrib/perl5/eg/g/ghosts new file mode 100644 index 0000000..96ec771 --- /dev/null +++ b/contrib/perl5/eg/g/ghosts @@ -0,0 +1,33 @@ +# This first section gives alternate sets defined in terms of the sets given +# by the second section. The order is important--all references must be +# forward references. + +Nnd=sun-nd +all=sun+mc+vax +baseline=sun+mc +sun=sun2+sun3 +vax=750+8600 +pep=manny+moe+jack + +# This second section defines the basic sets. Each host should have a line +# that specifies which sets it is a member of. Extra sets should be separated +# by white space. (The first section isn't strictly necessary, since all sets +# could be defined in the second section, but then it wouldn't be so readable.) + +basvax 8600 src +cdb0 sun3 sys +cdb1 sun3 sys +cdb2 sun3 sys +chief sun3 src +tis0 sun3 +manny sun3 sys +moe sun3 sys +jack sun3 sys +disney sun3 sys +huey sun3 nd +dewey sun3 nd +louie sun3 nd +bizet sun2 src sys +gif0 mc src +mc0 mc +dtv0 mc diff --git a/contrib/perl5/eg/g/gsh b/contrib/perl5/eg/g/gsh new file mode 100644 index 0000000..4bc5d87 --- /dev/null +++ b/contrib/perl5/eg/g/gsh @@ -0,0 +1,117 @@ +#! /usr/bin/perl + +# $RCSfile: gsh,v $$Revision: 4.1 $$Date: 92/08/07 17:20:20 $ + +# Do rsh globally--see man page + +$SIG{'QUIT'} = 'quit'; # install signal handler for SIGQUIT + +sub getswitches { + while ($ARGV[0] =~ /^-/) { # parse switches + $ARGV[0] =~ /^-h/ && ($showhost++,$silent++,shift(@ARGV),next); + $ARGV[0] =~ /^-s/ && ($silent++,shift(@ARGV),next); + $ARGV[0] =~ /^-d/ && ($dodist++,shift(@ARGV),next); + $ARGV[0] =~ /^-n/ && ($n=' -n',shift(@ARGV),next); + $ARGV[0] =~ /^-l/ && ($l=' -l ' . $ARGV[1],shift(@ARGV),shift(@ARGV), + next); + last; + } +} + +do getswitches(); # get any switches before class +$systype = shift; # get name representing set of hosts +do getswitches(); # same switches allowed after class + +if ($dodist) { # distribute input over all rshes? + `cat >/tmp/gsh$$`; # get input into a handy place + $dist = " </tmp/gsh$$"; # each rsh takes input from there +} + +$cmd = join(' ',@ARGV); # remaining args constitute the command +$cmd =~ s/'/'"'"'/g; # quote any embedded single quotes + +$one_of_these = ":$systype:"; # prepare to expand "macros" +$one_of_these =~ s/\+/:/g; # we hope to end up with list of +$one_of_these =~ s/-/:-/g; # colon separated attributes + +@ARGV = (); +push(@ARGV,'.grem') if -f '.grem'; +push(@ARGV,'.ghosts') if -f '.ghosts'; +push(@ARGV,'/etc/ghosts'); + +$remainder = ''; + +line: while (<>) { # for each line of ghosts + + s/[ \t]*\n//; # trim trailing whitespace + if (!$_ || /^#/) { # skip blank line or comment + next line; + } + + if (/^(\w+)=(.+)/) { # a macro line? + $name = $1; $repl = $2; + $repl =~ s/\+/:/g; + $repl =~ s/-/:-/g; + $one_of_these =~ s/:$name:/:$repl:/; # do expansion in "wanted" list + $repl =~ s/:/:-/g; + $one_of_these =~ s/:-$name:/:-$repl:/; + next line; + } + + # we have a normal line + + @attr = split(' '); # a list of attributes to match against + # which we put into an array + $host = $attr[0]; # the first attribute is the host name + if ($showhost) { + $showhost = "$host:\t"; + } + + $wanted = 0; + foreach $attr (@attr) { # iterate over attribute array + $wanted++ if index($one_of_these,":$attr:") >= 0; + $wanted = -9999 if index($one_of_these,":-$attr:") >= 0; + } + if ($wanted > 0) { + print "rsh $host$l$n '$cmd'\n" unless $silent; + $SIG{'INT'} = 'DEFAULT'; + if (open(PIPE,"rsh $host$l$n '$cmd'$dist 2>&1|")) { # start an rsh + $SIG{'INT'} = 'cont'; + for ($iter=0; <PIPE>; $iter++) { + unless ($iter) { + $remainder .= "$host+" + if /Connection timed out|Permission denied/; + } + print $showhost,$_; + } + close(PIPE); + } else { + print "(Can't execute rsh: $!)\n"; + $SIG{'INT'} = 'cont'; + } + } +} + +unlink "/tmp/gsh$$" if $dodist; + +if ($remainder) { + chop($remainder); + open(grem,">.grem") || (printf stderr "Can't make a .grem file: $!\n"); + print grem 'rem=', $remainder, "\n"; + close(grem); + print 'rem=', $remainder, "\n"; +} + +# here are a couple of subroutines that serve as signal handlers + +sub cont { + print "\rContinuing...\n"; + $remainder .= "$host+"; +} + +sub quit { + $| = 1; + print "\r"; + $SIG{'INT'} = ''; + kill 2, $$; +} diff --git a/contrib/perl5/eg/g/gsh.man b/contrib/perl5/eg/g/gsh.man new file mode 100644 index 0000000..2958707 --- /dev/null +++ b/contrib/perl5/eg/g/gsh.man @@ -0,0 +1,80 @@ +.\" $RCSfile: gsh.man,v $$Revision: 4.1 $$Date: 92/08/07 17:20:22 $ +.TH GSH 8 "13 May 1988" +.SH NAME +gsh \- global shell +.SH SYNOPSIS +.B gsh +[options] +.I host +[options] +.I command +.SH DESCRIPTION +.I gsh +works just like rsh(1C) except that you may specify a set of hosts to execute +the command on. +The host sets are defined in the file /etc/ghosts. +(An individual host name can be used as a set containing one member.) +You can give a command like + + gsh sun /etc/mungmotd + +to run /etc/mungmotd on all your Suns. +.P +You may specify the union of two or more sets by using + as follows: + + gsh 750+mc /etc/mungmotd + +which will run mungmotd on all 750's and Masscomps. +.P +Commonly used sets should be defined in /etc/ghosts. +For example, you could add a line that says + + pep=manny+moe+jack + +Another way to do that would be to add the word "pep" after each of the host +entries: + + manny sun3 pep +.br + moe sun3 pep +.br + jack sun3 pep + +Hosts and sets of host can also be excluded: + + foo=sun-sun2 + +Any host so excluded will never be included, even if a subsequent set on the +line includes it: + + foo=abc+def + bar=xyz-abc+foo + +comes out to xyz+def. + +You can define private host sets by creating .ghosts in your current directory +with entries just like /etc/ghosts. +Also, if there is a file .grem, it defines "rem" to be the remaining hosts +from the last gsh or gcp that didn't succeed everywhere. + +Options include all those defined by rsh, as well as + +.IP "\-d" 8 +Causes gsh to collect input till end of file, and then distribute that input +to each invokation of rsh. +.IP "\-h" 8 +Rather than print out the command followed by the output, merely prepends the +host name to each line of output. +.IP "\-s" 8 +Do work silently. +.PP +Interrupting with a SIGINT will cause the rsh to the current host to be skipped +and execution resumed with the next host. +To stop completely, send a SIGQUIT. +.SH SEE ALSO +rsh(1C) +.SH BUGS +All the bugs of rsh, since it calls rsh. + +Also, will not properly return data from the remote execution that contains +null characters. |