=item B<--delay>
-Length of delay (man at for details of specification)
+Length of delay (man at for details of specification; Debian systems
+see /usr/share/doc/at/timespec)
=item B<--email>
regex to parse it:
$delay =~ m/[+-]d(?:ela?y?)?[-+]([^\@]+)/;
- $delay = $1; $delay =~ s/_/ /;
+ $delay = $1;
+ $delay =~ s/_/ /g;
+ $delay =~ s/=/:/g;
-Thus, foo-delay-now+5_min@bar.baz becomes now+5 min
+Thus, foo-delay-now+5_min@bar.baz becomes now+5 min and
+foo-del+00=30=00@bar.baz becomes 00:30:00
=item B<--list>
=head1 EXAMPLES
+The following entry in your procmailrc (or similar) will do the dirty
+work:
+
+ :0 Hhbw
+ * !Message-Id: .*delay[0-9]+@
+ * ^TO \/you\+de[^@]+
+ |delay_mail --mailto you@foo.com --enqueue --email --delay $MATCH
+
+ delay_mail --list;
+
+and
+
+ atq;
+
+will tell you that things are queued up and ready to go.
+
+You can then bounce messages that you want to deal with later to
+you+delay+10=30am_tomorrow@foo.com or similar, and you'll receive the
+message again at 10:30 AM tomorrow to deal with.
=cut
GetOptions(\%options,'debug|d+','help|h|?','man|m',
'list|l','dequeue=s','process|p=s','enqueue|e',
+ 'queue=s',
'delay|D=s','email|E',
'mailto|mail-to|M=s',
);
$delay =~ s/\n//g;
if ($options{email}) {
$delay =~ m/[+-]d(?:ela?y?)?[-+]([^\@]+)/;
- $delay = $1; $delay =~ s/_/ /;
+ $delay = $1;
+ $delay =~ s/_/ /g;
+ $delay =~ s/=/:/g;
}
# slurp email
local $/;
my ($subject) = $email =~ /^Subject:\s*(.+)/mi;
$subject = decode_rfc1522($subject);
$subject =~ s/\n//g;
+ my $time = time;
# create a queue entry
- my $queue_fn = time . $$;
+ my $queue_fn = $time . $$;
my $q_fh = IO::File->new("$options{queue}/$queue_fn",'w') or
die "Unable to open $options{queue}/$queue_fn for writing";
print {$q_fh} "delay: $delay\n";
+ print {$q_fh} "time: $time\n";
print {$q_fh} "mailto: $options{mailto}\n";
print {$q_fh} "entry: $queue_fn\n";
print {$q_fh} "subject: $subject\n";
print {$q_fh} "#####\n";
print {$q_fh} $email;
my $at_fh;
- open($at_fh,'|-','at',$delay) or exit 1;
+ my $pid = open($at_fh,'|-','at',$delay) or exit 1;
print {$at_fh} "$0 '--queue' '$options{queue}' '--process' '$queue_fn';\n";
- close $at_fh;
- waitpid(-1,0);
- exit $?;
+ close $at_fh or exit $?;
+ exit 0;
}
elsif ($options{list}) {
my $dir = IO::Dir->new($options{queue}) or
push @queue,parse_queue_entry($entry);
}
for my $q_e (@queue) {
- print "$q_e->{entry}: send $q_e->{subject} to $q_e->{mailto} at $q_e->{delay}\n";
+ $q_e->{time} ||='';
+ print "$q_e->{entry}: send $q_e->{subject} to $q_e->{mailto} at $q_e->{delay} ($q_e->{time})\n";
}
}
elsif ($options{dequeue}) {
}
}
elsif ($options{process}) {
- my $q_e;
if (-e "$options{queue}/$options{process}") {
my $q_e = parse_queue_entry($options{process});
if (not defined $q_e) {
die "Unable to parse $options{process}";
}
# munge the message id
- my ($message_id) = $q_e->{email} =~ m/^Message-Id:\s*(.+)/;
+ my ($message_id) = $q_e->{email} =~ m/^Message-Id:\s*(.+)/mi;
if (not $message_id =~ s/\@/delay$q_e->{entry}@/){
$message_id =~ s/(\w)/delay$q_e->{entry}$1/;
}
- $q_e->{email} =~ s/^(Message-Id:\s*)(.+)/$1$message_id/;
+ $q_e->{email} =~ s/^(Message-Id:\s*)(.+)/$1$message_id/mi;
# send the message
my $sendmail_fh;
open($sendmail_fh,'|-','/usr/sbin/sendmail',$q_e->{mailto}) or
die "Unable to open sendmail to send message";
print {$sendmail_fh} $q_e->{email};
- close($sendmail_fh);
- waitpid(-1,0);
- if ($?) {
- print STDERR "Sendmail failed with $?\n";
- exit $?;
- }
+ close($sendmail_fh) or
+ print STDERR "Sendmail failed with $?\n" and
+ exit $?;
unlink("$options{queue}/$options{process}");
}
else {