diff -N -r -c sendmail-8.14.1/devtools/bin/configure.sh sendmail-8.14.1-tinycdb/devtools/bin/configure.sh
*** sendmail-8.14.1/devtools/bin/configure.sh	2003-08-21 02:08:35.000000000 +0800
--- sendmail-8.14.1-tinycdb/devtools/bin/configure.sh	2007-10-22 16:26:22.000000000 +0800
***************
*** 128,133 ****
--- 128,136 ----
  					continue
  				fi
  				;;
+ 			  cdb)
+ 				mapdef="$mapdef -DCDB"
+ 				;;
  			esac
  			libs="$libs -l$l"
  			break
diff -N -r -c sendmail-8.14.1/devtools/M4/header.m4 sendmail-8.14.1-tinycdb/devtools/M4/header.m4
*** sendmail-8.14.1/devtools/M4/header.m4	2002-08-02 05:58:26.000000000 +0800
--- sendmail-8.14.1-tinycdb/devtools/M4/header.m4	2007-10-22 16:30:03.000000000 +0800
***************
*** 25,32 ****
  define(`confBEFORE', `')
  define(`confLIBDIRS', `')
  define(`confINCDIRS', `')
! define(`confLIBSEARCH', `db bind resolv 44bsd')
! define(`confLIBSEARCHPATH', `/lib /usr/lib /usr/shlib')
  define(`confSITECONFIG', `site.config')
  define(`confBUILDBIN', `${SRCDIR}/devtools/bin')
  define(`confRANLIB', `echo')
--- 25,32 ----
  define(`confBEFORE', `')
  define(`confLIBDIRS', `')
  define(`confINCDIRS', `')
! define(`confLIBSEARCH', `db bind resolv 44bsd cdb')
! define(`confLIBSEARCHPATH', `/lib /usr/lib /usr/shlib /usr/lib64')
  define(`confSITECONFIG', `site.config')
  define(`confBUILDBIN', `${SRCDIR}/devtools/bin')
  define(`confRANLIB', `echo')
diff -N -r -c sendmail-8.14.1/README.cdb sendmail-8.14.1-tinycdb/README.cdb
*** sendmail-8.14.1/README.cdb	1970-01-01 08:00:00.000000000 +0800
--- sendmail-8.14.1-tinycdb/README.cdb	2007-09-11 16:33:20.000000000 +0800
***************
*** 0 ****
--- 1,37 ----
+ tinycdb patch for sendmail
+ 
+ tinycdb is a library that implements DJB's cdb database. This patch adds cdb
+ support for sendmail by means of tinycdb. You will need to install tinycdb
+ for sendmail sources patched with this patch to be able to build.
+ 
+ This patch will add a readonly map for cdb databases. Creation of cdb
+ databases are expected to be done with tinycdb's cdb commandline tool. It
+ supposts aliases in cdb format and supports sendmail's rewriting. The cdb
+ map will open the cdb file and keep it open for reads until the map is
+ closed which is not the case with previous cdb patches for sendmail.
+ 
+ BUILDING CDB DATABASES
+ 
+    TABLES (access, mailertable, virtusertable, ...)
+    cdb -c -m table.cdb table
+ 
+    ALIASES
+ 
+    Use sed to rip out the colons and then feed tinycdb's cdb program to 
+    create an aliases cdb database.
+ 
+    'sed -e s/:// /etc/aliases| cdb -c -m /etc/aliases.cdb'
+ 
+ EXAMPLES IN USING CDB MAP
+ 
+    access_db:
+    FEATURE(`access_db',`cdb -T<TMPF> /etc/mail/access.cdb')dnl
+ 
+    mailertable:
+    FEATURE(`mailertable',`cdb /etc/mail/mailertable.cdb')dnl
+ 
+    virtusertable:
+    FEATURE(`virtusertable',`cdb /etc/mail/virtusertable.cdb')dnl
+ 
+    aliases:
+    define(`ALIAS_FILE', `cdb /etc/aliases.cdb')
diff -N -r -c sendmail-8.14.1/sendmail/conf.c sendmail-8.14.1-tinycdb/sendmail/conf.c
*** sendmail-8.14.1/sendmail/conf.c	2007-04-04 05:32:29.000000000 +0800
--- sendmail-8.14.1-tinycdb/sendmail/conf.c	2007-10-22 15:47:09.000000000 +0800
***************
*** 509,514 ****
--- 509,521 ----
  		db_map_lookup, db_map_store);
  #endif /* NEWDB */
  
+ #if CDB 
+ 	MAPDEF("cdb", ".cdb", MCF_ALIASOK,
+ 		map_parseargs, cdb_map_open, cdb_map_close,
+ 		cdb_map_lookup, null_map_store);
+ 
+ #endif /* CDB */
+ 
  #if NDBM
  	MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
  		map_parseargs, ndbm_map_open, ndbm_map_close,
***************
*** 741,746 ****
--- 748,760 ----
  					  sizeof(buf));
  			(void) makemapentry(buf);
  		}
+ #if CDB
+ 		else if (strcmp(maptype[i], "cdb") == 0 && stab("aliases.cdb", ST_MAP, ST_FIND) == NULL)
+ 		{
+ 			(void) sm_strlcpy(buf, "aliases.cdb null", sizeof(buf));
+ 			(void) makemapentry(buf);
+ 		}
+ #endif /* CDB */
  #if NISPLUS
  		else if (strcmp(maptype[i], "nisplus") == 0 &&
  			 stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
***************
*** 1045,1050 ****
--- 1059,1067 ----
  	if (strcmp(service, "aliases") == 0)
  	{
  		maptype[svcno++] = "files";
+ # if CDB
+ 		maptype[svcno++] = "cdb";
+ #endif /* CDB */
  # if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
  		maptype[svcno++] = "netinfo";
  # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
***************
*** 5728,5733 ****
--- 5745,5753 ----
  #if NEWDB
  	"NEWDB",
  #endif /* NEWDB */
+ #if CDB
+ 	"CDB",
+ #endif /* CDB */
  #if NIS
  	"NIS",
  #endif /* NIS */
diff -N -r -c sendmail-8.14.1/sendmail/map.c sendmail-8.14.1-tinycdb/sendmail/map.c
*** sendmail-8.14.1/sendmail/map.c	2007-04-04 05:33:14.000000000 +0800
--- sendmail-8.14.1-tinycdb/sendmail/map.c	2007-09-04 16:34:23.000000000 +0800
***************
*** 19,24 ****
--- 19,28 ----
  # include <sm/ldap.h>
  #endif /* LDAPMAP */
  
+ #if CDB
+ #include <cdb.h>
+ #endif /* CDB */
+ 
  #if NDBM
  # include <ndbm.h>
  # ifdef R_FIRST
***************
*** 1890,1895 ****
--- 1894,2033 ----
  }
  
  #endif /* NDBM */
+ 
+ /*
+ ** CDB Modules
+ */
+ 
+ #if CDB
+ bool cdb_map_open(map, mode) 
+ 	MAP *map;
+ 	int mode;
+ {
+ 	struct cdb cdbmap;
+ 	struct cdb *cdbp;
+ 	cdbp = &cdbmap;
+ 	int fd, status;
+ 	
+ 	int i;
+ 	char buf[MAXPATHLEN];
+ 
+         if (tTd(38, 2))
+                 sm_dprintf("cdb_map_open(%s, %s, %d)\n",
+                         map->map_mname, map->map_file, mode);
+ 
+         mode &= O_ACCMODE;
+         if (mode != O_RDONLY)
+         {
+                 /* issue a pseudo-error message */
+                 errno = SM_EMAPCANTWRITE;
+                 return false;
+         }
+ 
+ 
+ 	        /* do initial file and directory checks */
+         if (sm_strlcpy(buf, map->map_file, sizeof buf) >= sizeof buf)
+         {
+                 errno = 0;
+                 if (!bitset(MF_OPTIONAL, map->map_mflags))
+                         syserr("cdb map \"%s\": map file %s name too long",
+                                 map->map_mname, map->map_file);
+                 return false;
+         }
+         i = strlen(buf);
+         if (i < 3 || strcmp(&buf[i - 4], ".cdb") != 0)
+         {
+                 if (sm_strlcat(buf, ".cdb", sizeof buf) >= sizeof buf)
+                 {
+                         errno = 0;
+                         if (!bitset(MF_OPTIONAL, map->map_mflags))
+                                 syserr("cdb map \"%s\": map file %s name too long",
+                                         map->map_mname, map->map_file);
+                         return false;
+                 }
+         }
+ 	fd = open(buf, O_RDONLY);
+ 	if (fd == -1) {
+ 		syserr("cdb %s could not be opened", buf);
+ 		return false;
+ 	}
+ 	status = cdb_init(cdbp, fd);
+ 	if (status != 0) {
+ 		syserr("initialization of cdbmap failed");
+ 		return false;
+ 	}
+ 	map->map_db1 = (ARBPTR_T)cdbp;
+ 	return true;
+ }
+ 
+ char * cdb_map_lookup (map, name, av, statp)
+ 	MAP * map;
+ 	char *name;
+ 	char **av;
+ 	int *statp;
+ {
+ 	char key[MAXNAME+1];
+ 	char * data = NULL;
+ 	struct cdb * cdbmap;
+ 	cdbmap = map->map_db1;
+ 	unsigned int klen, dlen;
+ 	int st;
+ 
+ 	if (tTd(38, 20))
+                 sm_dprintf("cdb_map_lookup(%s, %s)\n", map->map_mname, name);
+ 
+ 	klen = strlen(name);
+ 	if (klen > sizeof(key) - 1)
+                 klen = sizeof(key) - 1;
+         memmove(key, name, klen);
+         key[klen] = '\0';
+ 
+         if (!bitset(MF_NOFOLDCASE, map->map_mflags)) {
+                makelower(key);
+         }
+ 
+ 	st = 0;
+ 	if (bitset(MF_TRY0NULL, map->map_mflags)) {
+ 		st = cdb_find(cdbmap, key, klen);
+ 		if (st == 1) 
+ 			 map->map_mflags &= ~MF_TRY1NULL;
+ 	}
+ 	if (st != 1 && bitset(MF_TRY1NULL, map->map_mflags)) {
+ 		st = cdb_find(cdbmap, key, klen);
+ 		if (st == 1) 
+ 			 map->map_mflags &= ~MF_TRY0NULL;
+ 	}
+ 	if (st != 1) {
+ 		if (st < 0)
+ 			syserr("cdb_map_lookup: get (%s)", name);
+ 		return NULL;
+ 	}
+ 	else {
+ 		dlen = cdb_datalen(cdbmap);
+ 		data = malloc(dlen + 1);
+ 		cdb_read(cdbmap, data, dlen, cdb_datapos(cdbmap));
+ 		data[dlen] = '\0';
+ 	}
+ 	if  (bitset(MF_MATCHONLY, map->map_mflags))
+                 return map_rewrite(map, name, strlen(name), NULL);
+         else
+                 return map_rewrite(map, data, dlen, av);
+ }
+ 
+ 
+ void cdb_map_close(map)
+ 	MAP * map;
+ {
+ 	struct cdb * cdbmap;
+ 	int fd;
+ 	cdbmap = map->map_db1;
+ 	fd = cdb_fileno(cdbmap);
+ 	cdb_free(cdbmap);
+ 	close(fd);
+ }
+ 
+ #endif /* CDB */
+ 
  /*
  **  NEWDB (Hash and BTree) Modules
  */
***************
*** 6015,6021 ****
  	if (tTd(38, 20))
  		sm_dprintf("impl_map_lookup(%s, %s)\n",
  			map->map_mname, name);
! 
  #if NEWDB
  	if (bitset(MF_IMPL_HASH, map->map_mflags))
  		return db_map_lookup(map, name, av, pstat);
--- 6153,6162 ----
  	if (tTd(38, 20))
  		sm_dprintf("impl_map_lookup(%s, %s)\n",
  			map->map_mname, name);
! #if CDB
! 	if (bitset(MF_IMPL_CDB, map->map_mflags))
! 		return cdb_map_lookup(map, name, av, pstat);
! #endif /* CDB */
  #if NEWDB
  	if (bitset(MF_IMPL_HASH, map->map_mflags))
  		return db_map_lookup(map, name, av, pstat);
***************
*** 6065,6070 ****
--- 6206,6220 ----
  			map->map_mname, map->map_file, mode);
  
  	mode &= O_ACCMODE;
+ #if CDB
+ 	map->map_mflags != MF_IMPL_CDB;
+ 	if (cdb_map_open(map, mode))
+ 	{
+ 		return true;
+ 	}
+ 	else
+ 		map->map_mflags &= ~MF_IMPL_CDB;
+ #endif /* CDB */
  #if NEWDB
  	map->map_mflags |= MF_IMPL_HASH;
  	if (hash_map_open(map, mode))
***************
*** 6087,6101 ****
  		map->map_mflags &= ~MF_IMPL_NDBM;
  #endif /* NDBM */
  
! #if defined(NEWDB) || defined(NDBM)
  	if (Verbose)
  		message("WARNING: cannot open alias database %s%s",
  			map->map_file,
  			mode == O_RDONLY ? "; reading text version" : "");
! #else /* defined(NEWDB) || defined(NDBM) */
  	if (mode != O_RDONLY)
  		usrerr("Cannot rebuild aliases: no database format defined");
! #endif /* defined(NEWDB) || defined(NDBM) */
  
  	if (mode == O_RDONLY)
  		return stab_map_open(map, mode);
--- 6237,6251 ----
  		map->map_mflags &= ~MF_IMPL_NDBM;
  #endif /* NDBM */
  
! #if defined(NEWDB) || defined(NDBM) || defined(CDB)
  	if (Verbose)
  		message("WARNING: cannot open alias database %s%s",
  			map->map_file,
  			mode == O_RDONLY ? "; reading text version" : "");
! #else /* defined(NEWDB) || defined(NDBM) || defined(CDB) */
  	if (mode != O_RDONLY)
  		usrerr("Cannot rebuild aliases: no database format defined");
! #endif /* defined(NEWDB) || defined(NDBM) || defined(CDB) */
  
  	if (mode == O_RDONLY)
  		return stab_map_open(map, mode);
***************
*** 6115,6120 ****
--- 6265,6277 ----
  	if (tTd(38, 9))
  		sm_dprintf("impl_map_close(%s, %s, %lx)\n",
  			map->map_mname, map->map_file, map->map_mflags);
+ #if CDB
+ 	if (bitset(MF_IMPL_CDB, map->map_mflags))
+ 	{
+ 		cdb_map_close(map);
+ 		map->map_mflags &= ~MF_IMPL_CDB;
+ 	}
+ #endif /* CDB */
  #if NEWDB
  	if (bitset(MF_IMPL_HASH, map->map_mflags))
  	{
diff -N -r -c sendmail-8.14.1/sendmail/map.h sendmail-8.14.1-tinycdb/sendmail/map.h
*** sendmail-8.14.1/sendmail/map.h	2006-12-20 03:49:51.000000000 +0800
--- sendmail-8.14.1-tinycdb/sendmail/map.h	2007-09-04 14:26:35.000000000 +0800
***************
*** 18,23 ****
--- 18,27 ----
  
  extern char	*bogus_map_lookup __P((MAP *, char *, char **, int *));
  
+ extern bool	cdb_map_open  __P((MAP *, int));
+ extern char	*cdb_map_lookup __P((MAP *, char *, char **, int *));
+ extern void	cdb_map_close	__P((MAP *));
+ 
  extern bool	bt_map_open __P((MAP *, int));
  
  extern char	*db_map_lookup __P((MAP *, char *, char **, int *));
diff -N -r -c sendmail-8.14.1/sendmail/sendmail.h sendmail-8.14.1-tinycdb/sendmail/sendmail.h
*** sendmail-8.14.1/sendmail/sendmail.h	2007-02-28 06:21:13.000000000 +0800
--- sendmail-8.14.1-tinycdb/sendmail/sendmail.h	2007-09-04 14:27:51.000000000 +0800
***************
*** 1225,1231 ****
  #define MF_ALIASWAIT	0x00000800	/* alias map in aliaswait state */
  #define MF_IMPL_HASH	0x00001000	/* implicit: underlying hash database */
  #define MF_IMPL_NDBM	0x00002000	/* implicit: underlying NDBM database */
! /* 0x00004000	*/
  #define MF_APPEND	0x00008000	/* append new entry on rebuild */
  #define MF_KEEPQUOTES	0x00010000	/* don't dequote key before lookup */
  #define MF_NODEFER	0x00020000	/* don't defer if map lookup fails */
--- 1225,1231 ----
  #define MF_ALIASWAIT	0x00000800	/* alias map in aliaswait state */
  #define MF_IMPL_HASH	0x00001000	/* implicit: underlying hash database */
  #define MF_IMPL_NDBM	0x00002000	/* implicit: underlying NDBM database */
! #define MF_IMPL_CDB	0x00004000	/* implicit: underlying CDB database */
  #define MF_APPEND	0x00008000	/* append new entry on rebuild */
  #define MF_KEEPQUOTES	0x00010000	/* don't dequote key before lookup */
  #define MF_NODEFER	0x00020000	/* don't defer if map lookup fails */
