diff -N -r -c sendmail-pristine/README.CDB sendmail-cdb/README.CDB *** sendmail-pristine/README.CDB Wed Dec 31 20:00:00 1969 --- sendmail-cdb/README.CDB Fri May 7 18:39:01 1999 *************** *** 0 **** --- 1,61 ---- + Patches for using cdb with sendmail 8.9.3 + + This patch adds a sendmail map type for Dan Bernstein's cdb package. + + USAGE + + To compile cdb support into sendmail, you should add the following lines to + your site.config.m4: + + APPENDDEF(`confMAPDEF', `-DCDB') + APPENDDEF(`confLIBS', `-lcdb -lcdbmake') + + and then just rebuild as you normally would (you'll need to use Build -c so + that the Makefile gets rebuilt). + + This of course assumes that you have already installed the cdb package from + http://pobox.com/~djb/software/cdb-0.55.tar.gz + + Once compiled in, cdb can be used as any other maptype (alias rebuilding + included). Note that with aliases, it will not take precedence over hash or + dbm if the implicit map type is used. + + PERFORMANCE + + In the rather limited testing I've done (mostly single lookups on large + alias databases), it tends to be about 20% faster than Berkeley DB when + doing a sendmail -bv . Builds tend to take a lot longer, though + if you ifdef out the duplicate key checking code, it'll take about 25% of + the time of a hash build. Even then, this performance is coupled with + a very small db size (the size of a cdb database in bytes is: + 2048 + sum of lengths of keys + sum of lengths of values + 4 * number of keys) + + CODE NOTES + + The cdb map code is based upon the code for the db_map_* functions. As a + result, it has the pre-open/pre-locking stuff left in (I'm not sure what + of that is necessary, I'll go over it later). + + sm_cdb.h is added to the src directory, as much as I loathed having to do + so. Unfortunately, the API for cdbmake makes this nearly impossible any + other way. Both the file descriptor and cdbmake structure must persist + amongst the open, store, and close hooks (and the file position, though one + could get around that by doing an lseek(fd, 0, SEEK_END)). + + The other problem caused by the cdbmake API is the lack of duplicate key + checking. As a result, I have to manually grovel through the linked list of + arrays kept in the cdbmake structure to check for duplicate keys, which + makes builds actually slower than Berkeley DB. I may write a frontend to the + cdbmake functions (or replacements) to make builds more efficient in this + regard. + + I've tried to modify the documentation appropriately, but I'm not sure + I've made all necessary changes (and I'm not sure all the changes I made + were necessary). Feedback on this issue would be appreciated. + + Oh, and please forgive me for the goto's in cdb_map_lookup, I'll clean + that up later, I promise. :) + + FEEDBACK + + Any comments can be sent to kdoherty@uu.net. diff -N -r -c sendmail-pristine/doc/op/op.me sendmail-cdb/doc/op/op.me *** sendmail-pristine/doc/op/op.me Fri Jan 22 18:58:30 1999 --- sendmail-cdb/doc/op/op.me Fri May 7 17:05:40 1999 *************** *** 300,307 **** reads the DBM version of the alias file. It's ugly as sin, but it works. .lp ! If neither of these are defined, .i sendmail reads the alias file into memory on every invocation. This can be slow and should be avoided. --- 300,314 ---- reads the DBM version of the alias file. It's ugly as sin, but it works. + .ip CDB + Dan Bernstein's Constant DB package. + CDB provides a fast, simple interface for + lookups. Its primary drawback is an + awkward DB creation API, making for slower + DB builds (because of a nasty hack to + check for duplicate keys). .lp ! If none of these are defined, .i sendmail reads the alias file into memory on every invocation. This can be slow and should be avoided. *************** *** 1259,1269 **** .i gdbm package does not work. .)f ! or the Berkeley DB library. This form is in the file .i /etc/aliases.db (if using NEWDB) or .i /etc/aliases.dir and .i /etc/aliases.pag --- 1266,1280 ---- .i gdbm package does not work. .)f ! , the Berkeley DB, or ! the CDB library. This form is in the file .i /etc/aliases.db (if using NEWDB) or + .i /etc/aliases.cdb + (if using CDB) + or .i /etc/aliases.dir and .i /etc/aliases.pag *************** *** 1337,1343 **** .sh 3 "Rebuilding the alias database" .pp The ! .i hash or .i dbm version of the database --- 1348,1355 ---- .sh 3 "Rebuilding the alias database" .pp The ! .i hash , ! .i cdb , or .i dbm version of the database *************** *** 2626,2631 **** --- 2638,2644 ---- Allow maps (e.g., .i hash , .i btree , + .i cdb , and .i dbm files) *************** *** 4838,4843 **** --- 4851,4860 ---- (if .sm NEWDB is specified), + .q cdb + (if + .sm CDB + is specified), .q dbm (if .sm NDBM *************** *** 6357,6362 **** --- 6374,6385 ---- must be compiled with .b NDBM defined. + .ip cdb + Database lookups using the cdb(3) library. + .i Sendmail + must be compiled with + .b CDB + defined. .ip btree Database lookups using the btree interface to the Berkeley DB library. *************** *** 6718,6730 **** .q \&.pag and .q \&.dir ! to the given filename; the .i hash and .i btree maps append ! .q \&.db . For example, the map specification .(b Kuucp dbm \-o \-N /usr/lib/uucpmap --- 6741,6757 ---- .q \&.pag and .q \&.dir ! to the given filename, whereas the .i hash and .i btree maps append ! .q \&.db , ! and the ! .i cdb ! map appends ! .q \&.cdb . For example, the map specification .(b Kuucp dbm \-o \-N /usr/lib/uucpmap *************** *** 6958,6963 **** --- 6985,6993 ---- .i sendmail will read DBM files, but will create and use NEWDB files. + .ip CDB + If set, use the cdb package by Dan Bernstein. + This package is faster than DBM, NDBM, or NEWDB. .ip NIS Include support for NIS. If set together with *************** *** 8183,8188 **** --- 8213,8222 ---- .ip /etc/aliases.db The alias file in .i hash \|(3) + format. + .ip /etc/aliases.cdb + The alias file in + .i cdb \|(3) format. .ip /etc/aliases.{pag,dir} The alias file in diff -N -r -c sendmail-pristine/src/README sendmail-cdb/src/README *** sendmail-pristine/src/README Thu Feb 4 19:25:04 1999 --- sendmail-cdb/src/README Fri May 7 11:25:19 1999 *************** *** 106,111 **** --- 106,113 ---- libdb.a. NDBM The older NDBM implementation -- the very old V7 DBM implementation is no longer supported. + CDB Dan Bernstein's Constant DataBase. Designed to use a minimal + number of system calls for optimum lookup speed. NIS Network Information Services. To use this you must have NIS support on your system. NISPLUS NIS+ (the revised NIS released with Solaris 2). You must diff -N -r -c sendmail-pristine/src/conf.c sendmail-cdb/src/conf.c *** sendmail-pristine/src/conf.c Tue Apr 27 18:45:47 1999 --- sendmail-cdb/src/conf.c Fri May 7 18:41:03 1999 *************** *** 362,367 **** --- 362,373 ---- { register STAB *s; + #ifdef CDB + MAPDEF("cdb", ".cdb", MCF_ALIASOK|MCF_REBUILDABLE, + map_parseargs, cdb_map_open, cdb_map_close, + cdb_map_lookup, cdb_map_store); + #endif + #ifdef NEWDB MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, map_parseargs, hash_map_open, db_map_close, *************** *** 594,599 **** --- 600,613 ---- strcpy(buf, "aliases.files null"); (void) makemapentry(buf); } + #ifdef CDB + else if (strcmp(maptype[i], "cdb") == 0 && + stab("aliases.cdb", ST_MAP, ST_FIND) == NULL) + { + strcpy(buf, "aliases.cdb null"); + (void) makemapentry(buf); + } + #endif #ifdef NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) *************** *** 909,914 **** --- 923,931 ---- if (strcmp(service, "aliases") == 0) { maptype[svcno++] = "files"; + #ifdef CDB + maptype[svcno++] = "cdb"; + #endif # ifdef AUTO_NIS_ALIASES # ifdef NISPLUS maptype[svcno++] = "nisplus"; diff -N -r -c sendmail-pristine/src/map.c sendmail-cdb/src/map.c *** sendmail-pristine/src/map.c Tue Apr 27 18:45:48 1999 --- sendmail-cdb/src/map.c Fri May 7 17:02:48 1999 *************** *** 1901,1906 **** --- 1901,2471 ---- } #endif + + /* + ** CDB Modules + */ + + #ifdef CDB + #include "sm_cdb.h" + + /* + ** CDB_MAP_OPEN -- open a CDB database + */ + + bool + cdb_map_open(map, mode) + MAP *map; + int mode; + { + int i; + int omode; + int smode = S_IREAD; + int fd, dfd; + int sff; + int saveerrno; + struct stat st; + char buf[MAXNAME + 1]; + struct cdbmake *cdbm; + + /* do initial file and directory checks */ + snprintf(buf, sizeof buf - 4, "%s", map->map_file); + i = strlen(buf); + if (i < 4 || strcmp(&buf[i - 4], ".cdb") != 0) + (void) strcat(buf, ".cdb"); + + mode &= O_ACCMODE; + omode = mode; + + sff = SFF_ROOTOK|SFF_REGONLY; + if (mode == O_RDWR) + { + sff |= SFF_CREAT; + if (!bitset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) + sff |= SFF_NOSLINK; + if (!bitset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) + sff |= SFF_NOHLINK; + smode = S_IWRITE; + } + else + { + if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) + sff |= SFF_NOWLINK; + } + if (!bitset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail)) + sff |= SFF_SAFEDIRPATH; + i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st); + if (i == ENOENT && AutoRebuild && + bitset(MCF_REBUILDABLE, map->map_class->map_cflags) && + (bitset(MF_IMPL_CDB, map->map_mflags) || + bitset(MF_ALIAS, map->map_mflags)) && + mode == O_RDONLY) + { + bool impl = bitset(MF_IMPL_CDB, map->map_mflags); + extern bool impl_map_open __P((MAP *, int)); + + /* may be able to rebuild */ + map->map_mflags &= ~MF_IMPL_CDB; + if (!rebuildaliases(map, TRUE)) + return FALSE; + if (impl) + return impl_map_open(map, O_RDONLY); + else + return cdb_map_open(map, O_RDONLY); + } + + if (i != 0) + { + char *prob = "unsafe"; + + /* cannot open this map */ + if (i == ENOENT) + prob = "missing"; + if (tTd(38, 2)) + printf("\t%s map file: %s\n", prob, errstring(i)); + errno = i; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("cdb map \"%s\": %s map file %s", + map->map_mname, prob, buf); + return FALSE; + } + if (st.st_mode == ST_MODE_NOFILE) + omode |= O_CREAT|O_EXCL; + + map->map_lockfd = -1; + + #if LOCK_ON_OPEN + if (mode == O_RDWR) + omode |= O_TRUNC|O_EXLOCK; + else + omode |= O_SHLOCK; + #else + /* + ** Pre-lock the file to avoid race conditions. In particular, + ** since dbopen returns NULL if the file is zero length, we + ** must have a locked instance around the dbopen. + */ + + fd = open(buf, omode, DBMMODE); + if (fd < 0) + { + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("cdb_map_open: cannot pre-open database %s", buf); + return FALSE; + } + + /* make sure no baddies slipped in just before the open... */ + if (filechanged(buf, fd, &st)) + { + int save_errno = errno; + + (void) close(fd); + errno = save_errno; + syserr("cdb_map_open(%s): file changed after pre-open", buf); + return FALSE; + } + + /* if new file, get the "before" bits for later filechanged check */ + if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0) + { + int save_errno = errno; + + (void) close(fd); + errno = save_errno; + syserr("cdb_map_open(%s): cannot fstat pre-opened file", + buf); + return FALSE; + } + + /* actually lock the pre-opened file */ + if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX)) + syserr("cdb_map_open: cannot lock %s", buf); + + /* set up mode bits for dbopen */ + if (mode == O_RDWR) + omode |= O_TRUNC; + omode &= ~(O_EXCL|O_CREAT); + #endif + + #if !LOCK_ON_OPEN + if (mode == O_RDWR) + map->map_lockfd = fd; + else + (void) close(fd); + #endif + + fd = open(buf, omode, DBMMODE); + saveerrno = errno; + + if (fd < 0) + { + if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && + aliaswait(map, ".cdb", FALSE)) + return TRUE; + #if !LOCK_ON_OPEN + if (map->map_lockfd >= 0) + (void) close(map->map_lockfd); + #endif + errno = saveerrno; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("Cannot open cdb database %s", buf); + return FALSE; + } + + if (filechanged(buf, fd, &st)) + { + int save_errno = errno; + + close(fd); + #if !LOCK_ON_OPEN + if (map->map_lockfd >= 0) + close(map->map_lockfd); + #endif + errno = save_errno; + syserr("cdb_map_open(%s): file changed after open", buf); + return FALSE; + } + + if (mode == O_RDWR) + map->map_mflags |= MF_LOCKED; + #if LOCK_ON_OPEN + if (fd >= 0 && mode == O_RDONLY) + { + (void) lockfile(fd, buf, NULL, LOCK_UN); + } + #endif + + /* try to make sure that at least the database header is on disk */ + if (mode == O_RDWR) + { + #if _FFR_TRUSTED_USER + if (geteuid() == 0 && TrustedUid != 0) + { + if (fchown(fd, TrustedUid, -1) < 0) + { + int err = errno; + + sm_syslog(LOG_ALERT, NOQID, + "ownership change on %s failed: %s", + buf, errstring(err)); + message("050 ownership change on %s failed: %s", + buf, errstring(err)); + } + } + #endif + } + + if (fd >= 0 && fstat(fd, &st) >= 0) + map->map_mtime = st.st_mtime; + + if (mode == O_RDONLY) + { + map->map_db1 = (ARBPTR_T)mode; + map->map_db2 = (ARBPTR_T)fd; + } + else + { + cdbm = malloc(sizeof(struct cdbmake)); + cdbmake_init(cdbm); + map->map_db1 = (ARBPTR_T)mode; + map->map_db2 = (ARBPTR_T)malloc(sizeof(struct sm_cdbmake)); + ((struct sm_cdbmake *)map->map_db2)->fd = fd; + memcpy(&(((struct sm_cdbmake *)map->map_db2)->cdbm), + cdbm, sizeof(struct cdbmake)); + for (i = 0; i < sizeof(cdbm->final);i++) + write(fd, "\0", 1); + ((struct sm_cdbmake *)map->map_db2)->pos = sizeof(cdbm->final); + } + if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && + !aliaswait(map, ".cdb", TRUE)) + return FALSE; + + return TRUE; + } + + + /* + ** CDB_MAP_LOOKUP -- look up a key's value in an opened CDB database + */ + + char * + cdb_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; + { + int fd = (int)map->map_db2; + int i; + int st; + int saveerrno; + struct stat stbuf; + char keybuf[MAXNAME + 1]; + char buf[MAXNAME + 1]; + char *data; + uint32 klen, dlen; + + if (tTd(38, 20)) + printf("cdb_map_lookup(%s, %s)\n", + map->map_mname, name); + + if ((int)map->map_db1 != O_RDONLY) + { + *statp = EX_SOFTWARE; + return NULL; + } + + i = strlen(map->map_file); + if (i > MAXNAME) + i = MAXNAME; + strncpy(buf, map->map_file, i); + buf[i] = '\0'; + if (i > 4 && strcmp(&buf[i - 4], ".cdb") == 0) + buf[i - 4] = '\0'; + + klen = strlen(name); + bcopy(name, keybuf, klen); + keybuf[klen] = '\0'; + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + makelower(keybuf); + lockdb: + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(fd, buf, ".cdb", LOCK_SH); + if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime) + { + /* Reopen the database to sync the cache */ + int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR + : O_RDONLY; + + map->map_class->map_close(map); + map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + if (map->map_class->map_open(map, omode)) + { + map->map_mflags |= MF_OPEN; + map->map_pid = getpid(); + if ((omode && O_ACCMODE) == O_RDWR) + map->map_mflags |= MF_WRITABLE; + goto lockdb; + } + else + { + if (!bitset(MF_OPTIONAL, map->map_mflags)) + { + extern MAPCLASS BogusMapClass; + + *statp = EX_TEMPFAIL; + map->map_class = &BogusMapClass; + map->map_mflags |= MF_OPEN; + map->map_pid = getpid(); + syserr("Cannot reopen cdb database %s", + map->map_file); + } + return NULL; + } + } + + st = 1; + if (bitset(MF_TRY0NULL, map->map_mflags)) + { + if (cdb_seek(fd, keybuf, klen, &dlen) != 1) + { + *statp = EX_NOUSER; + st = 1; + if (!bitset(MF_TRY1NULL, map->map_mflags)) + goto cdb_error; + } + else + { + st = 0; + } + } + if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags)) + { + if (cdb_seek(fd, keybuf, ++klen, &dlen) != 1) + { + *statp = EX_NOUSER; + st = 1; + goto cdb_error; + } + else + { + map->map_mflags &= ~MF_TRY0NULL; + st = 0; + } + } + if (dlen == 0) + { + *statp = EX_UNAVAILABLE; + st = 1; + goto cdb_error; + } + if ((data = (char *)malloc(dlen + 1)) == NULL) + { + *statp = EX_OSERR; + st = -1; + goto cdb_error; + } + if ((i = read(fd, data, dlen)) != dlen) + { + *statp = EX_UNAVAILABLE; + st = -1; + goto cdb_error; + } + data[dlen] = '\0'; + + cdb_error: + saveerrno = errno; + if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) + (void) lockfile(fd, buf, ".cdb", LOCK_UN); + if (st != 0) + { + errno = saveerrno; + if (st < 0) + syserr("cdb_map_lookup: get (%s)", name); + return NULL; + } + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, name, strlen(name), NULL); + else + return map_rewrite(map, data, dlen, av); + } + + + /* + ** CDB_MAP_STORE -- Store a key and value in a CDB map + */ + + void + cdb_map_store(map, lhs, rhs) + register MAP *map; + char *lhs; + char *rhs; + { + register struct sm_cdbmake *sm_cdbm = + (struct sm_cdbmake *)map->map_db2; + struct cdbmake *cdbm = &(sm_cdbm->cdbm); + int fd = sm_cdbm->fd; + int i; + char keybuf[MAXNAME + 1]; + char buf[MAXNAME + 1]; + uint32 klen, dlen, hashnum, tmpklen; + char packbuf[8]; + struct cdbmake_hplist *hplist; /* this is required for some hairy + cdb internal stuff to check for + duplicate entries */ + + if (tTd(38, 12)) + printf("cdb_map_store(%s, %s, %s)\n", + map->map_mname, lhs, rhs); + + if ((int)map->map_db1 == O_RDONLY) + { + return; + } + + klen = strlen(lhs); + if (klen > sizeof keybuf - 1) + klen = sizeof keybuf - 1; + bcopy(lhs, keybuf, klen); + keybuf[klen] = '\0'; + if (!bitset(MF_NOFOLDCASE, map->map_mflags)) + { + makelower(keybuf); + } + + dlen = strlen(rhs); + + if (bitset(MF_INCLNULL, map->map_mflags)) + { + klen++; + dlen++; + } + + /* Get the hash of the string so we can check for it in the hplist */ + hashnum = CDBMAKE_HASHSTART; + for (i = 0;i < klen;i++) { + hashnum = cdbmake_hashadd(hashnum, keybuf[i]); + } + + /* Check for a duplicate key */ + /* + * NOTE: Using append with cdb would be very difficult because + * appending to an existing datum would skew the position numbers + * for any subsequent keys. One possible solution would be to + * rewrite the key name with nulls in the previous instance of + * the key, but this seems like really bad juju to me. + */ + if (!bitset(MF_APPEND, map->map_mflags)) + { + /* + * cdb keeps a linked list of arrays of the hashnum and file + * position of each key inserted into the database. We + * iterate through the linked list of arrays, checking first + * against hash number, then against the key length, and + * finally key string. + */ + for (hplist = cdbm->head;hplist;hplist = hplist->next) + { + for (i = 0;i < hplist->num;i++) + { + if (hplist->hp[i].h == hashnum) + { + lseek(fd, (off_t)hplist->hp[i].p, SEEK_SET); + read(fd, buf, 4); + tmpklen = cdb_unpack(buf); + if (tmpklen != klen) + { + continue; + } + else + { + lseek(fd, (off_t) 4, SEEK_CUR); + read(fd, buf, tmpklen); + if (!strncmp(keybuf, buf, klen)) + { + message("050 Warning: duplicate alias name %s", lhs); + } + } + } + } + } + lseek(fd, (off_t) 0, SEEK_END); + } + + /* Pack the sizes of key and data into packbuf (this is done to avoid + endianness problems) */ + cdbmake_pack(packbuf, klen); + cdbmake_pack(packbuf + 4, dlen); + + if (write(fd, packbuf, 8) < 8) + { + syserr("readaliases: cdb put (%s)", lhs); + } + + write(fd, keybuf, klen); + write(fd, rhs, dlen); + + if (!cdbmake_add(cdbm, hashnum, sm_cdbm->pos, malloc)) + { + syserr("readaliases: cdb put (%s)", lhs); + } + sm_cdbm->pos += (uint32)8; + sm_cdbm->pos += klen; + sm_cdbm->pos += dlen; + } + + /* + ** CDB_MAP_CLOSE -- close the CDB database file descriptor + */ + + void + cdb_map_close(map) + MAP *map; + { + if ((int)map->map_db1 == O_RDWR) + { + struct sm_cdbmake *sm_cdbm = (struct sm_cdbmake *)map->map_db2; + struct cdbmake *cdbm = &(sm_cdbm->cdbm); + int fd = sm_cdbm->fd; + uint32 klen, dlen, hashnum, len; + char packbuf[8]; + int i, j; + + /* Insert a check to see if this is aliases here */ + cdb_map_store(map, "@", "@"); + if (!cdbmake_split(cdbm, malloc)) { + /* Error handling? */ + } + for (i = 0;i < 256;i++) { + len = cdbmake_throw(cdbm, sm_cdbm->pos, i); + for (j = 0;j < len;j++) { + cdbmake_pack(packbuf, cdbm->hash[j].h); + cdbmake_pack(packbuf + 4, cdbm->hash[j].p); + if (write(fd, packbuf, 8) < 8) { + } + sm_cdbm->pos += 8; + } + } + lseek(fd, 0, SEEK_SET); + write(fd, cdbm->final, sizeof(cdbm->final)); + #if !LOCK_ON_OPEN + if (map->map_lockfd >= 0) + (void) close(map->map_lockfd); + #endif + close((int)((struct sm_cdbmake *)map->map_db2)->fd); + free(map->map_db2); + } + else { + #if !LOCK_ON_OPEN + if (map->map_lockfd >= 0) + (void) close(map->map_lockfd); + #endif + close((int)map->map_db2); + } + } + + #endif + /* ** NIS Modules */ *************** *** 4176,4181 **** --- 4741,4750 ---- if (bitset(MF_IMPL_NDBM, map->map_mflags)) return ndbm_map_lookup(map, name, av, pstat); #endif + #ifdef CDB + if (bitset(MF_IMPL_CDB, map->map_mflags)) + return cdb_map_lookup(map, name, av, pstat); + #endif return stab_map_lookup(map, name, av, pstat); } *************** *** 4200,4205 **** --- 4769,4778 ---- if (bitset(MF_IMPL_NDBM, map->map_mflags)) ndbm_map_store(map, lhs, rhs); #endif + #ifdef CDB + if (bitset(MF_IMPL_CDB, map->map_mflags)) + cdb_map_store(map, lhs, rhs); + #endif stab_map_store(map, lhs, rhs); } *************** *** 4238,4245 **** else map->map_mflags &= ~MF_IMPL_NDBM; #endif ! ! #if defined(NEWDB) || defined(NDBM) if (Verbose) message("WARNING: cannot open alias database %s%s", map->map_file, --- 4811,4826 ---- else map->map_mflags &= ~MF_IMPL_NDBM; #endif ! #ifdef CDB ! map->map_mflags |= MF_IMPL_CDB; ! if (cdb_map_open(map, mode)) ! { ! return TRUE; ! } ! else ! map->map_mflags &= ~MF_IMPL_CDB; ! #endif ! #if defined(NEWDB) || defined(NDBM) || defined(CDB) if (Verbose) message("WARNING: cannot open alias database %s%s", map->map_file, *************** *** 4280,4285 **** --- 4861,4874 ---- { ndbm_map_close(map); map->map_mflags &= ~MF_IMPL_NDBM; + } + #endif + + #ifdef CDB + if (bitset(MF_IMPL_CDB, map->map_mflags)) + { + cdb_map_close(map); + map->map_mflags &= ~MF_IMPL_CDB; } #endif } diff -N -r -c sendmail-pristine/src/sm_cdb.h sendmail-cdb/src/sm_cdb.h *** sendmail-pristine/src/sm_cdb.h Wed Dec 31 20:00:00 1969 --- sendmail-cdb/src/sm_cdb.h Wed Apr 28 15:45:23 1999 *************** *** 0 **** --- 1,17 ---- + /* + * sm_cdb.h -- Structs for easier management of CDB within sendmail. + */ + + #ifdef CDB + # ifndef SM_CDB_H + # define SM_CDB_H + # include + # include + # include + struct sm_cdbmake { + int fd; + struct cdbmake cdbm; + uint32 pos; + }; + # endif + #endif ----- End forwarded message ----- -- Elie Rosenblum elier@uu.net Team Lead - Mail Hosting / Transport (703)-645-4269 UUNET Server Operations ----- End forwarded message ----- -- / __ | Richard Rognlie / Sendmail Consultant / Sendmail, Inc. / / \ | richard@sendmail.com (O) 703.391.1755 \__/ / | (C) 703.626.0726 / | *BSD and Linux: The Ultimate Windows NT Service Packs