return @result;
}
+sub get_highest_msgnum {
+ my $mhfolder = shift;
+ my $msgnum;
+ my $highest;
+
+ $highest = 0;
+
+ foreach $msgnum (getfiles($mhfolder)) {
+ # Look for integers.
+ if ($msgnum =~ /^[0-9]+$/) {
+ if ($msgnum > $highest) {
+ $highest = $msgnum;
+ }
+ }
+ }
+
+ return $highest + 1;
+}
+
# We want to print the name of each list that has new mail only once,
# so use this hash to store the lists that have already been printed.
# Start the list out with SPAM already in it, since we don't care when
sub store_message {
my $msg = shift;
my $mhfolder = shift;
- my $mhmsg;
my $msgnum;
+ my $try;
+ my $mhmsg;
my $status;
# We must do this even in -n mode because later steps fail without
# it. This should be harmless.
mkfolder($mhfolder);
- # XXX: Grab the 'mhpath new' algorithm and implement it
- # internally. Furthermore, use the maildir delivery algorithm
- # (though slightly different: get filename, if exists increment
- # and start over, create file, if fail bomb) to make sure we
- # really do get a new message file.
- $mhmsg = `mhpath +$mhfolder new`;
- chomp($mhmsg);
- $msgnum = basename($mhmsg);
+ $msgnum = get_highest_msgnum($mhfolder);
+ for ($try = 0; ; $try++) {
+ $msgnum++;
+ $mhmsg = "$mhfolder/$msgnum";
+
+ if (not stat($mhmsg)) {
+ if ($! == ENOENT) {
+ # Now we have a non-existent file, let's try to create
+ # it. We must create a zero-byte file first because a
+ # file my appear between our happy stat results and
+ # our later rename(2), which would clobber said file.
+ # So attempt to create a file with this name. If it
+ # succeeds, in just a bit here we'll knowingly clobber
+ # this file with the rename(2) call.
+ if (sysopen(MSG, $mhmsg, O_WRONLY | O_EXCL | O_CREAT, 0600)) {
+ close(MSG);
+ last;
+ }
+ }
+ }
+
+ # This algorithm is different from the maildir one; let's make
+ # 10 tries instead of 3.
+ if ($try == 9) {
+ errx(&EX_TEMPFAIL, "Attempted filename exists.");
+ }
+
+ # This algorithm is different; i don't think we need to sleep.
+ #sleep(2);
+ }
logsave("+$mhfolder");