smdb.c revision 66494
164562Sgshapiro/*
264562Sgshapiro** Copyright (c) 1999-2000 Sendmail, 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
1064562Sgshapiro#ifndef lint
1166494Sgshapirostatic char id[] = "@(#)$Id: smdb.c,v 8.37.4.2 2000/08/24 17:08:00 gshapiro Exp $";
1264562Sgshapiro#endif /* ! lint */
1364562Sgshapiro
1464562Sgshapiro#include <fcntl.h>
1564562Sgshapiro#include <stdlib.h>
1664562Sgshapiro#include <unistd.h>
1764562Sgshapiro
1864562Sgshapiro
1964562Sgshapiro#include <sendmail/sendmail.h>
2064562Sgshapiro#include <libsmdb/smdb.h>
2164562Sgshapiro
2264562Sgshapiro/*
2364562Sgshapiro** SMDB_MALLOC_DATABASE -- Allocates a database structure.
2464562Sgshapiro**
2564562Sgshapiro**	Parameters:
2664562Sgshapiro**		None
2764562Sgshapiro**
2864562Sgshapiro**	Returns:
2964562Sgshapiro**		An pointer to an allocated SMDB_DATABASE structure or
3064562Sgshapiro**		NULL if it couldn't allocate the memory.
3164562Sgshapiro*/
3264562Sgshapiro
3364562SgshapiroSMDB_DATABASE *
3464562Sgshapirosmdb_malloc_database()
3564562Sgshapiro{
3664562Sgshapiro	SMDB_DATABASE *db;
3764562Sgshapiro
3864562Sgshapiro	db = (SMDB_DATABASE *) malloc(sizeof(SMDB_DATABASE));
3964562Sgshapiro
4064562Sgshapiro	if (db != NULL)
4164562Sgshapiro		memset(db, '\0', sizeof(SMDB_DATABASE));
4264562Sgshapiro
4364562Sgshapiro	return db;
4464562Sgshapiro}
4564562Sgshapiro
4664562Sgshapiro
4764562Sgshapiro/*
4864562Sgshapiro** SMDB_FREE_DATABASE -- Unallocates a database structure.
4964562Sgshapiro**
5064562Sgshapiro**	Parameters:
5164562Sgshapiro**		database -- a SMDB_DATABASE pointer to deallocate.
5264562Sgshapiro**
5364562Sgshapiro**	Returns:
5464562Sgshapiro**		None
5564562Sgshapiro*/
5664562Sgshapiro
5764562Sgshapirovoid
5864562Sgshapirosmdb_free_database(database)
5964562Sgshapiro	SMDB_DATABASE *database;
6064562Sgshapiro{
6164562Sgshapiro	if (database != NULL)
6264562Sgshapiro		free(database);
6364562Sgshapiro}
6464562Sgshapiro
6566494Sgshapiro/*
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:
7566494Sgshapiro**		TRUE if the lock was acquired.
7666494Sgshapiro**		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
9066494Sgshapiro	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)
10666494Sgshapiro	{
10766494Sgshapiro		return TRUE;
10866494Sgshapiro	}
10966494Sgshapiro	save_errno = errno;
11066494Sgshapiro
11166494Sgshapiro	/*
11266494Sgshapiro	**  On SunOS, if you are testing using -oQ/tmp/mqueue or
11366494Sgshapiro	**  -oA/tmp/aliases or anything like that, and /tmp is mounted
11466494Sgshapiro	**  as type "tmp" (that is, served from swap space), the
11566494Sgshapiro	**  previous fcntl will fail with "Invalid argument" errors.
11666494Sgshapiro	**  Since this is fairly common during testing, we will assume
11766494Sgshapiro	**  that this indicates that the lock is successfully grabbed.
11866494Sgshapiro	*/
11966494Sgshapiro
12066494Sgshapiro	if (save_errno == EINVAL)
12166494Sgshapiro	{
12266494Sgshapiro		return TRUE;
12366494Sgshapiro	}
12466494Sgshapiro
12566494Sgshapiro	if (!bitset(LOCK_NB, type) ||
12666494Sgshapiro	    (save_errno != EACCES && save_errno != EAGAIN))
12766494Sgshapiro	{
12866494Sgshapiro		int omode = -1;
12966494Sgshapiro# ifdef F_GETFL
13066494Sgshapiro		(void) fcntl(fd, F_GETFL, &omode);
13166494Sgshapiro		errno = save_errno;
13266494Sgshapiro# endif /* F_GETFL */
13366494Sgshapiro# if 0
13466494Sgshapiro		syslog(LOG_ERR, "cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
13566494Sgshapiro			filename, ext, fd, type, omode, geteuid());
13666494Sgshapiro# endif /* 0 */
13766494Sgshapiro		return FALSE;
13866494Sgshapiro	}
13966494Sgshapiro#else /* !HASFLOCK */
14066494Sgshapiro
14166494Sgshapiro	while ((i = flock(fd, type)) < 0 && errno == EINTR)
14266494Sgshapiro		continue;
14366494Sgshapiro	if (i >= 0)
14466494Sgshapiro	{
14566494Sgshapiro		return TRUE;
14666494Sgshapiro	}
14766494Sgshapiro	save_errno = errno;
14866494Sgshapiro
14966494Sgshapiro	if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK)
15066494Sgshapiro	{
15166494Sgshapiro		int omode = -1;
15266494Sgshapiro# ifdef F_GETFL
15366494Sgshapiro		(void) fcntl(fd, F_GETFL, &omode);
15466494Sgshapiro		errno = save_errno;
15566494Sgshapiro# endif /* F_GETFL */
15666494Sgshapiro# if 0
15766494Sgshapiro		syslog(LOG_ERR, "cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
15866494Sgshapiro			filename, ext, fd, type, omode, geteuid());
15966494Sgshapiro# endif /* 0 */
16066494Sgshapiro		return FALSE;
16166494Sgshapiro	}
16266494Sgshapiro#endif /* !HASFLOCK */
16366494Sgshapiro	errno = save_errno;
16466494Sgshapiro	return FALSE;
16566494Sgshapiro}
16666494Sgshapiro
16764562Sgshapiro/*
16864562Sgshapiro** SMDB_OPEN_DATABASE -- Opens a database.
16964562Sgshapiro**
17064562Sgshapiro**	This opens a database. If type is SMDB_DEFAULT it tries to
17164562Sgshapiro**	use a DB1 or DB2 hash. If that isn't available, it will try
17264562Sgshapiro**	to use NDBM. If a specific type is given it will try to open
17364562Sgshapiro**	a database of that type.
17464562Sgshapiro**
17564562Sgshapiro**	Parameters:
17664562Sgshapiro**		database -- An pointer to a SMDB_DATABASE pointer where the
17764562Sgshapiro**			   opened database will be stored. This should
17864562Sgshapiro**			   be unallocated.
17964562Sgshapiro**		db_name -- The name of the database to open. Do not include
18064562Sgshapiro**			  the file name extension.
18164562Sgshapiro**		mode -- The mode to set on the database file or files.
18264562Sgshapiro**		mode_mask -- Mode bits that must match on an opened database.
18364562Sgshapiro**		sff -- Flags to safefile.
18464562Sgshapiro**		type -- The type of database to open. Supported types
18564562Sgshapiro**		       vary depending on what was compiled in.
18664562Sgshapiro**		user_info -- Information on the user to use for file
18764562Sgshapiro**			    permissions.
18864562Sgshapiro**		params -- Params specific to the database being opened.
18964562Sgshapiro**			 Only supports some DB hash options right now
19064562Sgshapiro**			 (see smdb_db_open() for details).
19164562Sgshapiro**
19264562Sgshapiro**	Returns:
19364562Sgshapiro**		SMDBE_OK -- Success.
19464562Sgshapiro**		Anything else is an error. Look up more info about the
19564562Sgshapiro**		error in the comments for the specific open() used.
19664562Sgshapiro*/
19764562Sgshapiro
19864562Sgshapiroint
19964562Sgshapirosmdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info,
20064562Sgshapiro		   params)
20164562Sgshapiro	SMDB_DATABASE **database;
20264562Sgshapiro	char *db_name;
20364562Sgshapiro	int mode;
20464562Sgshapiro	int mode_mask;
20564562Sgshapiro	long sff;
20664562Sgshapiro	SMDB_DBTYPE type;
20764562Sgshapiro	SMDB_USER_INFO *user_info;
20864562Sgshapiro	SMDB_DBPARAMS *params;
20964562Sgshapiro{
21064562Sgshapiro	int result;
21164562Sgshapiro	bool type_was_default = FALSE;
21264562Sgshapiro
21364562Sgshapiro	if (type == SMDB_TYPE_DEFAULT)
21464562Sgshapiro	{
21564562Sgshapiro		type_was_default = TRUE;
21664562Sgshapiro#ifdef NEWDB
21764562Sgshapiro		type = SMDB_TYPE_HASH;
21864562Sgshapiro#else /* NEWDB */
21964562Sgshapiro# ifdef NDBM
22064562Sgshapiro		type = SMDB_TYPE_NDBM;
22164562Sgshapiro# endif /* NDBM */
22264562Sgshapiro#endif /* NEWDB */
22364562Sgshapiro	}
22464562Sgshapiro
22564562Sgshapiro	if (type == SMDB_TYPE_DEFAULT)
22664562Sgshapiro		return SMDBE_UNKNOWN_DB_TYPE;
22764562Sgshapiro
22864562Sgshapiro	if ((strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) ||
22964562Sgshapiro	    (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0))
23064562Sgshapiro	{
23164562Sgshapiro#ifdef NEWDB
23264562Sgshapiro		result = smdb_db_open(database, db_name, mode, mode_mask, sff,
23364562Sgshapiro				      type, user_info, params);
23464562Sgshapiro# ifdef NDBM
23564562Sgshapiro		if (result == ENOENT && type_was_default)
23664562Sgshapiro			type = SMDB_TYPE_NDBM;
23764562Sgshapiro		else
23864562Sgshapiro# endif /* NDBM */
23964562Sgshapiro			return result;
24064562Sgshapiro#else /* NEWDB */
24164562Sgshapiro		return SMDBE_UNSUPPORTED_DB_TYPE;
24264562Sgshapiro#endif /* NEWDB */
24364562Sgshapiro	}
24464562Sgshapiro
24564562Sgshapiro	if (strncmp(type, SMDB_TYPE_NDBM, SMDB_TYPE_NDBM_LEN) == 0)
24664562Sgshapiro	{
24764562Sgshapiro#ifdef NDBM
24864562Sgshapiro		result = smdb_ndbm_open(database, db_name, mode, mode_mask,
24964562Sgshapiro					sff, type, user_info, params);
25064562Sgshapiro		return result;
25164562Sgshapiro#else /* NDBM */
25264562Sgshapiro		return SMDBE_UNSUPPORTED_DB_TYPE;
25364562Sgshapiro#endif /* NDBM */
25464562Sgshapiro	}
25564562Sgshapiro
25664562Sgshapiro	return SMDBE_UNKNOWN_DB_TYPE;
25764562Sgshapiro}
25864562Sgshapiro
25964562Sgshapiro/*
26064562Sgshapiro** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
26164562Sgshapiro**
26264562Sgshapiro**	Just adds a . followed by a string to a db_name if there
26364562Sgshapiro**	is room and the db_name does not already have that extension.
26464562Sgshapiro**
26564562Sgshapiro**	Parameters:
26664562Sgshapiro**		full_name -- The final file name.
26764562Sgshapiro**		max_full_name_len -- The max length for full_name.
26864562Sgshapiro**		db_name -- The name of the db.
26964562Sgshapiro**		extension -- The extension to add.
27064562Sgshapiro**
27164562Sgshapiro**	Returns:
27264562Sgshapiro**		SMDBE_OK -- Success.
27364562Sgshapiro**		Anything else is an error. Look up more info about the
27464562Sgshapiro**		error in the comments for the specific open() used.
27564562Sgshapiro*/
27664562Sgshapiro
27764562Sgshapiroint
27864562Sgshapirosmdb_add_extension(full_name, max_full_name_len, db_name, extension)
27964562Sgshapiro	char *full_name;
28064562Sgshapiro	int max_full_name_len;
28164562Sgshapiro	char *db_name;
28264562Sgshapiro	char *extension;
28364562Sgshapiro{
28464562Sgshapiro	int extension_len;
28564562Sgshapiro	int db_name_len;
28664562Sgshapiro
28764562Sgshapiro	if (full_name == NULL || db_name == NULL || extension == NULL)
28864562Sgshapiro		return SMDBE_INVALID_PARAMETER;
28964562Sgshapiro
29064562Sgshapiro	extension_len = strlen(extension);
29164562Sgshapiro	db_name_len = strlen(db_name);
29264562Sgshapiro
29364562Sgshapiro	if (extension_len + db_name_len + 2 > max_full_name_len)
29464562Sgshapiro		return SMDBE_DB_NAME_TOO_LONG;
29564562Sgshapiro
29664562Sgshapiro	if (db_name_len < extension_len + 1 ||
29764562Sgshapiro	    db_name[db_name_len - extension_len - 1] != '.' ||
29864562Sgshapiro	    strcmp(&db_name[db_name_len - extension_len], extension) != 0)
29964562Sgshapiro		snprintf(full_name, max_full_name_len, "%s.%s", db_name,
30064562Sgshapiro			 extension);
30164562Sgshapiro	else
30264562Sgshapiro		(void) strlcpy(full_name, db_name, max_full_name_len);
30364562Sgshapiro
30464562Sgshapiro	return SMDBE_OK;
30564562Sgshapiro}
30664562Sgshapiro
30764562Sgshapiro/*
30864562Sgshapiro**  SMDB_LOCK_FILE -- Locks the database file.
30964562Sgshapiro**
31064562Sgshapiro**	Locks the actual database file.
31164562Sgshapiro**
31264562Sgshapiro**	Parameters:
31364562Sgshapiro**		lock_fd -- The resulting descriptor for the locked file.
31464562Sgshapiro**		db_name -- The name of the database without extension.
31564562Sgshapiro**		mode -- The open mode.
31664562Sgshapiro**		sff -- Flags to safefile.
31764562Sgshapiro**		extension -- The extension for the file.
31864562Sgshapiro**
31964562Sgshapiro**	Returns:
32064562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
32164562Sgshapiro*/
32264562Sgshapiro
32364562Sgshapiroint
32464562Sgshapirosmdb_lock_file(lock_fd, db_name, mode, sff, extension)
32564562Sgshapiro	int *lock_fd;
32664562Sgshapiro	char *db_name;
32764562Sgshapiro	int mode;
32864562Sgshapiro	long sff;
32964562Sgshapiro	char *extension;
33064562Sgshapiro{
33164562Sgshapiro	int result;
33264562Sgshapiro	char file_name[SMDB_MAX_NAME_LEN];
33364562Sgshapiro
33464562Sgshapiro	result = smdb_add_extension(file_name, SMDB_MAX_NAME_LEN, db_name,
33564562Sgshapiro				    extension);
33664562Sgshapiro	if (result != SMDBE_OK)
33764562Sgshapiro		return result;
33864562Sgshapiro
33964562Sgshapiro	*lock_fd = safeopen(file_name, mode & ~O_TRUNC, 0644, sff);
34064562Sgshapiro	if (*lock_fd < 0)
34164562Sgshapiro		return errno;
34264562Sgshapiro
34364562Sgshapiro	return SMDBE_OK;
34464562Sgshapiro}
34564562Sgshapiro
34664562Sgshapiro/*
34764562Sgshapiro**  SMDB_UNLOCK_FILE -- Unlocks a file
34864562Sgshapiro**
34964562Sgshapiro**	Unlocks a file.
35064562Sgshapiro**
35164562Sgshapiro**	Parameters:
35264562Sgshapiro**		lock_fd -- The descriptor for the locked file.
35364562Sgshapiro**
35464562Sgshapiro**	Returns:
35564562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
35664562Sgshapiro*/
35764562Sgshapiro
35864562Sgshapiroint
35964562Sgshapirosmdb_unlock_file(lock_fd)
36064562Sgshapiro	int lock_fd;
36164562Sgshapiro{
36264562Sgshapiro	int result;
36364562Sgshapiro
36464562Sgshapiro	result = close(lock_fd);
36564562Sgshapiro	if (result != 0)
36664562Sgshapiro		return errno;
36764562Sgshapiro
36864562Sgshapiro	return SMDBE_OK;
36964562Sgshapiro}
37064562Sgshapiro
37164562Sgshapiro/*
37266494Sgshapiro**  SMDB_LOCK_MAP -- Locks a database.
37366494Sgshapiro**
37466494Sgshapiro**	Parameters:
37566494Sgshapiro**		database -- database description.
37666494Sgshapiro**		type -- type of the lock.  Bits can be:
37766494Sgshapiro**			LOCK_EX -- exclusive lock.
37866494Sgshapiro**			LOCK_NB -- non-blocking.
37966494Sgshapiro**
38066494Sgshapiro**	Returns:
38166494Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
38266494Sgshapiro*/
38366494Sgshapiro
38466494Sgshapiroint
38566494Sgshapirosmdb_lock_map(database, type)
38666494Sgshapiro	SMDB_DATABASE *database;
38766494Sgshapiro	int type;
38866494Sgshapiro{
38966494Sgshapiro	int fd;
39066494Sgshapiro
39166494Sgshapiro	fd = database->smdb_lockfd(database);
39266494Sgshapiro	if (fd < 0)
39366494Sgshapiro		return SMDBE_NOT_FOUND;
39466494Sgshapiro	if (!smdb_lockfile(fd, type))
39566494Sgshapiro		return SMDBE_LOCK_NOT_GRANTED;
39666494Sgshapiro	return SMDBE_OK;
39766494Sgshapiro}
39866494Sgshapiro
39966494Sgshapiro/*
40066494Sgshapiro**  SMDB_UNLOCK_MAP -- Unlocks a database
40166494Sgshapiro**
40266494Sgshapiro**	Parameters:
40366494Sgshapiro**		database -- database description.
40466494Sgshapiro**
40566494Sgshapiro**	Returns:
40666494Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
40766494Sgshapiro*/
40866494Sgshapiro
40966494Sgshapiroint
41066494Sgshapirosmdb_unlock_map(database)
41166494Sgshapiro	SMDB_DATABASE *database;
41266494Sgshapiro{
41366494Sgshapiro	int fd;
41466494Sgshapiro
41566494Sgshapiro	fd = database->smdb_lockfd(database);
41666494Sgshapiro	if (fd < 0)
41766494Sgshapiro		return SMDBE_NOT_FOUND;
41866494Sgshapiro	if (!smdb_lockfile(fd, LOCK_UN))
41966494Sgshapiro		return SMDBE_LOCK_NOT_HELD;
42066494Sgshapiro	return SMDBE_OK;
42166494Sgshapiro}
42266494Sgshapiro
42366494Sgshapiro
42466494Sgshapiro/*
42564562Sgshapiro**  SMDB_SETUP_FILE -- Gets db file ready for use.
42664562Sgshapiro**
42764562Sgshapiro**	Makes sure permissions on file are safe and creates it if it
42864562Sgshapiro**	doesn't exist.
42964562Sgshapiro**
43064562Sgshapiro**	Parameters:
43164562Sgshapiro**		db_name -- The name of the database without extension.
43264562Sgshapiro**		extension -- The extension.
43364562Sgshapiro**		sff -- Flags to safefile.
43464562Sgshapiro**		mode_mask -- Mode bits that must match.
43564562Sgshapiro**		user_info -- Information on the user to use for file
43664562Sgshapiro**			    permissions.
43764562Sgshapiro**		stat_info -- A place to put the stat info for the file.
43864562Sgshapiro**	Returns:
43964562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
44064562Sgshapiro*/
44164562Sgshapiro
44264562Sgshapiroint
44364562Sgshapirosmdb_setup_file(db_name, extension, mode_mask, sff, user_info, stat_info)
44464562Sgshapiro	char *db_name;
44564562Sgshapiro	char *extension;
44664562Sgshapiro	int mode_mask;
44764562Sgshapiro	long sff;
44864562Sgshapiro	SMDB_USER_INFO *user_info;
44964562Sgshapiro	struct stat *stat_info;
45064562Sgshapiro{
45164562Sgshapiro	int st;
45264562Sgshapiro	int result;
45364562Sgshapiro	char db_file_name[SMDB_MAX_NAME_LEN];
45464562Sgshapiro
45564562Sgshapiro	result = smdb_add_extension(db_file_name, SMDB_MAX_NAME_LEN, db_name,
45664562Sgshapiro				    extension);
45764562Sgshapiro	if (result != SMDBE_OK)
45864562Sgshapiro		return result;
45964562Sgshapiro
46064562Sgshapiro	st = safefile(db_file_name, user_info->smdbu_id,
46164562Sgshapiro		      user_info->smdbu_group_id, user_info->smdbu_name,
46264562Sgshapiro		      sff, mode_mask, stat_info);
46364562Sgshapiro	if (st != 0)
46464562Sgshapiro		return st;
46564562Sgshapiro
46664562Sgshapiro	return SMDBE_OK;
46764562Sgshapiro}
46864562Sgshapiro
46964562Sgshapiro/*
47064562Sgshapiro**  SMDB_FILECHANGED -- Checks to see if a file changed.
47164562Sgshapiro**
47264562Sgshapiro**	Compares the passed in stat_info with a current stat on
47364562Sgshapiro**	the passed in file descriptor. Check filechanged for
47464562Sgshapiro**	return values.
47564562Sgshapiro**
47664562Sgshapiro**	Parameters:
47764562Sgshapiro**		db_name -- The name of the database without extension.
47864562Sgshapiro**		extension -- The extension.
47964562Sgshapiro**		db_fd -- A file descriptor for the database file.
48064562Sgshapiro**		stat_info -- An old stat_info.
48164562Sgshapiro**	Returns:
48264562Sgshapiro**		SMDBE_OK -- Success, otherwise errno.
48364562Sgshapiro*/
48464562Sgshapiro
48564562Sgshapiroint
48664562Sgshapirosmdb_filechanged(db_name, extension, db_fd, stat_info)
48764562Sgshapiro	char *db_name;
48864562Sgshapiro	char *extension;
48964562Sgshapiro	int db_fd;
49064562Sgshapiro	struct stat *stat_info;
49164562Sgshapiro{
49264562Sgshapiro	int result;
49364562Sgshapiro	char db_file_name[SMDB_MAX_NAME_LEN];
49464562Sgshapiro
49564562Sgshapiro	result = smdb_add_extension(db_file_name, SMDB_MAX_NAME_LEN, db_name,
49664562Sgshapiro				    extension);
49764562Sgshapiro	if (result != SMDBE_OK)
49864562Sgshapiro		return result;
49964562Sgshapiro
50064562Sgshapiro	result = filechanged(db_file_name, db_fd, stat_info);
50164562Sgshapiro
50264562Sgshapiro	return result;
50364562Sgshapiro}
50464562Sgshapiro/*
50564562Sgshapiro** SMDB_PRINT_AVAILABLE_TYPES -- Prints the names of the available types.
50664562Sgshapiro**
50764562Sgshapiro**	Parameters:
50864562Sgshapiro**		None
50964562Sgshapiro**
51064562Sgshapiro**	Returns:
51164562Sgshapiro**		None
51264562Sgshapiro*/
51364562Sgshapiro
51464562Sgshapirovoid
51564562Sgshapirosmdb_print_available_types()
51664562Sgshapiro{
51764562Sgshapiro#ifdef NDBM
51864562Sgshapiro	printf("dbm\n");
51964562Sgshapiro#endif /* NDBM */
52064562Sgshapiro#ifdef NEWDB
52164562Sgshapiro	printf("hash\n");
52264562Sgshapiro	printf("btree\n");
52364562Sgshapiro#endif /* NEWDB */
52464562Sgshapiro}
52564562Sgshapiro/*
52664562Sgshapiro** SMDB_DB_DEFINITION -- Given a database type, return database definition
52764562Sgshapiro**
52864562Sgshapiro**	Reads though a structure making an association with the database
52964562Sgshapiro**	type and the required cpp define from sendmail/README.
53064562Sgshapiro**	List size is dynamic and must be NULL terminated.
53164562Sgshapiro**
53264562Sgshapiro**	Parameters:
53364562Sgshapiro**		type -- The name of the database type.
53464562Sgshapiro**
53564562Sgshapiro**	Returns:
53664562Sgshapiro**		definition for type, otherwise NULL.
53764562Sgshapiro*/
53864562Sgshapiro
53964562Sgshapirotypedef struct
54064562Sgshapiro{
54164562Sgshapiro	SMDB_DBTYPE type;
54264562Sgshapiro	char *dbdef;
54364562Sgshapiro} dbtype;
54464562Sgshapiro
54564562Sgshapirostatic dbtype DatabaseDefs[] =
54664562Sgshapiro{
54764562Sgshapiro	{ SMDB_TYPE_HASH,	"NEWDB" },
54864562Sgshapiro	{ SMDB_TYPE_BTREE,	"NEWDB" },
54964562Sgshapiro	{ SMDB_TYPE_NDBM,	"NDBM"	},
55064562Sgshapiro	{ NULL,			"OOPS"	}
55164562Sgshapiro};
55264562Sgshapiro
55364562Sgshapirochar *
55464562Sgshapirosmdb_db_definition(type)
55564562Sgshapiro	SMDB_DBTYPE type;
55664562Sgshapiro{
55764562Sgshapiro	dbtype *ptr = DatabaseDefs;
55864562Sgshapiro
55964562Sgshapiro	while (ptr != NULL && ptr->type != NULL)
56064562Sgshapiro	{
56164562Sgshapiro		if (strcmp(type, ptr->type) == 0)
56264562Sgshapiro			return ptr->dbdef;
56364562Sgshapiro		ptr++;
56464562Sgshapiro	}
56564562Sgshapiro	return NULL;
56664562Sgshapiro}
567