AC_DEFINE_UNQUOTED([BACKUP_PREFIX], "$backup_prefix",
[The prefix that is prepended to the name of message files when they are "removed" by rmm. This should typically be `,' or `#'.])dnl
-dnl What method of locking to use?
-AS_CASE(["$host_os"],
- [aix*|cygwin*|linux*],
- [default_locktype="fcntl"; default_locking=FCNTL_LOCKING],
- [freebsd*|openbsd*|darwin*], [default_locktype="flock"; default_locking=FLOCK_LOCKING],
- [default_locktype="dot"; default_locking=DOT_LOCKING])
-
-AC_ARG_WITH([locking],
- AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@],
- [specify the file locking method]))
-
-AS_IF([test x"$with_locking" = x"dot"],
- [LOCKTYPE="dot"
- AC_DEFINE([DOT_LOCKING], [1], [Define to use dot based file locking.])],
- [test x"$with_locking" = x"flock"],
- [LOCKTYPE="flock"
- AC_DEFINE([FLOCK_LOCKING], [1], [Define to use flock() based locking.])],
- [test x"$with_locking" = x"lockf"],
- [LOCKTYPE="lockf"
- AC_DEFINE([LOCKF_LOCKING], [1], [Define to use lockf() based locking.])],
- [test x"$with_locking" = x"fcntl"],
- [LOCKTYPE="fcntl"
- AC_DEFINE([FCNTL_LOCKING], [1], [Define to use fnctl() based locking.])],
- [LOCKTYPE="$default_locktype"
- AC_DEFINE_UNQUOTED([$default_locking], [1])])
-
-dnl Should we use a locking directory?
-AC_ARG_ENABLE([lockdir],
- [AS_HELP_STRING([--enable-lockdir=dir], [Store dot-lock files in "dir"])], [
- AS_IF([test "x$enableval" = xyes],[
- AC_MSG_ERROR([--enable-lockdir requires an argument])])
- AS_IF([test "x$LOCKTYPE" != xdot],[
- AC_MSG_ERROR([Can only use --enable-lockdir with dot locking])])
- AC_DEFINE_UNQUOTED([LOCKDIR], ["$enableval"],
- [Directory to store dot-locking lock files])
-])
-
dnl What method of posting should post use?
AC_ARG_WITH([mts],
AS_HELP_STRING([--with-mts=@<:@smtp|sendmail/smtp|sendmail/pipe@:>@],
dnl Check for readline support
NMH_READLINE
+dnl Check the locking functions supported and what we should use by default
+NMH_LOCKING
+
dnl Check for iconv
NMH_CHECK_ICONV
#define NMH_ATTACH_HEADER "Nmh-Attachment" /* Default header for -attach */
+/*
+ * The type of locking we support
+ */
+
+enum locktype { FCNTL_LOCKING, FLOCK_LOCKING, LOCKF_LOCKING, DOT_LOCKING };
+
/*
* miscellaneous macros
*/
/*
* prototypes.h -- various prototypes
+ *
+ * If you modify functions here, please document their current behavior
+ * as much as practical.
*/
/*
char *getcpy (char *);
char *get_default_editor(void);
char *getfolder(int);
+/*
+ * Parse a lock type and return the type of lock it is
+ */
+enum locktype init_locktype(const char *);
+/*
+ * Lock open/close routines. The 3rd argument to lkopen/lfkopen is an
+ * integer which indicates the type of lock. A "0" means a shared (read)
+ * lock, and a "1" indicates an exclusive (write) lock.
+ */
int lkclose(int, char*);
int lkfclose(FILE *, char *);
-FILE *lkfopen(char *, char *);
-int lkopen(char *, int, mode_t);
+FILE *lkfopen(char *, char *, int);
+int lkopen(char *, int, mode_t, int);
int m_atoi (char *);
char *m_backup (char *);
int m_convert (struct msgs *, char *);
--- /dev/null
+dnl
+dnl Our functions to check the locking functions available and select a
+dnl default locking function for the spool file
+dnl
+dnl Since we're assuming POSIX as a minimum, we always assume we have fcntl
+dnl locking available.
+dnl
+
+AC_DEFUN([NMH_LOCKING],
+[AC_CHECK_FUNCS([flock lockf])
+AS_CASE(["$host_os"],
+ [aix*|cygwin*|linux*],
+ [default_locktype="fcntl"],
+ [freebsd*|openbsd*|darwin*], [default_locktype="flock"],
+ [default_locktype="dot"])
+
+AC_MSG_CHECKING([default locking method for the mail spool])
+
+AC_ARG_WITH([locking],
+ AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@],
+ [The default locking method for the mail spool file]), ,
+ [with_locking="$default_locktype"])
+
+AS_CASE([$with_locking],
+ [fcntl|dot], ,
+ [flock],
+ [AS_IF([test x"$ac_cv_func_flock" != x"yes"],
+ [AC_MSG_ERROR([flock locks not supported on this system])])],
+ [lockf],
+ [AS_IF([test x"$ac_cv_func_lockf" != x"yes"],
+ [AC_MSG_ERROR([lockf locks not supported on this system])])],
+ [no],
+ [AC_MSG_ERROR([--without-locking not supported])],
+ [AC_MSG_ERROR([Unknown locking type $with_locking])])
+
+AC_DEFINE_UNQUOTED([DEFAULT_LOCKING], [$with_locking],
+ [The default lock type for the mail spool file])
+
+AC_MSG_RESULT([$with_locking])
+
+dnl Should we use a locking directory?
+AC_ARG_ENABLE([lockdir],
+ [AS_HELP_STRING([--enable-lockdir=dir], [Store dot-lock files in "dir"])], [
+ AS_IF([test "x$enableval" = xyes],[
+ AC_MSG_ERROR([--enable-lockdir requires an argument])])
+ AC_DEFINE_UNQUOTED([LOCKDIR], ["$enableval"],
+ [Directory to store dot-locking lock files])
+])])
#endif
#include <time.h>
#include <errno.h>
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#else
+#include <fcntl.h>
+#ifdef HAVE_FLOCK
# include <sys/file.h>
#endif
-
-#if defined(LOCKF_LOCKING) || defined(FLOCK_LOCKING)
-# include <sys/file.h>
+#ifdef HAVE_LOCKF
+# include <unistd.h>
#endif
#include <signal.h>
char *lockdir = LOCKDIR;
#endif
-/* Are we using any kernel locking? */
-#if defined (FLOCK_LOCKING) || defined(LOCKF_LOCKING) || defined(FCNTL_LOCKING)
-# define KERNEL_LOCKING
-#endif
-
-#ifdef DOT_LOCKING
-
/* struct for getting name of lock file to create */
struct lockinfo {
char curlock[BUFSIZ];
/* top of list containing all open locks */
static struct lock *l_top = NULL;
-#endif /* DOT_LOCKING */
-/*
- * static prototypes
- */
-#ifdef KERNEL_LOCKING
-static int lkopen_kernel (char *, int, mode_t);
-#endif
+static int lkopen_fcntl (char *, int, mode_t, int);
+#ifdef HAVE_LOCKF
+static int lkopen_lockf (char *, int, mode_t, int);
+#endif /* HAVE_LOCKF */
#ifdef DOT_LOCKING
static int lkopen_dot (char *, int, mode_t);
}
#endif /* DOT_LOCKING */
+
+/*
+ * Return a locking algorithm based on the string name
+ */
+
+enum locktype
+init_locktype(const char *lockname)
+{
+ if (mh_strcasecmp(lockname, "fcntl") == 0) {
+ return FCNTL_LOCKING;
+ } else if (mh_strcasecmp(lockname, "lockf") == 0) {
+#ifdef HAVE_LOCKF
+ return LOCKF_LOCKING;
+#else /* ! HAVE_LOCKF */
+ adios(NULL, "lockf not supported on this system");
+#endif /* HAVE_LOCKF */
+ } else if (mh_strcasecmp(lockname, "flock") == 0) {
+#ifdef HAVE_FLOCK
+ return FLOCK_LOCKING;
+#else /* ! HAVE_FLOCK */
+ adios(NULL, "flock not supported on this system");
+#endif /* HAVE_FLOCK */
+ } else if (mh_strcasecmp(lockname, "dot") == 0) {
+ return DOT_LOCKING;
+ } else {
+ adios(NULL, "Unknown lock type: \"%s\"", lockname)
+ /* NOTREACHED */
+ return 0;
+ }
+}