This is sendmail version 8.6.3.
[unix-history] / usr.sbin / sendmail / src / map.c
index bfa2dc0..0ee24f8 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)map.c      8.2 (Berkeley) 7/11/93";
+static char sccsid[] = "@(#)map.c      8.17 (Berkeley) 10/15/93";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -85,6 +85,8 @@ static char sccsid[] = "@(#)map.c     8.2 (Berkeley) 7/11/93";
 */
 
 #define DBMMODE                0644
 */
 
 #define DBMMODE                0644
+
+extern bool    aliaswait __P((MAP *, char *, int));
 \f/*
 **  MAP_PARSEARGS -- parse config line arguments for database lookup
 **
 \f/*
 **  MAP_PARSEARGS -- parse config line arguments for database lookup
 **
@@ -247,8 +249,7 @@ map_rewrite(map, s, slen, av)
                        c = *bp++;
                        if (!(isascii(c) && isdigit(c)))
                                continue;
                        c = *bp++;
                        if (!(isascii(c) && isdigit(c)))
                                continue;
-                       c -= 0;
-                       for (avp = av; --c >= 0 && *avp != NULL; avp++)
+                       for (avp = av; --c >= '0' && *avp != NULL; avp++)
                                continue;
                        if (*avp == NULL)
                                continue;
                                continue;
                        if (*avp == NULL)
                                continue;
@@ -291,8 +292,7 @@ map_rewrite(map, s, slen, av)
                                *bp++ = '%';
                                goto pushc;
                        }
                                *bp++ = '%';
                                goto pushc;
                        }
-                       c -= '0';
-                       for (avp = av; --c >= 0 && *avp != NULL; avp++)
+                       for (avp = av; --c >= '0' && *avp != NULL; avp++)
                                continue;
                        if (*avp == NULL)
                                continue;
                                continue;
                        if (*avp == NULL)
                                continue;
@@ -332,8 +332,14 @@ initmaps(rebuild, e)
 {
        extern void map_init();
 
 {
        extern void map_init();
 
+#ifdef XDEBUG
+       checkfd012("entering initmaps");
+#endif
        CurEnv = e;
        stabapply(map_init, rebuild);
        CurEnv = e;
        stabapply(map_init, rebuild);
+#ifdef XDEBUG
+       checkfd012("exiting initmaps");
+#endif
 }
 
 void
 }
 
 void
@@ -353,7 +359,9 @@ map_init(s, rebuild)
 
        if (tTd(38, 2))
                printf("map_init(%s:%s)\n",
 
        if (tTd(38, 2))
                printf("map_init(%s:%s)\n",
-                       map->map_class->map_cname, map->map_file);
+                       map->map_class->map_cname == NULL ? "NULL" :
+                               map->map_class->map_cname,
+                       map->map_file == NULL ? "NULL" : map->map_file);
 
        /* if already open, close it (for nested open) */
        if (bitset(MF_OPEN, map->map_mflags))
 
        /* if already open, close it (for nested open) */
        if (bitset(MF_OPEN, map->map_mflags))
@@ -374,14 +382,18 @@ map_init(s, rebuild)
                {
                        if (tTd(38, 4))
                                printf("%s:%s: valid\n",
                {
                        if (tTd(38, 4))
                                printf("%s:%s: valid\n",
-                                       map->map_class->map_cname,
-                                       map->map_file);
+                                       map->map_class->map_cname == NULL ? "NULL" :
+                                               map->map_class->map_cname,
+                                       map->map_file == NULL ? "NULL" :
+                                               map->map_file);
                        map->map_mflags |= MF_OPEN;
                }
                else if (tTd(38, 4))
                        printf("%s:%s: invalid: %s\n",
                        map->map_mflags |= MF_OPEN;
                }
                else if (tTd(38, 4))
                        printf("%s:%s: invalid: %s\n",
-                               map->map_class->map_cname,
-                               map->map_file,
+                               map->map_class->map_cname == NULL ? "NULL" :
+                                       map->map_class->map_cname,
+                               map->map_file == NULL ? "NULL" :
+                                       map->map_file,
                                errstring(errno));
        }
 }
                                errstring(errno));
        }
 }
