first cut at merged map/alias implementation
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Tue, 18 May 1993 01:28:30 +0000 (17:28 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Tue, 18 May 1993 01:28:30 +0000 (17:28 -0800)
SCCS-vsn: usr.sbin/sendmail/src/useful.h 6.6
SCCS-vsn: usr.sbin/sendmail/src/conf.h 6.29
SCCS-vsn: usr.sbin/sendmail/src/parseaddr.c 6.53
SCCS-vsn: usr.sbin/sendmail/src/err.c 6.18
SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 6.64
SCCS-vsn: usr.sbin/sendmail/src/daemon.c 6.49
SCCS-vsn: usr.sbin/sendmail/src/readcf.c 6.37
SCCS-vsn: usr.sbin/sendmail/src/conf.c 6.56
SCCS-vsn: usr.sbin/sendmail/src/alias.c 6.46
SCCS-vsn: usr.sbin/sendmail/src/map.c 6.14

usr/src/usr.sbin/sendmail/src/alias.c
usr/src/usr.sbin/sendmail/src/conf.c
usr/src/usr.sbin/sendmail/src/conf.h
usr/src/usr.sbin/sendmail/src/daemon.c
usr/src/usr.sbin/sendmail/src/err.c
usr/src/usr.sbin/sendmail/src/map.c
usr/src/usr.sbin/sendmail/src/parseaddr.c
usr/src/usr.sbin/sendmail/src/readcf.c
usr/src/usr.sbin/sendmail/src/sendmail.h
usr/src/usr.sbin/sendmail/src/useful.h

index 6d0b1b3..6fbc6ee 100644 (file)
@@ -9,80 +9,13 @@
 # include "sendmail.h"
 # include <signal.h>
 # include <pwd.h>
 # include "sendmail.h"
 # include <signal.h>
 # include <pwd.h>
-# ifdef DBM
-ERROR: DBM is no longer supported -- use NDBM instead.
-# endif
-# ifdef NEWDB
-# include <db.h>
-# endif
-# ifdef NDBM
-# include <ndbm.h>
-# endif
-# ifdef NIS_ALIASES
-# include <rpcsvc/ypclnt.h>
-# endif
 
 #ifndef lint
 
 #ifndef lint
-#ifdef NEWDB
-#ifdef NDBM
-static char sccsid[] = "@(#)alias.c    6.45 (Berkeley) %G% (with NEWDB and NDBM)";
-#else
-static char sccsid[] = "@(#)alias.c    6.45 (Berkeley) %G% (with NEWDB)";
-#endif
-#else
-#ifdef NDBM
-static char sccsid[] = "@(#)alias.c    6.45 (Berkeley) %G% (with NDBM)";
-#else
-static char sccsid[] = "@(#)alias.c    6.45 (Berkeley) %G% (without NEWDB or NDBM)";
-#endif
-#endif
+static char sccsid[] = "@(#)alias.c    6.46 (Berkeley) %G%";
 #endif /* not lint */
 #endif /* not lint */
-\f/*
-**  Alias data structures
-*/
-#define ALIASDB                struct _aliasdb
 
 
 
 
-ALIASDB
-{
-       ALIASCLASS      *ad_class;      /* class of this database */
-       char            *ad_name;       /* name of alias file */
-       char            *ad_domain;     /* name of (NIS) domain */
-       void            *ad_dbp;        /* ndbm/nis database pointer */
-#ifdef NEWDB
-       DB              *ad_ndbp;       /* newdb database pointer */
-#endif
-       short           ad_flags;       /* flag bits */
-};
-
-/* bits for ad_flags */
-#define ADF_VALID      0x0001          /* database initialized */
-#define ADF_WRITABLE   0x0002          /* open for write */
-#define ADF_IMPLHASH   0x0004          /* IMPL: underlying hash database */
-#define ADF_IMPLNDBM   0x0008          /* IMPL: underlying NDBM database */
-
-
-ALIASCLASS
-{
-       char    *ac_name;               /* name of alias class */
-       char    *(*ac_lookup)__P((ALIASDB *, char *, ENVELOPE *));
-                                       /* lookup func */
-       void    (*ac_store)__P((ALIASDB *, char *, char *, ENVELOPE *));
-                                       /* database store func */
-       bool    (*ac_init)__P((ALIASDB *, ENVELOPE *));
-                                       /* initialization func */
-       void    (*ac_rebuild)__P((ALIASDB *, FILE *, int, ENVELOPE *));
-                                       /* initialization func */
-       void    (*ac_close)__P((ALIASDB *, ENVELOPE *));
-                                       /* close function */
-       short   ac_flags;               /* flag bits */
-};
-
-/* bits for ac_flags */
-#define ACF_BUILDABLE  0x0001          /* can build a cached version */
-
-
-ALIASDB        AliasDB[MAXALIASDB + 1];        /* actual database list */
+MAP    AliasDB[MAXALIASDB + 1];        /* actual database list */
 int    NAliasDBs;                      /* number of alias databases */
 \f/*
 **  ALIAS -- Compute aliases.
 int    NAliasDBs;                      /* number of alias databases */
 \f/*
 **  ALIAS -- Compute aliases.
@@ -215,15 +148,19 @@ aliaslookup(name, e)
        ENVELOPE *e;
 {
        register int dbno;
        ENVELOPE *e;
 {
        register int dbno;
-       register ALIASDB *ad;
+       register MAP *map;
        register char *p;
        register char *p;
+       char *nullargv[1];
 
 
+       nullargv[0] = NULL;
        for (dbno = 0; dbno < NAliasDBs; dbno++)
        {
        for (dbno = 0; dbno < NAliasDBs; dbno++)
        {
-               ad = &AliasDB[dbno];
-               if (!bitset(ADF_VALID, ad->ad_flags))
+               auto int stat;
+
+               map = &AliasDB[dbno];
+               if (!bitset(MF_VALID, map->map_flags))
                        continue;
                        continue;
-               p = (*ad->ad_class->ac_lookup)(ad, name, e);
+               p = (*map->map_class->map_lookup)(map, name, nullargv, &stat);
                if (p != NULL)
                        return p;
        }
                if (p != NULL)
                        return p;
        }
@@ -245,7 +182,7 @@ setalias(spec)
        char *spec;
 {
        register char *p;
        char *spec;
 {
        register char *p;
-       register ALIASDB *ad;
+       register MAP *map;
        char *class;
        STAB *s;
 
        char *class;
        STAB *s;
 
@@ -265,20 +202,21 @@ setalias(spec)
                        syserr("Too many alias databases defined, %d max", MAXALIASDB);
                        return;
                }
                        syserr("Too many alias databases defined, %d max", MAXALIASDB);
                        return;
                }
-               ad = &AliasDB[NAliasDBs];
+               map = &AliasDB[NAliasDBs];
+               bzero(map, sizeof *map);
 
                p = strpbrk(p, " ,/:");
                if (p != NULL && *p == ':')
                {
 
                p = strpbrk(p, " ,/:");
                if (p != NULL && *p == ':')
                {
-                       /* explicit class listed */
+                       /* map name */
                        *p++ = '\0';
                        class = spec;
                        spec = p;
                }
                else
                {
                        *p++ = '\0';
                        class = spec;
                        spec = p;
                }
                else
                {
-                       /* implicit class */
                        class = "implicit";
                        class = "implicit";
+                       map->map_flags = MF_OPTIONAL;
                }
 
                /* find end of spec */
                }
 
                /* find end of spec */
@@ -288,7 +226,7 @@ setalias(spec)
                        *p++ = '\0';
 
                /* look up class */
                        *p++ = '\0';
 
                /* look up class */
-               s = stab(class, ST_ALIASCLASS, ST_FIND);
+               s = stab(class, ST_MAPCLASS, ST_FIND);
                if (s == NULL)
                {
                        if (tTd(27, 1))
                if (s == NULL)
                {
                        if (tTd(27, 1))
@@ -296,9 +234,12 @@ setalias(spec)
                }
                else
                {
                }
                else
                {
-                       ad->ad_class = s->s_aliasclass;
-                       ad->ad_name = newstr(spec);
-                       NAliasDBs++;
+                       map->map_class = s->s_mapclass;
+                       if (map->map_class->map_parse(map, spec))
+                       {
+                               map->map_flags |= MF_VALID;
+                               NAliasDBs++;
+                       }
                }
        }
 }
                }
        }
 }
@@ -327,33 +268,34 @@ initaliases(rebuild, e)
        register ENVELOPE *e;
 {
        int dbno;
        register ENVELOPE *e;
 {
        int dbno;
-       register ALIASDB *ad;
+       register MAP *map;
 
        for (dbno = 0; dbno < NAliasDBs; dbno++)
        {
 
        for (dbno = 0; dbno < NAliasDBs; dbno++)
        {
-               ad = &AliasDB[dbno];
+               map = &AliasDB[dbno];
 
                if (tTd(27, 2))
                        printf("initaliases(%s:%s)\n",
 
                if (tTd(27, 2))
                        printf("initaliases(%s:%s)\n",
-                               ad->ad_class->ac_name, ad->ad_name);
+                               map->map_class->map_cname, map->map_file);
 
                if (rebuild)
                {
 
                if (rebuild)
                {
-                       rebuildaliases(ad, FALSE, e);
+                       rebuildaliases(map, FALSE, e);
                }
                else
                {
                }
                else
                {
-                       if (ad->ad_class->ac_init(ad, e))
+                       if (map->map_class->map_open(map, O_RDONLY))
                        {
                                if (tTd(27, 4))
                                        printf("%s:%s: valid\n",
                        {
                                if (tTd(27, 4))
                                        printf("%s:%s: valid\n",
-                                               ad->ad_class->ac_name,
-                                               ad->ad_name);
-                               ad->ad_flags |= ADF_VALID;
+                                               map->map_class->map_cname,
+                                               map->map_file);
+                               map->map_flags |= MF_VALID;
+                               aliaswait(map, e);
                        }
                        else if (tTd(27, 4))
                                printf("%s:%s: invalid: %s\n",
                        }
                        else if (tTd(27, 4))
                                printf("%s:%s: invalid: %s\n",
-                                       ad->ad_class->ac_name, ad->ad_name,
+                                       map->map_class->map_cname, map->map_file,
                                        errstring(errno));
                }
        }
                                        errstring(errno));
                }
        }
@@ -364,9 +306,8 @@ initaliases(rebuild, e)
 **     This can decide to reopen or rebuild the alias file
 */
 
 **     This can decide to reopen or rebuild the alias file
 */
 
-aliaswait(ad, ext, e)
-       ALIASDB *ad;
-       char *ext;
+aliaswait(map, e)
+       MAP *map;
        ENVELOPE *e;
 {
        int atcnt;
        ENVELOPE *e;
 {
        int atcnt;
@@ -380,8 +321,10 @@ aliaswait(ad, ext, e)
        atcnt = SafeAlias * 2;
        if (atcnt > 0)
        {
        atcnt = SafeAlias * 2;
        if (atcnt > 0)
        {
+               auto int st;
+
                while (atcnt-- >= 0 &&
                while (atcnt-- >= 0 &&
-                      ad->ad_class->ac_lookup(ad, "@", e) == NULL)
+                      map->map_class->map_lookup(map, "@", NULL, &st) == NULL)
                {
                        /*
                        **  Close and re-open the alias database in case
                {
                        /*
                        **  Close and re-open the alias database in case
@@ -391,36 +334,36 @@ aliaswait(ad, ext, e)
                        if (tTd(27, 2))
                                printf("aliaswait: sleeping\n");
 
                        if (tTd(27, 2))
                                printf("aliaswait: sleeping\n");
 
-                       ad->ad_class->ac_close(ad, e);
+                       map->map_class->map_close(map);
                        sleep(30);
                        sleep(30);
-                       ad->ad_class->ac_init(ad, e);
+                       map->map_class->map_open(map, O_RDONLY);
                }
        }
 
        /* see if we need to go into auto-rebuild mode */
                }
        }
 
        /* see if we need to go into auto-rebuild mode */
-       if (stat(ad->ad_name, &stb) < 0)
+       if (map->map_class->map_rebuild == NULL ||
+           stat(map->map_file, &stb) < 0)
                return;
        mtime = stb.st_mtime;
                return;
        mtime = stb.st_mtime;
-       (void) strcpy(buf, ad->ad_name);
-       (void) strcat(buf, ext);
+       (void) strcpy(buf, map->map_file);
+       if (map->map_class->map_ext != NULL)
+               (void) strcat(buf, map->map_class->map_ext);
        if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || atcnt < 0)
        {
                /* database is out of date */
                if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid())
                {
        if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || atcnt < 0)
        {
                /* database is out of date */
                if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid())
                {
-                       message("auto-rebuilding alias database %s",
-                               ad->ad_name);
-                       rebuildaliases(ad, TRUE, e);
+                       message("auto-rebuilding alias database %s", buf);
+                       rebuildaliases(map, TRUE, e);
                }
                else
                {
 #ifdef LOG
                        if (LogLevel > 3)
                                syslog(LOG_INFO, "alias database %s out of date",
                }
                else
                {
 #ifdef LOG
                        if (LogLevel > 3)
                                syslog(LOG_INFO, "alias database %s out of date",
-                                       ad->ad_name);
+                                       buf);
 #endif /* LOG */
 #endif /* LOG */
-                       message("Warning: alias database %s out of date",
-                               ad->ad_name);
+                       message("Warning: alias database %s out of date", buf);
                }
        }
 }
                }
        }
 }
@@ -428,7 +371,7 @@ aliaswait(ad, ext, e)
 **  REBUILDALIASES -- rebuild the alias database.
 **
 **     Parameters:
 **  REBUILDALIASES -- rebuild the alias database.
 **
 **     Parameters:
