diff options
Diffstat (limited to 'camel/camel-movemail.c')
-rw-r--r-- | camel/camel-movemail.c | 151 |
1 files changed, 28 insertions, 123 deletions
diff --git a/camel/camel-movemail.c b/camel/camel-movemail.c index 4e1d67563d..c71000f9b5 100644 --- a/camel/camel-movemail.c +++ b/camel/camel-movemail.c @@ -48,6 +48,8 @@ #include "camel-mime-filter.h" #include "camel-mime-filter-from.h" +#include "camel-lock-client.h" + #define d(x) #ifdef MOVEMAIL_PATH @@ -74,19 +76,20 @@ static int camel_movemail_copy(int fromfd, int tofd, off_t start, size_t bytes); * readers and writers into a private (presumably Camel-controlled) * directory. Dot locking is used on the source file (but not the * destination). + * + * Return Value: Returns -1 on error. **/ -void -camel_movemail (const char *source, const char *dest, CamelException *ex) +int +camel_movemail(const char *source, const char *dest, CamelException *ex) { - gboolean locked; - int sfd, dfd, tmpfd; - char *locktmpfile, *lockfile; + int lockid = -1; + int res = -1; + int sfd, dfd; struct stat st; - time_t now, timeout; int nread, nwrote; char buf[BUFSIZ]; - camel_exception_clear (ex); + camel_exception_clear(ex); /* Stat and then open the spool file. If it doesn't exist or * is empty, the user has no mail. (There's technically a race @@ -102,54 +105,19 @@ camel_movemail (const char *source, const char *dest, CamelException *ex) "%s: %s"), source, g_strerror (errno)); } - return; + return -1; } - if (st.st_size == 0) - return; - /* Create the unique lock file. */ - locktmpfile = g_strdup_printf ("%s.lock.XXXXXX", source); -#ifdef HAVE_MKSTEMP - tmpfd = mkstemp (locktmpfile); -#else - if (mktemp (locktmpfile)) { - tmpfd = open (locktmpfile, O_RDWR | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR); - } else - tmpfd = -1; -#endif - if (tmpfd == -1) { - g_free (locktmpfile); -#ifdef MOVEMAIL_PATH - if (errno == EACCES) { - /* movemail_external will fail if the dest file - * already exists, so if it does, return now, - * let the fetch code process the mail that's - * already there, and then the user can try again. - */ - if (stat (dest, &st) == 0) - return; - - movemail_external (source, dest, ex); - return; - } -#endif - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create lock file " - "for %s: %s"), source, - g_strerror (errno)); - return; - } - close (tmpfd); + if (st.st_size == 0) + return 0; + /* open files */ sfd = open (source, O_RDWR); if (sfd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not open mail file %s: %s"), source, g_strerror (errno)); - unlink (locktmpfile); - g_free (locktmpfile); - return; + return -1; } dfd = open (dest, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); @@ -159,79 +127,17 @@ camel_movemail (const char *source, const char *dest, CamelException *ex) "file %s: %s"), dest, g_strerror (errno)); close (sfd); - unlink (locktmpfile); - g_free (locktmpfile); - return; - } - - lockfile = g_strdup_printf ("%s.lock", source); - locked = FALSE; - time (&timeout); - timeout += 30; - - /* Loop trying to lock the file for 30 seconds. */ - while (time (&now) < timeout) { - /* Try to make the lock. */ - if (symlink (locktmpfile, lockfile) == 0) { - locked = TRUE; - break; - } - - /* If we fail for a reason other than that someone - * else has the lock, then abort. - */ - if (errno != EEXIST) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not create lock " - "file for %s: %s"), source, - g_strerror (errno)); - break; - } - - /* Check the modtime on the lock file. */ - if (stat (lockfile, &st) == -1) { - /* If the lockfile disappeared, try again. */ - if (errno == ENOENT) - continue; - - /* Some other error. Abort. */ - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not test lock " - "file for %s: %s"), source, - g_strerror (errno)); - break; - } - - /* If the lock file is stale, remove it and try again. */ - if (st.st_mtime < now - 60) { - unlink (lockfile); - continue; - } - - /* Otherwise, sleep and try again. */ - sleep (5); + return -1; } - if (!locked) { - /* Something has gone awry. */ - if (now >= timeout) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Timed out trying to get " - "lock file on %s. Try again " - "later."), source); - } - g_free (lockfile); - unlink (locktmpfile); - g_free (locktmpfile); - close (sfd); - close (dfd); - return; + /* lock our source mailbox */ + lockid = camel_lock_helper_lock(source, ex); + if (lockid == -1) { + close(sfd); + close(dfd); + return -1; } - /* OK. We have the file locked now. */ - - /* FIXME: Set a timer to keep the file locked. */ - while (1) { int written = 0; @@ -267,9 +173,10 @@ camel_movemail (const char *source, const char *dest, CamelException *ex) * close the destination file, then truncate the source file. */ if (!camel_exception_is_set (ex)) { - if (close (dfd) == 0) + if (close (dfd) == 0) { ftruncate (sfd, 0); - else { + res = 0; + } else { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to store mail in " "temp file %s: %s"), dest, @@ -279,11 +186,9 @@ camel_movemail (const char *source, const char *dest, CamelException *ex) close (dfd); close (sfd); - /* Clean up lock files. */ - unlink (lockfile); - g_free (lockfile); - unlink (locktmpfile); - g_free (locktmpfile); + camel_lock_helper_unlock(lockid); + + return res; } #ifdef MOVEMAIL_PATH |