@@ -400,7 +412,8 @@ ndbm_map_open(map, mode)
        MAP *map;
        int mode;
 {
        MAP *map;
        int mode;
 {
-       DBM *dbm;
+       register DBM *dbm;
+       struct stat st;
 
        if (tTd(38, 2))
                printf("ndbm_map_open(%s, %d)\n", map->map_file, mode);
 
        if (tTd(38, 2))
                printf("ndbm_map_open(%s, %d)\n", map->map_file, mode);
@@ -412,13 +425,20 @@ ndbm_map_open(map, mode)
        dbm = dbm_open(map->map_file, mode, DBMMODE);
        if (dbm == NULL)
        {
        dbm = dbm_open(map->map_file, mode, DBMMODE);
        if (dbm == NULL)
        {
+#ifdef MAYBENEXTRELEASE
+               if (aliaswait(map, ".pag", FALSE))
+                       return TRUE;
+#endif
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open DBM database %s", map->map_file);
                return FALSE;
        }
        map->map_db1 = (void *) dbm;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open DBM database %s", map->map_file);
                return FALSE;
        }
        map->map_db1 = (void *) dbm;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
-               aliaswait(map, ".pag");
+               if (!aliaswait(map, ".pag", TRUE))
+                       return FALSE;
+       if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0)
+               map->map_mtime = st.st_mtime;
        return TRUE;
 }
 
        return TRUE;
 }
 
@@ -435,6 +455,7 @@ ndbm_map_lookup(map, name, av, statp)
        int *statp;
 {
        datum key, val;
        int *statp;
 {
        datum key, val;
+       int fd;
        char keybuf[MAXNAME + 1];
 
        if (tTd(38, 20))
        char keybuf[MAXNAME + 1];
 
        if (tTd(38, 20))
@@ -450,7 +471,9 @@ ndbm_map_lookup(map, name, av, statp)
                makelower(keybuf);
                key.dptr = keybuf;
        }
                makelower(keybuf);
                key.dptr = keybuf;
        }