-**             ad -- the database to rebuild.
+**             map -- the database to rebuild.
 **             automatic -- set if this was automatically generated.
 **             e -- current envelope.
 **
 **             automatic -- set if this was automatically generated.
 **             e -- current envelope.
 **
@@ -440,15 +383,15 @@ aliaswait(ad, ext, e)
 **             DBM or DB version.
 */
 
 **             DBM or DB version.
 */
 
-rebuildaliases(ad, automatic, e)
-       register ALIASDB *ad;
+rebuildaliases(map, automatic, e)
+       register MAP *map;
        bool automatic;
        register ENVELOPE *e;
 {
        FILE *af;
        void (*oldsigint)();
 
        bool automatic;
        register ENVELOPE *e;
 {
        FILE *af;
        void (*oldsigint)();
 
-       if (!bitset(ACF_BUILDABLE, ad->ad_class->ac_flags))
+       if (map->map_class->map_rebuild == NULL)
                return;
 
 #ifdef LOG
                return;
 
 #ifdef LOG
@@ -457,31 +400,31 @@ rebuildaliases(ad, automatic, e)
                extern char *username();
 
                syslog(LOG_NOTICE, "alias database %s %srebuilt by %s",
                extern char *username();
 
                syslog(LOG_NOTICE, "alias database %s %srebuilt by %s",
-                       ad->ad_name, automatic ? "auto" : "", username());
+                       map->map_file, automatic ? "auto" : "", username());
        }
 #endif /* LOG */
 
        /* try to lock the source file */
        }
 #endif /* LOG */
 
        /* try to lock the source file */
-       if ((af = fopen(ad->ad_name, "r+")) == NULL)
+       if ((af = fopen(map->map_file, "r+")) == NULL)
        {
                if (tTd(27, 1))
                        printf("Can't open %s: %s\n",
        {
                if (tTd(27, 1))
                        printf("Can't open %s: %s\n",
-                               ad->ad_name, errstring(errno));
-               ad->ad_flags &= ~ADF_VALID;
+                               map->map_file, errstring(errno));
+               map->map_flags &= ~MF_VALID;
                errno = 0;
                return;
        }
 
        /* see if someone else is rebuilding the alias file */
                errno = 0;
                return;
        }
 
        /* see if someone else is rebuilding the alias file */
