aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-movemail.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/camel-movemail.c')
-rw-r--r--camel/camel-movemail.c151
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