From 85b5c5b8c9a24dddd6f050028ac62a6fed1f7333 Mon Sep 17 00:00:00 2001 From: Michael Elkins Date: Thu, 20 Jun 2002 23:33:13 +0000 Subject: [PATCH] remove debian/files move dotlocking code to dotlock.c. dotlocking code fixed to ignore whether or not the lockfile exists on open(). we only care about whether fcntl() was able to lock it. --- Makefile.am | 2 +- dotlock.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dotlock.h | 22 +++++++++++++ maildir.c | 71 ++++++------------------------------------ 4 files changed, 121 insertions(+), 63 deletions(-) create mode 100644 dotlock.c create mode 100644 dotlock.h diff --git a/Makefile.am b/Makefile.am index c1ee4e0..20d642d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS=debian bin_PROGRAMS=isync isync_SOURCES=main.c imap.c sync.c maildir.c isync.h list.c cram.c config.c \ - debug.h + debug.h dotlock.c dotlock.h isync_LDADD=@DEBUGOBJ@ isync_DEPENDENCIES=@DEBUGOBJ@ EXTRA_isync_SOURCES=debug.c diff --git a/dotlock.c b/dotlock.c new file mode 100644 index 0000000..7e3b65c --- /dev/null +++ b/dotlock.c @@ -0,0 +1,89 @@ +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer + * Copyright (C) 2002 Michael R. Elkins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * this file contains routines to establish a mutex using a `dotlock' file + */ +#include +#include +#include +#if TESTING +#include +#endif +#include "dotlock.h" + +static struct flock lck = { 0, SEEK_SET, 0, 0, 0 }; + +static void make_lock (int type) +{ + lck.l_type = type; + lck.l_pid = getpid (); +} + +int dotlock_lock (const char *path, int *fd) +{ + *fd = open (path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (*fd == -1) + return -1; + make_lock (F_WRLCK); + if (fcntl (*fd, F_SETLKW, &lck)) + { + close (*fd); + *fd = -1; + return -1; + } + return 0; +} + +int dotlock_unlock (int *fd) +{ + int r = 0; + + if (*fd != -1) + { + make_lock (F_UNLCK); + if (fcntl (*fd, F_SETLKW, &lck)) + r = -1; + close (*fd); + *fd = -1; + } + return r; +} + +#if TESTING +int main (void) +{ + int fd; + + if (dotlock_lock ("./lock", &fd)) + { + perror ("dotlock_lock"); + goto done; + } + puts("sleeping for 5 seconds"); + sleep(5); + if (dotlock_unlock (&fd)) + { + perror ("dotlock_lock"); + } +done: + exit (0); +} +#endif diff --git a/dotlock.h b/dotlock.h new file mode 100644 index 0000000..8f01c23 --- /dev/null +++ b/dotlock.h @@ -0,0 +1,22 @@ +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer + * Copyright (C) 2002 Michael R. Elkins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +int dotlock_lock (const char *, int *); +int dotlock_unlock (int *); diff --git a/maildir.c b/maildir.c index 799a3eb..0e3e7b8 100644 --- a/maildir.c +++ b/maildir.c @@ -29,26 +29,7 @@ #include #include #include "isync.h" - -static int -do_lock (int fd, int flag) -{ - struct flock lck; - - memset (&lck, 0, sizeof (lck)); - lck.l_type = flag; - lck.l_whence = SEEK_SET; - lck.l_start = 0; - lck.l_len = 0; - - if (fcntl (fd, F_SETLK, &lck)) - { - perror ("fcntl"); - return -1; - } - - return 0; -} +#include "dotlock.h" /* 2, */ static void @@ -117,44 +98,8 @@ read_uid (const char *path, const char *file, unsigned int *uid /* out */) return ret; } -/* NOTE: this is NOT NFS safe */ -static int -maildir_lock (mailbox_t * m) -{ - char path[_POSIX_PATH_MAX]; - - snprintf (path, sizeof (path), "%s/isynclock", m->path); - m->lockfd = open (path, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR); - if (m->lockfd == -1) - { - perror (path); - return -1; - } - if (do_lock (m->lockfd, F_WRLCK)) - { - close (m->lockfd); - m->lockfd = -1; - return -1; - } - return 0; -} - -static void -maildir_unlock (mailbox_t * m) -{ - char path[_POSIX_PATH_MAX]; - - if (m->lockfd != -1) - { - snprintf (path, sizeof (path), "%s/isynclock", m->path); - unlink (path); - do_lock (m->lockfd, F_UNLCK); - close (m->lockfd); - m->lockfd = -1; - } -} - -/* open a maildir mailbox. +/* + * open a maildir mailbox. * if OPEN_FAST is set, we just check to make * sure its a valid mailbox and don't actually parse it. any IMAP messages * with the \Recent flag set are guaranteed not to be in the mailbox yet, @@ -231,10 +176,12 @@ maildir_open (const char *path, int flags) } } - /* we need a mutex on the maildir because of the state files that isync + /* + * we need a mutex on the maildir because of the state files that isync * uses. */ - if (maildir_lock (m)) + snprintf (buf, sizeof (buf), "%s/isynclock", m->path); + if (dotlock_lock (buf, &m->lockfd)) goto err; /* check for the uidvalidity value */ @@ -311,7 +258,7 @@ maildir_open (const char *path, int flags) err: if (m->db) dbm_close (m->db); - maildir_unlock (m); + dotlock_unlock (&m->lockfd); free (m->path); free (m); return NULL; @@ -436,7 +383,7 @@ maildir_close (mailbox_t * mbox) dbm_close (mbox->db); /* release the mutex on the mailbox */ - maildir_unlock (mbox); + dotlock_unlock (&mbox->lockfd); /* per the maildir(5) specification, delivery agents are supposed to * set a 24-hour timer on items placed in the `tmp' directory.