-       if (!lockfile(fileno(af), ad->ad_name, LOCK_EX|LOCK_NB))
+       if (!lockfile(fileno(af), map->map_file, LOCK_EX|LOCK_NB))
        {
                /* yes, they are -- wait until done */
                message("Alias file %s is already being rebuilt",
        {
                /* yes, they are -- wait until done */
                message("Alias file %s is already being rebuilt",
-                       ad->ad_name);
+                       map->map_file);
                if (OpMode != MD_INITALIAS)
                {
                        /* wait for other rebuild to complete */
                if (OpMode != MD_INITALIAS)
                {
                        /* wait for other rebuild to complete */
-                       (void) lockfile(fileno(af), ad->ad_name,
+                       (void) lockfile(fileno(af), map->map_file,
                                        LOCK_EX);
                }
                (void) fclose(af);
                                        LOCK_EX);
                }
                (void) fclose(af);
@@ -491,14 +434,19 @@ rebuildaliases(ad, automatic, e)
 
        oldsigint = signal(SIGINT, SIG_IGN);
 
 
        oldsigint = signal(SIGINT, SIG_IGN);
 
-       ad->ad_class->ac_rebuild(ad, af, automatic, e);
+       map->map_class->map_open(map, O_RDWR);
+       if (bitset(MF_VALID, map->map_flags))
+       {
+               map->map_class->map_rebuild(map, af, automatic);
+               readaliases(map, af, automatic, e);
+       }
 
        /* close the file, thus releasing locks */
        fclose(af);
 
        /* add distinguished entries and close the database */
 
        /* close the file, thus releasing locks */
        fclose(af);
 
        /* add distinguished entries and close the database */
-       if (bitset(ADF_VALID, ad->ad_flags))
-               ad->ad_class->ac_close(ad, e);
+       if (bitset(MF_VALID, map->map_flags))
+               map->map_class->map_close(map);
 
        /* restore the old signal */
        (void) signal(SIGINT, oldsigint);
 
        /* restore the old signal */
        (void) signal(SIGINT, oldsigint);
@@ -510,10 +458,10 @@ rebuildaliases(ad, automatic, e)
 **     when we are not going to use the DBM stuff.
 **
 **     Parameters:
 **     when we are not going to use the DBM stuff.
 **
 **     Parameters:
-**             ad -- the alias database descriptor.
+**             map -- the alias database descriptor.
 **             af -- file to read the aliases from.
 **             automatic -- set if this was an automatic rebuild.
 **             af -- file to read the aliases from.
 **             automatic -- set if this was an automatic rebuild.
-**             e -- the current alias file.
+**             e -- the current envelope.
 **
 **     Returns:
 **             none.
 **
 **     Returns:
 **             none.
@@ -523,9 +471,8 @@ rebuildaliases(ad, automatic, e)
 **             Optionally, builds the .dir & .pag files.
 */
 
 **             Optionally, builds the .dir & .pag files.
 */
 
-static
-readaliases(ad, af, automatic, e)
-       register ALIASDB *ad;
+readaliases(map, af, automatic, e)
+       register MAP *map;
        FILE *af;
        int automatic;
        register ENVELOPE *e;
        FILE *af;
        int automatic;
        register ENVELOPE *e;
@@ -543,7 +490,7 @@ readaliases(ad, af, automatic, e)
        **  Read and interpret lines
        */
 
        **  Read and interpret lines
        */
 
-       FileName = ad->ad_name;
+       FileName = map->map_file;
        LineNumber = 0;
        naliases = bytes = longest = 0;
        skipping = FALSE;
        LineNumber = 0;
        naliases = bytes = longest = 0;
        skipping = FALSE;
@@ -708,7 +655,7 @@ readaliases(ad, af, automatic, e)
 
                lhssize = strlen(al.q_user);
                rhssize = strlen(rhs);
 
                lhssize = strlen(al.q_user);
                rhssize = strlen(rhs);
-               ad->ad_class->ac_store(ad, al.q_user, rhs, e);
+               map->map_class->map_store(map, al.q_user, rhs);
 
                if (al.q_paddr != NULL)
                        free(al.q_paddr);
 
                if (al.q_paddr != NULL)
                        free(al.q_paddr);
@@ -728,801 +675,14 @@ readaliases(ad, af, automatic, e)
        FileName = NULL;
        if (Verbose || !automatic)
                message("%s: %d aliases, longest %d bytes, %d bytes total",
        FileName = NULL;
        if (Verbose || !automatic)
                message("%s: %d aliases, longest %d bytes, %d bytes total",
-                       ad->ad_name, naliases, longest, bytes);
+                       map->map_file, naliases, longest, bytes);
 # ifdef LOG
        if (LogLevel > 7)
                syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
 # ifdef LOG
        if (LogLevel > 7)
                syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
-                       ad->ad_name, naliases, longest, bytes);
+                       map->map_file, naliases, longest, bytes);
 # endif /* LOG */
 }
 \f/*
 # endif /* LOG */
 }
 \f/*
-**  NDBM modules
-*/
-
-#ifdef NDBM
-
-/*
-**  NDBM_ALOOKUP -- look up alias in ndbm file
-*/
-
-char *
-ndbm_alookup(ad, name, e)
-       register ALIASDB *ad;
-       char *name;
-       ENVELOPE *e;
-{
-       int i;
-       datum rhs, lhs;
-       char keybuf[MAXNAME + 1];
-
-       if (tTd(27, 20))
-               printf("ndbm_lookup(%s)\n", name);
-
-       /* create a key for fetch */
-       i = strlen(name) + 1;
-       if (i > sizeof keybuf)
-               i = sizeof keybuf;
-       bcopy(name, keybuf, i);
-       if (!bitnset(M_USR_UPPER, LocalMailer->m_flags))
-               makelower(keybuf);
-
-       lhs.dsize = i;
-       lhs.dptr = keybuf;
-       rhs = dbm_fetch((DBM *) ad->ad_dbp, lhs);
-       return (rhs.dptr);
-}
-
-
-/*
-**  NDBM_ASTORE -- store a datum in the database
-*/
-
-void
-ndbm_astore(ad, lhs, rhs, e)
-       register ALIASDB *ad;
-       char *lhs;
-       char *rhs;
-       ENVELOPE *e;
-{
-       datum key;
-       datum data;
-       int stat;
-
-       key.dsize = strlen(lhs) + 1;
-       key.dptr = lhs;
-
-       data.dsize = strlen(rhs) + 1;
-       data.dptr = rhs;
-
-       stat = dbm_store((DBM *) ad->ad_dbp, key, data, DBM_INSERT);
-       if (stat > 0)
-       {
-               usrerr("050 Warning: duplicate alias name %s", lhs);
-               stat = dbm_store((DBM *) ad->ad_dbp, key, data, DBM_REPLACE);
-       }
-       if (stat != 0)
-               syserr("readaliases: dbm put (%s)", lhs);
-}
-
-
-/*
-**  NDBM_AINIT -- initialize DBM database
-*/
-
-bool
-ndbm_ainit(ad, e)
-       register ALIASDB *ad;
-       ENVELOPE *e;
-{
-       char buf[MAXNAME];
-
-       if (tTd(27, 2))
-               printf("ndbm_ainit(%s)\n", ad->ad_name);
-
-       /* open the database */
-       ad->ad_dbp = (void *) dbm_open(ad->ad_name, O_RDONLY, DBMMODE);
-       if (ad->ad_dbp == NULL)
-               return FALSE;
-
-       /* wait for @:@ to appear */
-       aliaswait(ad, ".pag", e);
-
-       return TRUE;
-}
-
-
-/*
-**  NDBM_AREBUILD -- rebuild hash database
-*/
-
-void
-ndbm_arebuild(ad, fp, automatic, e)
-       register ALIASDB *ad;
-       FILE *fp;
-       int automatic;
-       ENVELOPE *e;
-{
-       register DBM *db;
-       int i;
-       char buf[MAXNAME];
-
-       if (tTd(27, 2))
-               printf("ndbm_arebuild(%s)\n", ad->ad_name);
-
-       db = dbm_open(ad->ad_name, O_RDWR|O_CREAT|O_TRUNC, DBMMODE);
-       if (db == NULL)
-       {
-               syserr("ndbm_arebuild: cannot create %s", buf);
-               return;
-       }
-       ad->ad_dbp = (void *) db;
-       ad->ad_flags |= ADF_WRITABLE|ADF_VALID;
-
-       /* read and store the aliases */
-       readaliases(ad, fp, automatic, e);
-}
-
-/*
-**  NDBM_ACLOSE -- close the database
-*/
-
-void
-ndbm_aclose(ad, e)
-       register ALIASDB  *ad;
-       ENVELOPE *e;
-{
-       if (bitset(ADF_WRITABLE, ad->ad_flags))
-       {
-#ifdef YPCOMPAT
-               char buf[200];
-
-               (void) sprintf(buf, "%010ld", curtime());
-               ndbm_astore(ad, "YP_LAST_MODIFIED", buf, e);
-
-               (void) myhostname(buf, sizeof buf);
-               ndbm_astore(ad, "YP_MASTER_NAME", buf, e);
-#endif
-
-               /* write out the distinguished alias */
-               ndbm_astore(ad, "@", "@", e);
-       }
-       dbm_close((DBM *) ad->ad_dbp);
-}
-
-#endif
-\f/*
-**  HASH (NEWDB) Modules
-*/
-
-#ifdef NEWDB
-
-/*
-**  HASH_ALOOKUP -- look up alias in hash file
-*/
-
-char *
-hash_alookup(ad, name, e)
-       register ALIASDB *ad;
-       char *name;
-       ENVELOPE *e;
-{
-       int i;
-       DBT rhs, lhs;
-       int s;
-       char keybuf[MAXNAME + 1];
-
-       if (tTd(27, 20))
-               printf("hash_alookup(%s)\n", name);
-
-       /* create a key for fetch */
-       i = strlen(name) + 1;
-       if (i > sizeof keybuf)
-               i = sizeof keybuf;
-       bcopy(name, keybuf, i);
-       if (!bitnset(M_USR_UPPER, LocalMailer->m_flags))
-               makelower(keybuf);
-
-       lhs.size = i;
-       lhs.data = keybuf;
-       i = ad->ad_ndbp->get(ad->ad_ndbp, &lhs, &rhs, 0);
-       if (i == 0)
-               return (rhs.data);
-       return (NULL);
-}
-
-
-/*
-**  HASH_ASTORE -- store a datum in the database
-*/
-
-void
-hash_astore(ad, lhs, rhs, e)
-       register ALIASDB *ad;
-       char *lhs;
-       char *rhs;
-       ENVELOPE *e;
-{
-       int stat;
-       DBT key;
-       DBT data;
-
-       if (tTd(27, 20))
-               printf("hash_astore(%s, %s)\n", lhs, rhs);
-
-       key.size = strlen(lhs) + 1;
-       key.data = lhs;
-
-       data.size = strlen(rhs) + 1;
-       data.data = rhs;
-
-       stat = ad->ad_ndbp->put(ad->ad_ndbp, &key, &data, R_NOOVERWRITE);
-       if (stat > 0)
-       {
-               usrerr("050 Warning: duplicate alias name %s", lhs);
-               stat = ad->ad_ndbp->put(ad->ad_ndbp, &key, &data, 0);
-       }
-       if (stat != 0)
-               syserr("readaliases: db put (%s)", lhs);
-}
-
-
-/*
-**  HASH_AINIT -- initialize hash database
-*/
-
-bool
-hash_ainit(ad, e)
-       register ALIASDB *ad;
-       ENVELOPE *e;
-{
-       char buf[MAXNAME];
-
-       if (tTd(27, 2))
-               printf("hash_ainit(%s)\n", ad->ad_name);
-
-       /* open the database */
-       (void) strcpy(buf, ad->ad_name);
-       (void) strcat(buf, ".db");
-       ad->ad_ndbp = dbopen(buf, O_RDONLY, DBMMODE, DB_HASH, NULL);
-       if (ad->ad_ndbp == NULL)
-               return FALSE;
-
-       /* wait for @:@ to appear */
-       aliaswait(ad, ".db", e);
-       return TRUE;
-}
-
-
-/*
-**  HASH_AREBUILD -- rebuild hash database
-*/
-
-void
-hash_arebuild(ad, fp, automatic, e)
-       register ALIASDB *ad;
-       FILE *fp;
-       int automatic;
-       ENVELOPE *e;
-{
-       register DB *db;
-       char buf[MAXNAME];
-
-       if (tTd(27, 2))
-               printf("hash_arebuild(%s)\n", ad->ad_name);
-
-       (void) strcpy(buf, ad->ad_name);
-       (void) strcat(buf, ".db");
-       db = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL);
-       if (db == NULL)
-       {
-               syserr("hash_arebuild: cannot create %s", buf);
-               return;
-       }
-       ad->ad_ndbp = db;
-       ad->ad_flags |= ADF_WRITABLE|ADF_VALID;
-
-       /* read and store the aliases */
-       readaliases(ad, fp, automatic, e);
-}
-
-
-/*
-**  HASH_ACLOSE -- add distinguished entries and close the database
-*/
-
-void
-hash_aclose(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-       if (tTd(27, 9))
-               printf("hash_aclose(%x)\n", ad->ad_flags);
-
-       if (bitset(ADF_WRITABLE, ad->ad_flags))
-       {
-               /* write out the distinguished alias */
-               hash_astore(ad, "@", "@", e);
-       }
-
-       if (ad->ad_ndbp->close(ad->ad_ndbp) != 0)
-               syserr("readaliases: db close failure");
-}
-
-#endif
-\f/*
-**  STAB (Symbol Table) Modules
-*/
-
-
-/*
-**  STAB_ALOOKUP -- look up alias in symbol table
-*/
-
-char *
-stab_alookup(ad, name, e)
-       register ALIASDB *ad;
-       char *name;
-       ENVELOPE *e;
-{
-       register STAB *s;
-
-       if (tTd(27, 20))
-               printf("stab_lookup(%s)\n", name);
-
-       s = stab(name, ST_ALIAS, ST_FIND);
-       if (s != NULL)
-               return (s->s_alias);
-       return (NULL);
-}
-
-
-/*
-**  STAB_ASTORE -- store in symtab (actually using during init, not rebuild)
-*/
-
-void
-stab_astore(ad, lhs, rhs, e)
-       register ALIASDB *ad;
-       char *lhs;
-       char *rhs;
-       ENVELOPE *e;
-{
-       register STAB *s;
-
-       s = stab(lhs, ST_ALIAS, ST_ENTER);
-       s->s_alias = newstr(rhs);
-}
-
-
-/*
-**  STAB_AINIT -- initialize (reads data file)
-*/
-
-bool
-stab_ainit(ad, e)
-       register ALIASDB *ad;
-       ENVELOPE *e;
-{
-       FILE *af;
-
-       if (tTd(27, 2))
-               printf("stab_ainit(%s)\n", ad->ad_name);
-
-       af = fopen(ad->ad_name, "r");
-       if (af == NULL)
-               return FALSE;
-
-       readaliases(ad, af, TRUE, e);
-}
-
-
-/*
-**  STAB_AREBUILD -- rebuild alias file
-*/
-
-void
-stab_arebuild(ad, fp, automatic, e)
-       ALIASDB *ad;
-       FILE *fp;
-       int automatic;
-       ENVELOPE *e;
-{
-       if (tTd(27, 2))
-               printf("stab_arebuild(%s)\n", ad->ad_name);
-
-       ad->ad_flags |= ADF_WRITABLE|ADF_VALID;
-}
-
-
-/*
-**  STAB_ACLOSE -- close symbol table (???)
-*/
-
-void
-stab_aclose(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-       /* ignore it */
-}
-\f/*
-**  NIS Modules
-*/
-
-#ifdef NIS_ALIASES
-
-/*
-**  NIS_ALOOKUP
-*/
-
-char *
-nis_alookup(ad, name, e)
-       ALIASDB *ad;
-       char *name;
-       ENVELOPE *e;
-{
-       auto char *vp;
-       auto int vsize;
-       int yperr;
-       int keylen;
-
-       if (tTd(27, 20))
-               printf("nis_lookup(%s)\n", name);
-
-       keylen = strlen(name);
-       yperr = yp_match(ad->ad_domain, ad->ad_name, name, keylen,
-                       &vp, &vsize);
-       if (yperr == YPERR_KEY)
-               yperr = yp_match(ad->ad_domain, ad->ad_name, name, ++keylen,
-                               &vp, &vsize);
-       if (yperr == 0)
-               return vp;
-
-       if (tTd(27, 10))
-               printf("nis_alookup: yp_match(%s, %s, %s) => %s\n",
-                       ad->ad_domain, ad->ad_name, name, yperr_string(yperr));
-       if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
-               ad->ad_flags &= ~ADF_VALID;
-       return NULL;
-}
-
-/*
-**  NIS_ASTORE
-*/
-
-void
-nis_astore(ad, lhs, rhs, e)
-       ALIASDB *ad;
-       char *lhs;
-       char *rhs;
-       ENVELOPE *e;
-{
-       /* nothing */
-}
-
-/*
-**  NIS_AINIT
-*/
-
-bool
-nis_ainit(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-       register char *p;
-       int yperr;
-       auto char *vp;
-       auto int vsize;
-
-       if (tTd(27, 2))
-               printf("nis_ainit(%s)\n", ad->ad_name);
-
-       p = strchr(ad->ad_name, '@');
-       if (p != NULL)
-       {
-               *p++ = '\0';
-               if (*p != '\0')
-                       ad->ad_domain = p;
-       }
-       if (ad->ad_domain == NULL)
-               yp_get_default_domain(&ad->ad_domain);
-
-       if (*ad->ad_name == '\0')
-               ad->ad_name = "mail.aliases";
-
-       yperr = yp_match(ad->ad_domain, ad->ad_name, "@", 1,
-                       &vp, &vsize);
-       if (tTd(27, 10))
-               printf("nis_ainit: yp_match(%s, %s) => %s\n",
-                       ad->ad_domain, ad->ad_name, yperr_string(yperr));
-       if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
-               return TRUE;
-       return FALSE;
-}
-
-/*
-**  NIS_AREBUILD
-*/
-
-void
-nis_arebuild(ad, fp, automatic, e)
-       ALIASDB *ad;
-       FILE *fp;
-       int automatic;
-       ENVELOPE *e;
-{
-       if (tTd(27, 2))
-               printf("nis_arebuild(%s)\n", ad->ad_name);
-}
-
-
-/*
-**  NIS_ACLOSE
-*/
-
-void
-nis_aclose(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-       /* nothing */
-}
-
-#endif /* NIS_ALIASES */
-\f/*
-**  Implicit Modules
-**
-**     Tries several types.  For back compatibility.
-*/
-
-/*
-**  IMPL_ALOOKUP -- lookup in best open database
-*/
-
-char *
-impl_alookup(ad, name, e)
-       ALIASDB *ad;
-       char *name;
-       ENVELOPE *e;
-{
-       if (tTd(27, 20))
-               printf("impl_lookup(%s)\n", name);
-
-#ifdef NEWDB
-       if (bitset(ADF_IMPLHASH, ad->ad_flags))
-               return hash_alookup(ad, name, e);
-#endif
-#ifdef NDBM
-       if (bitset(ADF_IMPLNDBM, ad->ad_flags))
-               return ndbm_alookup(ad, name, e);
-#endif
-       return stab_alookup(ad, name, e);
-}
-
-/*
-**  IMPL_ASTORE -- store in open databases
-*/
-
-void
-impl_astore(ad, lhs, rhs, e)
-       ALIASDB *ad;
-       char *lhs;
-       char *rhs;
-       ENVELOPE *e;
-{
-#ifdef NEWDB
-       if (bitset(ADF_IMPLHASH, ad->ad_flags))
-               hash_astore(ad, lhs, rhs, e);
-#endif
-#ifdef NDBM
-       if (bitset(ADF_IMPLNDBM, ad->ad_flags))
-               ndbm_astore(ad, lhs, rhs, e);
-#endif
-       stab_astore(ad, lhs, rhs, e);
-}
-
-/*
-**  IMPL_AINIT -- implicit database lookup
-*/
-
-bool
-impl_ainit(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-       struct stat stb;
-
-       if (tTd(27, 2))
-               printf("impl_ainit(%s)\n", ad->ad_name);
-
-       if (stat(ad->ad_name, &stb) < 0)
-       {
-               /* no alias file at all */
-               return FALSE;
-       }
-
-#ifdef NEWDB
-       ad->ad_flags |= ADF_IMPLHASH;
-       if (hash_ainit(ad, e))
-       {
-               return TRUE;
-       }
-       ad->ad_flags &= ~ADF_IMPLHASH;
-#endif
-#ifdef NDBM
-       ad->ad_flags |= ADF_IMPLNDBM;
-       if (ndbm_ainit(ad, e))
-       {
-               return TRUE;
-       }
-       ad->ad_flags &= ~ADF_IMPLNDBM;
-#endif
-
-       if (Verbose)
-               message("WARNING: cannot open alias database %s", ad->ad_name);
-
-       if (stab_ainit(ad, e))
-       {
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-/*
-**  IMPL_AREBUILD -- rebuild alias database
-*/
-
-void
-impl_arebuild(ad, fp, automatic, e)
-       ALIASDB *ad;
-       FILE *fp;
-       int automatic;
-       ENVELOPE *e;
-{
-#ifdef NEWDB
-       DB *ndb;
-       char buf[MAXNAME];
-#endif
-
-       if (tTd(27, 2))
-               printf("impl_arebuild(%s)\n", ad->ad_name);
-
-#ifdef NEWDB
-       (void) strcpy(buf, ad->ad_name);
-       (void) strcat(buf, ".db");
-       ndb = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL);
-       if (ndb == NULL)
-       {
-               syserr("rebuildaliases: cannot create %s", buf);
-       }
-       else
-       {
-               ad->ad_ndbp = ndb;
-               ad->ad_flags |= ADF_IMPLHASH;
-#if defined(NDBM) && defined(YPCOMPAT)
-               if (access("/var/yp/Makefile", R_OK) != 0)
-#endif
-                       goto readem;
-       }
-#endif
-
-#ifdef NDBM
-       ad->ad_dbp = (void *) dbm_open(ad->ad_name, O_RDWR|O_CREAT|O_TRUNC, DBMMODE);
-       if (ad->ad_dbp == NULL)
-       {
-               syserr("rebuildaliases: cannot create %s.{pag,dir}",
-                       ad->ad_name);
-       }
-       else
-       {
-               ad->ad_flags |= ADF_IMPLNDBM;
-       }
-#endif
-
-       if (!bitset(ADF_IMPLHASH|ADF_IMPLNDBM, ad->ad_flags))
-               return;
-
-  readem:
-       ad->ad_flags |= ADF_WRITABLE|ADF_VALID;
-
-       /* read and store aliases */
-       readaliases(ad, fp, automatic, e);
-}
-
-
-/*
-**  IMPL_ACLOSE -- close any open database(s)
-*/
-
-void
-impl_aclose(ad, e)
-       ALIASDB *ad;
-       ENVELOPE *e;
-{
-#ifdef NEWDB
-       if (bitset(ADF_IMPLHASH, ad->ad_flags))
-               hash_aclose(ad, e);
-#endif
-
-#ifdef NDBM
-       if (bitset(ADF_IMPLNDBM, ad->ad_flags))
-               ndbm_aclose(ad, e);
-#endif
-}
-\f/*
-**  SETUPALIASES -- set up aliases classes
-*/
-
-#ifdef NEWDB
-ALIASCLASS     HashAClass =
-{
-       "hash",         hash_alookup,   hash_astore,
-       hash_ainit,     hash_arebuild,  hash_aclose,
-       ACF_BUILDABLE
-};
-#endif
-
-#ifdef NDBM
-ALIASCLASS     DbmAClass =
-{
-       "dbm",          ndbm_alookup,   ndbm_astore,
-       ndbm_ainit,     ndbm_arebuild,  ndbm_aclose,
-       ACF_BUILDABLE
-};
-#endif
-
-#ifdef NIS_ALIASES
-ALIASCLASS     NisAClass =
-{
-       "nis",          nis_alookup,    nis_astore,
-       nis_ainit,      nis_arebuild,   nis_aclose,
-       0
-};
-#endif
-
-ALIASCLASS     StabAClass =
-{
-       "stab",         stab_alookup,   stab_astore,
-       stab_ainit,     stab_arebuild,  stab_aclose,
-       0
-};
-
-ALIASCLASS     ImplAClass =
-{
-       "implicit",     impl_alookup,   impl_astore,
-       impl_ainit,     impl_arebuild,  impl_aclose,
-       ACF_BUILDABLE
-};
-
-setupaliases()
-{
-       register STAB *s;
-
-#ifdef NEWDB
-       s = stab("hash", ST_ALIASCLASS, ST_ENTER);
-       s->s_aliasclass = &HashAClass;
-#endif
-
-#ifdef NDBM
-       s = stab("dbm", ST_ALIASCLASS, ST_ENTER);
-       s->s_aliasclass = &DbmAClass;
-#endif
-
-#ifdef NIS_ALIASES
-       s = stab("nis", ST_ALIASCLASS, ST_ENTER);
-       s->s_aliasclass = &NisAClass;
-#endif
-
-#if !defined(NEWDB) && !defined(NDBM)
-       s = stab("stab", ST_ALIASCLASS, ST_ENTER);
-       s->s_aliasclass = &StabAClass;
-#endif
-
-       s = stab("implicit", ST_ALIASCLASS, ST_ENTER);
-       s->s_aliasclass = &ImplAClass;
-}
-\f/*
 **  FORWARD -- Try to forward mail
 **
 **     This is similar but not identical to aliasing.
 **  FORWARD -- Try to forward mail
 **
 **     This is similar but not identical to aliasing.
index f65aa1b..6b9fde6 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)conf.c     6.55 (Berkeley) %G%";
+static char sccsid[] = "@(#)conf.c     6.56 (Berkeley) %G%";
 #endif /* not lint */
 
 # include <sys/ioctl.h>
 #endif /* not lint */
 
 # include <sys/ioctl.h>
@@ -179,7 +179,6 @@ setdefaults(e)
        TimeOuts.to_q_warning = 0;              /* option T */
        PrivacyFlags = 0;                       /* option p */
        setdefuser();
        TimeOuts.to_q_warning = 0;              /* option T */
        PrivacyFlags = 0;                       /* option p */
        setdefuser();
-       setupaliases();
        setupmaps();
        setupmailers();
 }
        setupmaps();
        setupmailers();
 }
