diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-01-15 21:09:13 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-01-15 21:09:13 +0000 |
commit | 5062bcecfa81a7e0dd07894d6e93655a97239964 (patch) | |
tree | fd0e0dd2a71271dbe81c195cd9fbdd57fb7c20fb /gnu/usr.sbin/sendmail/libsmdb/smdb.c | |
parent | 91deaea81040227b9ba537ff047f1f863f75fc31 (diff) |
sendmail 8.11.2 with BSD Makefiles
Diffstat (limited to 'gnu/usr.sbin/sendmail/libsmdb/smdb.c')
-rw-r--r-- | gnu/usr.sbin/sendmail/libsmdb/smdb.c | 157 |
1 files changed, 156 insertions, 1 deletions
diff --git a/gnu/usr.sbin/sendmail/libsmdb/smdb.c b/gnu/usr.sbin/sendmail/libsmdb/smdb.c index c68b09ccc16..03756c87079 100644 --- a/gnu/usr.sbin/sendmail/libsmdb/smdb.c +++ b/gnu/usr.sbin/sendmail/libsmdb/smdb.c @@ -8,13 +8,14 @@ */ #ifndef lint -static char id[] = "@(#)$Sendmail: smdb.c,v 8.37 2000/03/17 07:32:43 gshapiro Exp $"; +static char id[] = "@(#)$Sendmail: smdb.c,v 8.37.4.2 2000/08/24 17:08:00 gshapiro Exp $"; #endif /* ! lint */ #include <fcntl.h> #include <stdlib.h> #include <unistd.h> + #include <sendmail/sendmail.h> #include <libsmdb/smdb.h> @@ -61,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. @@ -267,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 |