#!/usr/bin/perl -w use strict; our $pgm = $0; $pgm =~ s#.*/##; our $usage = <<'END'; usage: $pgm [] update |@[domain] [] [] $pgm [] assign |@[domain] $pgm [] show } will generate more aliases $pgm [] range [-[]] } if necessary opts: -G generator/lister program -N do not generate more aliases -l.., -d.., -F.., -m.. passed to generator notes: Always use $pgm to edit the comment of a pregen alias; otherwise we may lose track of the next number alias to pregenerate and reuse numbers. must always start with #, and you will need to quote the whole comment to protect it from your shell END our $generator; our @genopts; sub fetch_list { open P, "-!", $generator, qw(list) or die $!; while (

) { my ($alias,$user); if (m/^\# user/) { next; } elsif (m/^\# reject (\S+) (\#.*)$/) { ($alias,$comment) = ($1,$2); } elsif (m/^\#/) { next; # future extension } elsif (m/^([^#: ])\: [^#]* (\#.*)$/) { ($alias,$comment) = ($1,$2); } else { die "generator output $_ ?"; } my $localpart = $alias; $localpart =~ s/\@.*//; my $row = { Alias => $alias, LocalPart => $localpart }; if ($comment =~ m/^### PREGEN ([1-9]\d{0,8})$/) { $row->{Number}= $1; } $by_localpart{$row->{LocalPart}} = $row; $by_number[$row->{Number}] = $row if defined $row->{Number}; } $?=0; $!=0; close P or die "$generator $! $?"; } sub parse_target { @ARGV or badusage "missing specification for alias to change"; my $spec = shift @ARGV; my $target; if ($spec =~ m/^(\d{1,9})$/) { $target = $by_number[$spec]; die "no alias number $target\n" unless $target; } elsif ($spec =~ m/^(.*)\@[^\@]*/) { $target = $by_localpart{$1}; die "no alias with local part \`$1'\n" unless $target; die "incorrect or unchecked domain: \`$target->{Alias}' != \`$spec'\n" unless $spec eq $target->{Alias} || $spec eq $target->{LocalPart}.'@'; } else { badusage "bad specification for alias to change"; } } sub action_update { my $target = parse_target; @ARGV or badusage "missing update info\n"; if (defined $target->{Number} && $target->{Number} == $#by_number) { generate $target->{Number}+1; } exec $generator, qw(update), $target->{Alias}, @ARGV; die "$generator: $!"; } sub action_assign { (@ARGV==2 && $ARGV[1] =~ m/^#/) or badusage "invalid arguments to assign - forgot to quote it properly?"; action_update; } (@ARGV==1 && $ARGV[0] =~ or badusage "missing assignment info (new comment)"; $ARGV[0]=~ for (;;) { last unless @ARGV; last unless $ARGV[0] =~ m/^-/; my $arg = shift @ARGV; last if $arg =~ m/^--?$/; if ($arg =~ m/^-[ldFm]/) { push @genopts, $arg; } elsif ($arg =~ m/^-G/) { $generator = $'; #'; } else { badusage "unknown option \`$arg'"; } } our $child = $pgm; $child =~ s/-pregen/; fixme fixme this should be defaulting generator @ARGV or badusage "missing action\n"; my $action = shift @ARGV; $action =~ y/-/_/; { no strict qw(refs); &{"action_$action"}; }