@@ -201,97 +200,6 @@ setdefuser()
                strcpy(defuserbuf, "nobody");
 }
 \f/*
                strcpy(defuserbuf, "nobody");
 }
 \f/*
-**  SETUPMAPS -- set up map classes
-**
-**     Since these are compiled in, they cannot be in the config file.
-**
-*/
-
-setupmaps()
-{
-       register STAB *s;
-
-       /* host name lookup map */
-       {
-               extern bool host_map_init();
-               extern char *maphostname();
-
-               s = stab("host", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = host_map_init;
-               s->s_mapclass.map_lookup = maphostname;
-       }
-
-       /* dequote map */
-       {
-               extern bool dequote_init();
-               extern char *dequote_map();
-
-               s = stab("dequote", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = dequote_init;
-               s->s_mapclass.map_lookup = dequote_map;
-       }
-
-# ifdef DBM_MAP
-       /* dbm file access */
-       {
-               extern bool dbm_map_init();
-               extern char *dbm_map_lookup();
-
-               s = stab("dbm", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = dbm_map_init;
-               s->s_mapclass.map_lookup = dbm_map_lookup;
-       }
-# endif
-
-# ifdef BTREE_MAP
-       /* new database file access -- btree files */
-       {
-               extern bool bt_map_init();
-               extern char *db_map_lookup();
-
-               s = stab("btree", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = bt_map_init;
-               s->s_mapclass.map_lookup = db_map_lookup;
-       }
-# endif
-
-# ifdef HASH_MAP
-       /* new database file access -- hash files */
-       {
-               extern bool hash_map_init();
-               extern char *db_map_lookup();
-
-               s = stab("hash", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = hash_map_init;
-               s->s_mapclass.map_lookup = db_map_lookup;
-       }
-# endif
-
-# ifdef NIS_MAP
-       /* NIS map access */
-       {
-               extern bool nis_map_init();
-               extern char *nis_map_lookup();
-
-               s = stab("nis", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = nis_map_init;
-               s->s_mapclass.map_lookup = nis_map_lookup;
-       }
-# endif
-
-# ifdef USERDB_MAP
-       /* user database */
-       {
-               extern bool udb_map_init();
-               extern char *udb_map_lookup();
-
-               s = stab("udb", ST_MAPCLASS, ST_ENTER);
-               s->s_mapclass.map_init = udb_map_init;
-               s->s_mapclass.map_lookup = udb_map_lookup;
-       }
-# endif
-}
-\f/*
 **  HOST_MAP_INIT -- initialize host class structures
 */
 
 **  HOST_MAP_INIT -- initialize host class structures
 */
 
index 3a95f84..adce7f3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)conf.h      6.28 (Berkeley) %G%
+ *     @(#)conf.h      6.29 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,6 +15,7 @@
 # include <sys/param.h>
 # include <sys/stat.h>
 # include <fcntl.h>
 # include <sys/param.h>
 # include <sys/stat.h>
 # include <fcntl.h>
+# include "cdefs.h"
 
 /*
 **  Table sizes, etc....
 
 /*
 **  Table sizes, etc....
index 18f0fca..5988a67 100644 (file)
@@ -13,9 +13,9 @@
 
 #ifndef lint
 #ifdef DAEMON
 
 #ifndef lint
 #ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c   6.48 (Berkeley) %G% (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c   6.49 (Berkeley) %G% (with daemon mode)";
 #else
 #else
-static char sccsid[] = "@(#)daemon.c   6.48 (Berkeley) %G% (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c   6.49 (Berkeley) %G% (without daemon mode)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -56,7 +56,7 @@ static char sccsid[] = "@(#)daemon.c  6.48 (Berkeley) %G% (without daemon mode)";
 **             appropriate for communication.  Returns zero on
 **             success, else an exit status describing the
 **             error.
 **             appropriate for communication.  Returns zero on
 **             success, else an exit status describing the
 **             error.
-**     maphostname(map, hbuf, hbufsiz, avp)
+**     host_map_lookup(map, hbuf, avp, pstat)
 **             Convert the entry in hbuf into a canonical form.
 */
 
 **             Convert the entry in hbuf into a canonical form.
 */
 
@@ -400,8 +400,6 @@ gothostent:
                (void) close(s);
                if (hp && hp->h_addr_list[i])
                {
                (void) close(s);
                if (hp && hp->h_addr_list[i])
                {
-                       extern char *errstring();
-
                        if (tTd(16, 1))
                                printf("Connect failed (%s); trying new address....\n",
                                        errstring(sav_errno));
                        if (tTd(16, 1))
                                printf("Connect failed (%s); trying new address....\n",
                                        errstring(sav_errno));
@@ -433,8 +431,6 @@ gothostent:
                        return EX_TEMPFAIL;
                else
                {
                        return EX_TEMPFAIL;
                else
                {
-                       extern char *errstring();
-
                        message("%s", errstring(sav_errno));
                        return (EX_UNAVAILABLE);
                }
                        message("%s", errstring(sav_errno));
                        return (EX_UNAVAILABLE);
                }
@@ -681,12 +677,11 @@ finish:
        return hbuf;
 }
 \f/*
        return hbuf;
 }
 \f/*
-**  MAPHOSTNAME -- turn a hostname into canonical form
+**  HOST_MAP_LOOKUP -- turn a hostname into canonical form
 **
 **     Parameters:
 **             map -- a pointer to this map (unused).
 **
 **     Parameters:
 **             map -- a pointer to this map (unused).
-**             hbuf -- a buffer containing a hostname.
-**             hbsize -- the size of hbuf.
+**             name -- the (presumably unqualified) hostname.
 **             avp -- unused -- for compatibility with other mapping
 **                     functions.
 **             statp -- an exit status (out parameter) -- set to
 **             avp -- unused -- for compatibility with other mapping
 **                     functions.
 **             statp -- an exit status (out parameter) -- set to
@@ -703,10 +698,9 @@ finish:
 */
 
 char *
 */
 
 char *
-maphostname(map, hbuf, hbsize, avp, statp)
+host_map_lookup(map, name, avp, statp)
        MAP *map;
        MAP *map;
-       char *hbuf;
-       int hbsize;
+       char *name;
        char **avp;
        int *statp;
 {
        char **avp;
        int *statp;
 {
@@ -715,23 +709,21 @@ maphostname(map, hbuf, hbsize, avp, statp)
        char *cp;
        int i;
        register STAB *s;
        char *cp;
        int i;
        register STAB *s;
+       static char hbuf[MAXNAME];
        extern struct hostent *gethostbyaddr();
        extern int h_errno;
 
        extern struct hostent *gethostbyaddr();
        extern int h_errno;
 
-       /* allow room for null */
-       hbsize--;
-
        /*
        **  See if we have already looked up this name.  If so, just
        **  return it.
        */
 
        /*
        **  See if we have already looked up this name.  If so, just
        **  return it.
        */
 
-       s = stab(hbuf, ST_NAMECANON, ST_ENTER);
+       s = stab(name, ST_NAMECANON, ST_ENTER);
        if (bitset(NCF_VALID, s->s_namecanon.nc_flags))
        {
                if (tTd(9, 1))
        if (bitset(NCF_VALID, s->s_namecanon.nc_flags))
        {
                if (tTd(9, 1))
-                       printf("maphostname(%s, %d) => CACHE %s\n",
-                               hbuf, hbsize, s->s_namecanon.nc_cname);
+                       printf("host_map_lookup(%s) => CACHE %s\n",
+                               name, s->s_namecanon.nc_cname);
                errno = s->s_namecanon.nc_errno;
                h_errno = s->s_namecanon.nc_herrno;
                *statp = s->s_namecanon.nc_stat;
                errno = s->s_namecanon.nc_errno;
                h_errno = s->s_namecanon.nc_herrno;
                *statp = s->s_namecanon.nc_stat;
@@ -741,18 +733,19 @@ maphostname(map, hbuf, hbsize, avp, statp)
        /*
        **  If first character is a bracket, then it is an address
        **  lookup.  Address is copied into a temporary buffer to
        /*
        **  If first character is a bracket, then it is an address
        **  lookup.  Address is copied into a temporary buffer to
-       **  strip the brackets and to preserve hbuf if address is
+       **  strip the brackets and to preserve name if address is
        **  unknown.
        */
 
        **  unknown.
        */
 
-       if (*hbuf != '[')
+       if (*name != '[')
        {
                extern bool getcanonname();
 
                if (tTd(9, 1))
        {
                extern bool getcanonname();
 
                if (tTd(9, 1))
-                       printf("maphostname(%s, %d) => ", hbuf, hbsize);
+                       printf("host_map_lookup(%s) => ", name);
                s->s_namecanon.nc_flags |= NCF_VALID;           /* will be soon */
                s->s_namecanon.nc_flags |= NCF_VALID;           /* will be soon */
-               if (getcanonname(hbuf, hbsize))
+               (void) strcpy(hbuf, name);
+               if (getcanonname(hbuf, sizeof hbuf - 1))
                {
                        if (tTd(9, 1))
                                printf("%s\n", hbuf);
                {
                        if (tTd(9, 1))
                                printf("%s\n", hbuf);
@@ -801,7 +794,7 @@ maphostname(map, hbuf, hbsize, avp, statp)
                        **  Try to look it up in /etc/hosts
                        */
 
                        **  Try to look it up in /etc/hosts
                        */
 
-                       hp = gethostbyname(hbuf);
+                       hp = gethostbyname(name);
                        if (hp == NULL)
                        {
                                /* no dice there either */
                        if (hp == NULL)
                        {
                                /* no dice there either */
@@ -814,18 +807,18 @@ maphostname(map, hbuf, hbsize, avp, statp)
                        return hp->h_name;
                }
        }
                        return hp->h_name;
                }
        }
-       if ((cp = strchr(hbuf, ']')) == NULL)
+       if ((cp = strchr(name, ']')) == NULL)
                return (NULL);
        *cp = '\0';
                return (NULL);
        *cp = '\0';
-       in_addr = inet_addr(&hbuf[1]);
+       in_addr = inet_addr(&name[1]);
 
        /* check to see if this is one of our addresses */
        for (i = 0; MyIpAddrs[i].s_addr != 0; i++)
        {
                if (MyIpAddrs[i].s_addr == in_addr)
                {
 
        /* check to see if this is one of our addresses */
        for (i = 0; MyIpAddrs[i].s_addr != 0; i++)
        {
                if (MyIpAddrs[i].s_addr == in_addr)
                {
-                       strncpy(hbuf, MyHostName, hbsize);
-                       hbuf[hbsize] = '\0';
+                       strncpy(hbuf, MyHostName, sizeof hbuf - 1);
+                       hbuf[sizeof hbuf - 1] = '\0';
                        return hbuf;
                }
        }
                        return hbuf;
                }
        }
@@ -843,8 +836,8 @@ maphostname(map, hbuf, hbsize, avp, statp)
 
        /* found a match -- copy out */
        s->s_namecanon.nc_cname = newstr(hp->h_name);
 
        /* found a match -- copy out */
        s->s_namecanon.nc_cname = newstr(hp->h_name);
-       if (strlen(hp->h_name) > hbsize)
-               hp->h_name[hbsize] = '\0';
+       if (strlen(hp->h_name) > sizeof hbuf - 1)
+               hp->h_name[sizeof hbuf - 1] = '\0';
        (void) strcpy(hbuf, hp->h_name);
        s->s_namecanon.nc_stat = *statp = EX_OK;
        return hbuf;
        (void) strcpy(hbuf, hp->h_name);
        s->s_namecanon.nc_stat = *statp = EX_OK;
        return hbuf;
@@ -1017,8 +1010,7 @@ getauthinfo(fd)
 **
 **     Parameters:
 **             map -- a pointer to the database map.
 **
 **     Parameters:
 **             map -- a pointer to the database map.
-**             hbuf -- a buffer containing a hostname.
-**             hbsize -- size of hbuf.
+**             name -- a buffer containing a hostname.
 **             avp -- a pointer to a (cf file defined) argument vector.
 **             statp -- an exit status (out parameter).
 **
 **             avp -- a pointer to a (cf file defined) argument vector.
 **             statp -- an exit status (out parameter).
 **
@@ -1027,7 +1019,7 @@ getauthinfo(fd)
 **             FALSE otherwise.
 **
 **     Side Effects:
 **             FALSE otherwise.
 **
 **     Side Effects:
-**             Looks up the host specified in hbuf.  If it is not
+**             Looks up the host specified in name.  If it is not
 **             the canonical name for that host, replace it with
 **             the canonical name.  If the name is unknown, or it
 **             is already the canonical name, leave it unchanged.
 **             the canonical name for that host, replace it with
 **             the canonical name.  If the name is unknown, or it
 **             is already the canonical name, leave it unchanged.
@@ -1035,16 +1027,15 @@ getauthinfo(fd)
 
 /*ARGSUSED*/
 char *
 
 /*ARGSUSED*/
 char *
-maphostname(map, hbuf, hbsize, avp, statp)
+host_map_lookup(map, name, avp, statp)
        MAP *map;
        MAP *map;
-       char *hbuf;
-       int hbsize;
+       char *name;
        char **avp;
        char *statp;
 {
        register struct hostent *hp;
 
        char **avp;
        char *statp;
 {
        register struct hostent *hp;
 
-       hp = gethostbyname(hbuf);
+       hp = gethostbyname(name);
        if (hp != NULL)
                return hp->h_name;
        *statp = EX_NOHOST;
        if (hp != NULL)
                return hp->h_name;
        *statp = EX_NOHOST;
index 293ee5b..1e76b7b 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)err.c      6.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)err.c      6.18 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -352,8 +352,6 @@ fmtmsg(eb, to, num, eno, fmt, ap)
        /* output the error code, if any */
        if (eno != 0)
        {
        /* output the error code, if any */
        if (eno != 0)
        {
-               extern char *errstring();
-
                (void) sprintf(eb, ": %s", errstring(eno));
                eb += strlen(eb);
        }
                (void) sprintf(eb, ": %s", errstring(eno));
                eb += strlen(eb);
        }
@@ -374,11 +372,11 @@ fmtmsg(eb, to, num, eno, fmt, ap)
 **             none.
 */
 
 **             none.
 */
 
-char *
+const char *
 errstring(errno)
        int errno;
 {
 errstring(errno)
        int errno;
 {
-       extern char *sys_errlist[];
+       extern const char *const sys_errlist[];
        extern int sys_nerr;
        static char buf[MAXLINE];
 # ifdef SMTP
        extern int sys_nerr;
        static char buf[MAXLINE];
 # ifdef SMTP
index 3ef7171..295cf05 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)map.c      6.13 (Berkeley) %G%";
+static char sccsid[] = "@(#)map.c      6.14 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 
 #endif /* not lint */
 
 #include "sendmail.h"
 
-#ifdef DBM_MAP
+#ifdef NDBM
 #include <ndbm.h>
 #endif
 #include <ndbm.h>
 #endif
-#if defined(HASH_MAP) || defined(BTREE_MAP)
+#ifdef NEWDB
 #include <db.h>
 #endif
 #include <db.h>
 #endif
-#ifdef NIS_MAP
+#ifdef NIS
 #include <rpcsvc/ypclnt.h>
 #endif
 
 #include <rpcsvc/ypclnt.h>
 #endif
 
-
-#ifdef DBM_MAP
-
-/*
-**  DBM_MAP_INIT -- DBM-style map initialization
-**
-**     Parameters:
-**             map -- the pointer to the actual map
-**             mapname -- the name of the map (for error messages)
-**             args -- a pointer to the config file line arguments
-**
-**     Returns:
-**             TRUE -- if it could successfully open the map.
-**             FALSE -- otherwise.
-**
-**     Side Effects:
-**             Gives an error if it can't open the map.
-*/
-
-bool
-dbm_map_init(map, mapname, args)
-       MAP *map;
-       char *mapname;
-       char *args;
-{
-       DBM *dbm;
-
-       map_parseargs(map, &args);
-       if (map->map_file == NULL)
-       {
-               syserr("No file name for DBM map %s", mapname);
-               return FALSE;
-       }
-       dbm = dbm_open(map->map_file, O_RDONLY, 0644);
-       if (dbm == NULL)
-       {
-               if (!bitset(MF_OPTIONAL, map->map_flags))
-                       syserr("Cannot open DBM database %s", map->map_file);
-               return FALSE;
-       }
-       map->map_db = (void *) dbm;
-       return TRUE;
-}
-\f/*
-**  DBM_MAP_LOOKUP -- look up a datum in a DBM-type map
-**
-**     Parameters:
-**             map -- the map to look up in.
-**             buf -- a pointer to to the buffer containing the key.
-**                     This is a null terminated string.
-**             bufsiz -- the size of buf -- note that this is in general
-**                     larger that strlen(buf), and buf can be changed
-**                     in place if desired.
-**             av -- arguments from the config file (can be interpolated
-**                     into the final result).
-**             statp -- pointer to status word (out-parameter).
-**
-**     Returns:
-**             A pointer to the rewritten result.
-**             NULL if not found in the map.
-*/
-
-char *
-dbm_map_lookup(map, buf, bufsiz, av, statp)
-       MAP *map;
-       char buf[];
-       int bufsiz;
-       char **av;
-       int *statp;
-{
-       datum key, val;
-
-       key.dptr = buf;
-       key.dsize = strlen(buf);
-       if (!bitset(MF_NOFOLDCASE, map->map_flags))
-       {
-               register char *p;
-
-               for (p = buf; *p != '\0'; p++)
-                       if (isascii(*p) && isupper(*p))
-                               *p = tolower(*p);
-       }
-       if (bitset(MF_INCLNULL, map->map_flags))
-               key.dsize++;
-       (void) lockfile(dbm_dirfno((DBM *) map->map_db), map->map_file, LOCK_SH);
-       val = dbm_fetch((DBM *) map->map_db, key);
-       (void) lockfile(dbm_dirfno((DBM *) map->map_db), map->map_file, LOCK_UN);
-       if (val.dptr == NULL)
-               return NULL;
-       if (!bitset(MF_MATCHONLY, map->map_flags))
-               map_rewrite(val.dptr, val.dsize, buf, bufsiz, av);
-       return buf;
-}
-
-#endif /* DBM_MAP */
-\f
-#ifdef BTREE_MAP
-
 /*
 /*
-**  BTREE_MAP_INIT -- BTREE-style map initialization
+**  MAP.C -- implementations for various map classes.
 **
 **
-**     Parameters:
-**             map -- the pointer to the actual map
-**             mapname -- the name of the map (for error messages)
-**             args -- a pointer to the config file line arguments
-**
-**     Returns:
-**             TRUE -- if it could successfully open the map.
-**             FALSE -- otherwise.
+**     Each map class implements a series of functions:
 **
 **
-**     Side Effects:
-**             Gives an error if it can't open the map.
-*/
-
-bool
-bt_map_init(map, mapname, args)
-       MAP *map;
-       char *mapname;
-       char *args;
-{
-       DB *db;
-
-       map_parseargs(map, &args);
-       if (map->map_file == NULL)
-       {
-               syserr("No file name for BTREE map %s", mapname);
-               return FALSE;
-       }
-       db = dbopen(map->map_file, O_RDONLY, 0644, DB_BTREE, NULL);
-       if (db == NULL)
-       {
-               if (!bitset(MF_OPTIONAL, map->map_flags))
-                       syserr("Cannot open BTREE database %s", map->map_file);
-               return FALSE;
-       }
-       map->map_db = (void *) db;
-       return TRUE;
-}
-
-#endif /* BTREE_MAP */
-\f
-#ifdef HASH_MAP
-
-/*
-**  HASH_MAP_INIT -- HASH-style map initialization
+**     bool map_parse(MAP *map, char *args)
+**             Parse the arguments from the config file.  Return TRUE
+**             if they were ok, FALSE otherwise.  Fill in map with the
+**             values.
 **
 **
-**     Parameters:
-**             map -- the pointer to the actual map
-**             mapname -- the name of the map (for error messages)
-**             args -- a pointer to the config file line arguments
+**     char *map_lookup(MAP *map, char buf[], int bufsize,
+**                      char **args, int *pstat)
+**             Look up the key given in buf in the given map.  If found,
+**             do any rewriting the map wants (including "args" if desired)
+**             and return the value.  Set *pstat to the appropriate status
+**             on error and return NULL.
 **
 **
-**     Returns:
-**             TRUE -- if it could successfully open the map.
-**             FALSE -- otherwise.
+**     void map_store(MAP *map, char *key, char *value)
+**             Store the key:value pair in the map.
 **
 **
-**     Side Effects:
-**             Gives an error if it can't open the map.
-*/
-
-bool
-hash_map_init(map, mapname, args)
-       MAP *map;
-       char *mapname;
-       char *args;
-{
-       DB *db;
-
-       map_parseargs(map, &args);
-       if (map->map_file == NULL)
-       {
-               syserr("No file name for HASH map %s", mapname);
-               return FALSE;
-       }
-       db = dbopen(map->map_file, O_RDONLY, 0644, DB_HASH, NULL);
-       if (db == NULL)
-       {
-               if (!bitset(MF_OPTIONAL, map->map_flags))
-                       syserr("Cannot open HASH database %s", map->map_file);
-               return FALSE;
-       }
-       map->map_db = (void *) db;
-       return TRUE;
-}
-
-#endif /* HASH_MAP */
-\f
-#if defined(BTREE_MAP) || defined(HASH_MAP)
-
-/*
-**  DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
+**     void map_rebuild(MAP *map, FILE *fp, int automatic)
+**             Rebuild the map.  If automatic is set, this is an
+**             auto-rebuild.
 **
 **
-**     Parameters:
-**             map -- the map to look up in.
-**             buf -- a pointer to to the buffer containing the key.
-**                     This is a null terminated string.
-**             bufsiz -- the size of buf -- note that this is in general
-**                     larger that strlen(buf), and buf can be changed
-**                     in place if desired.
-**             av -- arguments from the config file (can be interpolated
-**                     into the final result).
-**             statp -- pointer to status word (out-parameter).
+**     bool map_open(MAP *map, int mode)
+**             Open the map for the indicated mode.  Return TRUE if it
+**             was opened successfully, FALSE otherwise.
 **
 **
-**     Returns:
-**             A pointer to the rewritten result.
-**             NULL if not found in the map.
+**     void map_close(MAP *map)
+**             Close the map.
 */
 
 */
 
-char *
-db_map_lookup(map, buf, bufsiz, av, statp)
-       MAP *map;
-       char buf[];
-       int bufsiz;
-       char **av;
-       int *statp;
-{
-       DBT key, val;
-
-       key.data = buf;
-       key.size = strlen(buf);
-       if (!bitset(MF_NOFOLDCASE, map->map_flags))
-       {
-               register char *p;
-
-               for (p = buf; *p != '\0'; p++)
-                       if (isascii(*p) && isupper(*p))
-                               *p = tolower(*p);
-       }
-       if (bitset(MF_INCLNULL, map->map_flags))
-               key.size++;
-       if (((DB *) map->map_db)->get((DB *) map->map_db, &key, &val, 0) != 0)
-               return NULL;
-       if (!bitset(MF_MATCHONLY, map->map_flags))
-               map_rewrite(val.data, val.size, buf, bufsiz, av);
-       return buf;
-}
-
-#endif /* BTREE_MAP || HASH_MAP */
+#define DBMMODE                0644
 \f/*
 **  MAP_PARSEARGS -- parse config line arguments for database lookup
 **
 \f/*
 **  MAP_PARSEARGS -- parse config line arguments for database lookup
 **
+**     This is a generic version of the map_parse method.
+**
 **     Parameters:
 **             map -- the map being initialized.
 **     Parameters:
 **             map -- the map being initialized.
-**             pp -- an indirect pointer to the config line.  It will
-**                     be replaced with a pointer to the next field
-**                     on the line.
+**             ap -- a pointer to the args on the config line.
 **
 **     Returns:
 **
 **     Returns:
-**             none
+**             TRUE -- if everything parsed OK.
+**             FALSE -- otherwise.
 **
 **     Side Effects:
 **             null terminates the filename; stores it in map
 */
 
 **
 **     Side Effects:
 **             null terminates the filename; stores it in map
 */
 
-map_parseargs(map, pp)
+bool
+map_parseargs(map, ap)
        MAP *map;
        MAP *map;
-       char **pp;
+       char *ap;
 {
 {
-       register char *p = *pp;
+       register char *p = ap;
 
        for (;;)
        {
 
        for (;;)
        {
@@ -335,137 +133,51 @@ map_parseargs(map, pp)
 
        while (*p != '\0' && isascii(*p) && isspace(*p))
                p++;
 
        while (*p != '\0' && isascii(*p) && isspace(*p))
                p++;
-       *pp = p;
        if (*p != '\0')
                map->map_rebuild = newstr(p);
        if (*p != '\0')
                map->map_rebuild = newstr(p);
-}
-\f
-# ifdef NIS_MAP
-
-/*
-**  NIS_MAP_INIT -- initialize DBM map
-**
-**     Parameters:
-**             map -- the pointer to the actual map.
-**             mapname -- the name of the map (for error messages).
-**             args -- a pointer to the config file line arguments.
-**
-**     Returns:
-**             TRUE -- if it could successfully open the map.
-**             FALSE -- otherwise.
-**
-**     Side Effects:
-**             Prints an error if it can't open the map.
-*/
 
 
-bool
-nis_map_init(map, mapname, args)
-       MAP *map;
-       char *mapname;
-       char *args;
-{
-       int yperr;
-       char *master;
-
-       /* parse arguments */
-       map_parseargs(map, &args);
        if (map->map_file == NULL)
        {
        if (map->map_file == NULL)
        {
-               syserr("No NIS map name for map %s", mapname);
+               syserr("No file name for %s map %s",
+                       map->map_class->map_cname, map->map_mname);
                return FALSE;
        }
                return FALSE;
        }
-       if (map->map_domain == NULL)
-               yp_get_default_domain(&map->map_domain);
-
-       /* check to see if this map actually exists */
-       yperr = yp_master(map->map_domain, map->map_file, &master);
-       if (yperr == 0)
-               return TRUE;
-       if (!bitset(MF_OPTIONAL, map->map_flags))
-               syserr("Cannot bind to domain %s: %s", map->map_domain,
-                       yperr_string(yperr));
-       return FALSE;
-}
-\f/*
-**  NIS_MAP_LOOKUP -- look up a datum in a NIS map
-**
-**     Parameters:
-**             map -- the map to look up in.
-**             buf -- a pointer to to the buffer containing the key.
-**                     This is a null terminated string.
-**             bufsiz -- the size of buf -- note that this is in general
-**                     larger that strlen(buf), and buf can be changed
-**                     in place if desired.
-**             av -- arguments from the config file (can be interpolated
-**                     into the final result).
-**             statp -- pointer to status word (out-parameter).
-**
-**     Returns:
-**             A pointer to the rewritten result.
-**             NULL if not found in the map.
-*/
-
-char *
-nis_map_lookup(map, buf, bufsiz, av, statp)
-       MAP *map;
-       char buf[];
-       int bufsiz;
-       char **av;
-       int *statp;
-{
-       char *vp;
-       auto int vsize;
-       int buflen;
-
-       if (!bitset(MF_NOFOLDCASE, map->map_flags))
-       {
-               register char *p;
-
-               for (p = buf; *p != '\0'; p++)
-                       if (isascii(*p) && isupper(*p))
-                               *p = tolower(*p);
-       }
-       buflen = strlen(buf);
-       if (bitset(MF_INCLNULL, map->map_flags))
-               buflen++;
-       if (yp_match(map->map_domain, map->map_file, buf, buflen,
-                    &vp, &vsize) != 0)
-               return NULL;
-       if (!bitset(MF_MATCHONLY, map->map_flags))
-               map_rewrite(vp, vsize, buf, bufsiz, av);
-       return buf;
+       return TRUE;
 }
 }
-
-#endif /* NIS_MAP */
 \f/*
 **  MAP_REWRITE -- rewrite a database key, interpolating %n indications.
 **
 \f/*
 **  MAP_REWRITE -- rewrite a database key, interpolating %n indications.
 **
+**     It also adds the map_app string.  It can be used as a utility
+**     in the map_lookup method.
+**
 **     Parameters:
 **     Parameters:
+**             map -- the map that causes this.
 **             s -- the string to rewrite, NOT necessarily null terminated.
 **             slen -- the length of s.
 **             s -- the string to rewrite, NOT necessarily null terminated.
 **             slen -- the length of s.
-**             buf -- the place to write it.
-**             buflen -- the length of buf.
 **             av -- arguments to interpolate into buf.
 **
 **     Returns:
 **             av -- arguments to interpolate into buf.
 **
 **     Returns:
-**             none.
+**             Pointer to rewritten result.
 **
 **     Side Effects:
 **             none.
 */
 
 **
 **     Side Effects:
 **             none.
 */
 
-map_rewrite(s, slen, buf, buflen, av)
+char *
+map_rewrite(map, s, slen, av)
+       register MAP *map;
        register char *s;
        int slen;
        register char *s;
        int slen;
-       char buf[];
-       int buflen;
        char **av;
 {
        register char *bp;
        char **av;
 {
        register char *bp;
-       char *buflim;
        register char c;
        char **avp;
        register char *ap;
        register char c;
        char **avp;
        register char *ap;
+       int i;
+       int len;
+       static int buflen = -1;
+       static char *buf = NULL;
 
        if (tTd(23, 1))
        {
 
        if (tTd(23, 1))
        {
@@ -474,40 +186,960 @@ map_rewrite(s, slen, buf, buflen, av)
                        printf("\t%s\n", *avp);
        }
 
                        printf("\t%s\n", *avp);
        }
 
+       /* count expected size of output (can safely overestimate) */
+       i = len = slen;
+       if (av != NULL)
+       {
+               bp = s;
+               for (i = slen; --i >= 0 && (c = *bp++) != 0; )
+               {
+                       if (c != '%')
+                               continue;
+                       if (--i < 0)
+                               break;
+                       c = *bp++;
+                       if (!(isascii(c) && isdigit(c)))
+                               continue;
+                       c -= 0;
+                       for (avp = av; --c >= 0 && *avp != NULL; avp++)
+                               continue;
+                       if (*avp == NULL)
+                               continue;
+                       len += strlen(*avp);
+               }
+       }
+       if (map->map_app != NULL)
+               len += strlen(map->map_app);
+       if (buflen < ++len)
+       {
+               /* need to malloc additional space */
+               buflen = len;
+               if (buf != NULL)
+                       free(buf);
+               buf = xalloc(buflen);
+       }
+
        bp = buf;
        bp = buf;
-       buflim = &buf[buflen - 2];
-       while (--slen >= 0 && (c = *s++) != '\0')
+       if (av == NULL)
+       {
+               bcopy(s, bp, slen);
+               bp += slen;
+       }
+       else
        {
        {
-               if (c != '%')
+               while (--slen >= 0 && (c = *s++) != '\0')
                {
                {
+                       if (c != '%')
+                       {
   pushc:
   pushc:
-                       if (bp < buflim)
                                *bp++ = c;
                                *bp++ = c;
-                       continue;
-               }
-               if (--slen < 0 || (c = *s++) == '\0')
-                       c = '%';
-               if (c == '%')
-                       goto pushc;
-               if (!(isascii(c) && isdigit(c)))
-               {
-                       *bp++ = '%';
-                       goto pushc;
-               }
-               c -= '0';
-               for (avp = av; --c >= 0 && *avp != NULL; avp++)
-                       continue;
-               if (*avp == NULL)
-                       continue;
-
-               /* transliterate argument into output string */
-               for (ap = *avp; (c = *ap++) != '\0'; )
-               {
-                       if (bp < buflim)
+                               continue;
+                       }
+                       if (--slen < 0 || (c = *s++) == '\0')
+                               c = '%';
+                       if (c == '%')
+                               goto pushc;
+                       if (!(isascii(c) && isdigit(c)))
+                       {
+                               *bp++ = '%';
+                               goto pushc;
+                       }
+                       c -= '0';
+                       for (avp = av; --c >= 0 && *avp != NULL; avp++)
+                               continue;
+                       if (*avp == NULL)
+                               continue;
+
+                       /* transliterate argument into output string */
+                       for (ap = *avp; (c = *ap++) != '\0'; )
                                *bp++ = c;
                }
        }
                                *bp++ = c;
                }
        }
-       *bp++ = '\0';
+       if (map->map_app != NULL)
+               strcpy(bp, map->map_app);
+       else
+               *bp = '\0';
        if (tTd(23, 1))
                printf("map_rewrite => %s\n", buf);
        if (tTd(23, 1))
                printf("map_rewrite => %s\n", buf);
+       return buf;
+}
+\f/*
+**  NDBM modules
+*/
+
+#ifdef NDBM
+
+/*
+**  DBM_MAP_OPEN -- DBM-style map open
+*/
+
+bool
+ndbm_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       DBM *dbm;
+
+       if (tTd(27, 2))
+               printf("ndbm_map_open(%s, %d)\n", map->map_file, mode);
+
+       /* open the database */
+       dbm = dbm_open(map->map_file, mode, DBMMODE);
+       if (dbm == NULL)
+       {
+               if (!bitset(MF_OPTIONAL, map->map_flags))
+                       syserr("Cannot open DBM database %s", map->map_file);
+               return FALSE;
+       }
+       map->map_db1 = (void *) dbm;
+       return TRUE;
+}
+
+
+/*
+**  DBM_MAP_LOOKUP -- look up a datum in a DBM-type map
+*/
+
+char *
+ndbm_map_lookup(map, name, av, statp)
+       MAP *map;
+       char *name;
+       char **av;
+       int *statp;
+{
+       datum key, val;
+       char keybuf[MAXNAME + 1];
+
+       if (tTd(27, 20))
+               printf("ndbm_map_lookup(%s)\n", name);
+
+       key.dptr = name;
+       key.dsize = strlen(name);
+       if (!bitset(MF_NOFOLDCASE, map->map_flags))
+       {
+               if (key.dsize > sizeof keybuf - 1)
+                       key.dsize = sizeof keybuf - 1;
+               bcopy(key.dptr, keybuf, key.dsize + 1);
+               makelower(keybuf);
+               key.dptr = keybuf;
+       }
+       if (bitset(MF_INCLNULL, map->map_flags))
+               key.dsize++;
+       (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH);
+       val = dbm_fetch((DBM *) map->map_db1, key);
+       (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN);
+       if (val.dptr == NULL)
+               return NULL;
+       if (bitset(MF_MATCHONLY, map->map_flags))
+               av = NULL;
+       return map_rewrite(map, val.dptr, val.dsize, av);
+}
+
+
+/*
+**  DBM_MAP_STORE -- store a datum in the database
+*/
+
+void
+ndbm_map_store(map, lhs, rhs)
+       register MAP *map;
+       char *lhs;
+       char *rhs;
+{
+       datum key;
+       datum data;
+       int stat;
+
+       if (tTd(27, 12))
+               printf("ndbm_map_store(%s, %s)\n", lhs, rhs);
+
+       key.dsize = strlen(lhs);
+       key.dptr = lhs;
+
+       data.dsize = strlen(rhs);
+       data.dptr = rhs;
+
+       if (bitset(MF_INCLNULL, map->map_flags))
+       {
+               key.dsize++;
+               data.dsize++;
+       }
+
+       stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
+       if (stat > 0)
+       {
+               usrerr("050 Warning: duplicate alias name %s", lhs);
+               stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE);
+       }
+       if (stat != 0)
+               syserr("readaliases: dbm put (%s)", lhs);
+}
+
+
+/*
+**  DBM_MAP_REBUILD -- rebuild DBM database
+*/
+
+void
+ndbm_map_rebuild(map, fp, automatic)
+       register MAP *map;
+       FILE *fp;
+       int automatic;
+{
+       register DBM *db;
+       int i;
+       char buf[MAXNAME];
+
+       if (tTd(27, 2))
+               printf("ndbm_map_rebuild(%s)\n", map->map_file);
+
+       db = dbm_open(map->map_file, O_RDWR|O_CREAT|O_TRUNC, DBMMODE);
+       if (db == NULL)
+       {
+               syserr("ndbm_map_rebuild: cannot create %s", buf);
+               return;
+       }
+       map->map_db1 = (void *) db;
+       map->map_flags |= MF_WRITABLE|MF_VALID;
+}
+
+/*
+**  NDBM_ACLOSE -- close the database
+*/
+
+void
+ndbm_map_close(map)
+       register MAP  *map;
+{
+       if (bitset(MF_WRITABLE, map->map_flags))
+       {
+#ifdef YPCOMPAT
+               char buf[200];
+
+               (void) sprintf(buf, "%010ld", curtime());
+               ndbm_map_store(map, "YP_LAST_MODIFIED", buf);
+
+               (void) myhostname(buf, sizeof buf);
+               ndbm_map_store(map, "YP_MASTER_NAME", buf);
+#endif
+
+               /* write out the distinguished alias */
+               ndbm_map_store(map, "@", "@");
+       }
+       dbm_close((DBM *) map->map_db1);
+}
+
+#endif
+\f/*
+**  HASH (NEWDB) Modules
+*/
+
+#ifdef NEWDB
+
+/*
+**  BTREE_MAP_PARSE -- BTREE-style map initialization
+*/
+
+bool
+bt_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       DB *db;
+       char buf[MAXNAME];
+
+       if (tTd(27, 2))
+               printf("bt_map_open(%s, %d)\n", map->map_file, mode);
+
+       (void) sprintf(buf, "%s.db", map->map_file);
+       db = dbopen(buf, mode, 0644, DB_BTREE, NULL);
+       if (db == NULL)
+       {
+               if (!bitset(MF_OPTIONAL, map->map_flags))
+                       syserr("Cannot open BTREE database %s", map->map_file);
+               return FALSE;
+       }
+       map->map_db2 = (void *) db;
+       return TRUE;
+}
+
+
+/*
+**  HASH_MAP_INIT -- HASH-style map initialization
+*/
+
+bool
+hash_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       DB *db;
+       char buf[MAXNAME];
+
+       if (tTd(27, 2))
+               printf("hash_map_open(%s, %d)\n", map->map_file, mode);
+
+       (void) sprintf(buf, "%s.db", map->map_file);
+       db = dbopen(buf, mode, 0644, DB_HASH, NULL);
+       if (db == NULL)
+       {
+               if (!bitset(MF_OPTIONAL, map->map_flags))
+                       syserr("Cannot open HASH database %s", map->map_file);
+               return FALSE;
+       }
+       map->map_db2 = (void *) db;
+       return TRUE;
+}
+
+
+/*
+**  DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
+*/
+
+char *
+db_map_lookup(map, name, av, statp)
+       MAP *map;
+       char *name;
+       char **av;
+       int *statp;
+{
+       DBT key, val;
+       char keybuf[MAXNAME + 1];
+
+       if (tTd(27, 20))
+               printf("db_map_lookup(%s)\n", name);
+
+       key.size = strlen(name);
+       if (key.size > sizeof keybuf - 1)
+               key.size = sizeof keybuf - 1;
+       key.data = keybuf;
+       bcopy(name, keybuf, key.size + 1);
+       if (!bitset(MF_NOFOLDCASE, map->map_flags))
+               makelower(keybuf);
+       if (bitset(MF_INCLNULL, map->map_flags))
+               key.size++;
+       if (((DB *) map->map_db2)->get((DB *) map->map_db2, &key, &val, 0) != 0)
+               return NULL;
+       if (bitset(MF_MATCHONLY, map->map_flags))
+               av = NULL;
+       return map_rewrite(map, val.data, val.size, av);
+}
+
+
+/*
+**  DB_MAP_STORE -- store a datum in the NEWDB database
+*/
+
+void
+db_map_store(map, lhs, rhs)
+       register MAP *map;
+       char *lhs;
+       char *rhs;
+{
+       int stat;
+       DBT key;
+       DBT data;
+       register DB *db = map->map_db2;
+
+       if (tTd(27, 20))
+               printf("db_map_store(%s, %s)\n", lhs, rhs);
+
+       key.size = strlen(lhs);
+       key.data = lhs;
+
+       data.size = strlen(rhs);
+       data.data = rhs;
+
+       if (bitset(MF_INCLNULL, map->map_flags))
+       {
+               key.size++;
+               data.size++;
+       }
+
+       stat = db->put(db, &key, &data, R_NOOVERWRITE);
+       if (stat > 0)
+       {
+               usrerr("050 Warning: duplicate alias name %s", lhs);
+               stat = db->put(db, &key, &data, 0);
+       }
+       if (stat != 0)
+               syserr("readaliases: db put (%s)", lhs);
+}
+
+
+/*
+**  HASH_MAP_REBUILD -- rebuild hash database
+*/
+
+void
+db_map_rebuild(map, fp, automatic, e)
+       register MAP *map;
+       FILE *fp;
+       int automatic;
+       ENVELOPE *e;
+{
+       register DB *db;
+       char buf[MAXNAME];
+
+       if (tTd(27, 2))
+               printf("hash_map_rebuild(%s)\n", map->map_file);
+
+       (void) strcpy(buf, map->map_file);
+       (void) strcat(buf, ".db");
+       db = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL);
+       if (db == NULL)
+       {
+               syserr("hash_map_rebuild: cannot create %s", buf);
+               return;
+       }
+       map->map_db2 = db;
+       map->map_flags |= MF_WRITABLE|MF_VALID;
+}
+
+
+/*
+**  DB_MAP_CLOSE -- add distinguished entries and close the database
+*/
+
+void
+db_map_close(map)
+       MAP *map;
+{
+       register DB *db = map->map_db2;
+
+       if (tTd(27, 9))
+               printf("db_map_close(%s, %x)\n", map->map_file, map->map_flags);
+
+       if (bitset(MF_WRITABLE, map->map_flags))
+       {
+               /* write out the distinguished alias */
+               db_map_store(map, "@", "@");
+       }
+
+       if (db->close(db) != 0)
+               syserr("readaliases: db close failure");
+}
+
+#endif
+\f/*
+**  NIS Modules
+*/
+
+# ifdef NIS
+
+/*
+**  NIS_MAP_OPEN -- open DBM map
+*/
+
+bool
+nis_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       int yperr;
+       char *master;
+
+       if (tTd(27, 2))
+               printf("nis_map_open(%s)\n", map->map_file);
+
+       if (map->map_domain == NULL)
+               yp_get_default_domain(&map->map_domain);
+
+       /* check to see if this map actually exists */
+       yperr = yp_master(map->map_domain, map->map_file, &master);
+       if (yperr == 0)
+               return TRUE;
+       if (!bitset(MF_OPTIONAL, map->map_flags))
+               syserr("Cannot bind to domain %s: %s", map->map_domain,
+                       yperr_string(yperr));
+       return FALSE;
+}
+
+bool
+nis_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       register char *p;
+       int yperr;
+       auto char *vp;
+       auto int vsize;
+
+       p = strchr(map->map_file, '@');
+       if (p != NULL)
+       {
+               *p++ = '\0';
+               if (*p != '\0')
+                       map->map_domain = p;
+       }
+       if (map->map_domain == NULL)
+               yp_get_default_domain(&map->map_domain);
+
+       if (*map->map_file == '\0')
+               map->map_file = "mail.aliases";
+
+       yperr = yp_match(map->map_domain, map->map_file, "@", 1,
+                       &vp, &vsize);
+       if (tTd(27, 10))
+               printf("nis_map_open: yp_match(%s, %s) => %s\n",
+                       map->map_domain, map->map_file, yperr_string(yperr));
+       if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
+               return TRUE;
+       return FALSE;
+}
+
+
+/*
+**  NIS_MAP_LOOKUP -- look up a datum in a NIS map
+*/
+
+char *
+nis_map_lookup(map, name, av, statp)
+       MAP *map;
+       char *name;
+       char **av;
+       int *statp;
+{
+       char *vp;
+       auto int vsize;
+       int buflen;
+       char keybuf[MAXNAME + 1];
+
+       if (tTd(27, 20))
+               printf("nis_map_lookup(%s)\n", name);
+
+       buflen = strlen(name);
+       if (buflen > sizeof keybuf - 1)
+               buflen = sizeof keybuf - 1;
+       bcopy(name, keybuf, buflen + 1);
+       if (!bitset(MF_NOFOLDCASE, map->map_flags))
+               makelower(keybuf);
+       if (bitset(MF_INCLNULL, map->map_flags))
+               buflen++;
+       yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
+                    &vp, &vsize);
+       if (yperr != 0)
+       {
+               if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
+                       map->map_flags &= ~MF_VALID;
+               return NULL;
+       }
+       if (bitset(MF_MATCHONLY, map->map_flags))
+               av = NULL;
+       return map_rewrite(map, val.dptr, val.dsize, av);
+}
+
+
+/*
+**  NIS_ASTORE
+*/
+
+void
+nis_map_store(map, lhs, rhs)
+       MAP *map;
+       char *lhs;
+       char *rhs;
+{
+       /* nothing */
+}
+
+/*
+**  NIS_AREBUILD
+*/
+
+void
+nis_map_rebuild(map, fp, automatic, e)
+       MAP *map;
+       FILE *fp;
+       int automatic;
+       ENVELOPE *e;
+{
+       if (tTd(27, 2))
+               printf("nis_map_rebuild(%s)\n", map->map_file);
+}
+
+
+/*
+**  NIS_ACLOSE
+*/
+
+void
+nis_map_close(map)
+       MAP *map;
+{
+       /* nothing */
+}
+
+#endif /* NIS */
+\f/*
+**  STAB (Symbol Table) Modules
+*/
+
+
+/*
+**  STAB_ALOOKUP -- look up alias in symbol table
+*/
+
+char *
+stab_map_lookup(map, name)
+       register MAP *map;
+       char *name;
+{
+       register STAB *s;
+
+       if (tTd(27, 20))
+               printf("stab_lookup(%s)\n", name);
+
+       s = stab(name, ST_ALIAS, ST_FIND);
+       if (s != NULL)
+               return (s->s_alias);
+       return (NULL);
+}
+
+
+/*
+**  STAB_ASTORE -- store in symtab (actually using during init, not rebuild)
+*/
+
+void
+stab_map_store(map, lhs, rhs)
+       register MAP *map;
+       char *lhs;
+       char *rhs;
+{
+       register STAB *s;
+
+       s = stab(lhs, ST_ALIAS, ST_ENTER);
+       s->s_alias = newstr(rhs);
+}
+
+
+/*
+**  STAB_AINIT -- initialize (reads data file)
+*/
+
+bool
+stab_map_open(map, mode)
+       register MAP *map;
+       int mode;
+{
+       FILE *af;
+
+       if (tTd(27, 2))
+               printf("stab_map_open(%s)\n", map->map_file);
+
+       if (mode != O_RDONLY)
+               return FALSE;
+
+       af = fopen(map->map_file, "r");
+       if (af == NULL)
+               return FALSE;
+       return TRUE;
+}
+
+
+/*
+**  STAB_AREBUILD -- rebuild alias file
+*/
+
+void
+stab_map_rebuild(map, fp, automatic, e)
+       MAP *map;
+       FILE *fp;
+       int automatic;
+       ENVELOPE *e;
+{
+       if (tTd(27, 2))
+               printf("stab_map_rebuild(%s)\n", map->map_file);
+
+       map->map_flags |= MF_WRITABLE|MF_VALID;
+}
+
+
+/*
+**  STAB_ACLOSE -- close symbol table (???)
+*/
+
+void
+stab_map_close(map)
+       MAP *map;
+{
+       /* ignore it */
+}
+\f/*
+**  Implicit Modules
+**
+**     Tries several types.  For back compatibility of aliases.
+*/
+
+
+/*
+**  IMPL_ALOOKUP -- lookup in best open database
+*/
+
+char *
+impl_map_lookup(map, name, av, pstat)
+       MAP *map;
+       char *name;
+       char **av;
+       int *pstat;
+{
+       if (tTd(27, 20))
+               printf("impl_map_lookup(%s)\n", name);
+
+#ifdef NEWDB
+       if (bitset(MF_IMPL_HASH, map->map_flags))
+               return db_map_lookup(map, name, av, pstat);
+#endif
+#ifdef NDBM
+       if (bitset(MF_IMPL_NDBM, map->map_flags))
+               return ndbm_map_lookup(map, name, av, pstat);
+#endif
+       return stab_map_lookup(map, name, av, pstat);
+}
+
+/*
+**  IMPL_ASTORE -- store in open databases
+*/
+
+void
+impl_map_store(map, lhs, rhs)
+       MAP *map;
+       char *lhs;
+       char *rhs;
+{
+#ifdef NEWDB
+       if (bitset(MF_IMPL_HASH, map->map_flags))
+               db_map_store(map, lhs, rhs);
+#endif
+#ifdef NDBM
+       if (bitset(MF_IMPL_NDBM, map->map_flags))
+               ndbm_map_store(map, lhs, rhs);
+#endif
+       stab_map_store(map, lhs, rhs);
+}
+
+/*
+**  IMPL_MAP_OPEN -- implicit database open
+*/
+
+bool
+impl_map_open(map, mode)
+       MAP *map;
+       int mode;
+{
+       struct stat stb;
+
+       if (tTd(27, 2))
+               printf("impl_map_open(%s)\n", map->map_file);
+
+       if (stat(map->map_file, &stb) < 0)
+       {
+               /* no alias file at all */
+               return FALSE;
+       }
+
+#ifdef NEWDB
+       if (hash_map_open(map, mode))
+       {
+               map->map_flags |= MF_IMPL_HASH;
+               return TRUE;
+       }
+#endif
+#ifdef NDBM
+       if (ndbm_map_open(map, mode))
+       {
+               map->map_flags |= MF_IMPL_NDBM;
+               return TRUE;
+       }
+#endif
+
+       if (Verbose)
+               message("WARNING: cannot open alias database %s", map->map_file);
+
+       if (stab_map_open(map, mode))
+       {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+/*
+**  IMPL_AREBUILD -- rebuild alias database
+*/
+
+void
+impl_map_rebuild(map, fp, automatic, e)
+       MAP *map;
+       FILE *fp;
+       int automatic;
+       ENVELOPE *e;
+{
+#ifdef NEWDB
+       DB *ndb;
+       char buf[MAXNAME];
+#endif
+
+       if (tTd(27, 2))
+               printf("impl_map_rebuild(%s)\n", map->map_file);
+
+#ifdef NEWDB
+       (void) strcpy(buf, map->map_file);
+       (void) strcat(buf, ".db");
+       ndb = dbopen(buf, O_RDWR|O_CREAT|O_TRUNC, DBMMODE, DB_HASH, NULL);
+       if (ndb == NULL)
+       {
+               syserr("rebuildaliases: cannot create %s", buf);
+       }
+       else
+       {
+               map->map_db2 = ndb;
+               map->map_flags |= MF_IMPL_HASH;
+#if defined(NDBM) && defined(YPCOMPAT)
+               if (access("/var/yp/Makefile", R_OK) != 0)
+#endif
+                       goto readem;
+       }
+#endif
+
+#ifdef NDBM
+       map->map_db1 = (void *) dbm_open(map->map_file, O_RDWR|O_CREAT|O_TRUNC, DBMMODE);
+       if (map->map_db1 == NULL)
+       {
+               syserr("rebuildaliases: cannot create %s.{pag,dir}",
+                       map->map_file);
+       }
+       else
+       {
+               map->map_flags |= MF_IMPL_NDBM;
+       }
+#endif
+
+       if (!bitset(MF_IMPL_HASH|MF_IMPL_NDBM, map->map_flags))
+               return;
+
+  readem:
+       map->map_flags |= MF_WRITABLE|MF_VALID;
+}
+
+
+/*
+**  IMPL_ACLOSE -- close any open database(s)
+*/
+
+void
+impl_map_close(map, e)
+       MAP *map;
+       ENVELOPE *e;
+{
+#ifdef NEWDB
+       if (bitset(MF_IMPL_HASH, map->map_flags))
+               db_map_close(map, e);
+#endif
+
+#ifdef NDBM
+       if (bitset(MF_IMPL_NDBM, map->map_flags))
+               ndbm_map_close(map, e);
+#endif
+}
+\f/*
+**  SETUPALIASES -- set up aliases classes
+*/
+
+extern bool    host_map_init __P((MAP *, char *));
+extern char    *host_map_lookup __P((MAP *, char *, char **, int *));
+
+extern bool    dequote_init __P((MAP *, char *));
+extern char    *dequote_map __P((MAP *, char *, char **, int *));
+
+#if 0
+extern bool    udb_map_parse __P((MAP *, char *));
+extern char    *udb_map_lookup __P((MAP *, char *, char **, int *));
+#endif
+
+static MAPCLASS        MapClasses[] =
+{
+#ifdef NEWDB
+       {
+               "hash",         ".db",  map_parseargs,
+               db_map_lookup,          db_map_store,
+               db_map_rebuild,         hash_map_open,  db_map_close,
+       },
+
+       {
+               "btree",        ".db",  map_parseargs,
+               db_map_lookup,          db_map_store,
+               db_map_rebuild,         bt_map_open,    db_map_close,
+       },
+#endif
+
+#ifdef NDBM
+       {
+               "dbm",          ".dir", map_parseargs,
+               ndbm_map_lookup,        ndbm_map_store,
+               ndbm_map_rebuild,       ndbm_map_open,  ndbm_map_close,
+       },
+#endif
+
+#ifdef NIS
+       {
+               "nis",          NULL,   map_parseargs,
+               nis_map_lookup,         NULL,
+               NULL,                   nis_map_open,   nis_map_close,
+       },
+#endif
+
+       {
+               "stab",         NULL,   map_parseargs,
+               stab_map_lookup,        stab_map_store,
+               NULL,                   stab_map_open,  stab_map_close,
+       },
+
+       {
+               "implicit",     NULL,   map_parseargs,
+               impl_map_lookup,        impl_map_store,
+               impl_map_rebuild,       impl_map_open,  impl_map_close,
+       },
+
+       /* host DNS lookup */
+       {
+               "host",         NULL,   host_map_init,
+               host_map_lookup,        NULL,
+               NULL,                   NULL,           NULL,
+       },
+
+       /* dequote map */
+       {
+               "dequote",      NULL,   dequote_init,
+               dequote_map,            NULL,
+               NULL,                   NULL,           NULL,
+       },
+
+#if 0
+# ifdef USERDB
+       /* user database */
+       {
+               "udb",          ".db",  udb_map_parse,
+               udb_map_lookup,         NULL,
+               NULL,                   NULL,           NULL,
+       },
+# endif
+#endif
+
+       {
+               NULL
+       }
+};
+
+setupmaps()
+{
+       register MAPCLASS *mc;
+       register STAB *s;
+
+       for (mc = MapClasses; mc->map_cname != NULL; mc++)
+       {
+               s = stab(mc->map_cname, ST_MAPCLASS, ST_ENTER);
+               s->s_mapclass = mc;
+       }
 }
 }
index 2345ab8..3f9ecea 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)parseaddr.c        6.52 (Berkeley) %G%";
+static char sccsid[] = "@(#)parseaddr.c        6.53 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -2157,8 +2157,7 @@ dequote_init(map, mapname, args)
 **
 **     Parameters:
 **             map -- the internal map structure (ignored).
 **
 **     Parameters:
 **             map -- the internal map structure (ignored).
-**             buf -- the buffer to dequote.
-**             bufsiz -- the size of that buffer.
+**             name -- the name to dequote.
 **             av -- arguments (ignored).
 **             statp -- pointer to status out-parameter.
 **
 **             av -- arguments (ignored).
 **             statp -- pointer to status out-parameter.
 **
@@ -2169,10 +2168,9 @@ dequote_init(map, mapname, args)
 */
 
 char *
 */
 
 char *
-dequote_map(map, buf, bufsiz, av, statp)
+dequote_map(map, name, av, statp)
        MAP *map;
        MAP *map;
-       char buf[];
-       int bufsiz;
+       char *name;
        char **av;
        int *statp;
 {
        char **av;
        int *statp;
 {
@@ -2193,7 +2191,7 @@ dequote_map(map, buf, bufsiz, av, statp)
        quotemode = FALSE;
        bslashmode = FALSE;
 
        quotemode = FALSE;
        bslashmode = FALSE;
 
-       for (p = q = buf; (c = *p++) != '\0'; )
+       for (p = q = name; (c = *p++) != '\0'; )
        {
                if (bslashmode)
                {
        {
                if (bslashmode)
                {
@@ -2251,5 +2249,5 @@ dequote_map(map, buf, bufsiz, av, statp)
            quotemode || quotecnt <= 0 || spacecnt != 0)
                return NULL;
        *q++ = '\0';
            quotemode || quotecnt <= 0 || spacecnt != 0)
                return NULL;
        *q++ = '\0';
-       return buf;
+       return name;
 }
 }
index 85d3239..774deed 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)readcf.c   6.36 (Berkeley) %G%";
+static char sccsid[] = "@(#)readcf.c   6.37 (Berkeley) %G%";
 #endif /* not lint */
 
 # include "sendmail.h"
 #endif /* not lint */
 
 # include "sendmail.h"
@@ -1401,9 +1401,10 @@ makemapentry(line)
 
        /* enter the map */
        map = stab(mapname, ST_MAP, ST_ENTER);
 
        /* enter the map */
        map = stab(mapname, ST_MAP, ST_ENTER);
-       map->s_map.map_class = &class->s_mapclass;
+       map->s_map.map_class = class->s_mapclass;
+       map->s_map.map_mname = newstr(mapname);
 
 
-       if ((*class->s_mapclass.map_init)(&map->s_map, mapname, p))
+       if ((*class->s_mapclass->map_parse)(&map->s_map, p))
                map->s_map.map_flags |= MF_VALID;
 }
 \f/*
                map->s_map.map_flags |= MF_VALID;
 }
 \f/*
index c579a48..8bb22eb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sendmail.h  6.63 (Berkeley) %G%
+ *     @(#)sendmail.h  6.64 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,7 +15,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 6.63            %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 6.64            %G%";
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
 # endif
 # else /*  _DEFINE */
 # define EXTERN extern
@@ -408,9 +408,6 @@ struct metamac
        char    metaname;       /* external code (after $) */
        char    metaval;        /* internal code (as above) */
 };
        char    metaname;       /* external code (after $) */
        char    metaval;        /* internal code (as above) */
 };
-
-
-#define ALIASCLASS     struct _aliasclass
 \f/*
 **  Information about currently open connections to mailers, or to
 **  hosts that we have looked up recently.
 \f/*
 **  Information about currently open connections to mailers, or to
 **  hosts that we have looked up recently.
@@ -493,21 +490,26 @@ NAMECANON
 MAP
 {
        MAPCLASS        *map_class;     /* the class of this map */
 MAP
 {
        MAPCLASS        *map_class;     /* the class of this map */
+       char            *map_mname;     /* name of this map */
        int             map_flags;      /* flags, see below */
        char            *map_file;      /* the (nominal) filename */
        int             map_flags;      /* flags, see below */
        char            *map_file;      /* the (nominal) filename */
-       void            *map_db;        /* the open database ptr */
+       void            *map_db1;       /* the open database ptr */
+       void            *map_db2;       /* an "extra" database pointer */
        char            *map_app;       /* to append to successful matches */
        char            *map_domain;    /* the (nominal) NIS domain */
        char            *map_rebuild;   /* program to run to do auto-rebuild */
        char            *map_app;       /* to append to successful matches */
        char            *map_domain;    /* the (nominal) NIS domain */
        char            *map_rebuild;   /* program to run to do auto-rebuild */
-       char            **map_deplist;  /* dependency list */
 };
 
 /* bit values for map_flags */
 };
 
 /* bit values for map_flags */
-# define MF_VALID      00001           /* this entry is valid */
-# define MF_INCLNULL   00002           /* include null byte in key */
-# define MF_OPTIONAL   00004           /* don't complain if map not found */
-# define MF_NOFOLDCASE 00010           /* don't fold case in keys */
-# define MF_MATCHONLY  00020           /* don't use the map value */
+# define MF_VALID      0x0001          /* this entry is valid */
+# define MF_INCLNULL   0x0002          /* include null byte in key */
+# define MF_OPTIONAL   0x0004          /* don't complain if map not found */
+# define MF_NOFOLDCASE 0x0008          /* don't fold case in keys */
+# define MF_MATCHONLY  0x0010          /* don't use the map value */
+# define MF_OPEN       0x0020          /* this entry is open */
+# define MF_WRITABLE   0x0040          /* open for writing */
+# define MF_IMPL_HASH  0x1000          /* implicit: underlying hash database */
+# define MF_IMPL_NDBM  0x2000          /* implicit: underlying NDBM database */
 
 
 /*
 
 
 /*
@@ -516,10 +518,20 @@ MAP
 
 MAPCLASS
 {
 
 MAPCLASS
 {
-       bool    (*map_init)__P((MAP *, char *, char *));
-                                       /* initialization function */
-       char    *(*map_lookup)__P((MAP *, char *, int, char **, int *));
+       char    *map_cname;             /* name of this map class */
+       char    *map_ext;               /* extension for database file */
+       bool    (*map_parse)__P((MAP *, char *));
+                                       /* argument parsing function */
+       char    *(*map_lookup)__P((MAP *, char *, char **, int *));
                                        /* lookup function */
                                        /* lookup function */
+       void    (*map_store)__P((MAP *, char *, char *));
+                                       /* store function */
+       void    (*map_rebuild)__P((MAP *, FILE *, int));
+                                       /* rebuild function */
+       bool    (*map_open)__P((MAP *, int));
+                                       /* open function */
+       void    (*map_close)__P((MAP *));
+                                       /* close function */
 };
 \f/*
 **  Symbol table definitions
 };
 \f/*
 **  Symbol table definitions
@@ -536,12 +548,11 @@ struct symtab
                ADDRESS         *sv_addr;       /* pointer to address header */
                MAILER          *sv_mailer;     /* pointer to mailer */
                char            *sv_alias;      /* alias */
                ADDRESS         *sv_addr;       /* pointer to address header */
                MAILER          *sv_mailer;     /* pointer to mailer */
                char            *sv_alias;      /* alias */
-               MAPCLASS        sv_mapclass;    /* mapping function class */
+               MAPCLASS        *sv_mapclass;   /* mapping function class */
                MAP             sv_map;         /* mapping function */
                char            *sv_hostsig;    /* host signature */
                MCI             sv_mci;         /* mailer connection info */
                NAMECANON       sv_namecanon;   /* canonical name cache */
                MAP             sv_map;         /* mapping function */
                char            *sv_hostsig;    /* host signature */
                MCI             sv_mci;         /* mailer connection info */
                NAMECANON       sv_namecanon;   /* canonical name cache */
-               ALIASCLASS      *sv_aliasclass; /* alias class (type) */
        }       s_value;
 };
 
        }       s_value;
 };
 
@@ -557,7 +568,6 @@ typedef struct symtab       STAB;
 # define ST_MAP                6       /* mapping function */
 # define ST_HOSTSIG    7       /* host signature */
 # define ST_NAMECANON  8       /* cached canonical name */
 # define ST_MAP                6       /* mapping function */
 # define ST_HOSTSIG    7       /* host signature */
 # define ST_NAMECANON  8       /* cached canonical name */
-# define ST_ALIASCLASS 9       /* alias class */
 # define ST_MCI                16      /* mailer connection info (offset) */
 
 # define s_class       s_value.sv_class
 # define ST_MCI                16      /* mailer connection info (offset) */
 
 # define s_class       s_value.sv_class
@@ -847,30 +857,30 @@ EXTERN u_char     tTdvect[100];
 **  Declarations of useful functions
 */
 
 **  Declarations of useful functions
 */
 
-extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
-extern char    *xalloc __P((int));
-extern bool    sameaddr __P((ADDRESS *, ADDRESS *));
-extern FILE    *dfopen __P((char *, int, int));
-extern EVENT   *setevent __P((time_t, int(*)(), int));
-extern char    *sfgets __P((char *, int, FILE *, time_t));
-extern char    *queuename __P((ENVELOPE *, int));
-extern time_t  curtime __P(());
-extern bool    transienterror __P((int));
-extern char    *errstring __P((int));
+extern ADDRESS         *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
+extern char            *xalloc __P((int));
+extern bool            sameaddr __P((ADDRESS *, ADDRESS *));
+extern FILE            *dfopen __P((char *, int, int));
+extern EVENT           *setevent __P((time_t, int(*)(), int));
+extern char            *sfgets __P((char *, int, FILE *, time_t));
+extern char            *queuename __P((ENVELOPE *, int));
+extern time_t          curtime __P(());
+extern bool            transienterror __P((int));
+extern const char      *errstring __P((int));
 
 /* ellipsis is a different case though */
 #ifdef __STDC__
 
 /* ellipsis is a different case though */
 #ifdef __STDC__
-extern void    auth_warning(ENVELOPE *, char *, ...);
-extern void    syserr(char *, ...);
-extern void    usrerr(char *, ...);
-extern void    message(char *, ...);
-extern void    nmessage(char *, ...);
+extern void            auth_warning(ENVELOPE *, char *, ...);
+extern void            syserr(char *, ...);
+extern void            usrerr(char *, ...);
+extern void            message(char *, ...);
+extern void            nmessage(char *, ...);
 #else
 #else
-extern void    auth_warning();
-extern void    syserr();
-extern void    usrerr();
-extern void    message();
-extern void    nmessage();
+extern void            auth_warning();
+extern void            syserr();
+extern void            usrerr();
+extern void            message();
+extern void            nmessage();
 #endif
 
 /*
 #endif
 
 /*
index 216ca78..3158f49 100644 (file)
@@ -4,20 +4,11 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)useful.h    6.5 (Berkeley) %G%
+ *     @(#)useful.h    6.6 (Berkeley) %G%
  */
 
 # include <sys/types.h>
 
  */
 
 # include <sys/types.h>
 
-/* support for ANSI prototypes (or not, as the case may be) */
-#ifndef __P
-# if defined(__STDC__) && defined(_FORGIVING_CC_)
-#  define __P(protos)  protos
-# else
-#  define __P(protos)  ()
-# endif
-#endif
-
 /* support for bool type */
 typedef char   bool;
 # define TRUE  1
 /* support for bool type */
 typedef char   bool;
 # define TRUE  1