chiark / gitweb /
Add innduct-forall
authorIan Jackson <ian@chiark.greenend.org.uk>
Mon, 28 Jun 2010 12:45:34 +0000 (13:45 +0100)
committerIan Jackson <ian@chiark.greenend.org.uk>
Mon, 28 Jun 2010 12:45:34 +0000 (13:45 +0100)
Makefile.am
Makefile.in
innduct-forall [new file with mode: 0755]

index 1e91beab3c5cb51be072264ee4607a0a02d0e9a2..124e9c1f692b4dd0f6abf4f485dbb68491450935 100644 (file)
@@ -40,7 +40,7 @@ WARNINGS= \
 CFLAGS = @CFLAGS@ $(WARNINGS) $(WERROR) $(CMDLINE_CFLAGS)
 
 bin_PROGRAMS = innduct
-bin_SCRIPTS = innduct-stats-report
+bin_SCRIPTS = innduct-stats-report innduct-forall
 man_MANS = innduct.8 innduct-stats-report.8
 innduct_SOURCES = duct.c conn.c filemon.c infile.c recv.c xmit.c \
                cli.c defer.c help.c statemc.c __oop-read-copy.c
index 6340dc6f5544eadb47327c6ec23830bdef94873a..f61647fc9a87592c17eb9ffde806a391c38fe445 100644 (file)
@@ -104,7 +104,7 @@ WARNINGS =          -Wall -Wformat=2 -Wno-format-zero-length        -Wshadow -Wpointer-arith
 CFLAGS = @CFLAGS@ $(WARNINGS) $(WERROR) $(CMDLINE_CFLAGS)
 
 bin_PROGRAMS = innduct
-bin_SCRIPTS = innduct-stats-report
+bin_SCRIPTS = innduct-stats-report innduct-forall
 man_MANS = innduct.8 innduct-stats-report.8
 innduct_SOURCES = duct.c conn.c filemon.c infile.c recv.c xmit.c               cli.c defer.c help.c statemc.c __oop-read-copy.c
 
diff --git a/innduct-forall b/innduct-forall
new file mode 100755 (executable)
index 0000000..e26aab5
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/perl -w
+use strict qw(vars refs);
+use IO::Handle;
+our $self= 'innduct-forall';
+our $deftable= '/etc/news/ducts.table';
+
+our $usage=<<END;
+usage:
+   $self [<ducts-table>] <pattern>
+where <pattern> is a sh command and may contain
+   !site    site name
+   !fqdn    fqdn or empty string
+   !opts    innduct options
+   !duct    shorthand for !opts !site !fqdn
+   !!       single !
+default ducts-table is $deftable
+END
+
+
+die "$self: bad usage\n$usage" unless
+    @ARGV>=1 && @ARGV<=2 && $ARGV[0] !~ m/^\-/;
+
+our $table= (@ARGV>1 ? shift @ARGV : $deftable);
+our $pattern= shift @ARGV;
+
+our $maxexit= 0;
+
+open T, '<', $table or die "$self: $table: $!\n";
+while (<T>) {
+    s/^\s*//; s/\s+$//;
+    next unless m/^[^\#]/;
+    my @v= split /\s+/, $_, 3;
+    my %c;
+    foreach my $f (qw(site fqdn opts)) {
+       my $v= shift @v;
+       $v='' unless defined $v;
+       $c{$f}= $v;
+    }
+    $c{'fqdn'}= $c{'site'} if $c{'fqdn'} eq '=';
+    $c{'duct'}= "$c{opts} $c{site} $c{fqdn}";
+    $c{'!'}= '!';
+    $_= $pattern;
+    s/\!(\w+|\!)/ 
+        my $v= $c{$1};
+        die "$self: unknown substitution $1\n" unless defined $v;
+        $v;
+    /ge;
+    my $r= system $_;
+    die "$self: run command: $!\n" if $r<0;
+    warn "$self: $c{site}: wait status $r: $_\n" if $r>0;
+    $r |= 128 if $r>0 && $r<128;
+    $r>>=8 if $r>=256;
+    $maxexit=$r if $r>$maxexit;
+}
+die "$self: $table: read: $!\n" if T->error;
+close T or die "$self: table: close: $!\n";
+
+exit $maxexit;