diff options
Diffstat (limited to 'makemap')
-rw-r--r-- | makemap/Makefile | 13 | ||||
-rw-r--r-- | makemap/Makefile.dist | 90 | ||||
-rw-r--r-- | makemap/makemap.0 | 58 | ||||
-rw-r--r-- | makemap/makemap.8 | 134 | ||||
-rw-r--r-- | makemap/makemap.c | 781 |
5 files changed, 1076 insertions, 0 deletions
diff --git a/makemap/Makefile b/makemap/Makefile new file mode 100644 index 0000000..e64e093 --- /dev/null +++ b/makemap/Makefile @@ -0,0 +1,13 @@ +# @(#)Makefile 8.4 (Berkeley) 6/10/97 + +PROG= makemap +MAN8= makemap.0 +CFLAGS+=-I${.CURDIR}/../src -DNEWDB -DNOT_SENDMAIL + +SRCS= makemap.c safefile.c + +safefile.c: ${.CURDIR}/../src/safefile.c + ln -s ${.CURDIR}/../src/safefile.c + +.include "../../Makefile.inc" +.include <bsd.prog.mk> diff --git a/makemap/Makefile.dist b/makemap/Makefile.dist new file mode 100644 index 0000000..ad1ca5d --- /dev/null +++ b/makemap/Makefile.dist @@ -0,0 +1,90 @@ +# +# This Makefile is designed to work on the old "make" program. It does +# not use the obj subdirectory. It also does not install documentation +# automatically -- think of it as a quick start for sites that have the +# old make program (I recommend that you get and port the new make if you +# are going to be doing any signficant work on sendmail). +# +# @(#)Makefile.dist 8.7 (Berkeley) 6/10/97 +# + +# use O=-O (usual) or O=-g (debugging) +O= -O + +# location of sendmail source directory +SRCDIR= ../src + +# define the database mechanisms available for map & alias lookups: +# -DNDBM -- use new DBM +# -DNEWDB -- use new Berkeley DB +# The really old (V7) DBM library is no longer supported. +# +DBMDEF= -DNDBM -DNEWDB + +# environment definitions (e.g., -D_AIX3) +ENVDEF= -DNOT_SENDMAIL + +# see also conf.h for additional compilation flags + +# include directories +INCDIRS=-I${SRCDIR} -I/usr/sww/include + +# loader options +LDOPTS= + +# library directories +LIBDIRS=-L/usr/sww/lib + +# libraries required on your system +LIBS= -ldb -ldbm + +# location of makemap binary (usually /usr/sbin or /usr/etc) +BINDIR= ${DESTDIR}/usr/sbin + +# additional .o files needed +OBJADD= + +################### end of user configuration flags ###################### + +CFLAGS= -I. $O ${INCDIRS} ${DBMDEF} ${ENVDEF} + +OBJS= makemap.o safefile.o ${OBJADD} + +LINKS= ${DESTDIR}/usr/ucb/newaliases ${DESTDIR}/usr/ucb/mailq +BINOWN= bin +BINGRP= bin +BINMODE=555 + +ALL= makemap makemap.0 + +all: ${ALL} + +makemap: ${BEFORE} ${OBJS} + ${CC} -o makemap ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS} + +safefile.c: ${SRCDIR}/safefile.c + ln -s ${SRCDIR}/safefile.c safefile.c + +#NROFF= nroff -h +NROFF= groff -Tascii +MANDOC= -mandoc + +makemap.0: makemap.8 + ${NROFF} ${MANDOC} makemap.8 > makemap.0 + +INSTALL=install + +install: install-makemap install-docs + +install-makemap: makemap + ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} makemap ${BINDIR} + +# doesn't actually install them -- you may want to install pre-nroff versions +install-docs: makemap.0 + +clean: + rm -f ${OBJS} makemap makemap.0 + +# dependencies +# gross overkill, and yet still not quite enough.... +${OBJS}: ${SRCDIR}/conf.h diff --git a/makemap/makemap.0 b/makemap/makemap.0 new file mode 100644 index 0000000..73a3862 --- /dev/null +++ b/makemap/makemap.0 @@ -0,0 +1,58 @@ +MAKEMAP(8) BSD System Manager's Manual MAKEMAP(8) + +NNAAMMEE + mmaakkeemmaapp - create database maps for sendmail + +SSYYNNOOPPSSIISS + mmaakkeemmaapp [--NN] [--dd] [--ff] [--oo] [--rr] [--vv] _m_a_p_t_y_p_e _m_a_p_n_a_m_e + +DDEESSCCRRIIPPTTIIOONN + mmaakkeemmaapp creates the database maps used by the keyed map lookups in + sendmail(8). It reads input from the standard input and outputs them to + the indicated _m_a_p_n_a_m_e. + + Depending on how it is compiled, mmaakkeemmaapp handles up to three different + database formats, selected using the _m_a_p_t_y_p_e parameter. They may be + + dbm DBM format maps. This requires the ndbm(3) library. + + btree B-Tree format maps. This requires the new Berkeley db(3) li- + brary. + + hash Hash format maps. This also requires the db(3) library. + + In all cases, mmaakkeemmaapp reads lines from the standard input consisting of + two words separated by white space. The first is the database key, the + second is the value. The value may contain ``%_n'' strings to indicated + parameter substitution. Literal percents should be doubled (``%%''). + Blank lines and lines beginning with ``#'' are ignored. + + FFllaaggss + + --NN Include the null byte that terminates strings in the map. + This must match the -N flag in the sendmail.cf ``K'' line. + + --dd Allow duplicate keys in the map. This is only allowed on B- + Tree format maps. If two identical keys are read, they will + both be inserted into the map. + + --ff Normally all upper case letters in the key are folded to low- + er case. This flag disables that behaviour. This is intend- + ed to mesh with the -f flag in the KK line in sendmail.cf. + The value is never case folded. + + --oo Append to an old file. This allows you to augment an exist- + ing file. + + --rr Allow replacement of existing keys. Normally mmaakkeemmaapp com- + plains if you repeat a key, and does not do the insert. + + --vv Verbosely print what it is doing. + +SSEEEE AALLSSOO + sendmail(8) + +HHIISSTTOORRYY + The mmaakkeemmaapp command appeared in 4.4BSD. + +4.4BSD November 16, 1992 1 diff --git a/makemap/makemap.8 b/makemap/makemap.8 new file mode 100644 index 0000000..3c1f6fa --- /dev/null +++ b/makemap/makemap.8 @@ -0,0 +1,134 @@ +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)makemap.8 8.4 (Berkeley) 7/23/97 +.\" +.Dd November 16, 1992 +.Dt MAKEMAP 8 +.Os BSD 4.4 +.Sh NAME +.Nm makemap +.Nd create database maps for sendmail +.Sh SYNOPSIS +.Nm +.Op Fl N +.Op Fl d +.Op Fl f +.Op Fl o +.Op Fl r +.Op Fl v +.Ar maptype +.Ar mapname +.Sh DESCRIPTION +.Nm +creates the database maps used by the keyed map lookups in +.Xr sendmail 8 . +It reads input from the standard input +and outputs them to the indicated +.Ar mapname . +.Pp +Depending on how it is compiled, +.Nm +handles up to three different database formats, +selected using the +.Ar maptype +parameter. +They may be +.Bl -tag -width Fl +.It Li dbm +DBM format maps. +This requires the +.Xr ndbm 3 +library. +.It Li btree +B-Tree format maps. +This requires the new Berkeley +.Xr db 3 +library. +.It Li hash +Hash format maps. +This also requires the +.Xr db 3 +library. +.El +.Pp +In all cases, +.Nm +reads lines from the standard input consisting of two +words separated by white space. +The first is the database key, +the second is the value. +The value may contain +``%\fIn\fP'' +strings to indicated parameter substitution. +Literal percents should be doubled +(``%%''). +Blank lines and lines beginning with ``#'' are ignored. +.Ss Flags +.Bl -tag -width Fl +.It Fl N +Include the null byte that terminates strings +in the map. +This must match the \-N flag in the sendmail.cf +``K'' line. +.It Fl d +Allow duplicate keys in the map. +This is only allowed on B-Tree format maps. +If two identical keys are read, +they will both be inserted into the map. +.It Fl f +Normally all upper case letters in the key +are folded to lower case. +This flag disables that behaviour. +This is intended to mesh with the +\-f flag in the +\fBK\fP +line in sendmail.cf. +The value is never case folded. +.It Fl o +Append to an old file. +This allows you to augment an existing file. +.It Fl r +Allow replacement of existing keys. +Normally +.Nm +complains if you repeat a key, +and does not do the insert. +.It Fl v +Verbosely print what it is doing. +.El +.Sh SEE ALSO +.Xr sendmail 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.4 . diff --git a/makemap/makemap.c b/makemap/makemap.c new file mode 100644 index 0000000..9d088c6 --- /dev/null +++ b/makemap/makemap.c @@ -0,0 +1,781 @@ +/* + * Copyright (c) 1992 Eric P. Allman. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)makemap.c 8.38 (Berkeley) 9/23/97"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/errno.h> +#ifndef ISC_UNIX +# include <sys/file.h> +#endif +#include "sendmail.h" + +#ifdef NDBM +#include <ndbm.h> +#endif + +#ifdef NEWDB +#include <db.h> +#endif + +enum type { T_DBM, T_BTREE, T_HASH, T_ERR, T_UNKNOWN }; + +union dbent +{ +#ifdef NDBM + datum dbm; +#endif +#ifdef NEWDB + DBT db; +#endif + struct + { + char *data; + size_t size; + } xx; +}; + +uid_t RealUid; +gid_t RealGid; +char *RealUserName; +uid_t RunAsUid; +uid_t RunAsGid; +char *RunAsUserName; +int Verbose = 2; +bool DontInitGroups = TRUE; +bool UnsafeGroupWrites = FALSE; +u_char tTdvect[100]; + +#define BUFSIZE 1024 + +main(argc, argv) + int argc; + char **argv; +{ + char *progname; + bool inclnull = FALSE; + bool notrunc = FALSE; + bool allowreplace = FALSE; + bool allowdups = FALSE; + bool verbose = FALSE; + bool foldcase = TRUE; + bool ignoresafeties = FALSE; + int exitstat; + int opt; + char *typename; + char *mapname; + char *ext; + int lineno; + int st; + int mode; + int putflags; + long dbcachesize = 1024 * 1024; + enum type type; + int fd; + union + { +#ifdef NDBM + DBM *dbm; +#endif +#ifdef NEWDB + DB *db; +#endif + void *dbx; + } dbp; + union dbent key, val; +#ifdef NEWDB + BTREEINFO bti; + HASHINFO hinfo; +#endif + char ibuf[BUFSIZE]; + char fbuf[MAXNAME]; + char dbuf[MAXNAME]; + char pbuf[MAXNAME]; + static char rnamebuf[MAXNAME]; /* holds RealUserName */ + struct passwd *pw; + int sff = SFF_ROOTOK|SFF_REGONLY|SFF_NOLINK|SFF_NOWLINK; + struct stat std, stp; + extern char *optarg; + extern int optind; + extern bool lockfile(); + + progname = argv[0]; + + RunAsUid = RealUid = getuid(); + RunAsGid = RealGid = getgid(); + pw = getpwuid(RealUid); + if (pw != NULL) + { + if (strlen(pw->pw_name) > MAXNAME - 1) + pw->pw_name[MAXNAME] = 0; + sprintf(rnamebuf, "%s", pw->pw_name); + } + else + sprintf(rnamebuf, "Unknown UID %d", RealUid); + RunAsUserName = RealUserName = rnamebuf; + +#if _FFR_NEW_MAKEMAP_FLAGS +#define OPTIONS "Nc:dforsv" +#else +#define OPTIONS "Ndforv" +#endif + while ((opt = getopt(argc, argv, OPTIONS)) != EOF) + { + switch (opt) + { + case 'N': + inclnull = TRUE; + break; + +#if _FFR_NEW_MAKEMAP_FLAGS + case 'c': + dbcachesize = atol(optarg); + break; +#endif + + case 'd': + allowdups = TRUE; + break; + + case 'f': + foldcase = FALSE; + break; + + case 'o': + notrunc = TRUE; + break; + + case 'r': + allowreplace = TRUE; + break; + +#if _FFR_NEW_MAKEMAP_FLAGS + case 's': + ignoresafeties = TRUE; + break; +#endif + + case 'v': + verbose = TRUE; + break; + + default: + type = T_ERR; + break; + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + type = T_ERR; + else + { + typename = argv[0]; + mapname = argv[1]; + ext = NULL; + + if (strcmp(typename, "dbm") == 0) + { + type = T_DBM; + } + else if (strcmp(typename, "btree") == 0) + { + type = T_BTREE; + ext = ".db"; + } + else if (strcmp(typename, "hash") == 0) + { + type = T_HASH; + ext = ".db"; + } + else + type = T_UNKNOWN; + } + + switch (type) + { + case T_ERR: +#if _FFR_NEW_MAKEMAP_FLAGS + fprintf(stderr, + "Usage: %s [-N] [-c cachesize] [-d] [-f] [-o] [-r] [-s] [-v] type mapname\n", + progname); +#else + fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname); +#endif + exit(EX_USAGE); + + case T_UNKNOWN: + fprintf(stderr, "%s: Unknown database type %s\n", + progname, typename); + exit(EX_USAGE); + +#ifndef NDBM + case T_DBM: +#endif +#ifndef NEWDB + case T_BTREE: + case T_HASH: +#endif + 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; + if (allowdups || allowreplace) + putflags = 0; + else + putflags = R_NOOVERWRITE; + break; + + case T_HASH: + bzero(&hinfo, sizeof hinfo); + if (allowreplace) + putflags = 0; + else + putflags = R_NOOVERWRITE; + break; +#endif +#ifdef NDBM + case T_DBM: + if (allowdups) + { + fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n", + progname, typename); + exit(EX_UNAVAILABLE); + } + if (allowreplace) + putflags = DBM_REPLACE; + else + putflags = DBM_INSERT; + break; +#endif + } + + /* + ** Adjust file names. + */ + + if (ext != NULL) + { + int el, fl; + + el = strlen(ext); + fl = strlen(mapname); + if (el + fl + 1 >= sizeof fbuf) + { + fprintf(stderr, "%s: file name too long", mapname); + exit(EX_USAGE); + } + if (fl < el || strcmp(&mapname[fl - el], ext) != 0) + { + strcpy(fbuf, mapname); + strcat(fbuf, ext); + mapname = fbuf; + } + } + + if (!notrunc) + sff |= SFF_CREAT; + switch (type) + { +#ifdef NEWDB + case T_BTREE: + case T_HASH: + if (strlen(mapname) >= sizeof dbuf) + { + fprintf(stderr, + "%s: map name too long\n", mapname); + exit(EX_USAGE); + } + strcpy(dbuf, mapname); + if (!ignoresafeties && + (st = safefile(dbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &std)) != 0) + { + fprintf(stderr, + "%s: could not create: %s\n", + dbuf, errstring(st)); + exit(EX_CANTCREAT); + } + break; +#endif +#ifdef NDBM + case T_DBM: + if (strlen(mapname) + 5 > sizeof dbuf) + { + fprintf(stderr, + "%s: map name too long\n", mapname); + exit(EX_USAGE); + } + sprintf(dbuf, "%s.dir", mapname); + if ((st = safefile(dbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &std)) != 0 && !ignoresafeties) + { + fprintf(stderr, + "%s: could not create: %s\n", + dbuf, errstring(st)); + exit(EX_CANTCREAT); + } + sprintf(pbuf, "%s.pag", mapname); + if ((st = safefile(pbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &stp)) != 0 && !ignoresafeties) + { + fprintf(stderr, + "%s: could not create: %s\n", + pbuf, errstring(st)); + exit(EX_CANTCREAT); + } + break; +#endif + default: + fprintf(stderr, + "%s: internal error: type %d\n", + progname, + type); + exit(EX_SOFTWARE); + } + + /* + ** Create the database. + */ + + mode = O_RDWR; + if (!notrunc) + mode |= O_CREAT|O_TRUNC; +#if O_EXLOCK + mode |= O_EXLOCK; +#else + /* pre-lock the database */ + if (ignoresafeties) + fd = dfopen(dbuf, mode & ~O_TRUNC, 0644, sff); + else + fd = safeopen(dbuf, mode & ~O_TRUNC, 0644, sff); + if (fd < 0) + { + fprintf(stderr, "%s: cannot create type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } +#endif + switch (type) + { +#ifdef NDBM + case T_DBM: + dbp.dbm = dbm_open(mapname, mode, 0644); + if (dbp.dbm != NULL && + dbm_dirfno(dbp.dbm) == dbm_pagfno(dbp.dbm)) + { + fprintf(stderr, "dbm map %s: cannot run with GDBM\n", + mapname); + dbm_close(dbp.dbm); + exit(EX_CONFIG); + } + if (!ignoresafeties && dbp.dbm != NULL && + (filechanged(dbuf, dbm_dirfno(dbp.dbm), &std, sff) || + filechanged(pbuf, dbm_pagfno(dbp.dbm), &stp, sff))) + { + fprintf(stderr, + "dbm map %s: file changed after open\n", + mapname); + dbm_close(dbp.dbm); + exit(EX_CANTCREAT); + } + break; +#endif + +#ifdef NEWDB + case T_HASH: + /* tweak some parameters for performance */ + hinfo.nelem = 4096; + hinfo.cachesize = dbcachesize; + + dbp.db = dbopen(mapname, mode, 0644, DB_HASH, &hinfo); + if (dbp.db != NULL) + { + if (!ignoresafeties && + filechanged(dbuf, dbp.db->fd(dbp.db), &std, sff)) + { + fprintf(stderr, + "db map %s: file changed after open\n", + mapname); + dbp.db->close(dbp.db); + exit(EX_CANTCREAT); + } +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else + (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } + break; + + case T_BTREE: + /* tweak some parameters for performance */ + bti.cachesize = dbcachesize; + + dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti); + if (dbp.db != NULL) + { + if (!ignoresafeties && + filechanged(dbuf, dbp.db->fd(dbp.db), &std, sff)) + { + fprintf(stderr, + "db map %s: file changed after open\n", + mapname); + dbp.db->close(dbp.db); + exit(EX_CANTCREAT); + } +# if OLD_NEWDB + (void) (*dbp.db->sync)(dbp.db); +# else + (void) (*dbp.db->sync)(dbp.db, 0); +# endif + } + break; +#endif + + default: + fprintf(stderr, "%s: internal error: type %d\n", + progname, type); + exit(EX_SOFTWARE); + } + + if (dbp.dbx == NULL) + { + fprintf(stderr, "%s: cannot open type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } + + /* + ** Copy the data + */ + + lineno = 0; + exitstat = EX_OK; + while (fgets(ibuf, sizeof ibuf, stdin) != NULL) + { + register char *p; + + lineno++; + + /* + ** Parse the line. + */ + + p = strchr(ibuf, '\n'); + if (p != NULL) + *p = '\0'; + else if (!feof(stdin)) + { + fprintf(stderr, "%s: %s: line %d: line too long (%d bytes max)\n", + progname, mapname, lineno, sizeof ibuf); + continue; + } + + if (ibuf[0] == '\0' || ibuf[0] == '#') + continue; + if (isspace(ibuf[0])) + { + fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n", + progname, mapname, lineno); + continue; + } + key.xx.data = ibuf; + for (p = ibuf; *p != '\0' && !isspace(*p); p++) + { + if (foldcase && isupper(*p)) + *p = tolower(*p); + } + key.xx.size = p - key.xx.data; + if (inclnull) + key.xx.size++; + if (*p != '\0') + *p++ = '\0'; + while (isspace(*p)) + p++; + if (*p == '\0') + { + fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n", + progname, mapname, lineno, key.xx.data); + continue; + } + val.xx.data = p; + val.xx.size = strlen(p); + if (inclnull) + val.xx.size++; + + /* + ** Do the database insert. + */ + + if (verbose) + { + printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data); + } + + switch (type) + { +#ifdef NDBM + case T_DBM: + st = dbm_store(dbp.dbm, key.dbm, val.dbm, putflags); + break; +#endif + +#ifdef NEWDB + case T_BTREE: + case T_HASH: + st = (*dbp.db->put)(dbp.db, &key.db, &val.db, putflags); + break; +#endif + } + + if (st < 0) + { + fprintf(stderr, "%s: %s: line %d: key %s: put error\n", + progname, mapname, lineno, key.xx.data); + perror(mapname); + exitstat = EX_IOERR; + } + else if (st > 0) + { + fprintf(stderr, + "%s: %s: line %d: key %s: duplicate key\n", + progname, mapname, lineno, key.xx.data); + } + } + + /* + ** Now close the database. + */ + + switch (type) + { +#ifdef NDBM + case T_DBM: + dbm_close(dbp.dbm); + break; +#endif + +#ifdef NEWDB + case T_HASH: + case T_BTREE: + if ((*dbp.db->close)(dbp.db) < 0) + { + fprintf(stderr, "%s: %s: error on close\n", + progname, mapname); + perror(mapname); + exitstat = EX_IOERR; + } +#endif + } + +#if !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. +** filename -- the file name (for error messages). +** ext -- the filename extension. +** 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. +*/ + +bool +lockfile(fd, filename, ext, type) + int fd; + char *filename; + char *ext; + int type; +{ +# if !HASFLOCK + int action; + struct flock lfd; + extern int errno; + + bzero(&lfd, 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; + + 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, type) >= 0) + return TRUE; + +# endif + + return FALSE; +} + +/*VARARGS2*/ +void +#ifdef __STDC__ +message(const char *msg, ...) +#else +message(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + const char *m; + VA_LOCAL_DECL + + m = msg; + if (isdigit(m[0]) && isdigit(m[1]) && isdigit(m[2]) && m[3] == ' ') + m += 4; + VA_START(msg); + vfprintf(stderr, m, ap); + VA_END; + fprintf(stderr, "\n"); +} + +/*VARARGS2*/ +void +#ifdef __STDC__ +syserr(const char *msg, ...) +#else +syserr(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + const char *m; + VA_LOCAL_DECL + + m = msg; + if (isdigit(m[0]) && isdigit(m[1]) && isdigit(m[2]) && m[3] == ' ') + m += 4; + VA_START(msg); + vfprintf(stderr, m, ap); + VA_END; + fprintf(stderr, "\n"); +} + +const char * +errstring(err) + int err; +{ + static char errstr[64]; +#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED) + extern char *sys_errlist[]; + extern int sys_nerr; +#endif + + /* handle pseudo-errors internal to sendmail */ + switch (err) + { + case E_SM_OPENTIMEOUT: + return "Timeout on file open"; + + case E_SM_NOSLINK: + return "Symbolic links not allowed"; + + case E_SM_NOHLINK: + return "Hard links not allowed"; + + case E_SM_REGONLY: + return "Regular files only"; + + case E_SM_ISEXEC: + return "Executable files not allowed"; + + case E_SM_WWDIR: + return "World writable directory"; + + case E_SM_GWDIR: + return "Group writable directory"; + + case E_SM_FILECHANGE: + return "File changed after open"; + + case E_SM_WWFILE: + return "World writable file"; + + case E_SM_GWFILE: + return "Group writable file"; + } + +#if HASSTRERROR + return strerror(err); +#else + if (err < 0 || err > sys_nerr) + { + sprintf(errstr, "Error %d", err); + return errstr; + } + return sys_errlist[err]; +#endif +} |