mod_dav.h revision a0c5ae524801374f36b3769d33d32ea1cca5ade3
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* Licensed to the Apache Software Foundation (ASF) under one or more
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * contributor license agreements. See the NOTICE file distributed with
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * this work for additional information regarding copyright ownership.
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * The ASF licenses this file to You under the Apache License, Version 2.0
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * (the "License"); you may not use this file except in compliance with
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * the License. You may obtain a copy of the License at
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * Unless required by applicable law or agreed to in writing, software
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * distributed under the License is distributed on an "AS IS" BASIS,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * See the License for the specific language governing permissions and
2e545ce2450a9953665f701bb05350f0d3f26275nd * limitations under the License.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * @brief DAV extension module for Apache 2.0.*
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * @defgroup MOD_DAV mod_dav
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor * @ingroup APACHE_MODS
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzorextern "C" {
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_XML_CONTENT_TYPE "text/xml; charset=\"utf-8\""
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_READ_BLOCKSIZE 2048 /* used for reading input blocks */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_RESPONSE_BODY_1 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>"
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_RESPONSE_BODY_2 "</title>\n</head><body>\n<h1>"
01f52ba6a87aa39d3873a441369828875c471823trawick#define DAV_INFINITY INT_MAX /* for the Depth: header */
01f52ba6a87aa39d3873a441369828875c471823trawick/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and
01f52ba6a87aa39d3873a441369828875c471823trawick * DAV_DECLARE_DATA with appropriate export and import tags for the platform
01f52ba6a87aa39d3873a441369828875c471823trawick#if !defined(WIN32)
01f52ba6a87aa39d3873a441369828875c471823trawick#define DAV_DECLARE(type) __declspec(dllexport) type __stdcall
01f52ba6a87aa39d3873a441369828875c471823trawick#define DAV_DECLARE_NONSTD(type) __declspec(dllexport) type
01f52ba6a87aa39d3873a441369828875c471823trawick#define DAV_DECLARE(type) __declspec(dllimport) type __stdcall
01f52ba6a87aa39d3873a441369828875c471823trawick#define DAV_DECLARE_NONSTD(type) __declspec(dllimport) type
01f52ba6a87aa39d3873a441369828875c471823trawick/* --------------------------------------------------------------------
01f52ba6a87aa39d3873a441369828875c471823trawick** ERROR MANAGEMENT
01f52ba6a87aa39d3873a441369828875c471823trawick** dav_error structure.
01f52ba6a87aa39d3873a441369828875c471823trawick** In most cases, mod_dav uses a pointer to a dav_error structure. If the
01f52ba6a87aa39d3873a441369828875c471823trawick** pointer is NULL, then no error has occurred.
01f52ba6a87aa39d3873a441369828875c471823trawick** In certain cases, a dav_error structure is directly used. In these cases,
01f52ba6a87aa39d3873a441369828875c471823trawick** a status value of 0 means that an error has not occurred.
01f52ba6a87aa39d3873a441369828875c471823trawick** Note: this implies that status != 0 whenever an error occurs.
4aa603e6448b99f9371397d439795c91a93637eand** The desc field is optional (it may be NULL). When NULL, it typically
01f52ba6a87aa39d3873a441369828875c471823trawick** implies that Apache has a proper description for the specified status.
01f52ba6a87aa39d3873a441369828875c471823trawicktypedef struct dav_error {
01f52ba6a87aa39d3873a441369828875c471823trawick int status; /* suggested HTTP status (0 for no error) */
01f52ba6a87aa39d3873a441369828875c471823trawick const char *desc; /* DAV:responsedescription and error log */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor int save_errno; /* copy of errno causing the error */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor const char *namespace; /* [optional] namespace of error */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor struct dav_error *prev; /* previous error (in stack) */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** Create a new error structure. save_errno will be filled with the current
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** errno value.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzorDAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** Create a new error structure with tagname and (optional) namespace;
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** namespace may be NULL, which means "DAV:". save_errno will be
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** filled with the current errno value.
fb9422f3bdba0c01312e22a55864dcc056583b7cgryzorDAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor const char *namespace,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor const char *tagname);
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** Push a new error description onto the stack of errors.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** This function is used to provide an additional description to an existing
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** <status> should contain the caller's view of what the current status is,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** given the underlying error. If it doesn't have a better idea, then the
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** caller should pass prev->status.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** <error_id> can specify a new error_id since the topmost description has
853ab6827637acc5cdd976cd2ea20a18f82ae184lgentisDAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status, int error_id,
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* error ID values... */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* IF: header errors */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_PARSE 100 /* general parsing error */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_MULTIPLE_NOT 101 /* multiple "Not" found */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_UNK_CHAR 102 /* unknown char in header */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_ABSENT 103 /* no locktokens given */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_TAGGED 104 /* in parsing tagged-list */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_IF_UNCLOSED_PAREN 105 /* in no-tagged-list */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* Prop DB errors */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_BAD_MAJOR 200 /* major version was wrong */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_READONLY 201 /* prop is read-only */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_NO_DATABASE 202 /* writable db not avail */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_NOT_FOUND 203 /* prop not found */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_BAD_LOCKDB 204 /* could not open lockdb */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_OPENING 205 /* problem opening propdb */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_PROP_EXEC 206 /* problem exec'ing patch */
853ab6827637acc5cdd976cd2ea20a18f82ae184lgentis/* Predefined DB errors */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* ### any to define?? */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* Predefined locking system errors */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_OPENDB 400 /* could not open lockdb */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_NO_DB 401 /* no database defined */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_CORRUPT_DB 402 /* DB is corrupt */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_UNK_STATE_TOKEN 403 /* unknown State-token */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_PARSE_TOKEN 404 /* bad opaquelocktoken */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor#define DAV_ERR_LOCK_SAVE_LOCK 405 /* err saving locks */
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** Some comments on Error ID values:
853ab6827637acc5cdd976cd2ea20a18f82ae184lgentis** The numbers do not necessarily need to be unique. Uniqueness simply means
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** that two errors that have not been predefined above can be distinguished
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** from each other. At the moment, mod_dav does not use this distinguishing
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** feature, but it could be used in the future to collapse <response> elements
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** into groups based on the error ID (and associated responsedescription).
4aa603e6448b99f9371397d439795c91a93637eand** If a compute_desc is provided, then the error ID should be unique within
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** the context of the compute_desc function (so the function can figure out
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** what to filled into the desc).
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** Basically, subsystems can ignore defining new error ID values if they want
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** to. The subsystems *do* need to return the predefined errors when
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** appropriate, so that mod_dav can figure out what to do. Subsystems can
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** simply leave the error ID field unfilled (zero) if there isn't an error
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** that must be placed there.
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor/* --------------------------------------------------------------------
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** HOOK STRUCTURES
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** These are here for forward-declaration purposes. For more info, see
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** the section title "HOOK HANDLING" for more information, plus each
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** structure definition.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar/* forward-declare this structure */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coartypedef struct dav_hooks_repository dav_hooks_repository;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar/* ### deprecated name */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar/* --------------------------------------------------------------------
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** RESOURCE HANDLING
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** Resource Types:
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** The base protocol defines only file and collection resources.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** The versioning protocol defines several additional resource types
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** to represent artifacts of a version control system.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** This enumeration identifies the type of URL used to identify the
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** resource. Since the same resource may have more than one type of
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** URL which can identify it, dav_resource_type cannot be used
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** alone to determine the type of the resource; attributes of the
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** dav_resource object must also be consulted.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coartypedef enum {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar DAV_RESOURCE_TYPE_REGULAR, /* file or collection; could be
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar * unversioned, or version selector,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar * or baseline selector */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar DAV_RESOURCE_TYPE_VERSION, /* version or baseline URL */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar DAV_RESOURCE_TYPE_HISTORY, /* version or baseline history URL */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar DAV_RESOURCE_TYPE_PRIVATE /* repository-private type */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** Opaque, repository-specific information for a resource.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coartypedef struct dav_resource_private dav_resource_private;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** Resource descriptor, generated by a repository provider.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** Note: the lock-null state is not explicitly represented here,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** since it may be expensive to compute. Use dav_get_resource_state()
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** to determine whether a non-existent resource is a lock-null resource.
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** A quick explanation of how the flags can apply to different resources:
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** unversioned file or collection:
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** type = DAV_RESOURCE_TYPE_REGULAR
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** exists = ? (1 if exists)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** collection = ? (1 if collection)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** versioned = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** baselined = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** working = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** version-controlled resource or configuration:
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** type = DAV_RESOURCE_TYPE_REGULAR
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** exists = 1
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** collection = ? (1 if collection)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** versioned = 1
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** baselined = ? (1 if configuration)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** working = ? (1 if checked out)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** type = DAV_RESOURCE_TYPE_HISTORY
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** exists = 1
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** collection = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** versioned = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** baselined = 0
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar** working = 0
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** type = DAV_RESOURCE_TYPE_VERSION
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** exists = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** collection = ? (1 if collection)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** versioned = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** baselined = ? (1 if baseline)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** working = 0
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** working resource:
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** type = DAV_RESOURCE_TYPE_WORKING
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** exists = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** collection = ? (1 if collection)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** versioned = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** baselined = 0
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** working = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** workspace:
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** type = DAV_RESOURCE_TYPE_WORKSPACE
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** exists = ? (1 if exists)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** collection = 1
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** versioned = ? (1 if version-controlled)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** baselined = ? (1 if baseline-controlled)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** working = ? (1 if checked out)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** activity:
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** type = DAV_RESOURCE_TYPE_ACTIVITY
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** exists = ? (1 if exists)
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** collection = 0
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** versioned = 0
0f40f560dcfc0a192b0d92b8dc00b13e980bfe9dgryzor** baselined = 0
typedef struct dav_resource {
} dav_resource;
} dav_buffer;
const char *str);
const char *str);
const char *str);
typedef struct dav_response
int status;
} dav_response;
int must_be_absolute);
const char *tagname);
const char *tagname);
int strip_white);
const char *uri);
const char *prefix);
const char *uri);
void *ctx;
} dav_provider;
** Example: http://apache.org/dav/props/
typedef struct dav_if_state_list
int condition;
#define DAV_IF_COND_NORMAL 0
const char *etag;
typedef struct dav_if_header
const char *uri;
typedef struct dav_locktoken_list
struct dav_hooks_liveprop
const char * const * namespace_uris;
int operation,
void **context,
int *defer_to_dead);
int operation,
void *context,
int operation,
void *context,
int operation,
void *context,
void *ctx;
const char * const *namespace_uris;
const char *ns_uri,
const char *name,
request_rec *r,
const char *name;
struct dav_hooks_propdb
** Note: usually, there is just a single document/namespaces for all
void *ctx;
#define DAV_TIMEOUT_INFINITE 0
} dav_lockdb;
typedef struct dav_lock
} dav_lock;
int resource_state,
int depth);
int depth,
int flags,
struct dav_hooks_locks
const char * (*get_supportedlock)(
apr_pool_t *p,
const char *char_token,
const char * (*format_locktoken)(
apr_pool_t *p,
int (*compare_locktoken)(
request_rec *r,
int ro,
int force,
void (*close_lockdb)(
int calltype,
int partial_ok,
int *locks_present);
int make_indirect,
void *ctx;
request_rec *r,
int ro,
const char *ns_uri,
const char *propname,
** differentiate/group the "desc" values.
typedef struct dav_prop_ctx
int operation;
int is_liveprop;
void *liveprop_ctx;
/* private to mod_dav.c */
request_rec *r;
} dav_prop_ctx;
void *walk_ctx;
int walk_type;
void *walk_ctx;
typedef struct dav_walker_ctx
int propfind_type;
int flags;
int status,
struct dav_hooks_repository
int handle_get;
request_rec *r,
const char *root_dir,
const char *label,
int use_checked_in,
int (*is_same_resource)(
int (*is_parent_resource)(
int depth,
void *ctx;
request_rec *r,
int parent_only,
request_rec *r,
int undo,
int unlock,
struct dav_hooks_vsn
const char *target);
int auto_checkout,
int create_activity,
int keep_checked_out,
const char *label,
int depth,
const char *label,
int replace);
const char *label);
void *ctx;
struct dav_hooks_binding {
void *ctx;
struct dav_hooks_search {
* DASL: <http://foo.bar.com/syntax1>
* DASL: <http://akuma.com/syntax2>
void *ctx;
typedef struct dav_options_provider
void *ctx;
const char *name,
typedef struct dav_resource_type_provider
const char **name,
const char **uri);
const char *name,
#ifdef __cplusplus