164562Sgshapiro/*
2261370Sgshapiro** Copyright (c) 1999-2002 Proofpoint, Inc. and its suppliers.
364562Sgshapiro**	All rights reserved.
464562Sgshapiro**
564562Sgshapiro** By using this file, you agree to the terms and conditions set
664562Sgshapiro** forth in the LICENSE file which can be found at the top level of
764562Sgshapiro** the sendmail distribution.
864562Sgshapiro*/
964562Sgshapiro
1090792Sgshapiro#include <sm/gen.h>
11266711SgshapiroSM_RCSID("@(#)$Id: smdb.c,v 8.59 2013-11-22 20:51:49 ca Exp $")
1264562Sgshapiro
1364562Sgshapiro#include <fcntl.h>
1464562Sgshapiro#include <stdlib.h>
1564562Sgshapiro#include <unistd.h>
1664562Sgshapiro
1764562Sgshapiro
1864562Sgshapiro#include <sendmail/sendmail.h>
1964562Sgshapiro#include <libsmdb/smdb.h>
2064562Sgshapiro
21141858Sgshapirostatic bool	smdb_lockfile __P((int, int));
22141858Sgshapiro
2390792Sgshapiro/*
2464562Sgshapiro** SMDB_MALLOC_DATABASE -- Allocates a database structure.
2564562Sgshapiro**
2664562Sgshapiro**	Parameters:
2764562Sgshapiro**		None
2864562Sgshapiro**
2964562Sgshapiro**	Returns:
3064562Sgshapiro**		An pointer to an allocated SMDB_DATABASE structure or
3164562Sgshapiro**		NULL if it couldn't allocate the memory.
3264562Sgshapiro*/
3364562Sgshapiro
3464562SgshapiroSMDB_DATABASE *
3564562Sgshapirosmdb_malloc_database()
3664562Sgshapiro{
3764562Sgshapiro	SMDB_DATABASE *db;
3864562Sgshapiro
3964562Sgshapiro	db = (SMDB_DATABASE *) malloc(sizeof(SMDB_DATABASE));
4064562Sgshapiro
4164562Sgshapiro	if (db != NULL)
4290792Sgshapiro		(void) memset(db, '\0', sizeof(SMDB_DATABASE));
4364562Sgshapiro
4464562Sgshapiro	return db;
4564562Sgshapiro}
4664562Sgshapiro
4764562Sgshapiro
4890792Sgshapiro/*
4964562Sgshapiro** SMDB_FREE_DATABASE -- Unallocates a database structure.
5064562Sgshapiro**
5164562Sgshapiro**	Parameters:
5264562Sgshapiro**		database -- a SMDB_DATABASE pointer to deallocate.
5364562Sgshapiro**
5464562Sgshapiro**	Returns:
5564562Sgshapiro**		None
5664562Sgshapiro*/
5764562Sgshapiro
5864562Sgshapirovoid
5964562Sgshapirosmdb_free_database(database)
6064562Sgshapiro	SMDB_DATABASE *database;
6164562Sgshapiro{
6264562Sgshapiro	if (database != NULL)
6364562Sgshapiro		free(database);
6464562Sgshapiro}
6590792Sgshapiro/*
6666494Sgshapiro**  SMDB_LOCKFILE -- lock a file using flock or (shudder) fcntl locking
6766494Sgshapiro**
6866494Sgshapiro**	Parameters:
6966494Sgshapiro**		fd -- the file descriptor of the file.
7066494Sgshapiro**		type -- type of the lock.  Bits can be:
7166494Sgshapiro**			LOCK_EX -- exclusive lock.
7266494Sgshapiro**			LOCK_NB -- non-blocking.
7366494Sgshapiro**
7466494Sgshapiro**	Returns:
7590792Sgshapiro**		true if the lock was acquired.
7690792Sgshapiro**		false otherwise.
7766494Sgshapiro*/
7864562Sgshapiro
7966494Sgshapirostatic bool
8066494Sgshapirosmdb_lockfile(fd, type)
8166494Sgshapiro	int fd;
8266494Sgshapiro	int type;
8366494Sgshapiro{
8466494Sgshapiro	int i;
8566494Sgshapiro	int save_errno;
8666494Sgshapiro#if !HASFLOCK
8766494Sgshapiro	int action;
8866494Sgshapiro	struct flock lfd;
8966494Sgshapiro
9090792Sgshapiro	(void) memset(&lfd, '\0', sizeof lfd);
9166494Sgshapiro	if (bitset(LOCK_UN, type))
9266494Sgshapiro		lfd.l_type = F_UNLCK;
9366494Sgshapiro	else if (bitset(LOCK_EX, type))
9466494Sgshapiro		lfd.l_type = F_WRLCK;
9566494Sgshapiro	else
9666494Sgshapiro		lfd.l_type = F_RDLCK;
9766494Sgshapiro
9866494Sgshapiro	if (bitset(LOCK_NB, type))
9966494Sgshapiro		action = F_SETLK;
10066494Sgshapiro	else
10166494Sgshapiro		action = F_SETLKW;
10266494Sgshapiro
10366494Sgshapiro	while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
10466494Sgshapiro		continue;
10566494Sgshapiro	if (i >= 0)
10690792Sgshapiro		return true;
10766494Sgshapiro	save_errno = errno;
10866494Sgshapiro
10966494Sgshapiro	/*
11066494Sgshapiro	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
11166494Sgshapiro	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
11266494Sgshapiro	**  as type "tmp" (that is, served from swap space), the
11366494Sgshapiro	**  previous fcntl will fail with "Invalid argument" errors.
11466494Sgshapiro	**  Since this is fairly common during testing, we will assume
11566494Sgshapiro	**  that this indicates that the lock is successfully grabbed.
11666494Sgshapiro	*/
11766494Sgshapiro
11866494Sgshapiro	if (save_errno == EINVAL)
11990792Sgshapiro		return true;
12066494Sgshapiro
12166494Sgshapiro	if (!bitset(LOCK_NB, type) ||
12266494Sgshapiro	    (save_errno != EACCES && save_errno != EAGAIN))
12366494Sgshapiro	{
12466494Sgshapiro# if 0
12594334Sgshapiro		int omode = fcntl(fd, F_GETFL, NULL);
12694334Sgshapiro		int euid = (int) geteuid();
12794334Sgshapiro
12866494Sgshapiro		syslog(LOG_ERR, "cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
12994334Sgshapiro		       filename, ext, fd, type, omode, euid);
13066494Sgshapiro# endif /* 0 */
13194334Sgshapiro		errno = save_errno;
13290792Sgshapiro		return false;
13366494Sgshapiro	}
13466494Sgshapiro#else /* !HASFLOCK */
13566494Sgshapiro
13666494Sgshapiro	while ((i = flock(fd, type)) < 0 && errno == EINTR)
13766494Sgshapiro		continue;
13866494Sgshapiro	if (i >= 0)
13990792Sgshapiro		return true;
14066494Sgshapiro	save_errno = errno;
14166494Sgshapiro
14266494Sgshapiro	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
14366494Sgshapiro	{
14466494Sgshapiro# if 0
14594334Sgshapiro		int omode = fcntl(fd, F_GETFL, NULL);
14694334Sgshapiro		int euid = (int) geteuid();
14794334Sgshapiro
14866494Sgshapiro		syslog(LOG_ERR, "cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
14994334Sgshapiro		       filename, ext, fd, type, omode, euid);
15066494Sgshapiro# endif /* 0 */
15194334Sgshapiro		errno = save_errno;
15290792Sgshapiro		return false;
15366494Sgshapiro	}
15466494Sgshapiro#endif /* !HASFLOCK */
15566494Sgshapiro	errno = save_errno;
15690792Sgshapiro	return false;
15766494Sgshapiro}
15890792Sgshapiro/*
15964562Sgshapiro** SMDB_OPEN_DATABASE -- Opens a database.
16064562Sgshapiro**
16164562Sgshapiro**	This opens a database. If type is SMDB_DEFAULT it tries to
16264562Sgshapiro**	use a DB1 or DB2 hash. If that isn't available, it will try
16364562Sgshapiro**	to use NDBM. If a specific type is given it will try to open
16464562Sgshapiro**	a database of that type.
16564562Sgshapiro**
16664562Sgshapiro**	Parameters:
16764562Sgshapiro**		database -- An pointer to a SMDB_DATABASE pointer where the
16864562Sgshapiro**			   opened database will be stored. This should
16964562Sgshapiro**			   be unallocated.
17064562Sgshapiro**		db_name -- The name of the database to open. Do not include
17164562Sgshapiro**			  the file name extension.
17264562Sgshapiro**		mode -- The mode to set on the database file or files.
17364562Sgshapiro**		mode_mask -- Mode bits that must match on an opened database.
17464562Sgshapiro**		sff -- Flags to safefile.
17564562Sgshapiro**		type -- The type of database to open. Supported types
17664562Sgshapiro**		       vary depending on what was compiled in.
17764562Sgshapiro**		user_info -- Information on the user to use for file
17864562Sgshapiro**			    permissions.
17964562Sgshapiro**		params -- Params specific to the database being opened.
18064562Sgshapiro**			 Only supports some DB hash options right now
18164562Sgshapiro**			 (see smdb_db_open() for details).
18264562Sgshapiro**
18364562Sgshapiro**	Returns:
18464562Sgshapiro**		SMDBE_OK -- Success.
18564562Sgshapiro**		Anything else is an error. Look up more info about the
18664562Sgshapiro**		error in the comments for the specific open() used.
18764562Sgshapiro*/
18864562Sgshapiro
18964562Sgshapiroint
19064562Sgshapirosmdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info,
19164562Sgshapiro		   params)
19264562Sgshapiro	SMDB_DATABASE **database;
19364562Sgshapiro	char *db_name;
19464562Sgshapiro	int mode;
19564562Sgshapiro	int mode_mask;
19664562Sgshapiro	long sff;
19764562Sgshapiro	SMDB_DBTYPE type;
19864562Sgshapiro	SMDB_USER_INFO *user_info;
19964562Sgshapiro	SMDB_DBPARAMS *params;
20064562Sgshapiro{
20190792Sgshapiro	bool type_was_default = false;
20264562Sgshapiro
20364562Sgshapiro	if (type == SMDB_TYPE_DEFAULT)
20464562Sgshapiro	{
20590792Sgshapiro		type_was_default = true;
20664562Sgshapiro#ifdef NEWDB
20764562Sgshapiro		type = SMDB_TYPE_HASH;
20864562Sgshapiro#else /* NEWDB */
20964562Sgshapiro# ifdef NDBM
21064562Sgshapiro		type = SMDB_TYPE_NDBM;
21164562Sgshapiro# endif /* NDBM */
21264562Sgshapiro#endif /* NEWDB */
21364562Sgshapiro	}
21464562Sgshapiro
21564562Sgshapiro	if (type == SMDB_TYPE_DEFAULT)
21664562Sgshapiro		return SMDBE_UNKNOWN_DB_TYPE;
21764562Sgshapiro
21864562Sgshapiro	if ((strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) ||
21964562Sgshapiro	    (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0))
22064562Sgshapiro	{
22164562Sgshapiro#ifdef NEWDB
22290792Sgshapiro		int result;
22390792Sgshapiro
22464562Sgshapiro		result = smdb_db_open(database, db_name, mode, mode_mask, sff,
22564562Sgshapiro				      type, user_info, params);
22664562Sgshapiro# ifdef NDBM
22764562Sgshapiro		if (result == ENOENT && type_was_default)
22864562Sgshapiro			type = SMDB_TYPE_NDBM;
22964562Sgshapiro		else
23064562Sgshapiro# endif /* NDBM */
23164562Sgshapiro			return result;
23264562Sgshapiro#else /* NEWDB */
23364562Sgshapiro		return SMDBE_UNSUPPORTED_DB_TYPE;
23464562Sgshapiro#endif /* NEWDB */
23564562Sgshapiro	}
23664562Sgshapiro
23764562Sgshapiro	if (strncmp(type, SMDB_TYPE_NDBM, SMDB_TYPE_NDBM_LEN) == 0)
23864562Sgshapiro	{
23964562Sgshapiro#ifdef NDBM
24090792Sgshapiro		int result;
24190792Sgshapiro
24264562Sgshapiro		result = smdb_ndbm_open(database, db_name, mode, mode_mask,
24364562Sgshapiro					sff, type, user_info, params);
24464562Sgshapiro		return result;
24564562Sgshapiro#else /* NDBM */
24664562Sgshapiro		return SMDBE_UNSUPPORTED_DB_TYPE;
24764562Sgshapiro#endif /* NDBM */
24864562Sgshapiro	}
24964562Sgshapiro
25064562Sgshapiro	return SMDBE_UNKNOWN_DB_TYPE;
25164562Sgshapiro}
25290792Sgshapiro/*
25364562Sgshapiro** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
25464562Sgshapiro**
25564562Sgshapiro**	Just adds a . followed by a string to a db_name if there
25664562Sgshapiro**	is room and the db_name does not already have that extension.
25764562Sgshapiro**
25864562Sgshapiro**	Parameters:
25964562Sgshapiro**		full_name -- The final file name.
26064562Sgshapiro**		max_full_name_len -- The max length for full_name.
26164562Sgshapiro**		db_name -- The name of the db.
26264562Sgshapiro**		extension -- The extension to add.
26364562Sgshapiro**
26464562Sgshapiro**	Returns:
26564562Sgshapiro**		SMDBE_OK -- Success.
26664562Sgshapiro**		Anything else is an error. Look up more info about the
26764562Sgshapiro**		error in the comments for the specific open() used.
26864562Sgshapiro*/
26964562Sgshapiro
27064562Sgshapiroint
27164562Sgshapirosmdb_add_extension(full_name, max_full_name_len, db_name, extension)
27264562Sgshapiro	char *full_name;
27364562Sgshapiro	int max_full_name_len;
27464562Sgshapiro	char *db_name;
27564562Sgshapiro	char *extension;
27664562Sgshapiro{
27764562Sgshapiro	int extension_len;
27864562Sgshapiro	int db_name_len;
27964562Sgshapiro
28064562Sgshapiro	if (full_name == NULL || db_name == NULL || extension == NULL)
28164562Sgshapiro		return SMDBE_INVALID_PARAMETER;
28264562Sgshapiro
28364562Sgshapiro	extension_len = strlen(extension);
28464562Sgshapiro	db_name_len = strlen(db_name);
28564562Sgshapiro
28664562Sgshapiro	if (extension_len + db_name_len + 2 > max_full_name_len)
28764562Sgshapiro		return SMDBE_DB_NAME_TOO_LONG;
28864562Sgshapiro
28964562Sgshapiro	if (db_name_len < extension_len + 1 ||
29064562Sgshapiro	    db_name[db_name_len - extension_len - 1] != '.' ||
29164562Sgshapiro	    strcmp(&db_name[db_name_len - extension_len], extension) != 0)
29290792Sgshapiro		(void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
29390792Sgshapiro				   db_name, extension);
29464562Sgshapiro	else
29590792Sgshapiro		(void) sm_strlcpy(full_name, db_name, max_full_name_len);
29664562Sgshapiro
29764562Sgshapiro	return SMDBE_OK;
29864562Sgshapiro}
29990792Sgshapiro/*
30064562Sgshapiro**  SMDB_LOCK_FILE -- Locks the database file.
30164562Sgshapiro**
30264562Sgshapiro**	Locks the actual database file.
30364562Sgshapiro**
30464562Sgshapiro**	Parameters:
30564562Sgshapiro**		lock_fd -- The resulting descriptor for the locked file.
30664562Sgshapiro**		db_name -- The name of the database without extension.
30764562Sgshapiro**		mode -- The open mode.
30864562Sgshapiro**		sff -- Flags to safefile.
30964562Sgshapiro**		extension -- The extension for the file.
31064562Sgshapiro**
31164562Sgshapiro**	Returns:
31264562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
31364562Sgshapiro*/
31464562Sgshapiro
31564562Sgshapiroint
31664562Sgshapirosmdb_lock_file(lock_fd, db_name, mode, sff, extension)
31764562Sgshapiro	int *lock_fd;
31864562Sgshapiro	char *db_name;
31964562Sgshapiro	int mode;
32064562Sgshapiro	long sff;
32164562Sgshapiro	char *extension;
32264562Sgshapiro{
32364562Sgshapiro	int result;
32498121Sgshapiro	char file_name[MAXPATHLEN];
32564562Sgshapiro
32698121Sgshapiro	result = smdb_add_extension(file_name, sizeof file_name, db_name,
32764562Sgshapiro				    extension);
32864562Sgshapiro	if (result != SMDBE_OK)
32964562Sgshapiro		return result;
33064562Sgshapiro
33198121Sgshapiro	*lock_fd = safeopen(file_name, mode & ~O_TRUNC, DBMMODE, sff);
33264562Sgshapiro	if (*lock_fd < 0)
33364562Sgshapiro		return errno;
33464562Sgshapiro
33564562Sgshapiro	return SMDBE_OK;
33664562Sgshapiro}
33790792Sgshapiro/*
33864562Sgshapiro**  SMDB_UNLOCK_FILE -- Unlocks a file
33964562Sgshapiro**
34064562Sgshapiro**	Unlocks a file.
34164562Sgshapiro**
34264562Sgshapiro**	Parameters:
34364562Sgshapiro**		lock_fd -- The descriptor for the locked file.
34464562Sgshapiro**
34564562Sgshapiro**	Returns:
34664562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
34764562Sgshapiro*/
34864562Sgshapiro
34964562Sgshapiroint
35064562Sgshapirosmdb_unlock_file(lock_fd)
35164562Sgshapiro	int lock_fd;
35264562Sgshapiro{
35364562Sgshapiro	int result;
35464562Sgshapiro
35564562Sgshapiro	result = close(lock_fd);
35664562Sgshapiro	if (result != 0)
35764562Sgshapiro		return errno;
35864562Sgshapiro
35964562Sgshapiro	return SMDBE_OK;
36064562Sgshapiro}
36190792Sgshapiro/*
36266494Sgshapiro**  SMDB_LOCK_MAP -- Locks a database.
36366494Sgshapiro**
36466494Sgshapiro**	Parameters:
36566494Sgshapiro**		database -- database description.
36666494Sgshapiro**		type -- type of the lock.  Bits can be:
36766494Sgshapiro**			LOCK_EX -- exclusive lock.
36866494Sgshapiro**			LOCK_NB -- non-blocking.
36966494Sgshapiro**
37066494Sgshapiro**	Returns:
37166494Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
37266494Sgshapiro*/
37366494Sgshapiro
37466494Sgshapiroint
37566494Sgshapirosmdb_lock_map(database, type)
37666494Sgshapiro	SMDB_DATABASE *database;
37766494Sgshapiro	int type;
37866494Sgshapiro{
37966494Sgshapiro	int fd;
38066494Sgshapiro
38166494Sgshapiro	fd = database->smdb_lockfd(database);
38266494Sgshapiro	if (fd < 0)
38366494Sgshapiro		return SMDBE_NOT_FOUND;
38466494Sgshapiro	if (!smdb_lockfile(fd, type))
38566494Sgshapiro		return SMDBE_LOCK_NOT_GRANTED;
38666494Sgshapiro	return SMDBE_OK;
38766494Sgshapiro}
38890792Sgshapiro/*
38966494Sgshapiro**  SMDB_UNLOCK_MAP -- Unlocks a database
39066494Sgshapiro**
39166494Sgshapiro**	Parameters:
39266494Sgshapiro**		database -- database description.
39366494Sgshapiro**
39466494Sgshapiro**	Returns:
39566494Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
39666494Sgshapiro*/
39766494Sgshapiro
39866494Sgshapiroint
39966494Sgshapirosmdb_unlock_map(database)
40066494Sgshapiro	SMDB_DATABASE *database;
40166494Sgshapiro{
40266494Sgshapiro	int fd;
40366494Sgshapiro
40466494Sgshapiro	fd = database->smdb_lockfd(database);
40566494Sgshapiro	if (fd < 0)
40666494Sgshapiro		return SMDBE_NOT_FOUND;
40766494Sgshapiro	if (!smdb_lockfile(fd, LOCK_UN))
40866494Sgshapiro		return SMDBE_LOCK_NOT_HELD;
40966494Sgshapiro	return SMDBE_OK;
41066494Sgshapiro}
41190792Sgshapiro/*
41264562Sgshapiro**  SMDB_SETUP_FILE -- Gets db file ready for use.
41364562Sgshapiro**
41464562Sgshapiro**	Makes sure permissions on file are safe and creates it if it
41564562Sgshapiro**	doesn't exist.
41664562Sgshapiro**
41764562Sgshapiro**	Parameters:
41864562Sgshapiro**		db_name -- The name of the database without extension.
41964562Sgshapiro**		extension -- The extension.
42064562Sgshapiro**		sff -- Flags to safefile.
42164562Sgshapiro**		mode_mask -- Mode bits that must match.
42264562Sgshapiro**		user_info -- Information on the user to use for file
42364562Sgshapiro**			    permissions.
42464562Sgshapiro**		stat_info -- A place to put the stat info for the file.
42564562Sgshapiro**	Returns:
42664562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
42764562Sgshapiro*/
42864562Sgshapiro
42964562Sgshapiroint
43064562Sgshapirosmdb_setup_file(db_name, extension, mode_mask, sff, user_info, stat_info)
43164562Sgshapiro	char *db_name;
43264562Sgshapiro	char *extension;
43364562Sgshapiro	int mode_mask;
43464562Sgshapiro	long sff;
43564562Sgshapiro	SMDB_USER_INFO *user_info;
43664562Sgshapiro	struct stat *stat_info;
43764562Sgshapiro{
43864562Sgshapiro	int st;
43964562Sgshapiro	int result;
44098121Sgshapiro	char db_file_name[MAXPATHLEN];
44164562Sgshapiro
44298121Sgshapiro	result = smdb_add_extension(db_file_name, sizeof db_file_name, db_name,
44364562Sgshapiro				    extension);
44464562Sgshapiro	if (result != SMDBE_OK)
44564562Sgshapiro		return result;
44664562Sgshapiro
44764562Sgshapiro	st = safefile(db_file_name, user_info->smdbu_id,
44864562Sgshapiro		      user_info->smdbu_group_id, user_info->smdbu_name,
44964562Sgshapiro		      sff, mode_mask, stat_info);
45064562Sgshapiro	if (st != 0)
45164562Sgshapiro		return st;
45264562Sgshapiro
45364562Sgshapiro	return SMDBE_OK;
45464562Sgshapiro}
45590792Sgshapiro/*
45664562Sgshapiro**  SMDB_FILECHANGED -- Checks to see if a file changed.
45764562Sgshapiro**
45864562Sgshapiro**	Compares the passed in stat_info with a current stat on
45964562Sgshapiro**	the passed in file descriptor. Check filechanged for
46064562Sgshapiro**	return values.
46164562Sgshapiro**
46264562Sgshapiro**	Parameters:
46364562Sgshapiro**		db_name -- The name of the database without extension.
46464562Sgshapiro**		extension -- The extension.
46564562Sgshapiro**		db_fd -- A file descriptor for the database file.
46664562Sgshapiro**		stat_info -- An old stat_info.
46764562Sgshapiro**	Returns:
46864562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
46964562Sgshapiro*/
47064562Sgshapiro
47164562Sgshapiroint
47264562Sgshapirosmdb_filechanged(db_name, extension, db_fd, stat_info)
47364562Sgshapiro	char *db_name;
47464562Sgshapiro	char *extension;
47564562Sgshapiro	int db_fd;
47664562Sgshapiro	struct stat *stat_info;
47764562Sgshapiro{
47864562Sgshapiro	int result;
47998121Sgshapiro	char db_file_name[MAXPATHLEN];
48064562Sgshapiro
48198121Sgshapiro	result = smdb_add_extension(db_file_name, sizeof db_file_name, db_name,
48264562Sgshapiro				    extension);
48364562Sgshapiro	if (result != SMDBE_OK)
48464562Sgshapiro		return result;
48590792Sgshapiro	return filechanged(db_file_name, db_fd, stat_info);
48664562Sgshapiro}
48790792Sgshapiro/*
48864562Sgshapiro** SMDB_PRINT_AVAILABLE_TYPES -- Prints the names of the available types.
48964562Sgshapiro**
49064562Sgshapiro**	Parameters:
49164562Sgshapiro**		None
49264562Sgshapiro**
49364562Sgshapiro**	Returns:
49464562Sgshapiro**		None
49564562Sgshapiro*/
49664562Sgshapiro
49764562Sgshapirovoid
49864562Sgshapirosmdb_print_available_types()
49964562Sgshapiro{
50064562Sgshapiro#ifdef NDBM
50164562Sgshapiro	printf("dbm\n");
50264562Sgshapiro#endif /* NDBM */
50364562Sgshapiro#ifdef NEWDB
50464562Sgshapiro	printf("hash\n");
50564562Sgshapiro	printf("btree\n");
50664562Sgshapiro#endif /* NEWDB */
50764562Sgshapiro}
50890792Sgshapiro/*
50964562Sgshapiro** SMDB_DB_DEFINITION -- Given a database type, return database definition
51064562Sgshapiro**
51164562Sgshapiro**	Reads though a structure making an association with the database
51264562Sgshapiro**	type and the required cpp define from sendmail/README.
51364562Sgshapiro**	List size is dynamic and must be NULL terminated.
51464562Sgshapiro**
51564562Sgshapiro**	Parameters:
51664562Sgshapiro**		type -- The name of the database type.
51764562Sgshapiro**
51864562Sgshapiro**	Returns:
51964562Sgshapiro**		definition for type, otherwise NULL.
52064562Sgshapiro*/
52164562Sgshapiro
52264562Sgshapirotypedef struct
52364562Sgshapiro{
52464562Sgshapiro	SMDB_DBTYPE type;
52564562Sgshapiro	char *dbdef;
52664562Sgshapiro} dbtype;
52764562Sgshapiro
52864562Sgshapirostatic dbtype DatabaseDefs[] =
52964562Sgshapiro{
53064562Sgshapiro	{ SMDB_TYPE_HASH,	"NEWDB" },
53164562Sgshapiro	{ SMDB_TYPE_BTREE,	"NEWDB" },
53264562Sgshapiro	{ SMDB_TYPE_NDBM,	"NDBM"	},
53364562Sgshapiro	{ NULL,			"OOPS"	}
53464562Sgshapiro};
53564562Sgshapiro
53664562Sgshapirochar *
53764562Sgshapirosmdb_db_definition(type)
53864562Sgshapiro	SMDB_DBTYPE type;
53964562Sgshapiro{
54064562Sgshapiro	dbtype *ptr = DatabaseDefs;
54164562Sgshapiro
54264562Sgshapiro	while (ptr != NULL && ptr->type != NULL)
54364562Sgshapiro	{
54464562Sgshapiro		if (strcmp(type, ptr->type) == 0)
54564562Sgshapiro			return ptr->dbdef;
54664562Sgshapiro		ptr++;
54764562Sgshapiro	}
54864562Sgshapiro	return NULL;
54964562Sgshapiro}
550