repos.c revision dc52cac281d8b311dc47d115ed979f923b667679
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* Licensed to the Apache Software Foundation (ASF) under one or more
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * contributor license agreements. See the NOTICE file distributed with
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * this work for additional information regarding copyright ownership.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * The ASF licenses this file to You under the Apache License, Version 2.0
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * (the "License"); you may not use this file except in compliance with
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * the License. You may obtain a copy of the License at
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * http://www.apache.org/licenses/LICENSE-2.0
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * Unless required by applicable law or agreed to in writing, software
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * distributed under the License is distributed on an "AS IS" BASIS,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * See the License for the specific language governing permissions and
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * limitations under the License.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** DAV filesystem-based repository provider
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#include "http_request.h" /* for ap_update_mtime() */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* to assist in debugging mod_dav's GET handling */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#define DAV_FS_COPY_BLOCKSIZE 16384 /* copy 16k at a time */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* context needed to identify a resource */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance apr_pool_t *pool; /* memory storage pool associated with request */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance const char *pathname; /* full pathname to resource */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance apr_finfo_t finfo; /* filesystem info */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* private context for doing a filesystem walk */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancetypedef struct {
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* the input walk parameters */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* reused as we walk */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* MOVE/COPY need a secondary path */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancetypedef struct {
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance dav_buffer work_buf; /* handy buffer for copymove_file() */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* CALLBACK: this is a secondary resource managed specially for us */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* copied from dav_walk_params (they are invariant across the walk) */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* an internal WALKTYPE to walk hidden files (the .DAV directory) */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* an internal WALKTYPE to call collections (again) after their contents */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#define DAV_CALLTYPE_POSTFIX 1000 /* a private call type */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* pull this in from the other source file */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Manceextern const dav_hooks_locks dav_hooks_locks_fs;
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* forward-declare the hook structures */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancestatic const dav_hooks_repository dav_hooks_repository_fs;
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancestatic const dav_hooks_liveprop dav_hooks_liveprop_fs;
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** The namespace URIs that we use. This list and the enumeration must
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** stay in sync.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancestatic const char * const dav_fs_namespace_uris[] =
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance DAV_FS_URI_DAV, /* the DAV: namespace URI */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance DAV_FS_URI_MYPROPS /* the namespace URI for our custom props */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** Does this platform support an executable flag?
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** ### need a way to portably abstract this query
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** DAV_FINFO_MASK gives the appropriate mask to use for the stat call
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** used to get file attributes.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#define DAV_FINFO_MASK (APR_FINFO_LINK | APR_FINFO_TYPE | APR_FINFO_INODE | \
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance APR_FINFO_SIZE | APR_FINFO_CTIME | APR_FINFO_MTIME | \
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* as above, but without APR_FINFO_PROT */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#define DAV_FINFO_MASK (APR_FINFO_LINK | APR_FINFO_TYPE | APR_FINFO_INODE | \
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance APR_FINFO_SIZE | APR_FINFO_CTIME | APR_FINFO_MTIME)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance** The single property that we define (in the DAV_FS_URI_MYPROPS namespace)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * prefix for temporary files
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancestatic const dav_liveprop_spec dav_fs_props[] =
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* standard DAV properties */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance "creationdate",
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance "getcontentlength",
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance "getlastmodified",
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance /* our custom properties */
c41f2d65ecbf5ad9d3233a21f406a7698338a04bFelix Gabriel Mance 0 /* handled special in dav_fs_is_writable */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance { 0 } /* sentinel */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mancestatic const dav_liveprop_group dav_fs_liveprop_group =
1cc559ec103ed20967587fff2e39cc88669f7b8fFelix Gabriel Mance/* define the dav_stream structure for our use */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance const char *pathname; /* we may need to remove it at close time */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* returns an appropriate HTTP status code given an APR status code for a
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * failed I/O operation. ### use something besides 500? */
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#define MAP_IO2HTTP(e) (APR_STATUS_IS_ENOSPC(e) ? HTTP_INSUFFICIENT_STORAGE : \
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance APR_STATUS_IS_ENOENT(e) ? HTTP_CONFLICT : \
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mance/* forward declaration for internal treewalkers */
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mancestatic dav_error * dav_fs_walk(const dav_walk_params *params, int depth,
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mancestatic dav_error * dav_fs_internal_walk(const dav_walk_params *params,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* --------------------------------------------------------------------
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance** PRIVATE REPOSITORY FUNCTIONS
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mancestatic request_rec *dav_fs_get_request_rec(const dav_resource *resource)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Manceapr_pool_t *dav_fs_pool(const dav_resource *resource)
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Manceconst char *dav_fs_pathname(const dav_resource *resource)
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance dav_resource_private *ctx = resource->info;
6e7fe479953725884826bd38e4779229d45d3a40Felix Gabriel Mance char *dirpath = ap_make_dirstr_parent(ctx->pool, ctx->pathname);
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance rv = apr_filepath_root(&rootpath, &testpath, 0, ctx->pool);
396f82c6cd926be759b60fd1e854acfde7068215Felix Gabriel Mance /* remove trailing slash from dirpath, unless it's a root path
"An incomplete/bad path was found in "
return NULL;
int is_move,
apr_pool_t * p,
const char *src,
const char *dst,
return err;
return err;
return NULL;
int is_move,
apr_pool_t * p,
const char *src;
const char *dst;
return NULL;
if (is_move) {
return NULL;
const char *src_dir;
const char *src_file;
const char *src_state1;
const char *src_state2;
const char *dst_dir;
const char *dst_file;
const char *dst_state1;
const char *dst_state2;
#if DAV_DEBUG
pbuf);
pbuf);
return err;
const char *dirpath;
const char *fname;
const char *state1;
const char *state2;
const char *pathname;
NULL);
NULL);
return NULL;
request_rec *r,
const char *root_dir,
const char *label,
int use_checked_in,
char *filename;
ctx->r = r;
return NULL;
char *dirpath;
const char *testroot;
const char *testpath;
return NULL;
return NULL;
return NULL;
static int dav_fs_is_same_resource(
static int dav_fs_is_parent_resource(
return APR_SUCCESS;
APR_OS_DEFAULT, p);
return rv;
switch (mode) {
case DAV_MODE_WRITE_TRUNC:
case DAV_MODE_WRITE_SEEKABLE:
ds->p = p;
ds->p);
return NULL;
if (!commit) {
!= APR_SUCCESS) {
rv,
if (rv) {
return NULL;
return NULL;
!= APR_SUCCESS) {
return NULL;
return NULL;
ap_set_etag(r);
return NULL;
return NULL;
return NULL;
int calltype)
return NULL;
return err;
int is_move,
int depth,
if (is_move)
return err;
return NULL;
return err;
int depth,
#if DAV_DEBUG
return err;
#if DAV_DEBUG
return err;
return NULL;
err);
err);
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return err;
return err;
return err;
return NULL;
#if DAV_DEBUG
return err;
NULL,
NULL,
NULL,
const char *value;
int global_ns;
return DAV_PROP_INSERT_NOTDEF;
switch (propid) {
case DAV_PROPID_creationdate:
return DAV_PROP_INSERT_NOTDEF;
case DAV_PROPID_getetag:
case DAV_PROPID_FS_executable:
return DAV_PROP_INSERT_NOTDEF;
return DAV_PROP_INSERT_NOTDEF;
return DAV_PROP_INSERT_NOTDEF;
s = apr_psprintf(p,
return what;
#ifdef DAV_FS_HAS_EXECUTABLE
int operation,
void **context,
int *defer_to_dead)
char value;
return NULL;
? NULL
/* DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); */
goto too_long;
goto too_long;
return NULL;
int operation,
void *context,
return NULL;
if (value)
!= APR_SUCCESS) {
return NULL;
int operation,
void *context,
int operation,
void *context,
if (value)
!= APR_SUCCESS) {
return NULL;
#ifdef DAV_FS_HAS_EXECUTABLE
#ifdef DAV_FS_HAS_EXECUTABLE