/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1