summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libsmdb
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsmdb')
-rw-r--r--contrib/sendmail/libsmdb/smdb.c156
-rw-r--r--contrib/sendmail/libsmdb/smdb1.c13
-rw-r--r--contrib/sendmail/libsmdb/smdb2.c13
-rw-r--r--contrib/sendmail/libsmdb/smndbm.c12
4 files changed, 190 insertions, 4 deletions
diff --git a/contrib/sendmail/libsmdb/smdb.c b/contrib/sendmail/libsmdb/smdb.c
index ee563a1..597cbff 100644
--- a/contrib/sendmail/libsmdb/smdb.c
+++ b/contrib/sendmail/libsmdb/smdb.c
@@ -8,7 +8,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: smdb.c,v 8.37.4.1 2000/05/25 18:56:09 gshapiro Exp $";
+static char id[] = "@(#)$Id: smdb.c,v 8.37.4.2 2000/08/24 17:08:00 gshapiro Exp $";
#endif /* ! lint */
#include <fcntl.h>
@@ -62,6 +62,107 @@ smdb_free_database(database)
free(database);
}
+ /*
+** SMDB_LOCKFILE -- lock a file using flock or (shudder) fcntl locking
+**
+** Parameters:
+** fd -- the file descriptor of the file.
+** type -- type of the lock. Bits can be:
+** LOCK_EX -- exclusive lock.
+** LOCK_NB -- non-blocking.
+**
+** Returns:
+** TRUE if the lock was acquired.
+** FALSE otherwise.
+*/
+
+static bool
+smdb_lockfile(fd, type)
+ int fd;
+ int type;
+{
+ int i;
+ int save_errno;
+#if !HASFLOCK
+ int action;
+ struct flock lfd;
+
+ memset(&lfd, '\0', sizeof lfd);
+ if (bitset(LOCK_UN, type))
+ lfd.l_type = F_UNLCK;
+ else if (bitset(LOCK_EX, type))
+ lfd.l_type = F_WRLCK;
+ else
+ lfd.l_type = F_RDLCK;
+
+ if (bitset(LOCK_NB, type))
+ action = F_SETLK;
+ else
+ action = F_SETLKW;
+
+ while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
+ continue;
+ if (i >= 0)
+ {
+ return TRUE;
+ }
+ save_errno = errno;
+
+ /*
+ ** On SunOS, if you are testing using -oQ/tmp/mqueue or
+ ** -oA/tmp/aliases or anything like that, and /tmp is mounted
+ ** as type "tmp" (that is, served from swap space), the
+ ** previous fcntl will fail with "Invalid argument" errors.
+ ** Since this is fairly common during testing, we will assume
+ ** that this indicates that the lock is successfully grabbed.
+ */
+
+ if (save_errno == EINVAL)
+ {
+ return TRUE;
+ }
+
+ if (!bitset(LOCK_NB, type) ||
+ (save_errno != EACCES && save_errno != EAGAIN))
+ {
+ int omode = -1;
+# ifdef F_GETFL
+ (void) fcntl(fd, F_GETFL, &omode);
+ errno = save_errno;
+# endif /* F_GETFL */
+# if 0
+ syslog(LOG_ERR, "cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
+ filename, ext, fd, type, omode, geteuid());
+# endif /* 0 */
+ return FALSE;
+ }
+#else /* !HASFLOCK */
+
+ while ((i = flock(fd, type)) < 0 && errno == EINTR)
+ continue;
+ if (i >= 0)
+ {
+ return TRUE;
+ }
+ save_errno = errno;
+
+ if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
+ {
+ int omode = -1;
+# ifdef F_GETFL
+ (void) fcntl(fd, F_GETFL, &omode);
+ errno = save_errno;
+# endif /* F_GETFL */
+# if 0
+ syslog(LOG_ERR, "cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
+ filename, ext, fd, type, omode, geteuid());
+# endif /* 0 */
+ return FALSE;
+ }
+#endif /* !HASFLOCK */
+ errno = save_errno;
+ return FALSE;
+}
/*
** SMDB_OPEN_DATABASE -- Opens a database.
@@ -268,6 +369,59 @@ smdb_unlock_file(lock_fd)
}
/*
+** SMDB_LOCK_MAP -- Locks a database.
+**
+** Parameters:
+** database -- database description.
+** type -- type of the lock. Bits can be:
+** LOCK_EX -- exclusive lock.
+** LOCK_NB -- non-blocking.
+**
+** Returns:
+** SMDBE_OK -- Success, otherwise errno.
+*/
+
+int
+smdb_lock_map(database, type)
+ SMDB_DATABASE *database;
+ int type;
+{
+ int fd;
+
+ fd = database->smdb_lockfd(database);
+ if (fd < 0)
+ return SMDBE_NOT_FOUND;
+ if (!smdb_lockfile(fd, type))
+ return SMDBE_LOCK_NOT_GRANTED;
+ return SMDBE_OK;
+}
+
+ /*
+** SMDB_UNLOCK_MAP -- Unlocks a database
+**
+** Parameters:
+** database -- database description.
+**
+** Returns:
+** SMDBE_OK -- Success, otherwise errno.
+*/
+
+int
+smdb_unlock_map(database)
+ SMDB_DATABASE *database;
+{
+ int fd;
+
+ fd = database->smdb_lockfd(database);
+ if (fd < 0)
+ return SMDBE_NOT_FOUND;
+ if (!smdb_lockfile(fd, LOCK_UN))
+ return SMDBE_LOCK_NOT_HELD;
+ return SMDBE_OK;
+}
+
+
+ /*
** SMDB_SETUP_FILE -- Gets db file ready for use.
**
** Makes sure permissions on file are safe and creates it if it
diff --git a/contrib/sendmail/libsmdb/smdb1.c b/contrib/sendmail/libsmdb/smdb1.c
index 59b11e5..c9eb96f 100644
--- a/contrib/sendmail/libsmdb/smdb1.c
+++ b/contrib/sendmail/libsmdb/smdb1.c
@@ -8,7 +8,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: smdb1.c,v 8.43 2000/03/17 07:32:43 gshapiro Exp $";
+static char id[] = "@(#)$Id: smdb1.c,v 8.43.4.1 2000/08/24 17:08:00 gshapiro Exp $";
#endif /* ! lint */
#include <unistd.h>
@@ -194,6 +194,16 @@ smdb1_fd(database, fd)
}
int
+smdb1_lockfd(database)
+ SMDB_DATABASE *database;
+{
+ SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
+
+ return db1->smdb1_lock_fd;
+}
+
+
+int
smdb1_get(database, key, data, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -482,6 +492,7 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
smdb_db->smdb_close = smdb1_close;
smdb_db->smdb_del = smdb1_del;
smdb_db->smdb_fd = smdb1_fd;
+ smdb_db->smdb_lockfd = smdb1_lockfd;
smdb_db->smdb_get = smdb1_get;
smdb_db->smdb_put = smdb1_put;
smdb_db->smdb_set_owner = smdb1_set_owner;
diff --git a/contrib/sendmail/libsmdb/smdb2.c b/contrib/sendmail/libsmdb/smdb2.c
index aa9395b..8f46c20 100644
--- a/contrib/sendmail/libsmdb/smdb2.c
+++ b/contrib/sendmail/libsmdb/smdb2.c
@@ -8,7 +8,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: smdb2.c,v 8.53.2.1.2.1 2000/05/25 18:56:10 gshapiro Exp $";
+static char id[] = "@(#)$Id: smdb2.c,v 8.53.2.1.2.2 2000/08/24 17:08:00 gshapiro Exp $";
#endif /* ! lint */
#include <fcntl.h>
@@ -265,6 +265,16 @@ smdb2_fd(database, fd)
}
int
+smdb2_lockfd(database)
+ SMDB_DATABASE *database;
+{
+ SMDB_DB2_DATABASE *db2 = (SMDB_DB2_DATABASE *) database->smdb_impl;
+
+ return db2->smdb2_lock_fd;
+}
+
+
+int
smdb2_get(database, key, data, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -621,6 +631,7 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params
smdb_db->smdb_close = smdb2_close;
smdb_db->smdb_del = smdb2_del;
smdb_db->smdb_fd = smdb2_fd;
+ smdb_db->smdb_lockfd = smdb2_lockfd;
smdb_db->smdb_get = smdb2_get;
smdb_db->smdb_put = smdb2_put;
smdb_db->smdb_set_owner = smdb2_set_owner;
diff --git a/contrib/sendmail/libsmdb/smndbm.c b/contrib/sendmail/libsmdb/smndbm.c
index f5bf388..8c78ffc 100644
--- a/contrib/sendmail/libsmdb/smndbm.c
+++ b/contrib/sendmail/libsmdb/smndbm.c
@@ -8,7 +8,7 @@
*/
#ifndef lint
-static char id[] = "@(#)$Id: smndbm.c,v 8.40 2000/03/19 05:03:30 ca Exp $";
+static char id[] = "@(#)$Id: smndbm.c,v 8.40.4.1 2000/08/24 17:08:00 gshapiro Exp $";
#endif /* ! lint */
#include <fcntl.h>
@@ -157,6 +157,15 @@ smdbm_fd(database, fd)
}
int
+smdbm_lockfd(database)
+ SMDB_DATABASE *database;
+{
+ SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
+
+ return db->smndbm_lock_fd;
+}
+
+int
smdbm_get(database, key, data, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -555,6 +564,7 @@ smdb_ndbm_open(database, db_name, mode, mode_mask, sff, type, user_info,
smdb_db->smdb_close = smdbm_close;
smdb_db->smdb_del = smdbm_del;
smdb_db->smdb_fd = smdbm_fd;
+ smdb_db->smdb_lockfd = smdbm_lockfd;
smdb_db->smdb_get = smdbm_get;
smdb_db->smdb_put = smdbm_put;
smdb_db->smdb_set_owner = smndbm_set_owner;
OpenPOWER on IntegriCloud