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.
+ * Lock open/close routines.
+ *
+ * The lk[f]opendata() functions are designed to open "data" files (anything
+ * not a mail spool file) using the locking mechanism configured for data
+ * files. The lk[f]openspool() functions are for opening the mail spool
+ * file, which will use the locking algorithm configured for the mail
+ * spool.
+ *
+ * All of these functions have a third argument, 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);
-int lkopen(char *, int, mode_t, int);
+int lkclosedata(int, char*);
+int lkclosespool(int, char*);
+int lkfclosedata(FILE *, char *);
+int lkfclosespool(FILE *, char *);
+FILE *lkfopendata(char *, char *, int);
+int lkopendata(char *, int, mode_t, int);
+FILE *lkfopenspool(char *, char *, int);
+int lkopenspool(char *, int, mode_t, int);
int m_atoi (char *);
char *m_backup (char *);
int m_convert (struct msgs *, char *);
sigaddset (&set, SIGTERM);
sigprocmask (SIG_BLOCK, &set, &oset);
- if (!(out = lkfopen (ctxpath, "w")))
+ if (!(out = lkfopendata (ctxpath, "w", 1)))
adios (ctxpath, "unable to write");
for (np = m_defs; np; np = np->n_next)
if (np->n_context)
fprintf (out, "%s: %s\n", np->n_name, np->n_field);
- lkfclose (out, ctxpath);
+ lkfclosedata (out, ctxpath);
sigprocmask (SIG_SETMASK, &oset, &set); /* reset the signal mask */
struct lock *l_next;
};
+enum locktype { FCNTL_LOCKING, FLOCK_LOCKING, LOCKF_LOCKING, DOT_LOCKING };
+
+/*
+ * Flags to indicate whether we've initialized the lock types, and
+ * our saved lock types
+ */
+static int datalockinit = 0;
+static int spoollockinit = 0;
+enum locktype datalocking, spoollocking;
+
+
/* top of list containing all open locks */
static struct lock *l_top = NULL;
+static int lkopen(char *, int, mode_t, enum locktype, int);
+static FILE *lkfopen(char *, const char *, mode_t, int);
+
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 enum locktype init_locktype(const char *);
+
static int lkopen_dot (char *, int, mode_t);
static void lockname (char *, struct lockinfo *, int);
static void timerON (char *, int);
#if !defined(HAVE_LIBLOCKFILE)
static int lockit (struct lockinfo *);
#endif
-#endif
/*
- * Base routine to open and lock a file,
- * and return a file descriptor.
+ * Base function: determine the data type used to lock files and
+ * call the underlying function.
*/
int
-lkopen (char *file, int access, mode_t mode)
+lkopendata(char *file, int access, mode_t mode, int exclusive)
{
-#ifdef KERNEL_LOCKING
- return lkopen_kernel(file, access, mode);
-#endif
+ if (! datalockinit) {
+ char *cp = context_find("datalocking");
+
+ if (cp) {
+ datalocking = init_locktype(cp);
+ } else {
+ /* We default to fcntl locking for data files */
+ datalocking = FCNTL_LOCKING;
+ }
-#ifdef DOT_LOCKING
- return lkopen_dot(file, access, mode);
-#endif
+ datalockinit = 1;
+ }
+
+ return lkopen(file, access, mode, datalocking, exclusive);
+}
+
+/*
+ * Internal routine to switch between different locking types.
+ */
+
+static int
+lkopen (char *file, int access, mode_t mode, enum locktype ltype,
+ int exclusive)
+{
+ switch (ltype) {
+
+ case FCNTL_LOCKING:
+ return lkopen_fcntl(file, access, mode, exclusive);
+
+ case DOT_LOCKING:
+ return lkopen_dot(file, access, mode, exclusive);
+
+#ifdef HAVE_FLOCK
+ case FLOCK_LOCKING:
+ return lkopen_flock(file, access, mode, exclusive);
+#endif /* HAVE_FLOCK */
+
+#ifdef HAVE_LOCKF
+ case LOCKF_LOCKING:
+ return lkopen_lockf(file, access, mode, exclusive);
+#endif /* HAVE_FLOCK */
+
+ default:
+ adios(NULL, "Internal locking error: unsupported lock type used!");
+ }
+
+ return -1;
}
*/
FILE *
-lkfopen (char *file, char *mode)
+lkfopen (char *file, char *mode, int exclusive)
{
int fd, access;
FILE *fp;
return NULL;
}
- if ((fd = lkopen (file, access, 0666)) == -1)
+ if ((fd = lkopen (file, access, 0666, exclusive)) == -1)
return NULL;
if ((fp = fdopen (fd, mode)) == NULL) {
* Return a locking algorithm based on the string name
*/
-enum locktype
+static enum locktype
init_locktype(const char *lockname)
{
if (mh_strcasecmp(lockname, "fcntl") == 0) {
} else if (mh_strcasecmp(lockname, "dot") == 0) {
return DOT_LOCKING;
} else {
- adios(NULL, "Unknown lock type: \"%s\"", lockname)
+ adios(NULL, "Unknown lock type: \"%s\"", lockname);
/* NOTREACHED */
return 0;
}