From: Ken Hornstein Date: Thu, 14 Mar 2013 19:57:07 +0000 (-0400) Subject: More locking updates; still doesn't compile yet. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/182f6368f75799e25563cbf355923a72c995078b?ds=inline;hp=-c More locking updates; still doesn't compile yet. --- 182f6368f75799e25563cbf355923a72c995078b diff --git a/configure.ac b/configure.ac index 96a99022..bfa3c518 100644 --- a/configure.ac +++ b/configure.ac @@ -646,9 +646,8 @@ man page install path : ${nmhman} RPM build root : ${nmhrpm} backup prefix : ${backup_prefix} transport system : ${MTS} -file locking type : ${LOCKTYPE} +spool default locking type : ${with_locking} default smtp servers : ${smtpservers} -default editor : ${editorpath} SASL support : ${sasl_support} TLS support : ${tls_support} ])])dnl diff --git a/h/mh.h b/h/mh.h index 2d977446..daf47c02 100644 --- a/h/mh.h +++ b/h/mh.h @@ -316,12 +316,6 @@ typedef struct m_getfld_state *m_getfld_state_t; #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 */ diff --git a/h/prototypes.h b/h/prototypes.h index fff761d4..921021d7 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -80,18 +80,26 @@ 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. + * 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 *); diff --git a/sbr/context_read.c b/sbr/context_read.c index a655effc..2008c26b 100644 --- a/sbr/context_read.c +++ b/sbr/context_read.c @@ -136,9 +136,9 @@ context_read (void) ctxpath = getcpy (m_maildir (cp)); - if ((ib = lkfopen (ctxpath, "r"))) { + if ((ib = lkfopendata (ctxpath, "r", 0))) { readconfig ((struct node **) 0, ib, cp, 1); - lkfclose (ib, ctxpath); + lkfclosedata (ib, ctxpath); } return; diff --git a/sbr/context_save.c b/sbr/context_save.c index 33cd23dd..86776c7d 100644 --- a/sbr/context_save.c +++ b/sbr/context_save.c @@ -43,12 +43,12 @@ context_save (void) 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 */ diff --git a/sbr/lock_file.c b/sbr/lock_file.c index 6653a28b..1e49a2a9 100644 --- a/sbr/lock_file.c +++ b/sbr/lock_file.c @@ -71,15 +71,30 @@ struct lock { 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); @@ -89,23 +104,62 @@ static void alrmser (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; } @@ -168,7 +222,7 @@ lkclose (int fd, char *file) */ FILE * -lkfopen (char *file, char *mode) +lkfopen (char *file, char *mode, int exclusive) { int fd, access; FILE *fp; @@ -190,7 +244,7 @@ lkfopen (char *file, char *mode) 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) { @@ -601,7 +655,7 @@ alrmser (int sig) * 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) { @@ -621,7 +675,7 @@ init_locktype(const char *lockname) } 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; }