/* * 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: edbfs.c,v 1.11 2007/06/15 02:53:00 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/string.h" #include "edb-int.h" #include "sm/fs.h" #include "sm/edbfs.h" /* ** HACK ** How to determine which DEFEDB directories are actually in use? ** todo: refer to configuration data? */ #define EDB_DIRS 1 /* currently only one directory */ #define EDB_MAX_DIRNAME PATH_MAX /* EDB FileSystem ConTeXt */ struct edb_fsctx_S { fs_ctx_P efx_fs_ctx; char efx_dirs[EDB_DIRS][EDB_MAX_DIRNAME]; int efx_fs_idx[EDB_DIRS]; }; /* ** EDB_CTX_CLOSE -- close a EDB context ** ** Parameters: ** edb_fsctx -- EDB context ** ** Returns: ** SM_SUCCESS ** ** Last code review: 2005-04-23 21:16:52 ** Last code change: */ sm_ret_T edb_fsctx_close(edb_fsctx_P edb_fsctx) { if (edb_fsctx == NULL) return SM_SUCCESS; sm_free_size(edb_fsctx, sizeof(*edb_fsctx)); return SM_SUCCESS; } /* ** EDB_CTX_OPEN -- open a EDB FS context ** ** Parameters: ** fs_ctx -- FS context ** base_path -- path to base directory ** pedb_fsctx -- (pointer to) EDB context (output) ** pkbfree -- (pointer to) free space (KB) (output) ** ** Returns: ** usual sm_error code; ENOMEM, etc ** ** Side Effects: may fill efx_fs_ctx partially ** ** Last code review: 2005-04-23 21:19:39 ** Last code change: 2005-04-23 21:19:23 */ sm_ret_T edb_fsctx_open(fs_ctx_P fs_ctx, const char *base_path, edb_fsctx_P *pedb_fsctx, ulong *pkbfree) { sm_ret_T ret; int j; uint u; size_t l; ulong kbfree, freemin; edb_fsctx_P edb_fsctx; SM_REQUIRE(pedb_fsctx != NULL); edb_fsctx = (edb_fsctx_P) sm_zalloc(sizeof(*edb_fsctx)); if (edb_fsctx == NULL) return sm_error_temp(SM_EM_EDB, ENOMEM); SM_IS_FS_CTX(fs_ctx); edb_fsctx->efx_fs_ctx = fs_ctx; if (base_path != NULL) { l = strlcpy(edb_fsctx->efx_dirs[0], base_path, sizeof(edb_fsctx->efx_dirs[0])); if (l >= sizeof(edb_fsctx->efx_dirs[0])) { ret = sm_error_perm(SM_EM_EDB, SM_E_2BIG); goto error; } } l = strlcat(edb_fsctx->efx_dirs[0], EDB_HOME, sizeof(edb_fsctx->efx_dirs[0])); if (l >= sizeof(edb_fsctx->efx_dirs[0])) { ret = sm_error_perm(SM_EM_EDB, SM_E_2BIG); goto error; } freemin = LONG_MAX; for (u = 0; u < EDB_DIRS; u++) { ret = fs_new(edb_fsctx->efx_fs_ctx, edb_fsctx->efx_dirs[u], &j); if (sm_is_err(ret)) goto error; edb_fsctx->efx_fs_idx[u] = j; ret = fs_getfree(edb_fsctx->efx_fs_ctx, j, &kbfree); if (sm_is_err(ret)) goto error; if (kbfree < freemin) freemin = kbfree; } *pkbfree = freemin; *pedb_fsctx = edb_fsctx; return SM_SUCCESS; error: if (edb_fsctx != NULL) sm_free_size(edb_fsctx, sizeof(*edb_fsctx)); return ret; } /* ** EDB_FS_GETFREE -- get free space in EDB FS ** ** Parameters: ** edb_fs_ctx -- EDB FS context ** pkbfree -- (pointer to) free space (KB) (output) ** ** Returns: ** usual sm_error code; fs_getfree() ** ** Last code review: 2005-04-21 23:48:48 ** Last code change: */ sm_ret_T edb_fs_getfree(edb_fsctx_P edb_fsctx, ulong *pkbfree) { sm_ret_T ret; int i; ulong kbfree, freemin; SM_REQUIRE(edb_fsctx != NULLPTR); SM_REQUIRE(pkbfree != NULLPTR); ret = SM_SUCCESS; freemin = LONG_MAX; for (i = 0; i < EDB_DIRS; i++) { ret = fs_getfree(edb_fsctx->efx_fs_ctx, edb_fsctx->efx_fs_idx[i], &kbfree); if (!sm_is_err(ret) && kbfree < freemin) freemin = kbfree; } *pkbfree = freemin; return ret; }