diff options
Diffstat (limited to 'modules/dav/fs')
-rw-r--r-- | modules/dav/fs/dbm.c | 47 | ||||
-rw-r--r-- | modules/dav/fs/lock.c | 2 | ||||
-rw-r--r-- | modules/dav/fs/repos.c | 75 |
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); |