summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/makemap/makemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/makemap/makemap.c')
-rw-r--r--usr.sbin/sendmail/makemap/makemap.c131
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;
+}