/* * 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; }