📄 dbm.c
字号:
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. *//*** DAV extension module for Apache 2.0.*** - Database support using DBM-style databases,** part of the filesystem repository implementation*//*** This implementation uses a SDBM database per file and directory to** record the properties. These databases are kept in a subdirectory (of** the directory in question or the directory that holds the file in** question) named by the macro DAV_FS_STATE_DIR (.DAV). The filename of the** database is equivalent to the target filename, and is** DAV_FS_STATE_FILE_FOR_DIR (.state_for_dir) for the directory itself.*/#include "apr_strings.h"#include "apr_file_io.h"#include "apr_dbm.h"#include "mod_dav.h"#include "repos.h"struct dav_db { apr_pool_t *pool; apr_dbm_t *file;};void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, const char **state1, const char **state2){ if (fname == NULL) fname = DAV_FS_STATE_FILE_FOR_DIR; apr_dbm_get_usednames(p, fname, state1, state2);}static dav_error * dav_fs_dbm_error(dav_db *db, apr_pool_t *p, apr_status_t status){ int save_errno = errno; int errcode; const char *errstr; dav_error *err; char errbuf[200]; if (status == APR_SUCCESS) return NULL; p = db ? db->pool : p; /* There might not be a <db> if we had problems creating it. */ if (db == NULL) { errcode = 1; errstr = "Could not open property database."; } else { (void) apr_dbm_geterror(db->file, &errcode, errbuf, sizeof(errbuf)); errstr = apr_pstrdup(p, errbuf); } err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, errstr); err->save_errno = save_errno; return err;}/* ensure that our state subdirectory is present *//* ### does this belong here or in dav_fs_repos.c ?? */void dav_fs_ensure_state_dir(apr_pool_t * p, const char *dirname){ const char *pathname = apr_pstrcat(p, dirname, "/" DAV_FS_STATE_DIR, NULL); /* ### do we need to deal with the umask? */ /* just try to make it, ignoring any resulting errors */ (void) apr_dir_make(pathname, APR_OS_DEFAULT, p);}/* dav_dbm_open_direct: Opens a *dbm database specified by path. * ro = boolean read-only flag. */dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, dav_db **pdb){ apr_status_t status; apr_dbm_t *file; *pdb = NULL; if ((status = apr_dbm_open(&file, pathname, ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, p)) != APR_SUCCESS && !ro) { /* ### do something with 'status' */ /* we can't continue if we couldn't open the file and we need to write */ return dav_fs_dbm_error(NULL, p, status); } /* may be NULL if we tried to open a non-existent db as read-only */ if (file != NULL) { /* we have an open database... return it */ *pdb = apr_pcalloc(p, sizeof(**pdb)); (*pdb)->pool = p; (*pdb)->file = file; } return NULL;}static dav_error * dav_dbm_open(apr_pool_t * p, const dav_resource *resource, int ro, dav_db **pdb){ const char *dirpath; const char *fname; const char *pathname; /* Get directory and filename for resource */ dav_fs_dir_file_name(resource, &dirpath, &fname); /* If not opening read-only, ensure the state dir exists */ if (!ro) { /* ### what are the perf implications of always checking this? */ dav_fs_ensure_state_dir(p, dirpath); } pathname = apr_pstrcat(p, dirpath, "/" DAV_FS_STATE_DIR "/", fname ? fname : DAV_FS_STATE_FILE_FOR_DIR, NULL); /* ### readers cannot open while a writer has this open; we should ### perform a few retries with random pauses. */ /* ### do we need to deal with the umask? */ return dav_dbm_open_direct(p, pathname, ro, pdb);}static void dav_dbm_close(dav_db *db){ apr_dbm_close(db->file);}static dav_error * dav_dbm_fetch(dav_db *db, dav_datum key, dav_datum *pvalue){ apr_status_t status = apr_dbm_fetch(db->file, key, pvalue); return dav_fs_dbm_error(db, NULL, status);}static dav_error * dav_dbm_store(dav_db *db, dav_datum key, dav_datum value){ apr_status_t status = apr_dbm_store(db->file, key, value); return dav_fs_dbm_error(db, NULL, status);}static dav_error * dav_dbm_delete(dav_db *db, dav_datum key){ apr_status_t status = apr_dbm_delete(db->file, key); return dav_fs_dbm_error(db, NULL, status);}static int dav_dbm_exists(dav_db *db, dav_datum key){ return apr_dbm_exists(db->file, key);}static dav_error * dav_dbm_firstkey(dav_db *db, dav_datum *pkey){ apr_status_t status = apr_dbm_firstkey(db->file, pkey); return dav_fs_dbm_error(db, NULL, status);}static dav_error * dav_dbm_nextkey(dav_db *db, dav_datum *pkey){ apr_status_t status = apr_dbm_nextkey(db->file, pkey); return dav_fs_dbm_error(db, NULL, status);}static void dav_dbm_freedatum(dav_db *db, dav_datum data){ apr_dbm_freedatum(db->file, data);}const dav_hooks_db dav_hooks_db_dbm ={ dav_dbm_open, dav_dbm_close, dav_dbm_fetch, dav_dbm_store, dav_dbm_delete, dav_dbm_exists, dav_dbm_firstkey, dav_dbm_nextkey, dav_dbm_freedatum,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -