summaryrefslogtreecommitdiffstats
path: root/modules/dav/fs
diff options
context:
space:
mode:
Diffstat (limited to 'modules/dav/fs')
-rw-r--r--modules/dav/fs/dbm.c47
-rw-r--r--modules/dav/fs/lock.c2
-rw-r--r--modules/dav/fs/repos.c75
3 files changed, 91 insertions, 33 deletions
diff --git a/modules/dav/fs/dbm.c b/modules/dav/fs/dbm.c
index 821168e..347d75d 100644
--- a/modules/dav/fs/dbm.c
+++ b/modules/dav/fs/dbm.c
@@ -37,6 +37,11 @@
#define APR_WANT_BYTEFUNC
#include "apr_want.h" /* for ntohs and htons */
+#include "apr_version.h"
+#if !APR_VERSION_AT_LEAST(2,0,0)
+#include "apu_version.h"
+#endif
+
#include "mod_dav.h"
#include "repos.h"
#include "http_log.h"
@@ -127,11 +132,30 @@ void dav_fs_ensure_state_dir(apr_pool_t * p, const char *dirname)
dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro,
dav_db **pdb)
{
- apr_status_t status;
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
+ const apr_dbm_driver_t *driver;
+ const apu_err_t *err;
+#endif
apr_dbm_t *file = NULL;
+ apr_status_t status;
*pdb = NULL;
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
+ if ((status = apr_dbm_get_driver(&driver, NULL, &err, p)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10289)
+ "mod_dav_fs: The DBM library '%s' could not be loaded: %s",
+ err->reason, err->msg);
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 1, status,
+ "Could not load library for property database.");
+ }
+ if ((status = apr_dbm_open2(&file, driver, pathname,
+ ro ? APR_DBM_READONLY : APR_DBM_RWCREATE,
+ APR_OS_DEFAULT, p))
+ != APR_SUCCESS && !ro) {
+ return dav_fs_dbm_error(NULL, p, status);
+ }
+#else
if ((status = apr_dbm_open(&file, pathname,
ro ? APR_DBM_READONLY : APR_DBM_RWCREATE,
APR_OS_DEFAULT, p))
@@ -143,6 +167,7 @@ dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro,
and we need to write */
return dav_fs_dbm_error(NULL, p, status);
}
+#endif
/* may be NULL if we tried to open a non-existent db as read-only */
if (file != NULL) {
@@ -355,29 +380,33 @@ static void dav_append_prop(apr_pool_t *pool,
/* the property is an empty value */
if (*name == ':') {
/* "no namespace" case */
- s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name+1);
+ s = apr_pstrcat(pool, "<", name+1, "/>" DEBUG_CR, NULL);
}
else {
- s = apr_psprintf(pool, "<ns%s/>" DEBUG_CR, name);
+ s = apr_pstrcat(pool, "<ns", name, "/>" DEBUG_CR, NULL);
}
}
else if (*lang != '\0') {
if (*name == ':') {
/* "no namespace" case */
- s = apr_psprintf(pool, "<%s xml:lang=\"%s\">%s</%s>" DEBUG_CR,
- name+1, lang, value, name+1);
+ s = apr_pstrcat(pool, "<", name+1, " xml:lang=\"",
+ lang, "\">", value, "</", name+1, ">" DEBUG_CR,
+ NULL);
}
else {
- s = apr_psprintf(pool, "<ns%s xml:lang=\"%s\">%s</ns%s>" DEBUG_CR,
- name, lang, value, name);
+ s = apr_pstrcat(pool, "<ns", name, " xml:lang=\"",
+ lang, "\">", value, "</ns", name, ">" DEBUG_CR,
+ NULL);
}
}
else if (*name == ':') {
/* "no namespace" case */
- s = apr_psprintf(pool, "<%s>%s</%s>" DEBUG_CR, name+1, value, name+1);
+ s = apr_pstrcat(pool, "<", name+1, ">", value, "</", name+1, ">"
+ DEBUG_CR, NULL);
}
else {
- s = apr_psprintf(pool, "<ns%s>%s</ns%s>" DEBUG_CR, name, value, name);
+ s = apr_pstrcat(pool, "<ns", name, ">", value, "</ns", name, ">"
+ DEBUG_CR, NULL);
}
apr_text_append(pool, phdr, s);
diff --git a/modules/dav/fs/lock.c b/modules/dav/fs/lock.c
index c058e2e..ef18c4a 100644
--- a/modules/dav/fs/lock.c
+++ b/modules/dav/fs/lock.c
@@ -953,7 +953,7 @@ static dav_error * dav_fs_add_locknull_state(
/*
** dav_fs_remove_locknull_state: Given a request, check to see if r->filename
-** is/was a lock-null resource. If so, return it to an existant state, i.e.
+** is/was a lock-null resource. If so, return it to an existent state, i.e.
** remove it from the list in the appropriate .DAV/locknull file.
*/
static dav_error * dav_fs_remove_locknull_state(
diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c
index 6a5ff76..64bc894 100644
--- a/modules/dav/fs/repos.c
+++ b/modules/dav/fs/repos.c
@@ -35,6 +35,7 @@
#include "mod_dav.h"
#include "repos.h"
+APLOG_USE_MODULE(dav_fs);
/* to assist in debugging mod_dav's GET handling */
#define DEBUG_GET_HANDLER 0
@@ -948,15 +949,29 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource,
else if (APR_STATUS_IS_EEXIST(rv)) {
rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT,
ds->p);
+ if (rv != APR_SUCCESS) {
+ return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv,
+ apr_psprintf(p, "Could not open an existing "
+ "resource for writing: %s.",
+ ds->pathname));
+ }
}
}
else {
rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
+ if (rv != APR_SUCCESS) {
+ return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv,
+ apr_psprintf(p, "Could not open an existing "
+ "resource for reading: %s.",
+ ds->pathname));
+ }
}
if (rv != APR_SUCCESS) {
return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv,
- "An error occurred while opening a resource.");
+ apr_psprintf(p, "An error occurred while opening "
+ "a resource for writing: %s.",
+ ds->pathname));
}
/* (APR registers cleanups for the fd with the pool) */
@@ -1572,6 +1587,19 @@ static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth)
status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
DAV_FINFO_MASK, pool);
if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
+ dav_resource_private *ctx = params->root->info;
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r,
+ APLOGNO(10472) "could not access file (%s) during directory walk",
+ fsctx->path1.buf);
+
+ /* If being tolerant, ignore failure due to losing a race
+ * with some other process deleting files out from under
+ * the directory walk. */
+ if ((params->walk_type & DAV_WALKTYPE_TOLERANT)
+ && APR_STATUS_IS_ENOENT(status)) {
+ continue;
+ }
/* woah! where'd it go? */
/* ### should have a better error here */
err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL);
@@ -1663,7 +1691,7 @@ static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth)
/* put a slash back on the end of the directory */
fsctx->path1.buf[fsctx->path1.cur_len - 1] = '/';
- /* these are all non-existant (files) */
+ /* these are all non-existent (files) */
fsctx->res1.exists = 0;
fsctx->res1.collection = 0;
memset(&fsctx->info1.finfo, 0, sizeof(fsctx->info1.finfo));
@@ -1853,27 +1881,26 @@ static dav_error * dav_fs_walk(const dav_walk_params *params, int depth,
return dav_fs_internal_walk(params, depth, 0, NULL, response);
}
-/* dav_fs_etag: Stolen from ap_make_etag. Creates a strong etag
- * for file path.
- * ### do we need to return weak tags sometimes?
+/* dav_fs_etag: Creates an etag for the file path.
*/
static const char *dav_fs_getetag(const dav_resource *resource)
{
- dav_resource_private *ctx = resource->info;
- /* XXX: This should really honor the FileETag setting */
+ etag_rec er;
- if (!resource->exists)
- return apr_pstrdup(ctx->pool, "");
+ dav_resource_private *ctx = resource->info;
- if (ctx->finfo.filetype != APR_NOFILE) {
- return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "-%"
- APR_UINT64_T_HEX_FMT "\"",
- (apr_uint64_t) ctx->finfo.size,
- (apr_uint64_t) ctx->finfo.mtime);
+ if (!resource->exists || !ctx->r) {
+ return "";
}
- return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "\"",
- (apr_uint64_t) ctx->finfo.mtime);
+ er.vlist_validator = NULL;
+ er.request_time = ctx->r->request_time;
+ er.finfo = &ctx->finfo;
+ er.pathname = ctx->pathname;
+ er.fd = NULL;
+ er.force_weak = 0;
+
+ return ap_make_etag_ex(ctx->r, &er);
}
static const dav_hooks_repository dav_hooks_repository_fs =
@@ -1913,7 +1940,7 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource,
const char *s;
apr_pool_t *p = resource->info->pool;
const dav_liveprop_spec *info;
- int global_ns;
+ long global_ns;
/* an HTTP-date can be 29 chars plus a null term */
/* a 64-bit size can be 20 chars plus a null term */
@@ -1994,18 +2021,20 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource,
/* DBG3("FS: inserting lp%d:%s (local %d)", ns, scan->name, scan->ns); */
if (what == DAV_PROP_INSERT_VALUE) {
- s = apr_psprintf(p, "<lp%d:%s>%s</lp%d:%s>" DEBUG_CR,
+ s = apr_psprintf(p, "<lp%ld:%s>%s</lp%ld:%s>" DEBUG_CR,
global_ns, info->name, value, global_ns, info->name);
}
else if (what == DAV_PROP_INSERT_NAME) {
- s = apr_psprintf(p, "<lp%d:%s/>" DEBUG_CR, global_ns, info->name);
+ s = apr_psprintf(p, "<lp%ld:%s/>" DEBUG_CR, global_ns, info->name);
}
else {
/* assert: what == DAV_PROP_INSERT_SUPPORTED */
- s = apr_psprintf(p,
- "<D:supported-live-property D:name=\"%s\" "
- "D:namespace=\"%s\"/>" DEBUG_CR,
- info->name, dav_fs_namespace_uris[info->ns]);
+ s = apr_pstrcat(p,
+ "<D:supported-live-property D:name=\"",
+ info->name,
+ "\" D:namespace=\"",
+ dav_fs_namespace_uris[info->ns],
+ "\"/>" DEBUG_CR, NULL);
}
apr_text_append(p, phdr, s);