Mozilla 1.6 patch for movemail

Joe Marcus Clarke marcus at marcuscom.com
Sat Mar 27 22:51:47 PST 2004


On Fri, 2004-03-26 at 10:53, Archie Cobbs wrote:
> Hi,
> 
> Not sure if this is useful, but here is a patch I'm using to make
> the Mozilla movemail service use BSD flock() style locking for the mail
> spool file instead of /var/mail/user.lock.
> 
> This patch is agains the www/mozilla port. Haven't investigated
> whether www/mozilla-devel has already addressed this problem.

Doesn't look like they have.  nsMovemailService.cpp hasn't been touched
since early February.  Can you submit this patch to Mozilla's Bugzilla
database?  It seems to me that since movemail support only exists for
UNIX that this style of locking would be preferred to be compatible with
more MUAs.

Joe

> 
> Cheers,
> -Archie
> 
> __________________________________________________________________________
> Archie Cobbs      *        CTO, Awarix        *      http://www.awarix.com
> 
> --- mailnews/local/src/nsMovemailService.cpp.orig	Fri Mar 26 09:32:09 2004
> +++ mailnews/local/src/nsMovemailService.cpp	Fri Mar 26 09:40:43 2004
> @@ -42,6 +42,7 @@
>  #endif
>  
>  #include <unistd.h>    // for link(), used in spool-file locking
> +#include <fcntl.h>     // for open(), used in spool-file locking
>  
>  #include "prenv.h"
>  #include "nspr.h"
> @@ -149,145 +150,17 @@
>  }
>  
> 
> -PRBool ObtainSpoolLock(const char *spoolnameStr,
> +int ObtainSpoolLock(const char *spoolnameStr,
>                         int seconds /* number of seconds to retry */)
>  {
> -    // How to lock:
> -    // step 1: create SPOOLNAME.mozlock
> -    //        1a: can remove it if it already exists (probably crash-droppings)
> -    // step 2: hard-link SPOOLNAME.mozlock to SPOOLNAME.lock for NFS atomicity
> -    //        2a: if SPOOLNAME.lock is >60sec old then nuke it from orbit
> -    //        2b: repeat step 2 until retry-count expired or hard-link succeeds
> -    // step 3: remove SPOOLNAME.mozlock
> -    // step 4: If step 2 hard-link failed, fail hard; we do not hold the lock
> -    // DONE.
> -    //
> -    // (step 2a not yet implemented)
> -    
> -    nsCAutoString mozlockstr(spoolnameStr);
> -    mozlockstr.Append(".mozlock");
> -    nsCAutoString lockstr(spoolnameStr);
> -    lockstr.Append(".lock");
> -
> -    nsresult rv;
> -
> -    // Create nsFileSpec and nsILocalFile for the spool.mozlock file
> -    nsFileSpec tmplocspec(mozlockstr.get());
> -    nsCOMPtr<nsILocalFile> tmplocfile;
> -    rv = NS_FileSpecToIFile(&tmplocspec, getter_AddRefs(tmplocfile));
> -    if (NS_FAILED(rv))
> -        return PR_FALSE;
> -    // THOUGHT: hmm, perhaps use MakeUnique to generate us a unique mozlock?
> -    // ... perhaps not, MakeUnique implementation looks racey -- use mktemp()?
> -
> -    // step 1: create SPOOLNAME.mozlock
> -#ifdef MOVEMAIL_DEBUG
> -    fprintf(stderr, "\n ...... maker(%s) ......\n",
> -            mozlockstr.get());
> -#endif
> -    rv = tmplocfile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
> -    if ( (NS_FAILED(rv) &&
> -          rv != NS_ERROR_FILE_ALREADY_EXISTS) ||
> -         !tmplocfile) {
> -        // can't create our .mozlock file... game over already
> -#ifdef MOVEMAIL_DEBUG
> -        fprintf(stderr, "\n cannot create blah.mozlock file! \n");
> -#endif
> -        return PR_FALSE;
> -    }
> -
> -    // step 2: hard-link .mozlock file to .lock file (this wackiness
> -    //         is necessary for non-racey locking on NFS-mounted spool dirs)
> -    // n.b. XPCOM utilities don't support hard-linking yet, so we
> -    // skip out to <unistd.h> and the POSIX interface for link()
> -    int link_result = 0;
> -    int retry_count = 0;
> -    
> -    do {
> -        link_result =
> -            link(mozlockstr.get(),lockstr.get());
> -
> -        retry_count++;
> -
> -#ifdef MOVEMAIL_DEBUG
> -        fprintf(stderr, "[try#%d] ", retry_count);
> -#endif
> -
> -        if ((seconds > 0) &&
> -            (link_result == -1)) {
> -            // pause 1sec, waiting for .lock to go away
> -            PRIntervalTime sleepTime = 1000; // 1 second
> -            PR_Sleep(sleepTime);
> -        }
> -    } while ((link_result == -1) && (retry_count < seconds));
> -#ifdef MOVEMAIL_DEBUG
> -    fprintf(stderr, "<<link result: %d>>", link_result);
> -#endif
> -
> -    // step 3: remove .mozlock file, in any case
> -    rv = tmplocfile->Remove(PR_FALSE /* non-recursive */);
> -#ifdef MOVEMAIL_DEBUG
> -    if (NS_FAILED(rv)) {
> -        // Could not delete our .mozlock file... very unusual, but
> -        // not fatal.
> -        fprintf(stderr,
> -                "\nBizarre, could not delete our .mozlock file.  Oh well.\n");
> -    }
> -#endif
> -
> -#ifdef MOVEMAIL_DEBUG
> -    fprintf(stderr, "::got to the end! %s\n",
> -            (link_result == 0) ? "GOT LOCK" : "DID NOT GET LOCK");
> -#endif
> -
> -    // step 4: now we know whether we succeeded or failed
> -    if (link_result == 0)
> -        return PR_TRUE; // got the lock.
> -    else
> -        return PR_FALSE; // didn't.  :(
> +    return open(spoolnameStr, O_RDWR|O_CREAT|O_EXLOCK, 0600);
>  }
>  
> 
> -// Remove our mail-spool-file lock (n.b. we should only try this if
> -// we're the ones who made the lock in the first place!)
> -PRBool YieldSpoolLock(const char *spoolnameStr)
> +void YieldSpoolLock(int fd)
>  {
> -#ifdef MOVEMAIL_DEBUG
> -    fprintf(stderr, "<<Attempting lockfile removal: %s.lock>>",
> -            spoolnameStr);
> -#endif
> -
> -    nsCAutoString lockstr(spoolnameStr);
> -    lockstr.Append(".lock");
> -
> -    nsresult rv;
> -
> -    // Create nsFileSpec and nsILocalFile for the spool.lock file
> -    nsFileSpec locklocspec(lockstr.get());
> -    nsCOMPtr<nsILocalFile> locklocfile;
> -    rv = NS_FileSpecToIFile(&locklocspec, getter_AddRefs(locklocfile));
> -    if (NS_FAILED(rv))
> -        return PR_FALSE;
> -
> -    // Check if the lock file exists
> -    PRBool exists;
> -    rv = locklocfile->Exists(&exists);
> -    if (NS_FAILED(rv))
> -        return PR_FALSE;
> -
> -    // Delete the file if it exists
> -    if (exists) {
> -        rv = locklocfile->Remove(PR_FALSE /* non-recursive */);
> -        if (NS_FAILED(rv))
> -            return PR_FALSE;
> -    }
> -
> -#ifdef MOVEMAIL_DEBUG
> -    fprintf(stderr, " LOCK YIELDING WAS SUCCESSFUL.\n");
> -#endif
> -
> -    // Success.
> -    return PR_TRUE;
> +    if (fd != -1)
> +	close(fd);
>  }
>  
> 
> @@ -314,6 +187,7 @@
>          // we now quest for the mail spool file...
>          nsFileSpec spoolFileSpec;
>          PRBool foundSpoolFile = PR_FALSE;
> +	int lock_fd = -1;
>  
>          // If $(MAIL) is set then we have things easy.
>          char * mailEnv = PR_GetEnv("MAIL");
> @@ -353,7 +227,7 @@
>          }
>  
>          // Try and obtain the lock for the spool file
> -        if (!ObtainSpoolLock(wholeboxname.get(), 5)) {
> +        if ((lock_fd = ObtainSpoolLock(wholeboxname.get(), 5)) == -1) {
>              nsAutoString lockFile = NS_ConvertUTF8toUCS2(wholeboxname);
>              lockFile += NS_LITERAL_STRING(".lock");
>              const PRUnichar *params[] = {
> @@ -487,14 +361,7 @@
>  freebuff_and_unlock:
>          PR_Free(buffer);
>          NS_IF_RELEASE(newMailParser);
> -        if (!YieldSpoolLock(wholeboxname.get())) {
> -            nsAutoString spoolLock = NS_ConvertUTF8toUCS2(wholeboxname);
> -            spoolLock += NS_LITERAL_STRING(".lock");
> -            const PRUnichar *params[] = {
> -                spoolLock.get()
> -            };
> -            Error(MOVEMAIL_CANT_DELETE_LOCK, params, 1);
> -        }
> +        YieldSpoolLock(lock_fd);
>      }
>  
>      in_server->SetServerBusy(PR_FALSE);
> _______________________________________________
> freebsd-gnome at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-gnome
> To unsubscribe, send any mail to "freebsd-gnome-unsubscribe at freebsd.org"
-- 
PGP Key : http://www.marcuscom.com/pgp.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: This is a digitally signed message part
Url : http://lists.freebsd.org/pipermail/freebsd-gnome/attachments/20040328/05f7b99b/attachment.bin


More information about the freebsd-gnome mailing list