chiark / gitweb /
In signal handler, crash if write() fails in an unexpected way
[innduct.git] / innduct-forall
1 #!/usr/bin/perl -w
2 use strict qw(vars refs);
3 use IO::Handle;
4 our $self= 'innduct-forall';
5 our $deftable= '/etc/news/ducts.table';
6
7 our $usage=<<END;
8 usage:
9    $self [<ducts-table>] <pattern>
10 where <pattern> is a sh command and may contain
11    !site    site name
12    !fqdn    fqdn or empty string
13    !opts    innduct options
14    !duct    shorthand for !opts !site !fqdn
15    !!       single !
16 default ducts-table is $deftable
17 END
18
19
20 die "$self: bad usage\n$usage" unless
21     @ARGV>=1 && @ARGV<=2 && $ARGV[0] !~ m/^\-/;
22
23 our $table= (@ARGV>1 ? shift @ARGV : $deftable);
24 our $pattern= shift @ARGV;
25
26 our $maxexit= 0;
27
28 open T, '<', $table or die "$self: $table: $!\n";
29 while (<T>) {
30     s/^\s*//; s/\s+$//;
31     next unless m/^[^\#]/;
32     my @v= split /\s+/, $_, 3;
33     my %c;
34     foreach my $f (qw(site fqdn opts)) {
35         my $v= shift @v;
36         $v='' unless defined $v;
37         $c{$f}= $v;
38     }
39     $c{'fqdn'}= $c{'site'} if $c{'fqdn'} eq '=';
40     $c{'duct'}= "$c{opts} $c{site} $c{fqdn}";
41     $c{'!'}= '!';
42     $_= $pattern;
43     s/\!(\w+|\!)/ 
44         my $v= $c{$1};
45         die "$self: unknown substitution $1\n" unless defined $v;
46         $v;
47     /ge;
48     my $r= system $_;
49     die "$self: run command: $!\n" if $r<0;
50     warn "$self: $c{site}: wait status $r: $_\n" if $r>0;
51     $r |= 128 if $r>0 && $r<128;
52     $r>>=8 if $r>=256;
53     $maxexit=$r if $r>$maxexit;
54 }
55 die "$self: $table: read: $!\n" if T->error;
56 close T or die "$self: table: close: $!\n";
57
58 exit $maxexit;