Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
nsMovemailService.cpp File Reference
#include <unistd.h>
#include "prenv.h"
#include "nspr.h"
#include "msgCore.h"
#include "nsMovemailService.h"
#include "nsIMovemailService.h"
#include "nsIMsgIncomingServer.h"
#include "nsIMovemailIncomingServer.h"
#include "nsIMsgProtocolInfo.h"
#include "nsIMsgMailSession.h"
#include "nsParseMailbox.h"
#include "nsIMsgFolder.h"
#include "nsIPrompt.h"
#include "nsILocalFile.h"
#include "nsFileStream.h"
#include "nsIFileSpec.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsMsgUtils.h"
#include "nsMsgLocalCID.h"
#include "nsMsgBaseCID.h"
#include "nsXPIDLString.h"
#include "nsCOMPtr.h"
#include "nsMsgFolderFlags.h"
#include "nsILineInputStream.h"
#include "nsNetUtil.h"
#include "nsAutoPtr.h"
#include "prlog.h"

Go to the source code of this file.


#define LOG(args)
#define PREF_MAIL_ROOT_MOVEMAIL   "mail.root.movemail"
#define PREF_MAIL_ROOT_MOVEMAIL_REL   "mail.root.movemail-rel"
#define NUM_DEFAULT_SPOOL_PATHS   (sizeof(gDefaultSpoolPaths)/sizeof(gDefaultSpoolPaths[0]))


 NS_IMPL_ISUPPORTS2 (nsMovemailService, nsIMovemailService, nsIMsgProtocolInfo) NS_IMETHODIMP nsMovemailService
PRBool ObtainSpoolLock (const char *spoolnameStr, int seconds)
PRBool YieldSpoolLock (const char *spoolnameStr)
static nsresult LocateSpoolFile (nsACString &spoolPath)


const char * gDefaultSpoolPaths []

Define Documentation

#define LOG (   args)

Definition at line 85 of file nsMovemailService.cpp.

Definition at line 97 of file nsMovemailService.cpp.

#define PREF_MAIL_ROOT_MOVEMAIL   "mail.root.movemail"

Definition at line 88 of file nsMovemailService.cpp.

#define PREF_MAIL_ROOT_MOVEMAIL_REL   "mail.root.movemail-rel"

Definition at line 89 of file nsMovemailService.cpp.

Function Documentation

static nsresult LocateSpoolFile ( nsACString &  spoolPath) [static]

Definition at line 275 of file nsMovemailService.cpp.

    PRBool isFile;
    nsresult rv;

    nsCOMPtr<nsILocalFile> spoolFile;
    rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(spoolFile));
    NS_ENSURE_SUCCESS(rv, rv);

    char * mailEnv = PR_GetEnv("MAIL");
    char * userEnv = PR_GetEnv("USER");
    if (!userEnv)
        userEnv = PR_GetEnv("USERNAME");

    if (mailEnv) {
        rv = spoolFile->InitWithNativePath(nsDependentCString(mailEnv));
        NS_ENSURE_SUCCESS(rv, rv);
        rv = spoolFile->IsFile(&isFile);
        if (NS_SUCCEEDED(rv) && isFile)
            spoolPath = mailEnv;
    else if (userEnv) {
        // Try to build the mailbox path from the username and a number
        // of guessed spool directory paths.
        nsCAutoString tmpPath;
        PRUint32 i;
        for (i = 0; i < NUM_DEFAULT_SPOOL_PATHS; i++) {
            tmpPath = gDefaultSpoolPaths[i];
            tmpPath += userEnv;
            rv = spoolFile->InitWithNativePath(tmpPath);
            NS_ENSURE_SUCCESS(rv, rv);
            rv = spoolFile->IsFile(&isFile);
            if (NS_SUCCEEDED(rv) && isFile) {
                spoolPath = tmpPath;

    return rv;

Here is the call graph for this function:

Definition at line 113 of file nsMovemailService.cpp.

    nsresult rv = NS_OK;
    return rv;
PRBool ObtainSpoolLock ( const char *  spoolnameStr,
int  seconds 

Definition at line 163 of file nsMovemailService.cpp.

    // 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);
    nsCAutoString lockstr(spoolnameStr);

    nsresult rv;

    // Create nsILocalFile for the spool.mozlock file
    nsCOMPtr<nsILocalFile> tmplocfile;
    rv = NS_NewNativeLocalFile(mozlockstr, PR_TRUE, 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
    rv = tmplocfile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
        // can't create our .mozlock file... game over already
        LOG(("Failed to create file %s\n", mozlockstr.get()));
        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());

        LOG(("Attempt %d of %d to create lock file", retry_count, seconds));

        if (seconds > 0 && link_result == -1) {
            // pause 1sec, waiting for .lock to go away
            PRIntervalTime sleepTime = 1000; // 1 second
    } while (link_result == -1 && retry_count < seconds);
    LOG(("Link result: %d", link_result));

    // step 3: remove .mozlock file, in any case
    rv = tmplocfile->Remove(PR_FALSE /* non-recursive */);
    if (NS_FAILED(rv)) {
        // Could not delete our .mozlock file... very unusual, but
        // not fatal.
        LOG(("Unable to delete %s", mozlockstr.get()));

    // step 4: now we know whether we succeeded or failed
    if (link_result == 0)
        return PR_TRUE; // got the lock.
        return PR_FALSE; // didn't.  :(

Here is the call graph for this function:

PRBool YieldSpoolLock ( const char *  spoolnameStr)

Definition at line 240 of file nsMovemailService.cpp.

    LOG(("YieldSpoolLock(%s)", spoolnameStr));

    nsCAutoString lockstr(spoolnameStr);

    nsresult rv;

    // Create nsILocalFile for the spool.lock file
    nsCOMPtr<nsILocalFile> locklocfile;
    rv = NS_NewNativeLocalFile(lockstr, PR_TRUE, 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;

    LOG(("YieldSpoolLock was successful."));

    // Success.
    return PR_TRUE;

Here is the call graph for this function:

Variable Documentation

Initial value:

Definition at line 91 of file nsMovemailService.cpp.