/*
 * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: ibdbf.c,v 1.15 2007/06/18 04:42:31 ca Exp $")
#include "sm/error.h"
#include "sm/fcntl.h"
#include "sm/memops.h"
#include "sm/stat.h"
#include "sm/time.h"
#include "sm/heap.h"
#include "sm/assert.h"
#include "sm/str.h"
#include "sm/io.h"
#include "sm/fdset.h"
#include "sm/cstr.h"
#include "sm/ibdb.h"
#include "sm/dirent.h"
#include "ibdb.h"

/*
**  IBDBF_GET_SEQ -- get first and last sequence number
**
**	Parameters:
**		base_dir -- name of base directory (can be NULL)
**		name -- name of IBDB file
**		flags -- flags (which IBDB to use)
**		first -- (pointer to) first sequence number (output)
**		last -- (pointer to) last sequence number (output)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
ibdbf_get_seq(const char *base_dir, char *name, uint flags, uint32_t *first, uint32_t *last)
{
	size_t namelen;
	uint32_t minseq, maxseq, seq;
	ulong val;
	char *p, *dir;
	struct dirent *d;
	DIR *f;

	SM_REQUIRE(name != NULL && *name != '\0');
	if (first != NULL)
		*first = 0;
	if (last != NULL)
		*last = 0;

	IBDB_DIR(dir, base_dir, flags);
	f = opendir(dir);
	if (f == NULL)
		return sm_error_perm(SM_EM_IBDB, errno);

	minseq = UINT32_MAX;
	maxseq = 0;
	namelen = strlen(name);

	/* Read the work directory */
	while ((d = readdir(f)) != NULL)
	{
		if (strlen(d->d_name) <= namelen)
			continue;
		if (strncmp(d->d_name, name, namelen) != 0)
			continue;
		val = strtoul(d->d_name + namelen, &p, 10);
		if (val == ULONG_MAX && errno == ERANGE)
			continue;
		if (/*val < 0l ||*/ val > (ulong) UINT32_MAX)
			continue;
		seq = (uint32_t) val;
		if (seq < minseq)
			minseq = seq;
		if (seq > maxseq)
			maxseq = seq;
	}
	(void) closedir(f);

	/* Nothing found? */
	if (minseq > maxseq)
		return sm_error_perm(SM_EM_IBDB, SM_E_NOTFOUND);

	/* Assign results */
	if (first != NULL)
		*first = minseq;
	if (last != NULL)
		*last = maxseq;
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1