-       (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_SH);
+       fd = dbm_dirfno((DBM *) map->map_db1);
+       if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+               (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
        val.dptr = NULL;
        if (bitset(MF_TRY0NULL, map->map_mflags))
        {
        val.dptr = NULL;
        if (bitset(MF_TRY0NULL, map->map_mflags))
        {
@@ -465,7 +488,8 @@ ndbm_map_lookup(map, name, av, statp)
                if (val.dptr != NULL)
                        map->map_mflags &= ~MF_TRY0NULL;
        }
                if (val.dptr != NULL)
                        map->map_mflags &= ~MF_TRY0NULL;
        }
-       (void) lockfile(dbm_dirfno((DBM *) map->map_db1), map->map_file, LOCK_UN);
+       if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+               (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
        if (val.dptr == NULL)
                return NULL;
        if (bitset(MF_MATCHONLY, map->map_mflags))
        if (val.dptr == NULL)
                return NULL;
        if (bitset(MF_MATCHONLY, map->map_mflags))
@@ -525,14 +549,21 @@ ndbm_map_close(map)
 {
        if (bitset(MF_WRITABLE, map->map_mflags))
        {
 {
        if (bitset(MF_WRITABLE, map->map_mflags))
        {
-#ifdef YPCOMPAT
+#ifdef NIS
+               bool inclnull;
                char buf[200];
 
                char buf[200];
 
+               inclnull = bitset(MF_INCLNULL, map->map_mflags);
+               map->map_mflags &= ~MF_INCLNULL;
+
                (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);
                (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);
+
+               if (inclnull)
+                       map->map_mflags |= MF_INCLNULL;
 #endif
 
                /* write out the distinguished alias */
 #endif
 
                /* write out the distinguished alias */
@@ -568,6 +599,8 @@ bt_map_open(map, mode)
        DB *db;
        int i;
        int omode;
        DB *db;
        int i;
        int omode;
+       int fd;
+       struct stat st;
        char buf[MAXNAME];
 
        if (tTd(38, 2))
        char buf[MAXNAME];
 
        if (tTd(38, 2))
@@ -577,7 +610,7 @@ bt_map_open(map, mode)
        if (omode == O_RDWR)
        {
                omode |= O_CREAT|O_TRUNC;
        if (omode == O_RDWR)
        {
                omode |= O_CREAT|O_TRUNC;
-#if defined(O_EXLOCK) && !defined(LOCKF)
+#if defined(O_EXLOCK) && defined(HASFLOCK)
                omode |= O_EXLOCK;
 # if !defined(OLD_NEWDB)
        }
                omode |= O_EXLOCK;
 # if !defined(OLD_NEWDB)
        }
@@ -595,27 +628,45 @@ bt_map_open(map, mode)
        db = dbopen(buf, omode, DBMMODE, DB_BTREE, NULL);
        if (db == NULL)
        {
        db = dbopen(buf, omode, DBMMODE, DB_BTREE, NULL);
        if (db == NULL)
        {
+#ifdef MAYBENEXTRELEASE
+               if (aliaswait(map, ".db", FALSE))
+                       return TRUE;
+#endif
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open BTREE database %s", map->map_file);
                return FALSE;
        }
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open BTREE database %s", map->map_file);
                return FALSE;
        }
-#if !defined(OLD_NEWDB) && !defined(LOCKF)
+#if !defined(OLD_NEWDB) && defined(HASFLOCK)
+       fd = db->fd(db);
 # if !defined(O_EXLOCK)
 # if !defined(O_EXLOCK)
-       if (mode == O_RDWR)
-               (void) lockfile(db->fd(db), map->map_file, LOCK_EX);
+       if (mode == O_RDWR && fd >= 0)
+       {
+               if (lockfile(fd, map->map_file, ".db", LOCK_EX))
+                       map->map_mflags |= MF_LOCKED;
+       }
 # else
 # else
-       if (mode == O_RDONLY)
-               (void) lockfile(db->fd(db), map->map_file, LOCK_UN);
+       if (mode == O_RDONLY && fd >= 0)
+               (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+       else
+               map->map_mflags |= MF_LOCKED;
 # endif
 #endif
 
        /* try to make sure that at least the database header is on disk */
        if (mode == O_RDWR)
 # endif
 #endif
 
        /* try to make sure that at least the database header is on disk */
        if (mode == O_RDWR)
+#ifdef OLD_NEWDB
+               (void) db->sync(db);
+#else
                (void) db->sync(db, 0);
 
                (void) db->sync(db, 0);
 
+       if (fd >= 0 && fstat(fd, &st) >= 0)
+               map->map_mtime = st.st_mtime;
+#endif
+
        map->map_db2 = (void *) db;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
        map->map_db2 = (void *) db;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
-               aliaswait(map, ".db");
+               if (!aliaswait(map, ".db", TRUE))
+                       return FALSE;
        return TRUE;
 }
 
        return TRUE;
 }
 
@@ -632,6 +683,8 @@ hash_map_open(map, mode)
        DB *db;
        int i;
        int omode;
        DB *db;
        int i;
        int omode;
+       int fd;
+       struct stat st;
        char buf[MAXNAME];
 
        if (tTd(38, 2))
        char buf[MAXNAME];
 
        if (tTd(38, 2))
@@ -641,7 +694,7 @@ hash_map_open(map, mode)
        if (omode == O_RDWR)
        {
                omode |= O_CREAT|O_TRUNC;
        if (omode == O_RDWR)
        {
                omode |= O_CREAT|O_TRUNC;
-#if defined(O_EXLOCK) && !defined(LOCKF)
+#if defined(O_EXLOCK) && defined(HASFLOCK)
                omode |= O_EXLOCK;
 # if !defined(OLD_NEWDB)
        }
                omode |= O_EXLOCK;
 # if !defined(OLD_NEWDB)
        }
@@ -659,27 +712,45 @@ hash_map_open(map, mode)
        db = dbopen(buf, omode, DBMMODE, DB_HASH, NULL);
        if (db == NULL)
        {
        db = dbopen(buf, omode, DBMMODE, DB_HASH, NULL);
        if (db == NULL)
        {
+#ifdef MAYBENEXTRELEASE
+               if (aliaswait(map, ".db", FALSE))
+                       return TRUE;
+#endif
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open HASH database %s", map->map_file);
                return FALSE;
        }
                if (!bitset(MF_OPTIONAL, map->map_mflags))
                        syserr("Cannot open HASH database %s", map->map_file);
                return FALSE;
        }
-#if !defined(OLD_NEWDB) && !defined(LOCKF)
+#if !defined(OLD_NEWDB) && defined(HASFLOCK)
+       fd = db->fd(db);
 # if !defined(O_EXLOCK)
 # if !defined(O_EXLOCK)
-       if (mode == O_RDWR)
-               (void) lockfile(db->fd(db), map->map_file, LOCK_EX);
+       if (mode == O_RDWR && fd >= 0)
+       {
+               if (lockfile(fd, map->map_file, ".db", LOCK_EX))
+                       map->map_mflags |= MF_LOCKED;
+       }
 # else
 # else
-       if (mode == O_RDONLY)
-               (void) lockfile(db->fd(db), map->map_file, LOCK_UN);
+       if (mode == O_RDONLY && fd >= 0)
+               (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+       else
+               map->map_mflags |= MF_LOCKED;
 # endif
 #endif
 
        /* try to make sure that at least the database header is on disk */
        if (mode == O_RDWR)
 # endif
 #endif
 
        /* try to make sure that at least the database header is on disk */
        if (mode == O_RDWR)
+#ifdef OLD_NEWDB
+               (void) db->sync(db);
+#else
                (void) db->sync(db, 0);
 
                (void) db->sync(db, 0);
 
+       if (fd >= 0 && fstat(fd, &st) >= 0)
+               map->map_mtime = st.st_mtime;
+#endif
+
        map->map_db2 = (void *) db;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
        map->map_db2 = (void *) db;
        if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
-               aliaswait(map, ".db");
+               if (!aliaswait(map, ".db", TRUE))
+                       return FALSE;
        return TRUE;
 }
 
        return TRUE;
 }
 
@@ -699,6 +770,7 @@ db_map_lookup(map, name, av, statp)
        register DB *db = (DB *) map->map_db2;
        int st;
        int saveerrno;
        register DB *db = (DB *) map->map_db2;
        int st;
        int saveerrno;
+       int fd;
        char keybuf[MAXNAME + 1];
 
        if (tTd(38, 20))
        char keybuf[MAXNAME + 1];
 
        if (tTd(38, 20))
@@ -712,7 +784,9 @@ db_map_lookup(map, name, av, statp)
        if (!bitset(MF_NOFOLDCASE, map->map_mflags))
                makelower(keybuf);
 #ifndef OLD_NEWDB
        if (!bitset(MF_NOFOLDCASE, map->map_mflags))
                makelower(keybuf);
 #ifndef OLD_NEWDB
-       (void) lockfile(db->fd(db), map->map_file, LOCK_SH);
+       fd = db->fd(db);
+       if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+               (void) lockfile(db->fd(db), map->map_file, ".db", LOCK_SH);
 #endif
        st = 1;
        if (bitset(MF_TRY0NULL, map->map_mflags))
 #endif
        st = 1;
        if (bitset(MF_TRY0NULL, map->map_mflags))
@@ -730,7 +804,8 @@ db_map_lookup(map, name, av, statp)
        }
        saveerrno = errno;
 #ifndef OLD_NEWDB
        }
        saveerrno = errno;
 #ifndef OLD_NEWDB
-       (void) lockfile(db->fd(db), map->map_file, LOCK_UN);
+       if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+               (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
 #endif
        if (st != 0)
        {
 #endif
        if (st != 0)
        {
@@ -817,6 +892,10 @@ db_map_close(map)
 
 # ifdef NIS
 
 
 # ifdef NIS
 
+# ifndef YPERR_BUSY
+#  define YPERR_BUSY   16
+# endif
+
 /*
 **  NIS_MAP_OPEN -- open DBM map
 */
 /*
 **  NIS_MAP_OPEN -- open DBM map
 */
@@ -837,7 +916,16 @@ nis_map_open(map, mode)
 
        if (mode != O_RDONLY)
        {
 
        if (mode != O_RDONLY)
        {
-               errno = ENODEV;
+               /* issue a pseudo-error message */
+#ifdef ENOSYS
+               errno = ENOSYS;
+#else
+# ifdef EFTYPE
+               errno = EFTYPE;
+# else
+               errno = ENXIO;
+# endif
+#endif
                return FALSE;
        }
 
                return FALSE;
        }
 
@@ -1012,6 +1100,9 @@ stab_map_open(map, mode)
        register MAP *map;
        int mode;
 {
        register MAP *map;
        int mode;
 {
+       FILE *af;
+       struct stat st;
+
        if (tTd(38, 2))
                printf("stab_map_open(%s)\n", map->map_file);
 
        if (tTd(38, 2))
                printf("stab_map_open(%s)\n", map->map_file);
 
@@ -1021,12 +1112,23 @@ stab_map_open(map, mode)
                return FALSE;
        }
 
                return FALSE;
        }
 
+       af = fopen(map->map_file, "r");
+       if (af == NULL)
+               return FALSE;
+       readaliases(map, af, TRUE);
+
+       if (fstat(fileno(af), &st) >= 0)
+               map->map_mtime = st.st_mtime;
+       fclose(af);
+
        return TRUE;
 }
 
 
 /*
        return TRUE;
 }
 
 
 /*
-**  STAB_MAP_CLOSE -- close symbol table (???)
+**  STAB_MAP_CLOSE -- close symbol table.
+**
+**     Since this is in memory, there is nothing to do.
 */
 
 void
 */
 
 void
@@ -1100,11 +1202,13 @@ impl_map_open(map, mode)
        struct stat stb;
 
        if (tTd(38, 2))
        struct stat stb;
 
        if (tTd(38, 2))
-               printf("impl_map_open(%s)\n", map->map_file);
+               printf("impl_map_open(%s, %d)\n", map->map_file, mode);
 
        if (stat(map->map_file, &stb) < 0)
        {
                /* no alias file at all */
 
        if (stat(map->map_file, &stb) < 0)
        {
                /* no alias file at all */
+               if (tTd(38, 3))
+                       printf("no map file\n");
                return FALSE;
        }
 
                return FALSE;
        }
 
@@ -1112,7 +1216,7 @@ impl_map_open(map, mode)
        map->map_mflags |= MF_IMPL_HASH;
        if (hash_map_open(map, mode))
        {
        map->map_mflags |= MF_IMPL_HASH;
        if (hash_map_open(map, mode))
        {
-#if defined(NDBM) && defined(YPCOMPAT)
+#if defined(NDBM) && defined(NIS)
                if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) != 0)
 #endif
                        return TRUE;
                if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) != 0)
 #endif
                        return TRUE;
@@ -1130,7 +1234,7 @@ impl_map_open(map, mode)
                map->map_mflags &= ~MF_IMPL_NDBM;
 #endif
 
                map->map_mflags &= ~MF_IMPL_NDBM;
 #endif
 
-#if !defined(NEWDB) && !defined(NDBM)
+#if defined(NEWDB) || defined(NDBM)
        if (Verbose)
                message("WARNING: cannot open alias database %s", map->map_file);
 #endif
        if (Verbose)
                message("WARNING: cannot open alias database %s", map->map_file);
 #endif