13 ###--------------------------------------------------------------------------
16 my $dom = $Odin::MAIL_DEFDOMAIN
;
19 sub record_opt
(\
%$$) {
20 my ($r, $o, $op) = @_;
22 if ($o eq "c") { $r->{comment
} = $op->arg; }
23 elsif ($o eq "x") { $r->{expire
} = Odin
::parse_time
$op->arg; }
24 elsif ($o eq "r") { $r->{recip
} = $op->arg; }
25 else { return undef; }
29 sub gen_opt
($\
$\
%$$) {
30 my ($dom, $g, $gp, $o, $op) = @_;
33 my $a = $op->arg; next OPT
unless defined $a;
34 $$g = Odin
::get_generator_class
$dom, $a;
36 defined (my $p = $op->arg) or next OPT
;
37 if ($p =~ /^([-\w]+)=(.*)$/) { $gp->{$1} = $2; }
38 else { $op->err("invalid parameter `$p'"); }
45 my $op = Odin
::OptParse
->new(@ARGV);
46 OPT
: while (my $o = $op->get) {
48 $dom = $op->arg or next OPT
;
49 exists $Odin::MAILDOM_POLICY
{$dom} or $op->err("unknown domain `$dom'");
55 print STDERR
"usage: $Odin::PROG [-d DOMAIN] COMMAND [ARGUMENT ...]\n";
60 my $op = shift(@ARGV) // "help";
63 Usage: $Odin::PROG [-d DOMAIN] COMMAND [ARGUMENTS ...]
71 new [-GENOPTS] [-RECOPTS] RECIP
77 GENOPTS ::= [-g GENERATOR] [-p PARAM=VALUE]
78 RECOPTS ::= [-c COMMENT] [-r RECIP] [-x EXPIRES]
80 } elsif ($op eq "list") {
81 @ARGV and Odin
::fail
"usage: list";
82 for my $r (Odin
::redir_query Odin
::open_db
, $dom, $Odin::WHO
,
83 "st = 'live' AND (expire = -1 OR expire >= ?)", $Odin::NOW
) {
84 my ($lpart, $expire, $recip, $comment) = @
$r;
86 Odin
::fmt_time
$expire => 25,
87 $lpart => 24, $recip => 32, $comment => 0;
89 } elsif ($op eq "dormant") {
90 @ARGV and Odin
::fail
"usage: list";
91 for my $r (Odin
::redir_query Odin
::open_db
, $dom, $Odin::WHO
,
93 (st = 'live' AND expire <> -1 AND expire < ?))",
95 my ($lpart, $expire, $recip, $comment) = @
$r;
96 Odin
::print_columns
$lpart => 24, $recip => 32, $comment => 0;
98 } elsif ($op eq "reserved") {
99 @ARGV and Odin
::fail
"usage: reserved";
100 for my $r (Odin
::redir_query Odin
::open_db
, $dom, $Odin::WHO
,
101 "st = 'reserved' AND expire >= ?", $Odin::NOW
) {
102 my ($lpart, $expire, $recip, $comment) = @
$r;
103 Odin
::print_columns Odin
::fmt_time
$expire => 25, $lpart => 0;
105 } elsif ($op eq "new") {
106 my $op = Odin
::OptParse
->new(@ARGV);
107 my $gencls = Odin
::default_generator_class
$dom;
110 while (my $o = $op->get) {
111 gen_opt
$dom, $gencls, %gp, $o, $op
112 or record_opt
%r, $o, $op
116 if (@a) { $r{recip
} = shift @a; }
118 $op->ok or Odin
::fail
"usage: new [-GENOPTS] [-RECOPTS] RECIP";
119 my $gen = $gencls->new($dom, \
%gp);
120 my $l = Odin
::new_redir
$dom, $gen, %r;
122 } elsif ($op eq "reserve") {
123 my $op = Odin
::OptParse
->new(@ARGV);
124 my $gencls = Odin
::default_generator_class
$dom;
126 while (my $o = $op->get) {
127 gen_opt
$dom, $gencls, %gp, $o, $op
134 $n =~ /^\d+$/ or $op->err("invalid count `$n'");
137 $op->ok or Odin
::fail
"usage: reserve [-GENOPTS] N";
138 my $gen = $gencls->new($dom, \
%gp);
139 for my $l (Odin
::reserve_redir
$dom, $gen, $n) { print $l, "\n"; }
140 } elsif ($op eq "release") {
141 my $op = Odin
::OptParse
->new(@ARGV);
143 while (my $o = $op->get) {
144 if ($o eq "a") { $all = 1; }
148 !!$all == !@a or $op->bad;
149 $op->ok or Odin
::fail
"usage: release {-a | LPART ...}";
150 if ($all) { Odin
::release_all_redir
$dom; }
151 else { Odin
::release_redir
$dom, @a; }
152 } elsif ($op eq "disable") {
153 @ARGV or Odin
::fail
"usage: disable LPART ...";
154 Odin
::disable_redir
$dom, @ARGV;
155 } elsif ($op eq "set") {
156 my $op = Odin
::OptParse
->new(@ARGV);
158 while (my $o = $op->get) {
159 record_opt
%r, $o, $op
163 my $l = shift @a or $op->bad;
165 $op->ok or Odin
::fail
"usage: set [-RECOPTS] LPART";
166 Odin
::modify_redir
$dom, $l, %r;
168 Odin
::fail
"unknown operation `$op'";