diff options
Diffstat (limited to 'usr.sbin/sendmail/makemap/makemap.c')
| -rw-r--r-- | usr.sbin/sendmail/makemap/makemap.c | 131 |
1 files changed, 125 insertions, 6 deletions
diff --git a/usr.sbin/sendmail/makemap/makemap.c b/usr.sbin/sendmail/makemap/makemap.c index 14548bd2b50a..c48a1c971360 100644 --- a/usr.sbin/sendmail/makemap/makemap.c +++ b/usr.sbin/sendmail/makemap/makemap.c @@ -33,15 +33,18 @@ */ #ifndef lint -static char sccsid[] = "@(#)makemap.c 8.6.1.1 (Berkeley) 3/6/95"; +static char sccsid[] = "@(#)makemap.c 8.14 (Berkeley) 11/5/95"; #endif /* not lint */ #include <stdio.h> #include <sysexits.h> #include <sys/types.h> -#include <sys/file.h> #include <ctype.h> #include <string.h> +#include <sys/errno.h> +#ifndef ISC_UNIX +# include <sys/file.h> +#endif #include "useful.h" #include "conf.h" @@ -80,6 +83,7 @@ main(argc, argv) bool inclnull = FALSE; bool notrunc = FALSE; bool allowreplace = FALSE; + bool allowdups = FALSE; bool verbose = FALSE; bool foldcase = TRUE; int exitstat; @@ -87,10 +91,12 @@ main(argc, argv) char *typename; char *mapname; char *ext; + char *lext; int lineno; int st; int mode; enum type type; + int fd; union { #ifdef NDBM @@ -102,14 +108,19 @@ main(argc, argv) void *dbx; } dbp; union dbent key, val; +#ifdef NEWDB + BTREEINFO bti; +#endif char ibuf[BUFSIZE]; char fbuf[MAXNAME]; + char lbuf[MAXNAME]; extern char *optarg; extern int optind; + extern bool lockfile(); progname = argv[0]; - while ((opt = getopt(argc, argv, "Nforv")) != EOF) + while ((opt = getopt(argc, argv, "Ndforv")) != EOF) { switch (opt) { @@ -117,6 +128,10 @@ main(argc, argv) inclnull = TRUE; break; + case 'd': + allowdups = TRUE; + break; + case 'f': foldcase = FALSE; break; @@ -148,10 +163,12 @@ main(argc, argv) typename = argv[0]; mapname = argv[1]; ext = NULL; + lext = NULL; if (strcmp(typename, "dbm") == 0) { type = T_DBM; + lext = ".dir"; } else if (strcmp(typename, "btree") == 0) { @@ -170,7 +187,7 @@ main(argc, argv) switch (type) { case T_ERR: - fprintf(stderr, "Usage: %s [-N] [-o] [-v] type mapname\n", progname); + fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname); exit(EX_USAGE); case T_UNKNOWN: @@ -188,6 +205,26 @@ main(argc, argv) fprintf(stderr, "%s: Type %s not supported in this version\n", progname, typename); exit(EX_UNAVAILABLE); + +#ifdef NEWDB + case T_BTREE: + bzero(&bti, sizeof bti); + if (allowdups) + bti.flags |= R_DUP; + break; + + case T_HASH: +#endif +#ifdef NDBM + case T_DBM: +#endif + if (allowdups) + { + fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n", + progname, typename); + exit(EX_UNAVAILABLE); + } + break; } /* @@ -208,6 +245,10 @@ main(argc, argv) } } + strcpy(lbuf, mapname); + if (lext != NULL) + strcat(lbuf, lext); + /* ** Create the database. */ @@ -215,6 +256,19 @@ main(argc, argv) mode = O_RDWR; if (!notrunc) mode |= O_CREAT|O_TRUNC; +#ifdef O_EXLOCK + mode |= O_EXLOCK; +#else + /* pre-lock the database */ + fd = open(lbuf, mode & ~O_TRUNC, 0644); + if (fd < 0) + { + fprintf(stderr, "%s: cannot create type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } + (void) lockfile(fd); +#endif switch (type) { #ifdef NDBM @@ -227,13 +281,25 @@ main(argc, argv) case T_HASH: dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL); if (dbp.db != NULL) + { +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } break; case T_BTREE: - dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, NULL); + dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti); if (dbp.db != NULL) + { +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } break; #endif @@ -244,7 +310,7 @@ main(argc, argv) if (dbp.dbx == NULL) { - fprintf(stderr, "%s: cannot create type %s map %s\n", + fprintf(stderr, "%s: cannot open type %s map %s\n", progname, typename, mapname); exit(EX_CANTCREAT); } @@ -373,5 +439,58 @@ main(argc, argv) #endif } +#ifndef O_EXLOCK + /* release locks */ + close(fd); +#endif + exit (exitstat); } +/* +** LOCKFILE -- lock a file using flock or (shudder) fcntl locking +** +** Parameters: +** fd -- the file descriptor of the file. +** +** Returns: +** TRUE if the lock was acquired. +** FALSE otherwise. +*/ + +bool +lockfile(fd) + int fd; +{ +# if !HASFLOCK + int action; + struct flock lfd; + extern int errno; + + bzero(&lfd, sizeof lfd); + lfd.l_type = F_WRLCK; + action = F_SETLKW; + + if (fcntl(fd, action, &lfd) >= 0) + return TRUE; + + /* + ** 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 (errno == EINVAL) + return TRUE; + +# else /* HASFLOCK */ + + if (flock(fd, LOCK_EX) >= 0) + return TRUE; + +# endif + + return FALSE; +} |
