Fixed a bug when not running setuid it wouldn't unlock.

2001-06-19  Not Zed  <NotZed@Ximian.com>

        * camel-lock-helper.c (unlock_id): Fixed a bug when not running
        setuid it wouldn't unlock.

        * camel-movemail.c (camel_movemail): use new
        locking daemon, also return an error code.

svn path=/trunk/; revision=10287
This commit is contained in:
Not Zed
2001-06-19 14:21:05 +00:00
committed by Michael Zucci
parent 131c4514f7
commit ea61a81256
4 changed files with 40 additions and 127 deletions

View File

@ -1,3 +1,11 @@
2001-06-19 Not Zed <NotZed@Ximian.com>
* camel-lock-helper.c (unlock_id): Fixed a bug when not running
setuid it wouldn't unlock.
* camel-movemail.c (camel_movemail): use new
locking daemon, also return an error code.
2001-06-18 Jeffrey Stedfast <fejj@ximian.com>
Note: Except for the info_free(), the NULL checks are

View File

@ -225,10 +225,10 @@ static int unlock_id(guint32 lockid)
seteuid(lock_root_uid);
camel_unlock_dot(info->path);
seteuid(lock_real_uid);
}
#else
camel_unlock_dot(info->path);
} else
#endif
camel_unlock_dot(info->path);
p->next = info->next;
free(info);
}

View File

@ -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);
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;
return -1;
}
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);
/* lock our source mailbox */
lockid = camel_lock_helper_lock(source, ex);
if (lockid == -1) {
close(sfd);
close(dfd);
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;
}
/* 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

View File

@ -35,7 +35,7 @@ extern "C" {
#include <camel/camel-exception.h>
void camel_movemail (const char *source, const char *dest, CamelException *ex);
int camel_movemail (const char *source, const char *dest, CamelException *ex);
#ifdef __cplusplus