]> diplodocus.org Git - minc/commitdiff
(get_new_msgnum): New function, loops across the list returned by
authorepg <>
Fri, 30 Aug 2002 07:33:07 +0000 (07:33 +0000)
committerepg <>
Fri, 30 Aug 2002 07:33:07 +0000 (07:33 +0000)
getfiles and returns the number for a new message to go into an mh
folder.  This is a replacement for the command 'mhpath new'.

(store_message): Address the XXX comment about using 'mhpath new' by
not using it, instead calling get_new_msgnum.  Furthermore, use an
algorithm similar to the maildir delivery algorithm to get the
filename to rename to.

minc

diff --git a/minc b/minc
index 36bf78e..ebe447f 100755 (executable)
--- a/minc
+++ b/minc
@@ -293,6 +293,25 @@ sub getfiles {
     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
@@ -302,22 +321,45 @@ my %FOLDERS = ('SPAM'=>1);
 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");