/* when used as a property database: */
- int version; /* *minor* version of this db */
+ int version; /* *minor* version of this db */
- dav_buffer ns_table; /* table of namespace URIs */
- short ns_count; /* number of entries in table */
- int ns_table_dirty; /* ns_table was modified */
+ dav_buffer ns_table; /* table of namespace URIs */
+ short ns_count; /* number of entries in table */
+ int ns_table_dirty; /* ns_table was modified */
apr_hash_t *uri_index; /* map URIs to (1-based) table indices */
- dav_buffer wb_key; /* work buffer for dav_gdbm_key */
+ dav_buffer wb_key; /* work buffer for dav_gdbm_key */
apr_datum_t iter; /* iteration key */
};
*/
void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname,
- const char **state1, const char **state2)
+ const char **state1, const char **state2)
{
if (fname == NULL)
- fname = DAV_FS_STATE_FILE_FOR_DIR;
+ fname = DAV_FS_STATE_FILE_FOR_DIR;
apr_dbm_get_usednames(p, fname, state1, state2);
}
* ro = boolean read-only flag.
*/
dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro,
- dav_db **pdb)
+ dav_db **pdb)
{
apr_status_t status;
apr_dbm_t *file;
&& !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);
+ /* 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;
+ /* we have an open database... return it */
+ *pdb = apr_pcalloc(p, sizeof(**pdb));
+ (*pdb)->pool = p;
+ (*pdb)->file = file;
}
return NULL;
/* If not opening read-only, ensure the state dir exists */
if (!ro) {
- /* ### what are the perf implications of always checking this? */
+ /* ### 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);
+ 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. */
*/
-#define DAV_GDBM_NS_KEY "METADATA"
-#define DAV_GDBM_NS_KEY_LEN 8
+#define DAV_GDBM_NS_KEY "METADATA"
+#define DAV_GDBM_NS_KEY_LEN 8
typedef struct {
unsigned char major;
-#define DAV_DBVSN_MAJOR 4
+#define DAV_DBVSN_MAJOR 4
/*
** V4 -- 0.9.9 ..
** Prior versions could have keys or values with invalid
unsigned char minor;
-#define DAV_DBVSN_MINOR 0
+#define DAV_DBVSN_MINOR 0
short ns_count;
* have the form "#:name".
*/
if (*name->ns == '\0') {
- nsbuf[0] = '\0';
- l_ns = 0;
+ nsbuf[0] = '\0';
+ l_ns = 0;
}
else {
int ns_id = (int)apr_hash_get(db->uri_index, name->ns,
}
static void dav_append_prop(apr_pool_t *pool,
- const char *name, const char *value,
- apr_text_header *phdr)
+ const char *name, const char *value,
+ apr_text_header *phdr)
{
const char *s;
const char *lang = value;
value += strlen(lang) + 1;
if (*value == '\0') {
- /* the property is an empty value */
- if (*name == ':') {
- /* "no namespace" case */
- s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name+1);
- }
- else {
- s = apr_psprintf(pool, "<ns%s/>" DEBUG_CR, name);
- }
+ /* the property is an empty value */
+ if (*name == ':') {
+ /* "no namespace" case */
+ s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name+1);
+ }
+ else {
+ s = apr_psprintf(pool, "<ns%s/>" DEBUG_CR, name);
+ }
}
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);
- }
- else {
- s = apr_psprintf(pool, "<ns%s xml:lang=\"%s\">%s</ns%s>" DEBUG_CR,
- name, lang, value, name);
- }
+ if (*name == ':') {
+ /* "no namespace" case */
+ s = apr_psprintf(pool, "<%s xml:lang=\"%s\">%s</%s>" DEBUG_CR,
+ name+1, lang, value, name+1);
+ }
+ else {
+ s = apr_psprintf(pool, "<ns%s xml:lang=\"%s\">%s</ns%s>" DEBUG_CR,
+ name, lang, value, name);
+ }
}
else if (*name == ':') {
- /* "no namespace" case */
- s = apr_psprintf(pool, "<%s>%s</%s>" DEBUG_CR, name+1, value, name+1);
+ /* "no namespace" case */
+ s = apr_psprintf(pool, "<%s>%s</%s>" DEBUG_CR, name+1, value, name+1);
}
else {
- s = apr_psprintf(pool, "<ns%s>%s</ns%s>" DEBUG_CR, name, value, name);
+ s = apr_psprintf(pool, "<ns%s>%s</ns%s>" DEBUG_CR, name, value, name);
}
apr_text_append(pool, phdr, s);
}
if (value.dptr == NULL) {
- dav_propdb_metadata m = {
- DAV_DBVSN_MAJOR, DAV_DBVSN_MINOR, 0
- };
+ dav_propdb_metadata m = {
+ DAV_DBVSN_MAJOR, DAV_DBVSN_MINOR, 0
+ };
/*
** If there is no METADATA key, then the database may be
DAV_ERR_PROP_BAD_MAJOR,
"Prop database has the wrong major "
"version number and cannot be used.");
- }
+ }
- /* initialize a new metadata structure */
- dav_set_bufsize(pool, &db->ns_table, sizeof(m));
- memcpy(db->ns_table.buf, &m, sizeof(m));
+ /* initialize a new metadata structure */
+ dav_set_bufsize(pool, &db->ns_table, sizeof(m));
+ memcpy(db->ns_table.buf, &m, sizeof(m));
}
else {
- dav_propdb_metadata m;
+ dav_propdb_metadata m;
int ns;
const char *uri;
- dav_set_bufsize(pool, &db->ns_table, value.dsize);
- memcpy(db->ns_table.buf, value.dptr, value.dsize);
+ dav_set_bufsize(pool, &db->ns_table, value.dsize);
+ memcpy(db->ns_table.buf, value.dptr, value.dsize);
- memcpy(&m, value.dptr, sizeof(m));
- if (m.major != DAV_DBVSN_MAJOR) {
- dav_dbm_close(db);
+ memcpy(&m, value.dptr, sizeof(m));
+ if (m.major != DAV_DBVSN_MAJOR) {
+ dav_dbm_close(db);
- return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
- DAV_ERR_PROP_BAD_MAJOR,
- "Prop database has the wrong major "
- "version number and cannot be used.");
- }
- db->version = m.minor;
- db->ns_count = ntohs(m.ns_count);
+ return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
+ DAV_ERR_PROP_BAD_MAJOR,
+ "Prop database has the wrong major "
+ "version number and cannot be used.");
+ }
+ db->version = m.minor;
+ db->ns_count = ntohs(m.ns_count);
- dav_dbm_freedatum(db, value);
+ dav_dbm_freedatum(db, value);
/* create db->uri_index */
for (ns = 0, uri = db->ns_table.buf + sizeof(dav_propdb_metadata);
{
if (db->ns_table_dirty) {
- dav_propdb_metadata m;
- apr_datum_t key;
- apr_datum_t value;
- dav_error *err;
+ dav_propdb_metadata m;
+ apr_datum_t key;
+ apr_datum_t value;
+ dav_error *err;
- key.dptr = DAV_GDBM_NS_KEY;
- key.dsize = DAV_GDBM_NS_KEY_LEN;
+ key.dptr = DAV_GDBM_NS_KEY;
+ key.dsize = DAV_GDBM_NS_KEY_LEN;
- value.dptr = db->ns_table.buf;
- value.dsize = db->ns_table.cur_len;
+ value.dptr = db->ns_table.buf;
+ value.dsize = db->ns_table.cur_len;
- /* fill in the metadata that we store into the prop db. */
- m.major = DAV_DBVSN_MAJOR;
- m.minor = db->version; /* ### keep current minor version? */
- m.ns_count = htons(db->ns_count);
+ /* fill in the metadata that we store into the prop db. */
+ m.major = DAV_DBVSN_MAJOR;
+ m.minor = db->version; /* ### keep current minor version? */
+ m.ns_count = htons(db->ns_count);
- memcpy(db->ns_table.buf, &m, sizeof(m));
+ memcpy(db->ns_table.buf, &m, sizeof(m));
- err = dav_dbm_store(db, key, value);
- /* ### what to do with the error? */
+ err = dav_dbm_store(db, key, value);
+ /* ### what to do with the error? */
}
dav_dbm_close(db);
module AP_MODULE_DECLARE_DATA dav_fs_module =
{
STANDARD20_MODULE_STUFF,
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- dav_fs_create_server_config, /* server config */
- dav_fs_merge_server_config, /* merge server config */
- dav_fs_cmds, /* command table */
- register_hooks, /* register hooks */
+ NULL, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ dav_fs_create_server_config, /* server config */
+ dav_fs_merge_server_config, /* merge server config */
+ dav_fs_cmds, /* command table */
+ register_hooks, /* register hooks */
};
#include "httpd.h"
#include "http_log.h"
-#include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */
+#include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */
#include "http_request.h" /* for ap_update_mtime() */
#include "mod_dav.h"
/* to assist in debugging mod_dav's GET handling */
#define DEBUG_GET_HANDLER 0
-#define DAV_FS_COPY_BLOCKSIZE 16384 /* copy 16k at a time */
+#define DAV_FS_COPY_BLOCKSIZE 16384 /* copy 16k at a time */
/* context needed to identify a resource */
struct dav_resource_private {
} dav_fs_copymove_walk_ctx;
/* an internal WALKTYPE to walk hidden files (the .DAV directory) */
-#define DAV_WALKTYPE_HIDDEN 0x4000
+#define DAV_WALKTYPE_HIDDEN 0x4000
/* an internal WALKTYPE to call collections (again) after their contents */
#define DAV_WALKTYPE_POSTFIX 0x8000
"DAV:",
"http://apache.org/dav/props/",
- NULL /* sentinel */
+ NULL /* sentinel */
};
enum {
- DAV_FS_URI_DAV, /* the DAV: namespace URI */
- DAV_FS_URI_MYPROPS /* the namespace URI for our custom props */
+ DAV_FS_URI_DAV, /* the DAV: namespace URI */
+ DAV_FS_URI_MYPROPS /* the namespace URI for our custom props */
};
/*
0 /* handled special in dav_fs_is_writable */
},
- { 0 } /* sentinel */
+ { 0 } /* sentinel */
};
static const dav_liveprop_group dav_fs_liveprop_group =
struct dav_stream {
apr_pool_t *p;
apr_file_t *f;
- const char *pathname; /* we may need to remove it at close time */
+ const char *pathname; /* we may need to remove it at close time */
};
/* forward declaration for internal treewalkers */
(void) apr_time_exp_gmt(&tms, sec);
if (style == DAV_STYLE_ISO8601) {
- /* ### should we use "-00:00" instead of "Z" ?? */
+ /* ### should we use "-00:00" instead of "Z" ?? */
- /* 20 chars plus null term */
- sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ",
+ /* 20 chars plus null term */
+ sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec);
return;
/* 29 chars plus null term */
sprintf(buf,
- "%s, %.2d %s %d %.2d:%.2d:%.2d GMT",
+ "%s, %.2d %s %d %.2d:%.2d:%.2d GMT",
apr_day_snames[tms.tm_wday],
tms.tm_mday, apr_month_snames[tms.tm_mon],
tms.tm_year + 1900,
apr_file_t *outf = NULL;
if (pbuf == NULL)
- pbuf = &work_buf;
+ pbuf = &work_buf;
dav_set_bufsize(p, pbuf, DAV_FS_COPY_BLOCKSIZE);
if ((apr_file_open(&inf, src, APR_READ | APR_BINARY, APR_OS_DEFAULT, p))
- != APR_SUCCESS) {
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not open file for reading");
+ != APR_SUCCESS) {
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not open file for reading");
}
/* ### do we need to deal with the umask? */
if ((apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY,
- APR_OS_DEFAULT, p)) != APR_SUCCESS) {
- apr_file_close(inf);
+ APR_OS_DEFAULT, p)) != APR_SUCCESS) {
+ apr_file_close(inf);
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not open file for writing");
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not open file for writing");
}
while (1) {
- apr_size_t len = DAV_FS_COPY_BLOCKSIZE;
- apr_status_t status;
-
- status = apr_file_read(inf, pbuf->buf, &len);
- if (status != APR_SUCCESS && status != APR_EOF) {
- apr_file_close(inf);
- apr_file_close(outf);
-
- if (apr_file_remove(dst, p) != APR_SUCCESS) {
- /* ### ACK! Inconsistent state... */
-
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not delete output after read "
- "failure. Server is now in an "
- "inconsistent state.");
- }
-
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not read input file");
- }
+ apr_size_t len = DAV_FS_COPY_BLOCKSIZE;
+ apr_status_t status;
+
+ status = apr_file_read(inf, pbuf->buf, &len);
+ if (status != APR_SUCCESS && status != APR_EOF) {
+ apr_file_close(inf);
+ apr_file_close(outf);
+
+ if (apr_file_remove(dst, p) != APR_SUCCESS) {
+ /* ### ACK! Inconsistent state... */
+
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not delete output after read "
+ "failure. Server is now in an "
+ "inconsistent state.");
+ }
+
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not read input file");
+ }
/* write any bytes that were read (applies to APR_EOF, too) */
if (apr_file_write_full(outf, pbuf->buf, len, NULL) != APR_SUCCESS) {
int save_errno = errno;
- apr_file_close(inf);
- apr_file_close(outf);
+ apr_file_close(inf);
+ apr_file_close(outf);
- if (apr_file_remove(dst, p) != APR_SUCCESS) {
- /* ### ACK! Inconsistent state... */
+ if (apr_file_remove(dst, p) != APR_SUCCESS) {
+ /* ### ACK! Inconsistent state... */
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not delete output after write "
- "failure. Server is now in an "
- "inconsistent state.");
- }
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not delete output after write "
+ "failure. Server is now in an "
+ "inconsistent state.");
+ }
- if (save_errno == ENOSPC) {
- return dav_new_error(p, HTTP_INSUFFICIENT_STORAGE, 0,
- "There is not enough storage to write to "
- "this resource.");
- }
+ if (save_errno == ENOSPC) {
+ return dav_new_error(p, HTTP_INSUFFICIENT_STORAGE, 0,
+ "There is not enough storage to write to "
+ "this resource.");
+ }
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not write output file");
- }
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not write output file");
+ }
if (status == APR_EOF)
break;
apr_file_close(outf);
if (is_move && apr_file_remove(src, p) != APR_SUCCESS) {
- dav_error *err;
- int save_errno = errno; /* save the errno that got us here */
-
- if (apr_file_remove(dst, p) != APR_SUCCESS) {
- /* ### ACK. this creates an inconsistency. do more!? */
-
- /* ### use something besides 500? */
- /* Note that we use the latest errno */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not remove source or destination "
- "file. Server is now in an inconsistent "
- "state.");
- }
+ dav_error *err;
+ int save_errno = errno; /* save the errno that got us here */
+
+ if (apr_file_remove(dst, p) != APR_SUCCESS) {
+ /* ### ACK. this creates an inconsistency. do more!? */
+
+ /* ### use something besides 500? */
+ /* Note that we use the latest errno */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not remove source or destination "
+ "file. Server is now in an inconsistent "
+ "state.");
+ }
- /* ### use something besides 500? */
- err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not remove source file after move. "
- "Destination was removed to ensure consistency.");
- err->save_errno = save_errno;
- return err;
+ /* ### use something besides 500? */
+ err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not remove source file after move. "
+ "Destination was removed to ensure consistency.");
+ err->save_errno = save_errno;
+ return err;
}
return NULL;
const char *dst_dir, const char *dst_file,
dav_buffer *pbuf)
{
- apr_finfo_t src_finfo; /* finfo for source file */
- apr_finfo_t dst_state_finfo; /* finfo for STATE directory */
+ apr_finfo_t src_finfo; /* finfo for source file */
+ apr_finfo_t dst_state_finfo; /* finfo for STATE directory */
apr_status_t rv;
const char *src;
const char *dst;
/* the source file doesn't exist */
rv = apr_stat(&src_finfo, src, APR_FINFO_NORM, p);
if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
- return NULL;
+ return NULL;
}
/* build the pathname for the destination state dir */
/* ensure that it exists */
rv = apr_dir_make(dst, APR_OS_DEFAULT, p);
if (rv != APR_SUCCESS) {
- if (!APR_STATUS_IS_EEXIST(rv)) {
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not create internal state directory");
- }
+ if (!APR_STATUS_IS_EEXIST(rv)) {
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not create internal state directory");
+ }
}
/* get info about the state directory */
rv = apr_stat(&dst_state_finfo, dst, APR_FINFO_NORM, p);
if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
- /* Ack! Where'd it go? */
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "State directory disappeared");
+ /* Ack! Where'd it go? */
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "State directory disappeared");
}
/* The mkdir() may have failed because a *file* exists there already */
if (dst_state_finfo.filetype != APR_DIR) {
- /* ### try to recover by deleting this file? (and mkdir again) */
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "State directory is actually a file");
+ /* ### try to recover by deleting this file? (and mkdir again) */
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "State directory is actually a file");
}
/* append the target file to the state directory pathname */
/* copy/move the file now */
if (is_move && src_finfo.device == dst_state_finfo.device) {
- /* simple rename is possible since it is on the same device */
- if (apr_file_rename(src, dst, p) != APR_SUCCESS) {
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not move state file.");
- }
+ /* simple rename is possible since it is on the same device */
+ if (apr_file_rename(src, dst, p) != APR_SUCCESS) {
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not move state file.");
+ }
}
else
{
- /* gotta copy (and delete) */
- return dav_fs_copymove_file(is_move, p, src, dst, pbuf);
+ /* gotta copy (and delete) */
+ return dav_fs_copymove_file(is_move, p, src, dst, pbuf);
}
return NULL;
}
static dav_error *dav_fs_copymoveset(int is_move, apr_pool_t *p,
- const dav_resource *src,
- const dav_resource *dst,
- dav_buffer *pbuf)
+ const dav_resource *src,
+ const dav_resource *dst,
+ dav_buffer *pbuf)
{
const char *src_dir;
const char *src_file;
dav_dbm_get_statefiles(p, dst_file, &dst_state1, &dst_state2);
#if DAV_DEBUG
if ((src_state2 != NULL && dst_state2 == NULL) ||
- (src_state2 == NULL && dst_state2 != NULL)) {
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: dav_dbm_get_statefiles() "
- "returned inconsistent results.");
+ (src_state2 == NULL && dst_state2 != NULL)) {
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "DESIGN ERROR: dav_dbm_get_statefiles() "
+ "returned inconsistent results.");
}
#endif
err = dav_fs_copymove_state(is_move, p,
- src_dir, src_state1,
- dst_dir, dst_state1,
- pbuf);
+ src_dir, src_state1,
+ dst_dir, dst_state1,
+ pbuf);
if (err == NULL && src_state2 != NULL) {
- err = dav_fs_copymove_state(is_move, p,
- src_dir, src_state2,
- dst_dir, dst_state2,
- pbuf);
-
- if (err != NULL) {
- /* ### CRAP. inconsistency. */
- /* ### should perform some cleanup at the target if we still
- ### have the original files */
-
- /* Change the error to reflect the bad server state. */
- err->status = HTTP_INTERNAL_SERVER_ERROR;
- err->desc =
- "Could not fully copy/move the properties. "
- "The server is now in an inconsistent state.";
- }
+ err = dav_fs_copymove_state(is_move, p,
+ src_dir, src_state2,
+ dst_dir, dst_state2,
+ pbuf);
+
+ if (err != NULL) {
+ /* ### CRAP. inconsistency. */
+ /* ### should perform some cleanup at the target if we still
+ ### have the original files */
+
+ /* Change the error to reflect the bad server state. */
+ err->status = HTTP_INTERNAL_SERVER_ERROR;
+ err->desc =
+ "Could not fully copy/move the properties. "
+ "The server is now in an inconsistent state.";
+ }
}
return err;
/* build the propset pathname for the file */
pathname = apr_pstrcat(p,
- dirpath,
- "/" DAV_FS_STATE_DIR "/",
- state1,
- NULL);
+ dirpath,
+ "/" DAV_FS_STATE_DIR "/",
+ state1,
+ NULL);
/* note: we may get ENOENT if the state dir is not present */
if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS
&& !APR_STATUS_IS_ENOENT(status)) {
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not remove properties.");
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not remove properties.");
}
if (state2 != NULL) {
- /* build the propset pathname for the file */
- pathname = apr_pstrcat(p,
- dirpath,
- "/" DAV_FS_STATE_DIR "/",
- state2,
- NULL);
+ /* build the propset pathname for the file */
+ pathname = apr_pstrcat(p,
+ dirpath,
+ "/" DAV_FS_STATE_DIR "/",
+ state2,
+ NULL);
if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS
&& !APR_STATUS_IS_ENOENT(status)) {
- /* ### CRAP. only removed half. */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not fully remove properties. "
- "The server is now in an inconsistent "
- "state.");
- }
+ /* ### CRAP. only removed half. */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not fully remove properties. "
+ "The server is now in an inconsistent "
+ "state.");
+ }
}
return NULL;
/* make sure the pathname does not have a trailing "/" */
len = strlen(s);
if (len > 1 && s[len - 1] == '/') {
- s[len - 1] = '\0';
+ s[len - 1] = '\0';
}
ctx->pathname = s;
/* make sure the URI does not have a trailing "/" */
len = strlen(r->uri);
if (len > 1 && r->uri[len - 1] == '/') {
- s = apr_pstrdup(r->pool, r->uri);
- s[len - 1] = '\0';
- resource->uri = s;
+ s = apr_pstrdup(r->pool, r->uri);
+ s[len - 1] = '\0';
+ resource->uri = s;
}
else {
- resource->uri = r->uri;
+ resource->uri = r->uri;
}
if (r->finfo.filetype != 0) {
resource->exists = 1;
resource->collection = r->finfo.filetype == APR_DIR;
- /* unused info in the URL will indicate a null resource */
-
- if (r->path_info != NULL && *r->path_info != '\0') {
- if (resource->collection) {
- /* only a trailing "/" is allowed */
- if (*r->path_info != '/' || r->path_info[1] != '\0') {
-
- /*
- ** This URL/filename represents a locknull resource or
- ** possibly a destination of a MOVE/COPY
- */
- resource->exists = 0;
- resource->collection = 0;
- }
- }
- else
- {
- /*
- ** The base of the path refers to a file -- nothing should
- ** be in path_info. The resource is simply an error: it
- ** can't be a null or a locknull resource.
- */
+ /* unused info in the URL will indicate a null resource */
+
+ if (r->path_info != NULL && *r->path_info != '\0') {
+ if (resource->collection) {
+ /* only a trailing "/" is allowed */
+ if (*r->path_info != '/' || r->path_info[1] != '\0') {
+
+ /*
+ ** This URL/filename represents a locknull resource or
+ ** possibly a destination of a MOVE/COPY
+ */
+ resource->exists = 0;
+ resource->collection = 0;
+ }
+ }
+ else
+ {
+ /*
+ ** The base of the path refers to a file -- nothing should
+ ** be in path_info. The resource is simply an error: it
+ ** can't be a null or a locknull resource.
+ */
return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
"The URL contains extraneous path "
"components. The resource could not "
"be identified.");
- }
+ }
- /* retain proper integrity across the structures */
- if (!resource->exists) {
- ctx->finfo.filetype = 0;
- }
- }
+ /* retain proper integrity across the structures */
+ if (!resource->exists) {
+ ctx->finfo.filetype = 0;
+ }
+ }
}
*result_resource = resource;
char *uri = ap_make_dirstr_parent(ctx->pool, resource->uri);
if (strlen(uri) > 1 && uri[strlen(uri) - 1] == '/')
uri[strlen(uri) - 1] = '\0';
- parent_resource->uri = uri;
+ parent_resource->uri = uri;
}
rv = apr_stat(&parent_ctx->finfo, parent_ctx->pathname,
dav_resource_private *ctx2 = res2->info;
if (res1->hooks != res2->hooks)
- return 0;
+ return 0;
if ((ctx1->finfo.filetype != 0) && (ctx2->finfo.filetype != 0)
&& (ctx1->finfo.valid & ctx2->finfo.valid & APR_FINFO_INODE)) {
apr_size_t len2;
if (res1->hooks != res2->hooks)
- return 0;
+ return 0;
/* it is safe to use ctx2 now */
len2 = strlen(ctx2->pathname);
}
static dav_error * dav_fs_open_stream(const dav_resource *resource,
- dav_stream_mode mode,
- dav_stream **stream)
+ dav_stream_mode mode,
+ dav_stream **stream)
{
apr_pool_t *p = resource->info->pool;
dav_stream *ds = apr_pcalloc(p, sizeof(*ds));
switch (mode) {
default:
- flags = APR_READ | APR_BINARY;
- break;
+ flags = APR_READ | APR_BINARY;
+ break;
case DAV_MODE_WRITE_TRUNC:
- flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY;
- break;
+ flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY;
+ break;
case DAV_MODE_WRITE_SEEKABLE:
- flags = APR_WRITE | APR_CREATE | APR_BINARY;
- break;
+ flags = APR_WRITE | APR_CREATE | APR_BINARY;
+ break;
}
ds->p = p;
ds->pathname = resource->info->pathname;
if (apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT,
- ds->p) != APR_SUCCESS) {
- /* ### use something besides 500? */
- return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "An error occurred while opening a resource.");
+ ds->p) != APR_SUCCESS) {
+ /* ### use something besides 500? */
+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "An error occurred while opening a resource.");
}
/* (APR registers cleanups for the fd with the pool) */
apr_file_close(stream->f);
if (!commit) {
- if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
- /* ### use a better description? */
+ if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
+ /* ### use a better description? */
return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "There was a problem removing (rolling "
- "back) the resource "
- "when it was being closed.");
- }
+ "There was a problem removing (rolling "
+ "back) the resource "
+ "when it was being closed.");
+ }
}
return NULL;
}
static dav_error * dav_fs_write_stream(dav_stream *stream,
- const void *buf, apr_size_t bufsize)
+ const void *buf, apr_size_t bufsize)
{
apr_status_t status;
"this resource.");
}
else if (status != APR_SUCCESS) {
- /* ### use something besides 500? */
- return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "An error occurred while writing to a "
- "resource.");
+ /* ### use something besides 500? */
+ return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "An error occurred while writing to a "
+ "resource.");
}
return NULL;
}
static dav_error * dav_fs_seek_stream(dav_stream *stream, apr_off_t abs_pos)
{
if (apr_file_seek(stream->f, APR_SET, &abs_pos) != APR_SUCCESS) {
- /* ### should check whether apr_file_seek set abs_pos was set to the
- * correct position? */
- /* ### use something besides 500? */
- return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not seek to specified position in the "
- "resource.");
+ /* ### should check whether apr_file_seek set abs_pos was set to the
+ * correct position? */
+ /* ### use something besides 500? */
+ return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not seek to specified position in the "
+ "resource.");
}
return NULL;
}
static dav_error * dav_fs_set_headers(request_rec *r,
- const dav_resource *resource)
+ const dav_resource *resource)
{
/* ### this function isn't really used since we have a get_pathname */
if (!resource->exists)
- return NULL;
+ return NULL;
/* make sure the proper mtime is in the request record */
ap_update_mtime(r, resource->info->finfo.mtime);
status = apr_dir_make(ctx->pathname, APR_OS_DEFAULT, ctx->pool);
if (status == ENOSPC) {
return dav_new_error(ctx->pool, HTTP_INSUFFICIENT_STORAGE, 0,
- "There is not enough storage to create "
- "this collection.");
+ "There is not enough storage to create "
+ "this collection.");
}
else if (status != APR_SUCCESS) {
- /* ### refine this error message? */
+ /* ### refine this error message? */
return dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0,
"Unable to create collection.");
}
dav_error *err = NULL;
if (wres->resource->collection) {
- if (calltype == DAV_CALLTYPE_POSTFIX) {
- /* Postfix call for MOVE. delete the source dir.
- * Note: when copying, we do not enable the postfix-traversal.
- */
- /* ### we are ignoring any error here; what should we do? */
- (void) apr_dir_remove(srcinfo->pathname, ctx->pool);
- }
+ if (calltype == DAV_CALLTYPE_POSTFIX) {
+ /* Postfix call for MOVE. delete the source dir.
+ * Note: when copying, we do not enable the postfix-traversal.
+ */
+ /* ### we are ignoring any error here; what should we do? */
+ (void) apr_dir_remove(srcinfo->pathname, ctx->pool);
+ }
else {
- /* copy/move of a collection. Create the new, target collection */
+ /* copy/move of a collection. Create the new, target collection */
if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT,
ctx->pool) != APR_SUCCESS) {
- /* ### assume it was a permissions problem */
- /* ### need a description here */
+ /* ### assume it was a permissions problem */
+ /* ### need a description here */
err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL);
}
- }
+ }
}
else {
- err = dav_fs_copymove_file(ctx->is_move, ctx->pool,
- srcinfo->pathname, dstinfo->pathname,
- &ctx->work_buf);
- /* ### push a higher-level description? */
+ err = dav_fs_copymove_file(ctx->is_move, ctx->pool,
+ srcinfo->pathname, dstinfo->pathname,
+ &ctx->work_buf);
+ /* ### push a higher-level description? */
}
/*
*/
if (err != NULL
&& !ap_is_HTTP_SERVER_ERROR(err->status)
- && (ctx->is_move
+ && (ctx->is_move
|| !dav_fs_is_same_resource(wres->resource, ctx->root))) {
- /* ### use errno to generate DAV:responsedescription? */
- dav_add_response(wres, err->status, NULL);
+ /* ### use errno to generate DAV:responsedescription? */
+ dav_add_response(wres, err->status, NULL);
/* the error is in the multistatus now. do not stop the traversal. */
return NULL;
dav_walk_params params = { 0 };
dav_response *multi_status;
- params.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_HIDDEN;
- params.func = dav_fs_copymove_walker;
- params.pool = src->info->pool;
- params.root = src;
+ params.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_HIDDEN;
+ params.func = dav_fs_copymove_walker;
+ params.pool = src->info->pool;
+ params.root = src;
/* params.walk_ctx is managed by dav_fs_internal_walk() */
- /* postfix is needed for MOVE to delete source dirs */
+ /* postfix is needed for MOVE to delete source dirs */
if (is_move)
params.walk_type |= DAV_WALKTYPE_POSTFIX;
/* note that we return the error OR the multistatus. never both */
- if ((err = dav_fs_internal_walk(¶ms, depth, is_move, dst,
+ if ((err = dav_fs_internal_walk(¶ms, depth, is_move, dst,
&multi_status)) != NULL) {
/* on a "real" error, then just punt. nothing else to do. */
return err;
"the COPY/MOVE process.");
}
- return NULL;
+ return NULL;
}
/* not a collection */
if ((err = dav_fs_copymove_file(is_move, src->info->pool,
- src->info->pathname, dst->info->pathname,
- &work_buf)) != NULL) {
- /* ### push a higher-level description? */
- return err;
+ src->info->pathname, dst->info->pathname,
+ &work_buf)) != NULL) {
+ /* ### push a higher-level description? */
+ return err;
}
-
+
/* copy/move properties as well */
return dav_fs_copymoveset(is_move, src->info->pool, src, dst, &work_buf);
}
#if DAV_DEBUG
if (src->hooks != dst->hooks) {
- /*
- ** ### strictly speaking, this is a design error; we should not
- ** ### have reached this point.
- */
- return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: a mix of repositories "
- "was passed to copy_resource.");
+ /*
+ ** ### strictly speaking, this is a design error; we should not
+ ** ### have reached this point.
+ */
+ return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "DESIGN ERROR: a mix of repositories "
+ "was passed to copy_resource.");
}
#endif
if ((err = dav_fs_copymove_resource(0, src, dst, depth,
- response)) == NULL) {
+ response)) == NULL) {
/* update state of destination resource to show it exists */
dst->exists = 1;
#if DAV_DEBUG
if (src->hooks != dst->hooks) {
- /*
- ** ### strictly speaking, this is a design error; we should not
- ** ### have reached this point.
- */
- return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: a mix of repositories "
- "was passed to move_resource.");
+ /*
+ ** ### strictly speaking, this is a design error; we should not
+ ** ### have reached this point.
+ */
+ return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "DESIGN ERROR: a mix of repositories "
+ "was passed to move_resource.");
}
#endif
* Assume source exists, else we wouldn't get called.
*/
if (dstinfo->finfo.filetype != 0) {
- if (dstinfo->finfo.device == srcinfo->finfo.device) {
- /* target exists and is on the same device. */
- can_rename = 1;
- }
+ if (dstinfo->finfo.device == srcinfo->finfo.device) {
+ /* target exists and is on the same device. */
+ can_rename = 1;
+ }
}
else {
- const char *dirpath;
- apr_finfo_t finfo;
+ const char *dirpath;
+ apr_finfo_t finfo;
apr_status_t rv;
- /* destination does not exist, but the parent directory should,
- * so try it
- */
- dirpath = ap_make_dirstr_parent(dstinfo->pool, dstinfo->pathname);
+ /* destination does not exist, but the parent directory should,
+ * so try it
+ */
+ dirpath = ap_make_dirstr_parent(dstinfo->pool, dstinfo->pathname);
/*
* XXX: If missing dev ... then what test?
* Really need a try and failover for those platforms.
*
*/
rv = apr_stat(&finfo, dirpath, APR_FINFO_DEV, dstinfo->pool);
- if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)
+ if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE)
&& (finfo.valid & srcinfo->finfo.valid & APR_FINFO_DEV)
- && (finfo.device == srcinfo->finfo.device)) {
- can_rename = 1;
- }
+ && (finfo.device == srcinfo->finfo.device)) {
+ can_rename = 1;
+ }
}
/* if we can't simply rename, then do it the hard way... */
/* ### APR has no rename? */
if (apr_file_rename(srcinfo->pathname, dstinfo->pathname,
srcinfo->pool) != APR_SUCCESS) {
- /* ### should have a better error than this. */
- return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not rename resource.");
+ /* ### should have a better error than this. */
+ return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not rename resource.");
}
/* update resource states */
src->collection = 0;
if ((err = dav_fs_copymoveset(1, src->info->pool,
- src, dst, NULL)) == NULL) {
- /* no error. we're done. go ahead and return now. */
- return NULL;
+ src, dst, NULL)) == NULL) {
+ /* no error. we're done. go ahead and return now. */
+ return NULL;
}
/* error occurred during properties move; try to put resource back */
if (apr_file_rename(dstinfo->pathname, srcinfo->pathname,
srcinfo->pool) != APR_SUCCESS) {
- /* couldn't put it back! */
- return dav_push_error(srcinfo->pool,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "The resource was moved, but a failure "
- "occurred during the move of its "
- "properties. The resource could not be "
- "restored to its original location. The "
- "server is now in an inconsistent state.",
- err);
+ /* couldn't put it back! */
+ return dav_push_error(srcinfo->pool,
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "The resource was moved, but a failure "
+ "occurred during the move of its "
+ "properties. The resource could not be "
+ "restored to its original location. The "
+ "server is now in an inconsistent state.",
+ err);
}
/* update resource states again */
/* resource moved back, but properties may be inconsistent */
return dav_push_error(srcinfo->pool,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "The resource was moved, but a failure "
- "occurred during the move of its properties. "
- "The resource was moved back to its original "
- "location, but its properties may have been "
- "partially moved. The server may be in an "
- "inconsistent state.",
- err);
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "The resource was moved, but a failure "
+ "occurred during the move of its properties. "
+ "The resource was moved back to its original "
+ "location, but its properties may have been "
+ "partially moved. The server may be in an "
+ "inconsistent state.",
+ err);
}
static dav_error * dav_fs_delete_walker(dav_walk_resource *wres, int calltype)
*/
if (wres->resource->exists &&
(!wres->resource->collection || calltype == DAV_CALLTYPE_POSTFIX)) {
- /* try to remove the resource */
- apr_status_t result;
+ /* try to remove the resource */
+ apr_status_t result;
- result = wres->resource->collection
- ? apr_dir_remove(info->pathname, wres->pool)
- : apr_file_remove(info->pathname, wres->pool);
+ result = wres->resource->collection
+ ? apr_dir_remove(info->pathname, wres->pool)
+ : apr_file_remove(info->pathname, wres->pool);
- /*
+ /*
** If an error occurred, then add it to multistatus response.
** Note that we add it for the root resource, too. It is quite
** possible to delete the whole darn tree, yet fail on the root.
**
** (also: remember we are deleting via a postfix traversal)
*/
- if (result != APR_SUCCESS) {
+ if (result != APR_SUCCESS) {
/* ### assume there is a permissions problem */
/* ### use errno to generate DAV:responsedescription? */
dav_add_response(wres, HTTP_FORBIDDEN, NULL);
- }
+ }
}
return NULL;
*/
if (resource->collection) {
dav_walk_params params = { 0 };
- dav_error *err = NULL;
+ dav_error *err = NULL;
dav_response *multi_status;
- params.walk_type = (DAV_WALKTYPE_NORMAL
+ params.walk_type = (DAV_WALKTYPE_NORMAL
| DAV_WALKTYPE_HIDDEN
| DAV_WALKTYPE_POSTFIX);
- params.func = dav_fs_delete_walker;
- params.pool = info->pool;
- params.root = resource;
+ params.func = dav_fs_delete_walker;
+ params.pool = info->pool;
+ params.root = resource;
- if ((err = dav_fs_walk(¶ms, DAV_INFINITY,
+ if ((err = dav_fs_walk(¶ms, DAV_INFINITY,
&multi_status)) != NULL) {
/* on a "real" error, then just punt. nothing else to do. */
return err;
resource->exists = 0;
resource->collection = 0;
- return NULL;
+ return NULL;
}
/* not a collection; remove the file and its properties */
if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) {
- /* ### put a description in here */
- return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);
+ /* ### put a description in here */
+ return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL);
}
/* update resource state */
? DAV_CALLTYPE_COLLECTION
: DAV_CALLTYPE_MEMBER);
if (err != NULL) {
- return err;
+ return err;
}
if (depth == 0 || !isdir) {
- return NULL;
+ return NULL;
}
/* put a trailing slash onto the directory, in preparation for appending
* files to it as we discovery them within the directory */
dav_check_bufsize(pool, &fsctx->path1, DAV_BUFFER_PAD);
fsctx->path1.buf[fsctx->path1.cur_len++] = '/';
- fsctx->path1.buf[fsctx->path1.cur_len] = '\0'; /* in pad area */
+ fsctx->path1.buf[fsctx->path1.cur_len] = '\0'; /* in pad area */
/* if a secondary path is present, then do that, too */
if (fsctx->path2.buf != NULL) {
- dav_check_bufsize(pool, &fsctx->path2, DAV_BUFFER_PAD);
- fsctx->path2.buf[fsctx->path2.cur_len++] = '/';
- fsctx->path2.buf[fsctx->path2.cur_len] = '\0'; /* in pad area */
+ dav_check_bufsize(pool, &fsctx->path2, DAV_BUFFER_PAD);
+ fsctx->path2.buf[fsctx->path2.cur_len++] = '/';
+ fsctx->path2.buf[fsctx->path2.cur_len] = '\0'; /* in pad area */
}
/* Note: the URI should ALREADY have a trailing "/" */
/* open and scan the directory */
if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) {
- /* ### need a better error */
- return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
+ /* ### need a better error */
+ return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
}
while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
- apr_size_t len;
+ apr_size_t len;
apr_status_t status;
- len = strlen(dirent.name);
+ len = strlen(dirent.name);
- /* avoid recursing into our current, parent, or state directories */
- if (dirent.name[0] == '.'
+ /* avoid recursing into our current, parent, or state directories */
+ if (dirent.name[0] == '.'
&& (len == 1 || (dirent.name[1] == '.' && len == 2))) {
- continue;
- }
+ continue;
+ }
- if (params->walk_type & DAV_WALKTYPE_AUTH) {
- /* ### need to authorize each file */
- /* ### example: .htaccess is normally configured to fail auth */
+ if (params->walk_type & DAV_WALKTYPE_AUTH) {
+ /* ### need to authorize each file */
+ /* ### example: .htaccess is normally configured to fail auth */
- /* stuff in the state directory is never authorized! */
- if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) {
- continue;
- }
- }
- /* skip the state dir unless a HIDDEN is performed */
- if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
- && !strcmp(dirent.name, DAV_FS_STATE_DIR)) {
- continue;
- }
+ /* stuff in the state directory is never authorized! */
+ if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) {
+ continue;
+ }
+ }
+ /* skip the state dir unless a HIDDEN is performed */
+ if (!(params->walk_type & DAV_WALKTYPE_HIDDEN)
+ && !strcmp(dirent.name, DAV_FS_STATE_DIR)) {
+ continue;
+ }
- /* append this file onto the path buffer (copy null term) */
- dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);
+ /* append this file onto the path buffer (copy null term) */
+ dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0);
/* ### Optimize me, dirent can give us what we need! */
status = apr_lstat(&fsctx->info1.finfo, fsctx->path1.buf,
APR_FINFO_NORM, pool);
if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
- /* woah! where'd it go? */
- /* ### should have a better error here */
- err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
- break;
- }
-
- /* copy the file to the URI, too. NOTE: we will pad an extra byte
- for the trailing slash later. */
- dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1);
-
- /* if there is a secondary path, then do that, too */
- if (fsctx->path2.buf != NULL) {
- dav_buffer_place_mem(pool, &fsctx->path2, dirent.name, len + 1, 0);
- }
-
- /* set up the (internal) pathnames for the two resources */
- fsctx->info1.pathname = fsctx->path1.buf;
- fsctx->info2.pathname = fsctx->path2.buf;
-
- /* set up the URI for the current resource */
- fsctx->res1.uri = fsctx->uri_buf.buf;
-
- /* ### for now, only process regular files (e.g. skip symlinks) */
- if (fsctx->info1.finfo.filetype == APR_REG) {
- /* call the function for the specified dir + file */
- if ((err = (*params->func)(&fsctx->wres,
+ /* woah! where'd it go? */
+ /* ### should have a better error here */
+ err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL);
+ break;
+ }
+
+ /* copy the file to the URI, too. NOTE: we will pad an extra byte
+ for the trailing slash later. */
+ dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1);
+
+ /* if there is a secondary path, then do that, too */
+ if (fsctx->path2.buf != NULL) {
+ dav_buffer_place_mem(pool, &fsctx->path2, dirent.name, len + 1, 0);
+ }
+
+ /* set up the (internal) pathnames for the two resources */
+ fsctx->info1.pathname = fsctx->path1.buf;
+ fsctx->info2.pathname = fsctx->path2.buf;
+
+ /* set up the URI for the current resource */
+ fsctx->res1.uri = fsctx->uri_buf.buf;
+
+ /* ### for now, only process regular files (e.g. skip symlinks) */
+ if (fsctx->info1.finfo.filetype == APR_REG) {
+ /* call the function for the specified dir + file */
+ if ((err = (*params->func)(&fsctx->wres,
DAV_CALLTYPE_MEMBER)) != NULL) {
- /* ### maybe add a higher-level description? */
- break;
- }
- }
- else if (fsctx->info1.finfo.filetype == APR_DIR) {
- apr_size_t save_path_len = fsctx->path1.cur_len;
- apr_size_t save_uri_len = fsctx->uri_buf.cur_len;
- apr_size_t save_path2_len = fsctx->path2.cur_len;
-
- /* adjust length to incorporate the subdir name */
- fsctx->path1.cur_len += len;
- fsctx->path2.cur_len += len;
-
- /* adjust URI length to incorporate subdir and a slash */
- fsctx->uri_buf.cur_len += len + 1;
- fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/';
- fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0';
-
- /* switch over to a collection */
- fsctx->res1.collection = 1;
- fsctx->res2.collection = 1;
-
- /* recurse on the subdir */
- /* ### don't always want to quit on error from single child */
- if ((err = dav_fs_walker(fsctx, depth - 1)) != NULL) {
- /* ### maybe add a higher-level description? */
- break;
- }
-
- /* put the various information back */
- fsctx->path1.cur_len = save_path_len;
- fsctx->path2.cur_len = save_path2_len;
- fsctx->uri_buf.cur_len = save_uri_len;
-
- fsctx->res1.collection = 0;
- fsctx->res2.collection = 0;
-
- /* assert: res1.exists == 1 */
- }
+ /* ### maybe add a higher-level description? */
+ break;
+ }
+ }
+ else if (fsctx->info1.finfo.filetype == APR_DIR) {
+ apr_size_t save_path_len = fsctx->path1.cur_len;
+ apr_size_t save_uri_len = fsctx->uri_buf.cur_len;
+ apr_size_t save_path2_len = fsctx->path2.cur_len;
+
+ /* adjust length to incorporate the subdir name */
+ fsctx->path1.cur_len += len;
+ fsctx->path2.cur_len += len;
+
+ /* adjust URI length to incorporate subdir and a slash */
+ fsctx->uri_buf.cur_len += len + 1;
+ fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/';
+ fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0';
+
+ /* switch over to a collection */
+ fsctx->res1.collection = 1;
+ fsctx->res2.collection = 1;
+
+ /* recurse on the subdir */
+ /* ### don't always want to quit on error from single child */
+ if ((err = dav_fs_walker(fsctx, depth - 1)) != NULL) {
+ /* ### maybe add a higher-level description? */
+ break;
+ }
+
+ /* put the various information back */
+ fsctx->path1.cur_len = save_path_len;
+ fsctx->path2.cur_len = save_path2_len;
+ fsctx->uri_buf.cur_len = save_uri_len;
+
+ fsctx->res1.collection = 0;
+ fsctx->res2.collection = 0;
+
+ /* assert: res1.exists == 1 */
+ }
}
/* ### check the return value of this? */
apr_dir_close(dirp);
if (err != NULL)
- return err;
+ return err;
if (params->walk_type & DAV_WALKTYPE_LOCKNULL) {
- apr_size_t offset = 0;
+ apr_size_t offset = 0;
- /* null terminate the directory name */
- fsctx->path1.buf[fsctx->path1.cur_len - 1] = '\0';
+ /* null terminate the directory name */
+ fsctx->path1.buf[fsctx->path1.cur_len - 1] = '\0';
- /* Include any lock null resources found in this collection */
- fsctx->res1.collection = 1;
- if ((err = dav_fs_get_locknull_members(&fsctx->res1,
+ /* Include any lock null resources found in this collection */
+ fsctx->res1.collection = 1;
+ if ((err = dav_fs_get_locknull_members(&fsctx->res1,
&fsctx->locknull_buf)) != NULL) {
/* ### maybe add a higher-level description? */
return err;
- }
-
- /* put a slash back on the end of the directory */
- fsctx->path1.buf[fsctx->path1.cur_len - 1] = '/';
-
- /* these are all non-existant (files) */
- fsctx->res1.exists = 0;
- fsctx->res1.collection = 0;
- memset(&fsctx->info1.finfo, 0, sizeof(fsctx->info1.finfo));
-
- while (offset < fsctx->locknull_buf.cur_len) {
- apr_size_t len = strlen(fsctx->locknull_buf.buf + offset);
- dav_lock *locks = NULL;
-
- /*
- ** Append the locknull file to the paths and the URI. Note that
- ** we don't have to pad the URI for a slash since a locknull
- ** resource is not a collection.
- */
- dav_buffer_place_mem(pool, &fsctx->path1,
- fsctx->locknull_buf.buf + offset, len + 1, 0);
- dav_buffer_place_mem(pool, &fsctx->uri_buf,
- fsctx->locknull_buf.buf + offset, len + 1, 0);
- if (fsctx->path2.buf != NULL) {
- dav_buffer_place_mem(pool, &fsctx->path2,
- fsctx->locknull_buf.buf + offset,
+ }
+
+ /* put a slash back on the end of the directory */
+ fsctx->path1.buf[fsctx->path1.cur_len - 1] = '/';
+
+ /* these are all non-existant (files) */
+ fsctx->res1.exists = 0;
+ fsctx->res1.collection = 0;
+ memset(&fsctx->info1.finfo, 0, sizeof(fsctx->info1.finfo));
+
+ while (offset < fsctx->locknull_buf.cur_len) {
+ apr_size_t len = strlen(fsctx->locknull_buf.buf + offset);
+ dav_lock *locks = NULL;
+
+ /*
+ ** Append the locknull file to the paths and the URI. Note that
+ ** we don't have to pad the URI for a slash since a locknull
+ ** resource is not a collection.
+ */
+ dav_buffer_place_mem(pool, &fsctx->path1,
+ fsctx->locknull_buf.buf + offset, len + 1, 0);
+ dav_buffer_place_mem(pool, &fsctx->uri_buf,
+ fsctx->locknull_buf.buf + offset, len + 1, 0);
+ if (fsctx->path2.buf != NULL) {
+ dav_buffer_place_mem(pool, &fsctx->path2,
+ fsctx->locknull_buf.buf + offset,
len + 1, 0);
- }
-
- /* set up the (internal) pathnames for the two resources */
- fsctx->info1.pathname = fsctx->path1.buf;
- fsctx->info2.pathname = fsctx->path2.buf;
-
- /* set up the URI for the current resource */
- fsctx->res1.uri = fsctx->uri_buf.buf;
-
- /*
- ** To prevent a PROPFIND showing an expired locknull
- ** resource, query the lock database to force removal
- ** of both the lock entry and .locknull, if necessary..
- ** Sure, the query in PROPFIND would do this.. after
- ** the locknull resource was already included in the
- ** return.
- **
- ** NOTE: we assume the caller has opened the lock database
- ** if they have provided DAV_WALKTYPE_LOCKNULL.
- */
- /* ### we should also look into opening it read-only and
- ### eliding timed-out items from the walk, yet leaving
- ### them in the locknull database until somebody opens
- ### the thing writable.
- */
- /* ### probably ought to use has_locks. note the problem
- ### mentioned above, though... we would traverse this as
- ### a locknull, but then a PROPFIND would load the lock
- ### info, causing a timeout and the locks would not be
- ### reported. Therefore, a null resource would be returned
- ### in the PROPFIND.
- ###
- ### alternative: just load unresolved locks. any direct
- ### locks will be timed out (correct). any indirect will
- ### not (correct; consider if a parent timed out -- the
- ### timeout routines do not walk and remove indirects;
- ### even the resolve func would probably fail when it
- ### tried to find a timed-out direct lock).
- */
- if ((err = dav_lock_query(params->lockdb, &fsctx->res1,
+ }
+
+ /* set up the (internal) pathnames for the two resources */
+ fsctx->info1.pathname = fsctx->path1.buf;
+ fsctx->info2.pathname = fsctx->path2.buf;
+
+ /* set up the URI for the current resource */
+ fsctx->res1.uri = fsctx->uri_buf.buf;
+
+ /*
+ ** To prevent a PROPFIND showing an expired locknull
+ ** resource, query the lock database to force removal
+ ** of both the lock entry and .locknull, if necessary..
+ ** Sure, the query in PROPFIND would do this.. after
+ ** the locknull resource was already included in the
+ ** return.
+ **
+ ** NOTE: we assume the caller has opened the lock database
+ ** if they have provided DAV_WALKTYPE_LOCKNULL.
+ */
+ /* ### we should also look into opening it read-only and
+ ### eliding timed-out items from the walk, yet leaving
+ ### them in the locknull database until somebody opens
+ ### the thing writable.
+ */
+ /* ### probably ought to use has_locks. note the problem
+ ### mentioned above, though... we would traverse this as
+ ### a locknull, but then a PROPFIND would load the lock
+ ### info, causing a timeout and the locks would not be
+ ### reported. Therefore, a null resource would be returned
+ ### in the PROPFIND.
+ ###
+ ### alternative: just load unresolved locks. any direct
+ ### locks will be timed out (correct). any indirect will
+ ### not (correct; consider if a parent timed out -- the
+ ### timeout routines do not walk and remove indirects;
+ ### even the resolve func would probably fail when it
+ ### tried to find a timed-out direct lock).
+ */
+ if ((err = dav_lock_query(params->lockdb, &fsctx->res1,
&locks)) != NULL) {
- /* ### maybe add a higher-level description? */
- return err;
- }
+ /* ### maybe add a higher-level description? */
+ return err;
+ }
- /* call the function for the specified dir + file */
- if (locks != NULL &&
- (err = (*params->func)(&fsctx->wres,
+ /* call the function for the specified dir + file */
+ if (locks != NULL &&
+ (err = (*params->func)(&fsctx->wres,
DAV_CALLTYPE_LOCKNULL)) != NULL) {
- /* ### maybe add a higher-level description? */
- return err;
- }
+ /* ### maybe add a higher-level description? */
+ return err;
+ }
- offset += len + 1;
- }
+ offset += len + 1;
+ }
- /* reset the exists flag */
- fsctx->res1.exists = 1;
+ /* reset the exists flag */
+ fsctx->res1.exists = 1;
}
if (params->walk_type & DAV_WALKTYPE_POSTFIX) {
- /* replace the dirs' trailing slashes with null terms */
- fsctx->path1.buf[--fsctx->path1.cur_len] = '\0';
- fsctx->uri_buf.buf[--fsctx->uri_buf.cur_len] = '\0';
- if (fsctx->path2.buf != NULL) {
- fsctx->path2.buf[--fsctx->path2.cur_len] = '\0';
- }
+ /* replace the dirs' trailing slashes with null terms */
+ fsctx->path1.buf[--fsctx->path1.cur_len] = '\0';
+ fsctx->uri_buf.buf[--fsctx->uri_buf.cur_len] = '\0';
+ if (fsctx->path2.buf != NULL) {
+ fsctx->path2.buf[--fsctx->path2.cur_len] = '\0';
+ }
- /* this is a collection which exists */
- fsctx->res1.collection = 1;
+ /* this is a collection which exists */
+ fsctx->res1.collection = 1;
- return (*params->func)(&fsctx->wres, DAV_CALLTYPE_POSTFIX);
+ return (*params->func)(&fsctx->wres, DAV_CALLTYPE_POSTFIX);
}
return NULL;
#if DAV_DEBUG
if ((params->walk_type & DAV_WALKTYPE_LOCKNULL) != 0
- && params->lockdb == NULL) {
- return dav_new_error(params->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: walker called to walk locknull "
- "resources, but a lockdb was not provided.");
+ && params->lockdb == NULL) {
+ return dav_new_error(params->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "DESIGN ERROR: walker called to walk locknull "
+ "resources, but a lockdb was not provided.");
}
#endif
cm_ctx.root = params->root;
cm_ctx.pool = params->pool;
- fsctx.res2 = *root_dst;
- fsctx.res2.exists = 0;
- fsctx.res2.collection = 0;
+ fsctx.res2 = *root_dst;
+ fsctx.res2.exists = 0;
+ fsctx.res2.collection = 0;
fsctx.res2.uri = NULL; /* we don't track this */
fsctx.res2.pool = params->pool;
- fsctx.res2.info = &fsctx.info2;
- fsctx.info2 = *root_dst->info;
+ fsctx.res2.info = &fsctx.info2;
+ fsctx.info2 = *root_dst->info;
- /* res2 does not exist -- clear its finfo structure */
- memset(&fsctx.info2.finfo, 0, sizeof(fsctx.info2.finfo));
+ /* res2 does not exist -- clear its finfo structure */
+ memset(&fsctx.info2.finfo, 0, sizeof(fsctx.info2.finfo));
/* the pathname is stored in the path2 buffer */
- dav_buffer_init(params->pool, &fsctx.path2, fsctx.info2.pathname);
- fsctx.info2.pathname = fsctx.path2.buf;
+ dav_buffer_init(params->pool, &fsctx.path2, fsctx.info2.pathname);
+ fsctx.info2.pathname = fsctx.path2.buf;
}
/* prep the URI buffer */
/* if we have a directory, then ensure the URI has a trailing "/" */
if (fsctx.res1.collection
- && fsctx.uri_buf.buf[fsctx.uri_buf.cur_len - 1] != '/') {
+ && fsctx.uri_buf.buf[fsctx.uri_buf.cur_len - 1] != '/') {
- /* this will fall into the pad area */
- fsctx.uri_buf.buf[fsctx.uri_buf.cur_len++] = '/';
- fsctx.uri_buf.buf[fsctx.uri_buf.cur_len] = '\0';
+ /* this will fall into the pad area */
+ fsctx.uri_buf.buf[fsctx.uri_buf.cur_len++] = '/';
+ fsctx.uri_buf.buf[fsctx.uri_buf.cur_len] = '\0';
}
/* the current resource's URI is stored in the uri_buf buffer */
dav_resource_private *ctx = resource->info;
if (!resource->exists)
- return apr_pstrdup(ctx->pool, "");
+ return apr_pstrdup(ctx->pool, "");
if (ctx->finfo.filetype != 0) {
return apr_psprintf(ctx->pool, "\"%lx-%lx-%lx\"",
- (unsigned long) ctx->finfo.inode,
- (unsigned long) ctx->finfo.size,
- (unsigned long) ctx->finfo.mtime);
+ (unsigned long) ctx->finfo.inode,
+ (unsigned long) ctx->finfo.size,
+ (unsigned long) ctx->finfo.mtime);
}
return apr_psprintf(ctx->pool, "\"%lx\"", (unsigned long) ctx->finfo.mtime);
};
static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource,
- int propid, dav_prop_insert what,
- apr_text_header *phdr)
+ int propid, dav_prop_insert what,
+ apr_text_header *phdr)
{
const char *value;
const char *s;
** hook function.
*/
if (!resource->exists)
- return DAV_PROP_INSERT_NOTDEF;
+ return DAV_PROP_INSERT_NOTDEF;
switch (propid) {
case DAV_PROPID_creationdate:
- /*
- ** Closest thing to a creation date. since we don't actually
- ** perform the operations that would modify ctime (after we
- ** create the file), then we should be pretty safe here.
- */
- dav_format_time(DAV_STYLE_ISO8601,
+ /*
+ ** Closest thing to a creation date. since we don't actually
+ ** perform the operations that would modify ctime (after we
+ ** create the file), then we should be pretty safe here.
+ */
+ dav_format_time(DAV_STYLE_ISO8601,
resource->info->finfo.ctime,
buf);
- value = buf;
- break;
+ value = buf;
+ break;
case DAV_PROPID_getcontentlength:
- /* our property, but not defined on collection resources */
- if (resource->collection)
- return DAV_PROP_INSERT_NOTDEF;
+ /* our property, but not defined on collection resources */
+ if (resource->collection)
+ return DAV_PROP_INSERT_NOTDEF;
- (void) sprintf(buf, "%" APR_OFF_T_FMT, resource->info->finfo.size);
- value = buf;
- break;
+ (void) sprintf(buf, "%" APR_OFF_T_FMT, resource->info->finfo.size);
+ value = buf;
+ break;
case DAV_PROPID_getetag:
- value = dav_fs_getetag(resource);
- break;
+ value = dav_fs_getetag(resource);
+ break;
case DAV_PROPID_getlastmodified:
- dav_format_time(DAV_STYLE_RFC822,
+ dav_format_time(DAV_STYLE_RFC822,
resource->info->finfo.mtime,
buf);
- value = buf;
- break;
+ value = buf;
+ break;
case DAV_PROPID_FS_executable:
- /* our property, but not defined on collection resources */
- if (resource->collection)
- return DAV_PROP_INSERT_NOTDEF;
+ /* our property, but not defined on collection resources */
+ if (resource->collection)
+ return DAV_PROP_INSERT_NOTDEF;
/* our property, but not defined on this platform */
if (!(resource->info->finfo.valid & APR_FINFO_UPROT))
return DAV_PROP_INSERT_NOTDEF;
/* the files are "ours" so we only need to check owner exec privs */
- if (resource->info->finfo.protection & APR_UEXECUTE)
- value = "T";
- else
- value = "F";
- break;
+ if (resource->info->finfo.protection & APR_UEXECUTE)
+ value = "T";
+ else
+ value = "F";
+ break;
default:
/* ### what the heck was this property? */
- return DAV_PROP_INSERT_NOTDEF;
+ return DAV_PROP_INSERT_NOTDEF;
}
/* assert: value != NULL */
/* 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%d:%s>%s</lp%d:%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%d:%s/>" DEBUG_CR, global_ns, info->name);
}
else {
/* assert: what == DAV_PROP_INSERT_SUPPORTED */
/* if we have the executable property, and this isn't a collection,
then the property is writable. */
if (propid == DAV_PROPID_FS_executable && !resource->collection)
- return 1;
+ return 1;
#endif
(void) dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info);
}
static dav_error *dav_fs_patch_validate(const dav_resource *resource,
- const apr_xml_elem *elem,
- int operation,
- void **context,
- int *defer_to_dead)
+ const apr_xml_elem *elem,
+ int operation,
+ void **context,
+ int *defer_to_dead)
{
const apr_text *cdata;
const apr_text *f_cdata;
dav_elem_private *priv = elem->priv;
if (priv->propid != DAV_PROPID_FS_executable) {
- *defer_to_dead = 1;
- return NULL;
+ *defer_to_dead = 1;
+ return NULL;
}
if (operation == DAV_PROP_OP_DELETE) {
- return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
- "The 'executable' property cannot be removed.");
+ return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+ "The 'executable' property cannot be removed.");
}
cdata = elem->first_cdata.first;
/* ### hmm. this isn't actually looking at all the possible text items */
f_cdata = elem->first_child == NULL
- ? NULL
- : elem->first_child->following_cdata.first;
+ ? NULL
+ : elem->first_child->following_cdata.first;
/* DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); */
if (cdata == NULL) {
- if (f_cdata == NULL) {
- return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
- "The 'executable' property expects a single "
- "character, valued 'T' or 'F'. There was no "
- "value submitted.");
- }
- cdata = f_cdata;
+ if (f_cdata == NULL) {
+ return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+ "The 'executable' property expects a single "
+ "character, valued 'T' or 'F'. There was no "
+ "value submitted.");
+ }
+ cdata = f_cdata;
}
else if (f_cdata != NULL)
- goto too_long;
+ goto too_long;
if (cdata->next != NULL || strlen(cdata->text) != 1)
- goto too_long;
+ goto too_long;
value = cdata->text[0];
if (value != 'T' && value != 'F') {
- return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
- "The 'executable' property expects a single "
- "character, valued 'T' or 'F'. The value "
- "submitted is invalid.");
+ return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
+ "The 'executable' property expects a single "
+ "character, valued 'T' or 'F'. The value "
+ "submitted is invalid.");
}
*context = (void *)(value == 'T');
too_long:
return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0,
- "The 'executable' property expects a single "
- "character, valued 'T' or 'F'. The value submitted "
- "has too many characters.");
+ "The 'executable' property expects a single "
+ "character, valued 'T' or 'F'. The value submitted "
+ "has too many characters.");
}
static dav_error *dav_fs_patch_exec(const dav_resource *resource,
- const apr_xml_elem *elem,
- int operation,
- void *context,
- dav_liveprop_rollback **rollback_ctx)
+ const apr_xml_elem *elem,
+ int operation,
+ void *context,
+ dav_liveprop_rollback **rollback_ctx)
{
int value = context != NULL;
apr_fileperms_t perms = resource->info->finfo.protection;
/* don't do anything if there is no change. no rollback info either. */
/* DBG2("new value=%d (old=%d)", value, old_value); */
if (value == old_value)
- return NULL;
+ return NULL;
perms &= ~APR_UEXECUTE;
if (value)
- perms |= APR_UEXECUTE;
+ perms |= APR_UEXECUTE;
if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) {
- return dav_new_error(resource->info->pool,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not set the executable flag of the "
- "target resource.");
+ return dav_new_error(resource->info->pool,
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not set the executable flag of the "
+ "target resource.");
}
/* update the resource and set up the rollback context */
}
static void dav_fs_patch_commit(const dav_resource *resource,
- int operation,
- void *context,
- dav_liveprop_rollback *rollback_ctx)
+ int operation,
+ void *context,
+ dav_liveprop_rollback *rollback_ctx)
{
/* nothing to do */
}
static dav_error *dav_fs_patch_rollback(const dav_resource *resource,
- int operation,
- void *context,
- dav_liveprop_rollback *rollback_ctx)
+ int operation,
+ void *context,
+ dav_liveprop_rollback *rollback_ctx)
{
apr_fileperms_t perms = resource->info->finfo.protection & ~APR_UEXECUTE;
int value = rollback_ctx != NULL;
/* restore the executable bit */
if (value)
- perms |= APR_UEXECUTE;
+ perms |= APR_UEXECUTE;
if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) {
- return dav_new_error(resource->info->pool,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "After a failure occurred, the resource's "
- "executable flag could not be restored.");
+ return dav_new_error(resource->info->pool,
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "After a failure occurred, the resource's "
+ "executable flag could not be restored.");
}
/* restore the resource's state */
return;
if (!resource->exists) {
- /* a lock-null resource */
- /*
- ** ### technically, we should insert empty properties. dunno offhand
- ** ### what part of the spec said this, but it was essentially thus:
- ** ### "the properties should be defined, but may have no value".
- */
- return;
+ /* a lock-null resource */
+ /*
+ ** ### technically, we should insert empty properties. dunno offhand
+ ** ### what part of the spec said this, but it was essentially thus:
+ ** ### "the properties should be defined, but may have no value".
+ */
+ return;
}
(void) dav_fs_insert_prop(resource, DAV_PROPID_creationdate,
- what, phdr);
+ what, phdr);
(void) dav_fs_insert_prop(resource, DAV_PROPID_getcontentlength,
- what, phdr);
+ what, phdr);
(void) dav_fs_insert_prop(resource, DAV_PROPID_getlastmodified,
- what, phdr);
+ what, phdr);
(void) dav_fs_insert_prop(resource, DAV_PROPID_getetag,
- what, phdr);
+ what, phdr);
#ifdef DAV_FS_HAS_EXECUTABLE
/* Only insert this property if it is defined for this platform. */
(void) dav_fs_insert_prop(resource, DAV_PROPID_FS_executable,
- what, phdr);
+ what, phdr);
#endif
/* ### we know the others aren't defined as liveprops */
#define _DAV_FS_REPOS_H_
/* the subdirectory to hold all DAV-related information for a directory */
-#define DAV_FS_STATE_DIR ".DAV"
-#define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir"
-#define DAV_FS_LOCK_NULL_FILE ".locknull"
+#define DAV_FS_STATE_DIR ".DAV"
+#define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir"
+#define DAV_FS_LOCK_NULL_FILE ".locknull"
/* ensure that our state subdirectory is present */
extern const dav_hooks_db dav_hooks_db_dbm;
dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro,
- dav_db **pdb);
+ dav_db **pdb);
void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname,
- const char **state1, const char **state2);
+ const char **state1, const char **state2);
dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key);
dav_error * dav_dbm_store(dav_db *db, apr_datum_t key, apr_datum_t value);
dav_error * dav_dbm_fetch(dav_db *db, apr_datum_t key, apr_datum_t *pvalue);
#endif
-#define DAV_VERSION AP_SERVER_BASEREVISION
+#define DAV_VERSION AP_SERVER_BASEREVISION
-#define DAV_XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
-#define DAV_XML_CONTENT_TYPE "text/xml; charset=\"utf-8\""
+#define DAV_XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+#define DAV_XML_CONTENT_TYPE "text/xml; charset=\"utf-8\""
-#define DAV_READ_BLOCKSIZE 2048 /* used for reading input blocks */
+#define DAV_READ_BLOCKSIZE 2048 /* used for reading input blocks */
-#define DAV_RESPONSE_BODY_1 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>"
-#define DAV_RESPONSE_BODY_2 "</title>\n</head><body>\n<h1>"
-#define DAV_RESPONSE_BODY_3 "</h1>\n<p>"
-#define DAV_RESPONSE_BODY_4 "</p>\n"
-#define DAV_RESPONSE_BODY_5 "</body></html>\n"
+#define DAV_RESPONSE_BODY_1 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>"
+#define DAV_RESPONSE_BODY_2 "</title>\n</head><body>\n<h1>"
+#define DAV_RESPONSE_BODY_3 "</h1>\n<p>"
+#define DAV_RESPONSE_BODY_4 "</p>\n"
+#define DAV_RESPONSE_BODY_5 "</body></html>\n"
-#define DAV_DO_COPY 0
-#define DAV_DO_MOVE 1
+#define DAV_DO_COPY 0
+#define DAV_DO_MOVE 1
#if 1
-#define DAV_DEBUG 1
-#define DEBUG_CR "\n"
-#define DBG0(f) ap_log_error(APLOG_MARK, \
- APLOG_ERR, 0, NULL, (f))
-#define DBG1(f,a1) ap_log_error(APLOG_MARK, \
- APLOG_ERR, 0, NULL, f, a1)
-#define DBG2(f,a1,a2) ap_log_error(APLOG_MARK, \
- APLOG_ERR, 0, NULL, f, a1, a2)
+#define DAV_DEBUG 1
+#define DEBUG_CR "\n"
+#define DBG0(f) ap_log_error(APLOG_MARK, \
+ APLOG_ERR, 0, NULL, (f))
+#define DBG1(f,a1) ap_log_error(APLOG_MARK, \
+ APLOG_ERR, 0, NULL, f, a1)
+#define DBG2(f,a1,a2) ap_log_error(APLOG_MARK, \
+ APLOG_ERR, 0, NULL, f, a1, a2)
#define DBG3(f,a1,a2,a3) ap_log_error(APLOG_MARK, \
- APLOG_ERR, 0, NULL, f, a1, a2, a3)
+ APLOG_ERR, 0, NULL, f, a1, a2, a3)
#else
#undef DAV_DEBUG
-#define DEBUG_CR ""
+#define DEBUG_CR ""
#endif
-#define DAV_INFINITY INT_MAX /* for the Depth: header */
+#define DAV_INFINITY INT_MAX /* for the Depth: header */
/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and
* DAV_DECLARE_DATA with appropriate export and import tags for the platform
** implies that Apache has a proper description for the specified status.
*/
typedef struct dav_error {
- int status; /* suggested HTTP status (0 for no error) */
- int error_id; /* DAV-specific error ID */
- const char *desc; /* DAV:responsedescription and error log */
+ int status; /* suggested HTTP status (0 for no error) */
+ int error_id; /* DAV-specific error ID */
+ const char *desc; /* DAV:responsedescription and error log */
- int save_errno; /* copy of errno causing the error */
+ int save_errno; /* copy of errno causing the error */
const char *namespace; /* [optional] namespace of error */
const char *tagname; /* name of error-tag */
- struct dav_error *prev; /* previous error (in stack) */
+ struct dav_error *prev; /* previous error (in stack) */
} dav_error;
/* error ID values... */
/* IF: header errors */
-#define DAV_ERR_IF_PARSE 100 /* general parsing error */
-#define DAV_ERR_IF_MULTIPLE_NOT 101 /* multiple "Not" found */
-#define DAV_ERR_IF_UNK_CHAR 102 /* unknown char in header */
-#define DAV_ERR_IF_ABSENT 103 /* no locktokens given */
-#define DAV_ERR_IF_TAGGED 104 /* in parsing tagged-list */
-#define DAV_ERR_IF_UNCLOSED_PAREN 105 /* in no-tagged-list */
+#define DAV_ERR_IF_PARSE 100 /* general parsing error */
+#define DAV_ERR_IF_MULTIPLE_NOT 101 /* multiple "Not" found */
+#define DAV_ERR_IF_UNK_CHAR 102 /* unknown char in header */
+#define DAV_ERR_IF_ABSENT 103 /* no locktokens given */
+#define DAV_ERR_IF_TAGGED 104 /* in parsing tagged-list */
+#define DAV_ERR_IF_UNCLOSED_PAREN 105 /* in no-tagged-list */
/* Prop DB errors */
-#define DAV_ERR_PROP_BAD_MAJOR 200 /* major version was wrong */
-#define DAV_ERR_PROP_READONLY 201 /* prop is read-only */
-#define DAV_ERR_PROP_NO_DATABASE 202 /* writable db not avail */
-#define DAV_ERR_PROP_NOT_FOUND 203 /* prop not found */
-#define DAV_ERR_PROP_BAD_LOCKDB 204 /* could not open lockdb */
-#define DAV_ERR_PROP_OPENING 205 /* problem opening propdb */
-#define DAV_ERR_PROP_EXEC 206 /* problem exec'ing patch */
+#define DAV_ERR_PROP_BAD_MAJOR 200 /* major version was wrong */
+#define DAV_ERR_PROP_READONLY 201 /* prop is read-only */
+#define DAV_ERR_PROP_NO_DATABASE 202 /* writable db not avail */
+#define DAV_ERR_PROP_NOT_FOUND 203 /* prop not found */
+#define DAV_ERR_PROP_BAD_LOCKDB 204 /* could not open lockdb */
+#define DAV_ERR_PROP_OPENING 205 /* problem opening propdb */
+#define DAV_ERR_PROP_EXEC 206 /* problem exec'ing patch */
/* Predefined DB errors */
/* ### any to define?? */
/* Predefined locking system errors */
-#define DAV_ERR_LOCK_OPENDB 400 /* could not open lockdb */
-#define DAV_ERR_LOCK_NO_DB 401 /* no database defined */
-#define DAV_ERR_LOCK_CORRUPT_DB 402 /* DB is corrupt */
-#define DAV_ERR_LOCK_UNK_STATE_TOKEN 403 /* unknown State-token */
-#define DAV_ERR_LOCK_PARSE_TOKEN 404 /* bad opaquelocktoken */
-#define DAV_ERR_LOCK_SAVE_LOCK 405 /* err saving locks */
+#define DAV_ERR_LOCK_OPENDB 400 /* could not open lockdb */
+#define DAV_ERR_LOCK_NO_DB 401 /* no database defined */
+#define DAV_ERR_LOCK_CORRUPT_DB 402 /* DB is corrupt */
+#define DAV_ERR_LOCK_UNK_STATE_TOKEN 403 /* unknown State-token */
+#define DAV_ERR_LOCK_PARSE_TOKEN 404 /* bad opaquelocktoken */
+#define DAV_ERR_LOCK_SAVE_LOCK 405 /* err saving locks */
/*
** Some comments on Error ID values:
typedef struct dav_resource {
dav_resource_type type;
- int exists; /* 0 => null resource */
+ int exists; /* 0 => null resource */
- int collection; /* 0 => file; can be 1 for
+ int collection; /* 0 => file; can be 1 for
* REGULAR, VERSION, and WORKING resources,
* and is always 1 for WORKSPACE */
- int versioned; /* 0 => unversioned; can be 1 for
+ int versioned; /* 0 => unversioned; can be 1 for
* REGULAR and WORKSPACE resources,
* and is always 1 for VERSION and WORKING */
* REGULAR, VERSION, and WORKSPACE resources;
* versioned == 1 when baselined == 1 */
- int working; /* 0 => not checked out; can be 1 for
+ int working; /* 0 => not checked out; can be 1 for
* REGULAR and WORKSPACE resources,
* and is always 1 for WORKING */
- const char *uri; /* the URI for this resource */
+ const char *uri; /* the URI for this resource */
dav_resource_private *info; /* the provider's private info */
- const dav_hooks_repository *hooks; /* hooks used for this resource */
+ const dav_hooks_repository *hooks; /* hooks used for this resource */
/* When allocating items related specifically to this resource, the
following pool should be used. Its lifetime will be at least as
/* buffer for reuse; can grow to accomodate needed size */
typedef struct
{
- apr_size_t alloc_len; /* how much has been allocated */
- apr_size_t cur_len; /* how much is currently being used */
- char *buf; /* buffer contents */
+ apr_size_t alloc_len; /* how much has been allocated */
+ apr_size_t cur_len; /* how much is currently being used */
+ char *buf; /* buffer contents */
} dav_buffer;
-#define DAV_BUFFER_MINSIZE 256 /* minimum size for buffer */
-#define DAV_BUFFER_PAD 64 /* amount of pad when growing */
+#define DAV_BUFFER_MINSIZE 256 /* minimum size for buffer */
+#define DAV_BUFFER_PAD 64 /* amount of pad when growing */
/* set the cur_len to the given size and ensure space is available */
DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf,
/* contains results from one of the getprop functions */
typedef struct
{
- apr_text * propstats; /* <propstat> element text */
- apr_text * xmlns; /* namespace decls for <response> elem */
+ apr_text * propstats; /* <propstat> element text */
+ apr_text * xmlns; /* namespace decls for <response> elem */
} dav_get_props_result;
/* holds the contents of a <response> element */
typedef struct dav_response
{
- const char *href; /* always */
- const char *desc; /* optional description at <response> level */
+ const char *href; /* always */
+ const char *desc; /* optional description at <response> level */
/* use status if propresult.propstats is NULL. */
dav_get_props_result propresult;
typedef struct
{
- request_rec *rnew; /* new subrequest */
- dav_error err; /* potential error response */
+ request_rec *rnew; /* new subrequest */
+ dav_error err; /* potential error response */
} dav_lookup_result;
/* defines type of property info a provider is to return */
typedef enum {
- DAV_PROP_INSERT_NOTDEF, /* property is defined by this provider,
- but nothing was inserted because the
- (live) property is not defined for this
- resource (it may be present as a dead
- property). */
+ DAV_PROP_INSERT_NOTDEF, /* property is defined by this provider,
+ but nothing was inserted because the
+ (live) property is not defined for this
+ resource (it may be present as a dead
+ property). */
DAV_PROP_INSERT_NOTSUPP, /* property is recognized by this provider,
but it is not supported, and cannot be
treated as a dead property */
- DAV_PROP_INSERT_NAME, /* a property name (empty elem) was
- inserted into the text block */
- DAV_PROP_INSERT_VALUE, /* a property name/value pair was inserted
- into the text block */
+ DAV_PROP_INSERT_NAME, /* a property name (empty elem) was
+ inserted into the text block */
+ DAV_PROP_INSERT_VALUE, /* a property name/value pair was inserted
+ into the text block */
DAV_PROP_INSERT_SUPPORTED /* a supported live property was added to
the text block as a
<DAV:supported-live-property> element */
/* ### this stuff is private to dav/fs/repos.c; move it... */
/* format a time string (buf must be at least DAV_TIMEBUF_SIZE chars) */
-#define DAV_STYLE_ISO8601 1
-#define DAV_STYLE_RFC822 2
-#define DAV_TIMEBUF_SIZE 30
+#define DAV_STYLE_ISO8601 1
+#define DAV_STYLE_RFC822 2
+#define DAV_TIMEBUF_SIZE 30
int dav_get_depth(request_rec *r, int def_depth);
dav_if_state_type type;
int condition;
-#define DAV_IF_COND_NORMAL 0
-#define DAV_IF_COND_NOT 1 /* "Not" was applied */
+#define DAV_IF_COND_NORMAL 0
+#define DAV_IF_COND_NOT 1 /* "Not" was applied */
- const char *etag; /* etag */
- dav_locktoken *locktoken; /* locktoken */
+ const char *etag;
+ dav_locktoken *locktoken;
struct dav_if_state_list *next;
} dav_if_state_list;
struct dav_if_state_list *state;
struct dav_if_header *next;
- int dummy_header; /* used internally by the lock/etag validation */
+ int dummy_header; /* used internally by the lock/etag validation */
} dav_if_header;
typedef struct dav_locktoken_list
** ### we may need more context... ie. the lock database
*/
dav_prop_insert (*insert_prop)(const dav_resource *resource,
- int propid, dav_prop_insert what,
- apr_text_header *phdr);
+ int propid, dav_prop_insert what,
+ apr_text_header *phdr);
/*
** Determine whether a given property is writable.
** database. Note: it will be set to zero on entry.
*/
dav_error * (*patch_validate)(const dav_resource *resource,
- const apr_xml_elem *elem,
- int operation,
- void **context,
- int *defer_to_dead);
+ const apr_xml_elem *elem,
+ int operation,
+ void **context,
+ int *defer_to_dead);
/* ### doc... */
dav_error * (*patch_exec)(const dav_resource *resource,
- const apr_xml_elem *elem,
- int operation,
- void *context,
- dav_liveprop_rollback **rollback_ctx);
+ const apr_xml_elem *elem,
+ int operation,
+ void *context,
+ dav_liveprop_rollback **rollback_ctx);
/* ### doc... */
void (*patch_commit)(const dav_resource *resource,
- int operation,
- void *context,
- dav_liveprop_rollback *rollback_ctx);
+ int operation,
+ void *context,
+ dav_liveprop_rollback *rollback_ctx);
/* ### doc... */
dav_error * (*patch_rollback)(const dav_resource *resource,
- int operation,
- void *context,
- dav_liveprop_rollback *rollback_ctx);
+ int operation,
+ void *context,
+ dav_liveprop_rollback *rollback_ctx);
/*
** If a provider needs a context to associate with this hooks structure,
**
** WARNING: the TEST ranges should never be "shipped".
*/
-#define DAV_PROPID_CORE 10000 /* ..10099. defined by mod_dav */
-#define DAV_PROPID_FS 10100 /* ..10299.
- mod_dav filesystem provider. */
-#define DAV_PROPID_TEST1 10300 /* ..10399 */
-#define DAV_PROPID_TEST2 10400 /* ..10499 */
-#define DAV_PROPID_TEST3 10500 /* ..10599 */
+#define DAV_PROPID_CORE 10000 /* ..10099. defined by mod_dav */
+#define DAV_PROPID_FS 10100 /* ..10299.
+ mod_dav filesystem provider. */
+#define DAV_PROPID_TEST1 10300 /* ..10399 */
+#define DAV_PROPID_TEST2 10400 /* ..10499 */
+#define DAV_PROPID_TEST3 10500 /* ..10599 */
/* Next: 10600 */
struct dav_hooks_propdb
{
dav_error * (*open)(apr_pool_t *p, const dav_resource *resource, int ro,
- dav_db **pdb);
+ dav_db **pdb);
void (*close)(dav_db *db);
/*
*/
typedef struct
{
- const dav_hooks_locks *hooks; /* the hooks used for this lockdb */
- int ro; /* was it opened readonly? */
+ const dav_hooks_locks *hooks; /* the hooks used for this lockdb */
+ int ro; /* was it opened readonly? */
dav_lockdb_private *info;
} dav_lock_type;
typedef enum {
- DAV_LOCKREC_DIRECT, /* lock asserted on this resource */
- DAV_LOCKREC_INDIRECT, /* lock inherited from a parent */
- DAV_LOCKREC_INDIRECT_PARTIAL /* most info is not filled in */
+ DAV_LOCKREC_DIRECT, /* lock asserted on this resource */
+ DAV_LOCKREC_INDIRECT, /* lock inherited from a parent */
+ DAV_LOCKREC_INDIRECT_PARTIAL /* most info is not filled in */
} dav_lock_rectype;
/*
*/
typedef struct dav_lock
{
- dav_lock_rectype rectype; /* type of lock record */
- int is_locknull; /* lock establishes a locknull resource */
+ dav_lock_rectype rectype; /* type of lock record */
+ int is_locknull; /* lock establishes a locknull resource */
/* ### put the resource in here? */
- dav_lock_scope scope; /* scope of the lock */
- dav_lock_type type; /* type of lock */
- int depth; /* depth of the lock */
- time_t timeout; /* when the lock will timeout */
+ dav_lock_scope scope; /* scope of the lock */
+ dav_lock_type type; /* type of lock */
+ int depth; /* depth of the lock */
+ time_t timeout; /* when the lock will timeout */
- const dav_locktoken *locktoken; /* the token that was issued */
+ const dav_locktoken *locktoken; /* the token that was issued */
- const char *owner; /* (XML) owner of the lock */
- const char *auth_user; /* auth'd username owning lock */
+ const char *owner; /* (XML) owner of the lock */
+ const char *auth_user; /* auth'd username owning lock */
- dav_lock_private *info; /* private to the lockdb */
+ dav_lock_private *info; /* private to the lockdb */
- struct dav_lock *next; /* for managing a list of locks */
+ struct dav_lock *next; /* for managing a list of locks */
} dav_lock;
/* Property-related public lock functions */
const char *dav_lock_get_activelock(request_rec *r, dav_lock *locks,
- dav_buffer *pbuf);
+ dav_buffer *pbuf);
/* LockDB-related public lock functions */
dav_error * dav_lock_parse_lockinfo(request_rec *r,
- const dav_resource *resrouce,
- dav_lockdb *lockdb,
- const apr_xml_doc *doc,
- dav_lock **lock_request);
+ const dav_resource *resrouce,
+ dav_lockdb *lockdb,
+ const apr_xml_doc *doc,
+ dav_lock **lock_request);
int dav_unlock(request_rec *r, const dav_resource *resource,
- const dav_locktoken *locktoken);
+ const dav_locktoken *locktoken);
dav_error * dav_add_lock(request_rec *r, const dav_resource *resource,
- dav_lockdb *lockdb, dav_lock *request,
- dav_response **response);
+ dav_lockdb *lockdb, dav_lock *request,
+ dav_response **response);
dav_error * dav_notify_created(request_rec *r,
- dav_lockdb *lockdb,
- const dav_resource *resource,
- int resource_state,
- int depth);
+ dav_lockdb *lockdb,
+ const dav_resource *resource,
+ int resource_state,
+ int depth);
DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb,
const dav_resource *resource,
dav_lock **locks);
dav_error * dav_validate_request(request_rec *r, dav_resource *resource,
- int depth, dav_locktoken *locktoken,
- dav_response **response, int flags,
+ int depth, dav_locktoken *locktoken,
+ dav_response **response, int flags,
dav_lockdb *lockdb);
/*
** flags:
** The lock provider may store private information into lock->info.
*/
dav_error * (*create_lock)(dav_lockdb *lockdb,
- const dav_resource *resource,
- dav_lock **lock);
+ const dav_resource *resource,
+ dav_lock **lock);
/*
** Get the locks associated with the specified resource.
** order. If no locks are present, then *locks will be NULL.
*/
dav_error * (*get_locks)(dav_lockdb *lockdb,
- const dav_resource *resource,
- int calltype,
- dav_lock **locks);
+ const dav_resource *resource,
+ int calltype,
+ dav_lock **locks);
-#define DAV_GETLOCKS_RESOLVED 0 /* resolve indirects to directs */
-#define DAV_GETLOCKS_PARTIAL 1 /* leave indirects partially filled */
-#define DAV_GETLOCKS_COMPLETE 2 /* fill out indirect locks */
+#define DAV_GETLOCKS_RESOLVED 0 /* resolve indirects to directs */
+#define DAV_GETLOCKS_PARTIAL 1 /* leave indirects partially filled */
+#define DAV_GETLOCKS_COMPLETE 2 /* fill out indirect locks */
/*
** Find a particular lock on a resource (specified by its locktoken).
** lock structure will be filled out as a DAV_LOCKREC_INDIRECT.
*/
dav_error * (*find_lock)(dav_lockdb *lockdb,
- const dav_resource *resource,
- const dav_locktoken *locktoken,
- int partial_ok,
- dav_lock **lock);
+ const dav_resource *resource,
+ const dav_locktoken *locktoken,
+ int partial_ok,
+ dav_lock **lock);
/*
** Quick test to see if the resource has *any* locks on it.
** exist (i.e. it may not perform timeout checks).
*/
dav_error * (*has_locks)(dav_lockdb *lockdb,
- const dav_resource *resource,
- int *locks_present);
+ const dav_resource *resource,
+ int *locks_present);
/*
** Append the specified lock(s) to the set of locks on this resource.
** Multiple locks are specified using the lock->next links.
*/
dav_error * (*append_locks)(dav_lockdb *lockdb,
- const dav_resource *resource,
- int make_indirect,
- const dav_lock *lock);
+ const dav_resource *resource,
+ int make_indirect,
+ const dav_lock *lock);
/*
** Remove any lock that has the specified locktoken.
** If locktoken == NULL, then ALL locks are removed.
*/
dav_error * (*remove_lock)(dav_lockdb *lockdb,
- const dav_resource *resource,
- const dav_locktoken *locktoken);
+ const dav_resource *resource,
+ const dav_locktoken *locktoken);
/*
** Refresh all locks, found on the specified resource, which has a
** Note that the locks will be fully resolved.
*/
dav_error * (*refresh_locks)(dav_lockdb *lockdb,
- const dav_resource *resource,
- const dav_locktoken_list *ltl,
- time_t new_time,
- dav_lock **locks);
+ const dav_resource *resource,
+ const dav_locktoken_list *ltl,
+ time_t new_time,
+ dav_lock **locks);
/*
** Look up the resource associated with a particular locktoken.
** for the resource defining a lock with this locktoken.
*/
dav_error * (*lookup_resource)(dav_lockdb *lockdb,
- const dav_locktoken *locktoken,
- const dav_resource *start_resource,
- const dav_resource **resource);
+ const dav_locktoken *locktoken,
+ const dav_resource *start_resource,
+ const dav_resource **resource);
/*
** If a provider needs a context to associate with this hooks structure,
};
/* what types of resources can be discovered by dav_get_resource_state() */
-#define DAV_RESOURCE_LOCK_NULL 10 /* resource lock-null */
-#define DAV_RESOURCE_NULL 11 /* resource null */
-#define DAV_RESOURCE_EXISTS 12 /* resource exists */
-#define DAV_RESOURCE_ERROR 13 /* an error occurred */
+#define DAV_RESOURCE_LOCK_NULL 10 /* resource lock-null */
+#define DAV_RESOURCE_NULL 11 /* resource null */
+#define DAV_RESOURCE_EXISTS 12 /* resource exists */
+#define DAV_RESOURCE_ERROR 13 /* an error occurred */
/* --------------------------------------------------------------------
dav_propdb *propdb;
int operation;
-#define DAV_PROP_OP_SET 1 /* set a property value */
-#define DAV_PROP_OP_DELETE 2 /* delete a prop value */
+#define DAV_PROP_OP_SET 1 /* set a property value */
+#define DAV_PROP_OP_DELETE 2 /* delete a prop value */
/* ### add a GET? */
- apr_xml_elem *prop; /* property to affect */
+ apr_xml_elem *prop; /* property to affect */
- dav_error *err; /* error (if any) */
+ dav_error *err; /* error (if any) */
/* private items to the propdb */
int is_liveprop;
void *liveprop_ctx;
- struct dav_rollback_item *rollback; /* optional rollback info */
+ struct dav_rollback_item *rollback; /* optional rollback info */
/* private to mod_dav.c */
request_rec *r;
void dav_prop_commit(dav_prop_ctx *ctx);
void dav_prop_rollback(dav_prop_ctx *ctx);
-#define DAV_PROP_CTX_HAS_ERR(dpc) ((dpc).err && (dpc).err->status >= 300)
+#define DAV_PROP_CTX_HAS_ERR(dpc) ((dpc).err && (dpc).err->status >= 300)
/* --------------------------------------------------------------------
*/
enum {
- DAV_CALLTYPE_MEMBER = 1, /* called for a member resource */
- DAV_CALLTYPE_COLLECTION, /* called for a collection */
- DAV_CALLTYPE_LOCKNULL /* called for a locknull resource */
+ DAV_CALLTYPE_MEMBER = 1, /* called for a member resource */
+ DAV_CALLTYPE_COLLECTION, /* called for a collection */
+ DAV_CALLTYPE_LOCKNULL /* called for a locknull resource */
};
typedef struct
typedef struct
{
int walk_type;
-#define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */
-#define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */
-#define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */
+#define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */
+#define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */
+#define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */
/* callback function and a client context for the walk */
dav_error * (*func)(dav_walk_resource *wres, int calltype);
/* ### client data... phasing out this big glom */
- request_rec *r; /* original request */
+ request_rec *r; /* original request */
/* for PROPFIND operations */
apr_xml_doc *doc;
int propfind_type;
-#define DAV_PROPFIND_IS_ALLPROP 1
-#define DAV_PROPFIND_IS_PROPNAME 2
-#define DAV_PROPFIND_IS_PROP 3
+#define DAV_PROPFIND_IS_ALLPROP 1
+#define DAV_PROPFIND_IS_PROPNAME 2
+#define DAV_PROPFIND_IS_PROP 3
- apr_text *propstat_404; /* (cached) propstat giving a 404 error */
+ apr_text *propstat_404; /* (cached) propstat giving a 404 error */
- const dav_if_header *if_header; /* for validation */
- const dav_locktoken *locktoken; /* for UNLOCK */
- const dav_lock *lock; /* for LOCK */
- int skip_root; /* for dav_inherit_locks() */
+ const dav_if_header *if_header; /* for validation */
+ const dav_locktoken *locktoken; /* for UNLOCK */
+ const dav_lock *lock; /* for LOCK */
+ int skip_root; /* for dav_inherit_locks() */
int flags;
- dav_buffer work_buf; /* for dav_validate_request() */
+ dav_buffer work_buf; /* for dav_validate_request() */
} dav_walker_ctx;
typedef struct dav_stream dav_stream;
typedef enum {
- DAV_MODE_WRITE_TRUNC, /* truncate and open for writing */
- DAV_MODE_WRITE_SEEKABLE /* open for writing; random access */
+ DAV_MODE_WRITE_TRUNC, /* truncate and open for writing */
+ DAV_MODE_WRITE_SEEKABLE /* open for writing; random access */
} dav_stream_mode;
dav_error * (*get_resource)(
request_rec *r,
const char *root_dir,
- const char *label,
+ const char *label,
int use_checked_in,
dav_resource **resource
);
** stream will be returned in *stream.
*/
dav_error * (*open_stream)(const dav_resource *resource,
- dav_stream_mode mode,
- dav_stream **stream);
+ dav_stream_mode mode,
+ dav_stream **stream);
/*
** Close the specified stream.
** All of the bytes must be written, or an error should be returned.
*/
dav_error * (*write_stream)(dav_stream *stream,
- const void *buf, apr_size_t bufsize);
+ const void *buf, apr_size_t bufsize);
/*
** Seek to an absolute position in the stream. This is used to support
** This may be NULL if handle_get is FALSE.
*/
dav_error * (*set_headers)(request_rec *r,
- const dav_resource *resource);
+ const dav_resource *resource);
/*
** The provider should deliver the resource into the specified filter.
dav_error * (*copy_resource)(
const dav_resource *src,
dav_resource *dst,
- int depth,
+ int depth,
dav_response **response
);
* in the response, add it.
*/
void dav_add_vary_header(request_rec *in_req,
- request_rec *out_req,
- const dav_resource *resource);
+ request_rec *out_req,
+ const dav_resource *resource);
/*
** Flags specifying auto-versioning behavior, returned by
** then this should be set to NULL.
*/
dav_error * (*merge)(dav_resource *target, dav_resource *source,
- int no_auto_merge, int no_checkout,
- apr_xml_elem *prop_elem,
- ap_filter_t *output);
+ int no_auto_merge, int no_checkout,
+ apr_xml_elem *prop_elem,
+ ap_filter_t *output);
/*
** If a provider needs a context to associate with this hooks structure,
* exist.
*/
dav_error * (*bind_resource)(const dav_resource *resource,
- dav_resource *binding);
+ dav_resource *binding);
/*
** If a provider needs a context to associate with this hooks structure,
* and the responses (in the body) as the HTTP response.
*/
dav_error * (*search_resource)(request_rec *r,
- dav_response **response);
+ dav_response **response);
/*
** If a provider needs a context to associate with this hooks structure,
apr_size_t dav_get_limit_xml_body(const request_rec *r);
typedef struct {
- int propid; /* live property ID */
- const dav_hooks_liveprop *provider; /* the provider defining this prop */
+ int propid; /* live property ID */
+ const dav_hooks_liveprop *provider; /* the provider defining this prop */
} dav_elem_private;
#ifdef __cplusplus
** values for the response.
** (Handling the PUT would not be difficult, though)
*/
-#define DAV_DISABLE_WRITABLE_PROPS 1
+#define DAV_DISABLE_WRITABLE_PROPS 1
-#define DAV_EMPTY_VALUE "\0" /* TWO null terms */
+#define DAV_EMPTY_VALUE "\0" /* TWO null terms */
struct dav_propdb {
- apr_pool_t *p; /* the pool we should use */
- request_rec *r; /* the request record */
+ apr_pool_t *p; /* the pool we should use */
+ request_rec *r; /* the request record */
- const dav_resource *resource; /* the target resource */
+ const dav_resource *resource; /* the target resource */
- int deferred; /* open of db has been deferred */
- dav_db *db; /* underlying database containing props */
+ int deferred; /* open of db has been deferred */
+ dav_db *db; /* underlying database containing props */
- apr_array_header_t *ns_xlate; /* translation of an elem->ns to URI */
- dav_namespace_map *mapping; /* namespace mapping */
+ apr_array_header_t *ns_xlate; /* translation of an elem->ns to URI */
+ dav_namespace_map *mapping; /* namespace mapping */
- dav_lockdb *lockdb; /* the lock database */
+ dav_lockdb *lockdb; /* the lock database */
- dav_buffer wb_lock; /* work buffer for lockdiscovery property */
+ dav_buffer wb_lock; /* work buffer for lockdiscovery property */
/* if we ever run a GET subreq, it will be stored here */
request_rec *subreq;
"lockdiscovery",
"supportedlock",
- NULL /* sentinel */
+ NULL /* sentinel */
};
enum {
DAV_PROPID_CORE_getcontenttype = DAV_PROPID_CORE,
*provider = NULL;
if (ns_uri == NULL) {
- /* policy: liveprop providers cannot define no-namespace properties */
- return DAV_PROPID_CORE_UNKNOWN;
+ /* policy: liveprop providers cannot define no-namespace properties */
+ return DAV_PROPID_CORE_UNKNOWN;
}
/* check liveprop providers first, so they can define core properties */
/* check for core property */
if (strcmp(ns_uri, "DAV:") == 0) {
- const char * const *p = dav_core_props;
+ const char * const *p = dav_core_props;
- for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid)
- if (strcmp(propname, *p) == 0) {
- return propid;
- }
+ for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid)
+ if (strcmp(propname, *p) == 0) {
+ return propid;
+ }
}
/* no provider for this property */
/* these are defined as read-only */
if (propid == DAV_PROPID_CORE_lockdiscovery
#if DAV_DISABLE_WRITABLE_PROPS
- || propid == DAV_PROPID_CORE_getcontenttype
- || propid == DAV_PROPID_CORE_getcontentlanguage
+ || propid == DAV_PROPID_CORE_getcontenttype
+ || propid == DAV_PROPID_CORE_getcontentlanguage
#endif
- || propid == DAV_PROPID_CORE_supportedlock
+ || propid == DAV_PROPID_CORE_supportedlock
) {
- return 0;
+ return 0;
}
/* these are defined as read/write */
if (propid == DAV_PROPID_CORE_getcontenttype
- || propid == DAV_PROPID_CORE_getcontentlanguage
- || propid == DAV_PROPID_CORE_UNKNOWN) {
+ || propid == DAV_PROPID_CORE_getcontentlanguage
+ || propid == DAV_PROPID_CORE_UNKNOWN) {
- return 1;
+ return 1;
}
/*
}
static dav_error * dav_insert_coreprop(dav_propdb *propdb,
- int propid, const char *name,
- dav_prop_insert what,
- apr_text_header *phdr,
- dav_prop_insert *inserted)
+ int propid, const char *name,
+ dav_prop_insert what,
+ apr_text_header *phdr,
+ dav_prop_insert *inserted)
{
const char *value = NULL;
dav_error *err;
/* fast-path the common case */
if (propid == DAV_PROPID_CORE_UNKNOWN)
- return NULL;
+ return NULL;
switch (propid) {
case DAV_PROPID_CORE_lockdiscovery:
if (propdb->lockdb != NULL) {
- dav_lock *locks;
-
- if ((err = dav_lock_query(propdb->lockdb, propdb->resource,
- &locks)) != NULL) {
- return dav_push_error(propdb->p, err->status, 0,
- "DAV:lockdiscovery could not be "
- "determined due to a problem fetching "
- "the locks for this resource.",
- err);
- }
-
- /* fast-path the no-locks case */
- if (locks == NULL) {
- value = "";
- }
- else {
- /*
- ** This may modify the buffer. value may point to
- ** wb_lock.pbuf or a string constant.
- */
- value = dav_lock_get_activelock(propdb->r, locks,
- &propdb->wb_lock);
-
- /* make a copy to isolate it from changes to wb_lock */
- value = apr_pstrdup(propdb->p, propdb->wb_lock.buf);
- }
+ dav_lock *locks;
+
+ if ((err = dav_lock_query(propdb->lockdb, propdb->resource,
+ &locks)) != NULL) {
+ return dav_push_error(propdb->p, err->status, 0,
+ "DAV:lockdiscovery could not be "
+ "determined due to a problem fetching "
+ "the locks for this resource.",
+ err);
+ }
+
+ /* fast-path the no-locks case */
+ if (locks == NULL) {
+ value = "";
+ }
+ else {
+ /*
+ ** This may modify the buffer. value may point to
+ ** wb_lock.pbuf or a string constant.
+ */
+ value = dav_lock_get_activelock(propdb->r, locks,
+ &propdb->wb_lock);
+
+ /* make a copy to isolate it from changes to wb_lock */
+ value = apr_pstrdup(propdb->p, propdb->wb_lock.buf);
+ }
}
- break;
+ break;
case DAV_PROPID_CORE_supportedlock:
if (propdb->lockdb != NULL) {
- value = (*propdb->lockdb->hooks->get_supportedlock)(propdb->resource);
+ value = (*propdb->lockdb->hooks->get_supportedlock)(propdb->resource);
}
- break;
+ break;
case DAV_PROPID_CORE_getcontenttype:
- if (propdb->subreq == NULL) {
- dav_do_prop_subreq(propdb);
- }
- if (propdb->subreq->content_type != NULL) {
- value = propdb->subreq->content_type;
- }
- break;
+ if (propdb->subreq == NULL) {
+ dav_do_prop_subreq(propdb);
+ }
+ if (propdb->subreq->content_type != NULL) {
+ value = propdb->subreq->content_type;
+ }
+ break;
case DAV_PROPID_CORE_getcontentlanguage:
{
- const char *lang;
-
- if (propdb->subreq == NULL) {
- dav_do_prop_subreq(propdb);
- }
- if ((lang = apr_table_get(propdb->subreq->headers_out,
- "Content-Language")) != NULL) {
- value = lang;
- }
- break;
+ const char *lang;
+
+ if (propdb->subreq == NULL) {
+ dav_do_prop_subreq(propdb);
+ }
+ if ((lang = apr_table_get(propdb->subreq->headers_out,
+ "Content-Language")) != NULL) {
+ value = lang;
+ }
+ break;
}
default:
- /* fall through to interpret as a dead property */
- break;
+ /* fall through to interpret as a dead property */
+ break;
}
/* if something was supplied, then insert it */
if (value != NULL) {
- const char *s;
+ const char *s;
if (what == DAV_PROP_INSERT_SUPPORTED) {
- /* use D: prefix to refer to the DAV: namespace URI,
+ /* use D: prefix to refer to the DAV: namespace URI,
* and let the namespace attribute default to "DAV:"
*/
s = apr_psprintf(propdb->p,
"<D:supported-live-property D:name=\"%s\"/>" DEBUG_CR,
name);
}
- else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
- /* use D: prefix to refer to the DAV: namespace URI */
- s = apr_psprintf(propdb->p, "<D:%s>%s</D:%s>" DEBUG_CR,
- name, value, name);
- }
- else {
- /* use D: prefix to refer to the DAV: namespace URI */
- s = apr_psprintf(propdb->p, "<D:%s/>" DEBUG_CR, name);
- }
- apr_text_append(propdb->p, phdr, s);
-
- *inserted = what;
+ else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
+ /* use D: prefix to refer to the DAV: namespace URI */
+ s = apr_psprintf(propdb->p, "<D:%s>%s</D:%s>" DEBUG_CR,
+ name, value, name);
+ }
+ else {
+ /* use D: prefix to refer to the DAV: namespace URI */
+ s = apr_psprintf(propdb->p, "<D:%s/>" DEBUG_CR, name);
+ }
+ apr_text_append(propdb->p, phdr, s);
+
+ *inserted = what;
}
return NULL;
}
static dav_error * dav_insert_liveprop(dav_propdb *propdb,
- const apr_xml_elem *elem,
- dav_prop_insert what,
- apr_text_header *phdr,
- dav_prop_insert *inserted)
+ const apr_xml_elem *elem,
+ dav_prop_insert what,
+ apr_text_header *phdr,
+ dav_prop_insert *inserted)
{
dav_elem_private *priv = elem->priv;
if (priv->provider == NULL) {
/* this is a "core" property that we define */
- return dav_insert_coreprop(propdb, priv->propid, elem->name,
- what, phdr, inserted);
+ return dav_insert_coreprop(propdb, priv->propid, elem->name,
+ what, phdr, inserted);
}
/* ask the provider (that defined this prop) to insert the prop */
*inserted = (*priv->provider->insert_prop)(propdb->resource, priv->propid,
- what, phdr);
+ what, phdr);
return NULL;
}
}
static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, int ns,
- const char *ns_uri, apr_text_header *phdr)
+ const char *ns_uri, apr_text_header *phdr)
{
const char *s;
/* ask the DB provider to open the thing */
err = (*propdb->db_hooks->open)(propdb->p, propdb->resource, ro,
- &propdb->db);
+ &propdb->db);
if (err != NULL) {
- return dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
- DAV_ERR_PROP_OPENING,
- "Could not open the property database.",
- err);
+ return dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
+ DAV_ERR_PROP_OPENING,
+ "Could not open the property database.",
+ err);
}
/*
}
dav_error *dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
- const dav_resource *resource,
- int ro,
- apr_array_header_t * ns_xlate,
- dav_propdb **p_propdb)
+ const dav_resource *resource,
+ int ro,
+ apr_array_header_t * ns_xlate,
+ dav_propdb **p_propdb)
{
dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb));
#if DAV_DEBUG
if (resource->uri == NULL) {
- return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "INTERNAL DESIGN ERROR: resource must define "
- "its URI.");
+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "INTERNAL DESIGN ERROR: resource must define "
+ "its URI.");
}
#endif
void dav_close_propdb(dav_propdb *propdb)
{
if (propdb->db == NULL)
- return;
+ return;
(*propdb->db_hooks->close)(propdb->db);
}
(void) (*db_hooks->define_namespaces)(propdb->db, xi);
/* get the first property name, beginning the scan */
- (void) (*db_hooks->first_name)(propdb->db, &name);
- while (name.ns != NULL) {
-
- /*
- ** We also look for <DAV:getcontenttype> and
- ** <DAV:getcontentlanguage>. If they are not stored as dead
- ** properties, then we need to perform a subrequest to get
- ** their values (if any).
- */
+ (void) (*db_hooks->first_name)(propdb->db, &name);
+ while (name.ns != NULL) {
+
+ /*
+ ** We also look for <DAV:getcontenttype> and
+ ** <DAV:getcontentlanguage>. If they are not stored as dead
+ ** properties, then we need to perform a subrequest to get
+ ** their values (if any).
+ */
if (*name.ns == 'D' && strcmp(name.ns, "DAV:") == 0
&& *name.name == 'g') {
if (strcmp(name.name, "getcontenttype") == 0) {
else if (strcmp(name.name, "getcontentlanguage") == 0) {
found_contentlang = 1;
}
- }
+ }
- if (what == DAV_PROP_INSERT_VALUE) {
+ if (what == DAV_PROP_INSERT_VALUE) {
dav_error *err;
int found;
if ((err = (*db_hooks->output_value)(propdb->db, &name,
xi, &hdr,
&found)) != NULL) {
- /* ### anything better to do? */
- /* ### probably should enter a 500 error */
- goto next_key;
+ /* ### anything better to do? */
+ /* ### probably should enter a 500 error */
+ goto next_key;
}
/* assert: found == 1 */
- }
- else {
+ }
+ else {
/* the value was not requested, so just add an empty
tag specifying the property name. */
dav_output_prop_name(propdb->p, &name, xi, &hdr);
- }
+ }
- next_key:
- (void) (*db_hooks->next_name)(propdb->db, &name);
- }
+ next_key:
+ (void) (*db_hooks->next_name)(propdb->db, &name);
+ }
/* all namespaces have been entered into xi. generate them into
the output now. */
/* insert the standard properties */
/* ### should be handling the return errors here */
(void)dav_insert_coreprop(propdb,
- DAV_PROPID_CORE_supportedlock, "supportedlock",
- what, &hdr, &unused_inserted);
+ DAV_PROPID_CORE_supportedlock, "supportedlock",
+ what, &hdr, &unused_inserted);
(void)dav_insert_coreprop(propdb,
- DAV_PROPID_CORE_lockdiscovery, "lockdiscovery",
- what, &hdr, &unused_inserted);
+ DAV_PROPID_CORE_lockdiscovery, "lockdiscovery",
+ what, &hdr, &unused_inserted);
/* if we didn't find these, then do the whole subreq thing. */
if (!found_contenttype) {
- /* ### should be handling the return error here */
- (void)dav_insert_coreprop(propdb,
- DAV_PROPID_CORE_getcontenttype,
- "getcontenttype",
- what, &hdr, &unused_inserted);
+ /* ### should be handling the return error here */
+ (void)dav_insert_coreprop(propdb,
+ DAV_PROPID_CORE_getcontenttype,
+ "getcontenttype",
+ what, &hdr, &unused_inserted);
}
if (!found_contentlang) {
- /* ### should be handling the return error here */
- (void)dav_insert_coreprop(propdb,
- DAV_PROPID_CORE_getcontentlanguage,
- "getcontentlanguage",
- what, &hdr, &unused_inserted);
+ /* ### should be handling the return error here */
+ (void)dav_insert_coreprop(propdb,
+ DAV_PROPID_CORE_getcontentlanguage,
+ "getcontentlanguage",
+ what, &hdr, &unused_inserted);
}
/* if not just reporting on supported live props,
* terminate the result */
if (what != DAV_PROP_INSERT_SUPPORTED) {
apr_text_append(propdb->p, &hdr,
- "</D:prop>" DEBUG_CR
- "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
- "</D:propstat>" DEBUG_CR);
+ "</D:prop>" DEBUG_CR
+ "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
+ "</D:propstat>" DEBUG_CR);
}
result.propstats = hdr.first;
/* we will ALWAYS provide a "good" result, even if it is EMPTY */
apr_text_append(propdb->p, &hdr_good,
- "<D:propstat>" DEBUG_CR
- "<D:prop>" DEBUG_CR);
+ "<D:propstat>" DEBUG_CR
+ "<D:prop>" DEBUG_CR);
/* ### the marks should be in a buffer! */
/* allocate zeroed-memory for the marks. These marks indicate which
xi = dav_xmlns_create(propdb->p);
for (elem = elem->first_child; elem; elem = elem->next) {
- dav_elem_private *priv;
- dav_error *err;
- dav_prop_insert inserted;
+ dav_elem_private *priv;
+ dav_error *err;
+ dav_prop_insert inserted;
dav_prop_name name;
/*
** the property, then try looking it up in the propdb.
*/
- if (elem->priv == NULL) {
- elem->priv = apr_pcalloc(propdb->p, sizeof(*priv));
- }
- priv = elem->priv;
+ if (elem->priv == NULL) {
+ elem->priv = apr_pcalloc(propdb->p, sizeof(*priv));
+ }
+ priv = elem->priv;
- /* cache the propid; dav_get_props() could be called many times */
- if (priv->propid == 0)
- dav_find_liveprop(propdb, elem);
+ /* cache the propid; dav_get_props() could be called many times */
+ if (priv->propid == 0)
+ dav_find_liveprop(propdb, elem);
if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {
- /* insert the property. returns 1 if an insertion was done. */
- if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
+ /* insert the property. returns 1 if an insertion was done. */
+ if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
&hdr_good, &inserted)) != NULL) {
- /* ### need to propagate the error to the caller... */
- /* ### skip it for now, as if nothing was inserted */
- }
- if (inserted == DAV_PROP_INSERT_VALUE) {
- have_good = 1;
-
- /*
- ** Add the liveprop's namespace URIs. Note that provider==NULL
- ** for core properties.
- */
- if (priv->provider != NULL) {
- const char * const * scan_ns_uri;
-
- for (scan_ns_uri = priv->provider->namespace_uris;
- *scan_ns_uri != NULL;
- ++scan_ns_uri) {
+ /* ### need to propagate the error to the caller... */
+ /* ### skip it for now, as if nothing was inserted */
+ }
+ if (inserted == DAV_PROP_INSERT_VALUE) {
+ have_good = 1;
+
+ /*
+ ** Add the liveprop's namespace URIs. Note that provider==NULL
+ ** for core properties.
+ */
+ if (priv->provider != NULL) {
+ const char * const * scan_ns_uri;
+
+ for (scan_ns_uri = priv->provider->namespace_uris;
+ *scan_ns_uri != NULL;
+ ++scan_ns_uri) {
int ns;
ns = dav_get_liveprop_ns_index(*scan_ns_uri);
dav_insert_xmlns(propdb->p, "lp", ns, *scan_ns_uri,
&hdr_ns);
- }
- }
+ }
+ }
/* property added. move on to the next property. */
- continue;
- }
+ continue;
+ }
else if (inserted == DAV_PROP_INSERT_NOTDEF) {
/* nothing to do. fall thru to allow property to be handled
as a dead property */
#endif
}
- /* The property wasn't a live property, so look in the dead property
+ /* The property wasn't a live property, so look in the dead property
database. */
/* make sure propdb is really open */
}
apr_text_append(propdb->p, &hdr_good,
- "</D:prop>" DEBUG_CR
- "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
- "</D:propstat>" DEBUG_CR);
+ "</D:prop>" DEBUG_CR
+ "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
+ "</D:propstat>" DEBUG_CR);
/* default to start with the good */
result.propstats = hdr_good.first;
/* we may not have any "bad" results */
if (hdr_bad.first != NULL) {
/* "close" the bad propstat */
- apr_text_append(propdb->p, &hdr_bad,
+ apr_text_append(propdb->p, &hdr_bad,
"</D:prop>" DEBUG_CR
"<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR
"</D:propstat>" DEBUG_CR);
- /* if there are no good props, then just return the bad */
- if (!have_good) {
- result.propstats = hdr_bad.first;
- }
- else {
- /* hook the bad propstat to the end of the good one */
- hdr_good.last->next = hdr_bad.first;
- }
+ /* if there are no good props, then just return the bad */
+ if (!have_good) {
+ result.propstats = hdr_bad.first;
+ }
+ else {
+ /* hook the bad propstat to the end of the good one */
+ hdr_good.last->next = hdr_bad.first;
+ }
}
/* add in all the various namespaces, and return them */
DAV_PROP_INSERT_SUPPORTED, body, &unused_inserted);
}
else {
- (*hooks->insert_prop)(propdb->resource, propid,
+ (*hooks->insert_prop)(propdb->resource, propid,
DAV_PROP_INSERT_SUPPORTED, body);
}
}
** be SET or DELETEd.
*/
if (priv->propid == 0) {
- dav_find_liveprop(propdb, prop);
+ dav_find_liveprop(propdb, prop);
- /* it's a liveprop if a provider was found */
- /* ### actually the "core" props should really be liveprops, but
- ### there is no "provider" for those and the r/w props are
- ### treated as dead props anyhow */
- ctx->is_liveprop = priv->provider != NULL;
+ /* it's a liveprop if a provider was found */
+ /* ### actually the "core" props should really be liveprops, but
+ ### there is no "provider" for those and the r/w props are
+ ### treated as dead props anyhow */
+ ctx->is_liveprop = priv->provider != NULL;
}
if (!dav_rw_liveprop(propdb, priv)) {
- ctx->err = dav_new_error(propdb->p, HTTP_CONFLICT,
- DAV_ERR_PROP_READONLY,
- "Property is read-only.");
- return;
+ ctx->err = dav_new_error(propdb->p, HTTP_CONFLICT,
+ DAV_ERR_PROP_READONLY,
+ "Property is read-only.");
+ return;
}
if (ctx->is_liveprop) {
- int defer_to_dead = 0;
+ int defer_to_dead = 0;
- ctx->err = (*priv->provider->patch_validate)(propdb->resource,
- prop, ctx->operation,
- &ctx->liveprop_ctx,
- &defer_to_dead);
- if (ctx->err != NULL || !defer_to_dead)
- return;
+ ctx->err = (*priv->provider->patch_validate)(propdb->resource,
+ prop, ctx->operation,
+ &ctx->liveprop_ctx,
+ &defer_to_dead);
+ if (ctx->err != NULL || !defer_to_dead)
+ return;
- /* clear is_liveprop -- act as a dead prop now */
- ctx->is_liveprop = 0;
+ /* clear is_liveprop -- act as a dead prop now */
+ ctx->is_liveprop = 0;
}
/*
** database. Make sure the thing is truly open (and writable).
*/
if (propdb->deferred
- && (ctx->err = dav_really_open_db(propdb, 0 /* ro */)) != NULL) {
- return;
+ && (ctx->err = dav_really_open_db(propdb, 0 /* ro */)) != NULL) {
+ return;
}
/*
** did not exist.
*/
if (propdb->db == NULL) {
- ctx->err = dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
- DAV_ERR_PROP_NO_DATABASE,
- "Attempted to set/remove a property "
- "without a valid, open, read/write "
- "property database.");
- return;
+ ctx->err = dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
+ DAV_ERR_PROP_NO_DATABASE,
+ "Attempted to set/remove a property "
+ "without a valid, open, read/write "
+ "property database.");
+ return;
}
if (ctx->operation == DAV_PROP_OP_SET) {
- /*
- ** Prep the element => propdb namespace index mapping, inserting
- ** namespace URIs into the propdb that don't exist.
- */
+ /*
+ ** Prep the element => propdb namespace index mapping, inserting
+ ** namespace URIs into the propdb that don't exist.
+ */
(void) (*propdb->db_hooks->map_namespaces)(propdb->db,
propdb->ns_xlate,
&propdb->mapping);
}
else if (ctx->operation == DAV_PROP_OP_DELETE) {
- /*
- ** There are no checks to perform here. If a property exists, then
- ** we will delete it. If it does not exist, then it does not matter
- ** (see S12.13.1).
- **
- ** Note that if a property does not exist, that does not rule out
- ** that a SET will occur during this PROPPATCH (thusly creating it).
- */
+ /*
+ ** There are no checks to perform here. If a property exists, then
+ ** we will delete it. If it does not exist, then it does not matter
+ ** (see S12.13.1).
+ **
+ ** Note that if a property does not exist, that does not rule out
+ ** that a SET will occur during this PROPPATCH (thusly creating it).
+ */
}
}
ctx->rollback = apr_pcalloc(propdb->p, sizeof(*ctx->rollback));
if (ctx->is_liveprop) {
- err = (*priv->provider->patch_exec)(propdb->resource,
- ctx->prop, ctx->operation,
- ctx->liveprop_ctx,
- &ctx->rollback->liveprop);
+ err = (*priv->provider->patch_exec)(propdb->resource,
+ ctx->prop, ctx->operation,
+ ctx->liveprop_ctx,
+ &ctx->rollback->liveprop);
}
else {
dav_prop_name name;
name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, ctx->prop->ns);
name.name = ctx->prop->name;
- /* save the old value so that we can do a rollback. */
- if ((err = (*propdb->db_hooks
+ /* save the old value so that we can do a rollback. */
+ if ((err = (*propdb->db_hooks
->get_rollback)(propdb->db, &name,
&ctx->rollback->deadprop)) != NULL)
- goto error;
+ goto error;
- if (ctx->operation == DAV_PROP_OP_SET) {
+ if (ctx->operation == DAV_PROP_OP_SET) {
- /* Note: propdb->mapping was set in dav_prop_validate() */
+ /* Note: propdb->mapping was set in dav_prop_validate() */
err = (*propdb->db_hooks->store)(propdb->db, &name, ctx->prop,
propdb->mapping);
- /*
- ** If an error occurred, then assume that we didn't change the
- ** value. Remove the rollback item so that we don't try to set
- ** its value during the rollback.
- */
+ /*
+ ** If an error occurred, then assume that we didn't change the
+ ** value. Remove the rollback item so that we don't try to set
+ ** its value during the rollback.
+ */
/* ### euh... where is the removal? */
- }
- else if (ctx->operation == DAV_PROP_OP_DELETE) {
-
- /*
- ** Delete the property. Ignore errors -- the property is there, or
- ** we are deleting it for a second time.
- */
- /* ### but what about other errors? */
- (void) (*propdb->db_hooks->remove)(propdb->db, &name);
- }
+ }
+ else if (ctx->operation == DAV_PROP_OP_DELETE) {
+
+ /*
+ ** Delete the property. Ignore errors -- the property is there, or
+ ** we are deleting it for a second time.
+ */
+ /* ### but what about other errors? */
+ (void) (*propdb->db_hooks->remove)(propdb->db, &name);
+ }
}
error:
/* push a more specific error here */
if (err != NULL) {
- /*
- ** Use HTTP_INTERNAL_SERVER_ERROR because we shouldn't have seen
- ** any errors at this point.
- */
- ctx->err = dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
- DAV_ERR_PROP_EXEC,
- "Could not execute PROPPATCH.", err);
+ /*
+ ** Use HTTP_INTERNAL_SERVER_ERROR because we shouldn't have seen
+ ** any errors at this point.
+ */
+ ctx->err = dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
+ DAV_ERR_PROP_EXEC,
+ "Could not execute PROPPATCH.", err);
}
}
*/
if (ctx->is_liveprop) {
- (*priv->provider->patch_commit)(ctx->propdb->resource,
- ctx->operation,
- ctx->liveprop_ctx,
- ctx->rollback->liveprop);
+ (*priv->provider->patch_commit)(ctx->propdb->resource,
+ ctx->operation,
+ ctx->liveprop_ctx,
+ ctx->rollback->liveprop);
}
}
/* do nothing if there is no rollback information. */
if (ctx->rollback == NULL)
- return;
+ return;
/*
** ### if we have an error, and a rollback occurs, then the namespace
*/
if (ctx->is_liveprop) {
- err = (*priv->provider->patch_rollback)(ctx->propdb->resource,
- ctx->operation,
- ctx->liveprop_ctx,
- ctx->rollback->liveprop);
+ err = (*priv->provider->patch_rollback)(ctx->propdb->resource,
+ ctx->operation,
+ ctx->liveprop_ctx,
+ ctx->rollback->liveprop);
}
else {
err = (*ctx->propdb->db_hooks
}
if (err != NULL) {
- if (ctx->err == NULL)
- ctx->err = err;
- else {
- dav_error *scan = err;
-
- /* hook previous errors at the end of the rollback error */
- while (scan->prev != NULL)
- scan = scan->prev;
- scan->prev = ctx->err;
- ctx->err = err;
- }
+ if (ctx->err == NULL)
+ ctx->err = err;
+ else {
+ dav_error *scan = err;
+
+ /* hook previous errors at the end of the rollback error */
+ while (scan->prev != NULL)
+ scan = scan->prev;
+ scan->prev = ctx->err;
+ ctx->err = err;
+ }
}
}
static const char * const dav_core_namespace_uris[] =
{
"DAV:",
- NULL /* sentinel */
+ NULL /* sentinel */
};
/*
{ 0, "resourcetype", DAV_PROPID_resourcetype, 0 },
{ 0, "source", DAV_PROPID_source, 1 },
- { 0 } /* sentinel */
+ { 0 } /* sentinel */
};
static const dav_liveprop_group dav_core_liveprop_group =
switch (resource->type) {
case DAV_RESOURCE_TYPE_VERSION:
if (resource->baselined) {
- value = "<D:baseline/>";
+ value = "<D:baseline/>";
break;
}
/* fall through */
case DAV_RESOURCE_TYPE_REGULAR:
case DAV_RESOURCE_TYPE_WORKING:
if (resource->collection) {
- value = "<D:collection/>";
+ value = "<D:collection/>";
}
- else {
- /* ### should we denote lock-null resources? */
+ else {
+ /* ### should we denote lock-null resources? */
- value = ""; /* becomes: <D:resourcetype/> */
- }
+ value = ""; /* becomes: <D:resourcetype/> */
+ }
break;
case DAV_RESOURCE_TYPE_HISTORY:
- value = "<D:version-history/>";
+ value = "<D:version-history/>";
break;
case DAV_RESOURCE_TYPE_WORKSPACE:
- value = "<D:collection/>";
+ value = "<D:collection/>";
break;
case DAV_RESOURCE_TYPE_ACTIVITY:
- value = "<D:activity/>";
+ value = "<D:activity/>";
break;
default:
- /* ### bad juju */
+ /* ### bad juju */
return DAV_PROP_INSERT_NOTDEF;
}
break;
{
/* grow the buffer if necessary */
if (pbuf->cur_len + extra_needed > pbuf->alloc_len) {
- char *newbuf;
+ char *newbuf;
- pbuf->alloc_len += extra_needed + DAV_BUFFER_PAD;
- newbuf = apr_palloc(p, pbuf->alloc_len);
- memcpy(newbuf, pbuf->buf, pbuf->cur_len);
- pbuf->buf = newbuf;
+ pbuf->alloc_len += extra_needed + DAV_BUFFER_PAD;
+ newbuf = apr_palloc(p, pbuf->alloc_len);
+ memcpy(newbuf, pbuf->buf, pbuf->cur_len);
+ pbuf->buf = newbuf;
}
}
/* grow if we don't have enough for the requested size plus padding */
if (size + DAV_BUFFER_PAD > pbuf->alloc_len) {
- /* set the new length; min of MINSIZE */
- pbuf->alloc_len = size + DAV_BUFFER_PAD;
- if (pbuf->alloc_len < DAV_BUFFER_MINSIZE)
- pbuf->alloc_len = DAV_BUFFER_MINSIZE;
+ /* set the new length; min of MINSIZE */
+ pbuf->alloc_len = size + DAV_BUFFER_PAD;
+ if (pbuf->alloc_len < DAV_BUFFER_MINSIZE)
+ pbuf->alloc_len = DAV_BUFFER_MINSIZE;
- pbuf->buf = apr_palloc(p, pbuf->alloc_len);
+ pbuf->buf = apr_palloc(p, pbuf->alloc_len);
}
pbuf->cur_len = size;
}
/* first thing to do is parse the URI into various components */
if (apr_uri_parse(r->pool, uri, &comp) != APR_SUCCESS) {
- result.err.status = HTTP_BAD_REQUEST;
- result.err.desc = "Invalid syntax in Destination URI.";
- return result;
+ result.err.status = HTTP_BAD_REQUEST;
+ result.err.desc = "Invalid syntax in Destination URI.";
+ return result;
}
/* the URI must be an absoluteURI (WEBDAV S9.3) */
if (comp.scheme == NULL && must_be_absolute) {
- result.err.status = HTTP_BAD_REQUEST;
- result.err.desc = "Destination URI must be an absolute URI.";
- return result;
+ result.err.status = HTTP_BAD_REQUEST;
+ result.err.desc = "Destination URI must be an absolute URI.";
+ return result;
}
/* the URI must not have a query (args) or a fragment */
if (comp.query != NULL || comp.fragment != NULL) {
- result.err.status = HTTP_BAD_REQUEST;
- result.err.desc =
- "Destination URI contains invalid components "
- "(a query or a fragment).";
- return result;
+ result.err.status = HTTP_BAD_REQUEST;
+ result.err.desc =
+ "Destination URI contains invalid components "
+ "(a query or a fragment).";
+ return result;
}
/* If the scheme or port was provided, then make sure that it matches
*/
if (comp.hostname != NULL
&& strrchr(comp.hostname, '.') == NULL
- && (domain = strchr(r->server->server_hostname, '.')) != NULL) {
- comp.hostname = apr_pstrcat(r->pool, comp.hostname, domain, NULL);
+ && (domain = strchr(r->server->server_hostname, '.')) != NULL) {
+ comp.hostname = apr_pstrcat(r->pool, comp.hostname, domain, NULL);
}
/* now, if a hostname was provided, then verify that it represents the
port, since we've verified the URI matches ours */
#ifdef APACHE_PORT_HANDLING_IS_BUSTED
if (comp.hostname != NULL &&
- !ap_matches_request_vhost(r, comp.hostname, port)) {
- result.err.status = HTTP_BAD_GATEWAY;
- result.err.desc = "Destination URI refers to a different server.";
- return result;
+ !ap_matches_request_vhost(r, comp.hostname, port)) {
+ result.err.status = HTTP_BAD_GATEWAY;
+ result.err.desc = "Destination URI refers to a different server.";
+ return result;
}
#endif
int dav_validate_root(const apr_xml_doc *doc, const char *tagname)
{
return doc->root &&
- doc->root->ns == APR_XML_NS_DAV_ID &&
- strcmp(doc->root->name, tagname) == 0;
+ doc->root->ns == APR_XML_NS_DAV_ID &&
+ strcmp(doc->root->name, tagname) == 0;
}
/* find and return the (unique) child with a given DAV: tagname */
apr_xml_elem *child = elem->first_child;
for (; child; child = child->next)
- if (child->ns == APR_XML_NS_DAV_ID && !strcmp(child->name, tagname))
- return child;
+ if (child->ns == APR_XML_NS_DAV_ID && !strcmp(child->name, tagname))
+ return child;
return NULL;
}
const char *timeout = apr_pstrdup(r->pool, timeout_const), *val;
if (timeout == NULL)
- return DAV_TIMEOUT_INFINITE;
+ return DAV_TIMEOUT_INFINITE;
/* Use the first thing we understand, or infinity if
* we don't understand anything.
*/
while ((val = ap_getword_white(r->pool, &timeout)) && strlen(val)) {
- if (!strncmp(val, "Infinite", 8)) {
- return DAV_TIMEOUT_INFINITE;
- }
-
- if (!strncmp(val, "Second-", 7)) {
- val += 7;
- /* ### We need to handle overflow better:
- * ### timeout will be <= 2^32 - 1
- */
- expires = atol(val);
- now = time(NULL);
- return now + expires;
- }
+ if (!strncmp(val, "Infinite", 8)) {
+ return DAV_TIMEOUT_INFINITE;
+ }
+
+ if (!strncmp(val, "Second-", 7)) {
+ val += 7;
+ /* ### We need to handle overflow better:
+ * ### timeout will be <= 2^32 - 1
+ */
+ expires = atol(val);
+ now = time(NULL);
+ return now + expires;
+ }
}
return DAV_TIMEOUT_INFINITE;
/* add_if_resource returns a new if_header, linking it to next_ih.
*/
static dav_if_header *dav_add_if_resource(apr_pool_t *p, dav_if_header *next_ih,
- const char *uri, apr_size_t uri_len)
+ const char *uri, apr_size_t uri_len)
{
dav_if_header *ih;
if ((ih = apr_pcalloc(p, sizeof(*ih))) == NULL)
- return NULL;
+ return NULL;
ih->uri = uri;
ih->uri_len = uri_len;
/* add_if_state adds a condition to an if_header.
*/
static dav_error * dav_add_if_state(apr_pool_t *p, dav_if_header *ih,
- const char *state_token,
- dav_if_state_type t, int condition,
- const dav_hooks_locks *locks_hooks)
+ const char *state_token,
+ dav_if_state_type t, int condition,
+ const dav_hooks_locks *locks_hooks)
{
dav_if_state_list *new_sl;
new_sl->type = t;
if (t == dav_if_opaquelock) {
- dav_error *err;
+ dav_error *err;
- if ((err = (*locks_hooks->parse_locktoken)(p, state_token,
- &new_sl->locktoken)) != NULL) {
- /* ### maybe add a higher-level description */
- return err;
- }
+ if ((err = (*locks_hooks->parse_locktoken)(p, state_token,
+ &new_sl->locktoken)) != NULL) {
+ /* ### maybe add a higher-level description */
+ return err;
+ }
}
else
- new_sl->etag = state_token;
+ new_sl->etag = state_token;
new_sl->next = ih->state;
ih->state = new_sl;
{
char *sp;
char *token;
-
+
token = *str + 1;
while (*token && (*token == ' ' || *token == '\t'))
- token++;
+ token++;
if ((sp = strchr(token, term)) == NULL)
- return NULL;
+ return NULL;
*sp = '\0';
*str = sp;
char *str;
char *list;
const char *state_token;
- const char *uri = NULL; /* scope of current production; NULL=no-tag */
+ const char *uri = NULL; /* scope of current production; NULL=no-tag */
apr_size_t uri_len = 0;
dav_if_header *ih = NULL;
apr_uri_t parsed_uri;
const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r);
enum {no_tagged, tagged, unknown} list_type = unknown;
int condition;
-
+
*p_ih = NULL;
if ((str = apr_pstrdup(r->pool, apr_table_get(r->headers_in, "If"))) == NULL)
- return NULL;
+ return NULL;
while (*str) {
- switch(*str) {
- case '<':
- /* Tagged-list production - following states apply to this uri */
- if (list_type == no_tagged
- || ((uri = dav_fetch_next_token(&str, '>')) == NULL)) {
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_TAGGED,
- "Invalid If-header: unclosed \"<\" or "
- "unexpected tagged-list production.");
- }
+ switch(*str) {
+ case '<':
+ /* Tagged-list production - following states apply to this uri */
+ if (list_type == no_tagged
+ || ((uri = dav_fetch_next_token(&str, '>')) == NULL)) {
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_TAGGED,
+ "Invalid If-header: unclosed \"<\" or "
+ "unexpected tagged-list production.");
+ }
/* 2518 specifies this must be an absolute URI; just take the
* relative part for later comparison against r->uri */
DAV_ERR_IF_TAGGED,
"Invalid URI in tagged If-header.");
}
- /* note that parsed_uri.path is allocated; we can trash it */
-
- /* clean up the URI a bit */
- ap_getparents(parsed_uri.path);
- uri_len = strlen(parsed_uri.path);
- if (uri_len > 1 && parsed_uri.path[uri_len - 1] == '/')
- parsed_uri.path[--uri_len] = '\0';
-
- uri = parsed_uri.path;
- list_type = tagged;
- break;
-
- case '(':
- /* List production */
-
- /* If a uri has not been encountered, this is a No-Tagged-List */
- if (list_type == unknown)
- list_type = no_tagged;
-
- if ((list = dav_fetch_next_token(&str, ')')) == NULL) {
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_UNCLOSED_PAREN,
- "Invalid If-header: unclosed \"(\".");
- }
-
- if ((ih = dav_add_if_resource(r->pool, ih, uri, uri_len)) == NULL) {
- /* ### dav_add_if_resource() should return an error for us! */
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_PARSE,
- "Internal server error parsing \"If:\" "
- "header.");
- }
-
- condition = DAV_IF_COND_NORMAL;
-
- while (*list) {
- /* List is the entire production (in a uri scope) */
-
- switch (*list) {
- case '<':
- if ((state_token = dav_fetch_next_token(&list, '>')) == NULL) {
- /* ### add a description to this error */
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_PARSE, NULL);
- }
-
- if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_opaquelock,
- condition, locks_hooks)) != NULL) {
- /* ### maybe add a higher level description */
- return err;
- }
- condition = DAV_IF_COND_NORMAL;
- break;
-
- case '[':
- if ((state_token = dav_fetch_next_token(&list, ']')) == NULL) {
- /* ### add a description to this error */
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_PARSE, NULL);
- }
-
- if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_etag,
- condition, locks_hooks)) != NULL) {
- /* ### maybe add a higher level description */
- return err;
- }
- condition = DAV_IF_COND_NORMAL;
- break;
-
- case 'N':
- if (list[1] == 'o' && list[2] == 't') {
- if (condition != DAV_IF_COND_NORMAL) {
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_MULTIPLE_NOT,
- "Invalid \"If:\" header: "
- "Multiple \"not\" entries "
- "for the same state.");
- }
- condition = DAV_IF_COND_NOT;
- }
- list += 2;
- break;
-
- case ' ':
- case '\t':
- break;
-
- default:
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_UNK_CHAR,
+ /* note that parsed_uri.path is allocated; we can trash it */
+
+ /* clean up the URI a bit */
+ ap_getparents(parsed_uri.path);
+ uri_len = strlen(parsed_uri.path);
+ if (uri_len > 1 && parsed_uri.path[uri_len - 1] == '/')
+ parsed_uri.path[--uri_len] = '\0';
+
+ uri = parsed_uri.path;
+ list_type = tagged;
+ break;
+
+ case '(':
+ /* List production */
+
+ /* If a uri has not been encountered, this is a No-Tagged-List */
+ if (list_type == unknown)
+ list_type = no_tagged;
+
+ if ((list = dav_fetch_next_token(&str, ')')) == NULL) {
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_UNCLOSED_PAREN,
+ "Invalid If-header: unclosed \"(\".");
+ }
+
+ if ((ih = dav_add_if_resource(r->pool, ih, uri, uri_len)) == NULL) {
+ /* ### dav_add_if_resource() should return an error for us! */
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_PARSE,
+ "Internal server error parsing \"If:\" "
+ "header.");
+ }
+
+ condition = DAV_IF_COND_NORMAL;
+
+ while (*list) {
+ /* List is the entire production (in a uri scope) */
+
+ switch (*list) {
+ case '<':
+ if ((state_token = dav_fetch_next_token(&list, '>')) == NULL) {
+ /* ### add a description to this error */
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_PARSE, NULL);
+ }
+
+ if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_opaquelock,
+ condition, locks_hooks)) != NULL) {
+ /* ### maybe add a higher level description */
+ return err;
+ }
+ condition = DAV_IF_COND_NORMAL;
+ break;
+
+ case '[':
+ if ((state_token = dav_fetch_next_token(&list, ']')) == NULL) {
+ /* ### add a description to this error */
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_PARSE, NULL);
+ }
+
+ if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_etag,
+ condition, locks_hooks)) != NULL) {
+ /* ### maybe add a higher level description */
+ return err;
+ }
+ condition = DAV_IF_COND_NORMAL;
+ break;
+
+ case 'N':
+ if (list[1] == 'o' && list[2] == 't') {
+ if (condition != DAV_IF_COND_NORMAL) {
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_MULTIPLE_NOT,
+ "Invalid \"If:\" header: "
+ "Multiple \"not\" entries "
+ "for the same state.");
+ }
+ condition = DAV_IF_COND_NOT;
+ }
+ list += 2;
+ break;
+
+ case ' ':
+ case '\t':
+ break;
+
+ default:
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_UNK_CHAR,
apr_psprintf(r->pool,
"Invalid \"If:\" "
"header: Unexpected "
"character encountered "
"(0x%02x, '%c').",
*list, *list));
- }
+ }
- list++;
- }
- break;
+ list++;
+ }
+ break;
- case ' ':
- case '\t':
- break;
+ case ' ':
+ case '\t':
+ break;
- default:
- return dav_new_error(r->pool, HTTP_BAD_REQUEST,
- DAV_ERR_IF_UNK_CHAR,
+ default:
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
+ DAV_ERR_IF_UNK_CHAR,
apr_psprintf(r->pool,
"Invalid \"If:\" header: "
"Unexpected character "
"encountered (0x%02x, '%c').",
*str, *str));
- }
+ }
- str++;
+ str++;
}
*p_ih = ih;
}
static int dav_find_submitted_locktoken(const dav_if_header *if_header,
- const dav_lock *lock_list,
- const dav_hooks_locks *locks_hooks)
+ const dav_lock *lock_list,
+ const dav_hooks_locks *locks_hooks)
{
for (; if_header != NULL; if_header = if_header->next) {
- const dav_if_state_list *state_list;
-
- for (state_list = if_header->state;
- state_list != NULL;
- state_list = state_list->next) {
-
- if (state_list->type == dav_if_opaquelock) {
- const dav_lock *lock;
-
- /* given state_list->locktoken, match it */
-
- /*
- ** The resource will have one or more lock tokens. We only
- ** need to match one of them against any token in the
- ** If: header.
- **
- ** One token case: It is an exclusive or shared lock. Either
- ** way, we must find it.
- **
- ** N token case: They are shared locks. By policy, we need
- ** to match only one. The resource's other
- ** tokens may belong to somebody else (so we
- ** shouldn't see them in the If: header anyway)
- */
- for (lock = lock_list; lock != NULL; lock = lock->next) {
-
- if (!(*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) {
- return 1;
- }
- }
- }
- }
+ const dav_if_state_list *state_list;
+
+ for (state_list = if_header->state;
+ state_list != NULL;
+ state_list = state_list->next) {
+
+ if (state_list->type == dav_if_opaquelock) {
+ const dav_lock *lock;
+
+ /* given state_list->locktoken, match it */
+
+ /*
+ ** The resource will have one or more lock tokens. We only
+ ** need to match one of them against any token in the
+ ** If: header.
+ **
+ ** One token case: It is an exclusive or shared lock. Either
+ ** way, we must find it.
+ **
+ ** N token case: They are shared locks. By policy, we need
+ ** to match only one. The resource's other
+ ** tokens may belong to somebody else (so we
+ ** shouldn't see them in the If: header anyway)
+ */
+ for (lock = lock_list; lock != NULL; lock = lock->next) {
+
+ if (!(*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) {
+ return 1;
+ }
+ }
+ }
+ }
}
return 0;
* Returns NULL if path/uri meets if-header and lock requirements
*/
static dav_error * dav_validate_resource_state(apr_pool_t *p,
- const dav_resource *resource,
- dav_lockdb *lockdb,
- const dav_if_header *if_header,
+ const dav_resource *resource,
+ dav_lockdb *lockdb,
+ const dav_if_header *if_header,
int flags,
- dav_buffer *pbuf,
+ dav_buffer *pbuf,
request_rec *r)
{
dav_error *err;
*/
if (lockdb == NULL) {
- /* we're in State 1. no locks. */
- lock_list = NULL;
+ /* we're in State 1. no locks. */
+ lock_list = NULL;
}
else {
- /*
- ** ### hrm... we don't need to have these fully
- ** ### resolved since we're only looking at the
- ** ### locktokens...
- **
- ** ### use get_locks w/ calltype=PARTIAL
- */
- if ((err = dav_lock_query(lockdb, resource, &lock_list)) != NULL) {
- return dav_push_error(p,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "The locks could not be queried for "
- "verification against a possible \"If:\" "
- "header.",
- err);
- }
-
- /* lock_list now determines whether we're in State 1, 2, or 3. */
+ /*
+ ** ### hrm... we don't need to have these fully
+ ** ### resolved since we're only looking at the
+ ** ### locktokens...
+ **
+ ** ### use get_locks w/ calltype=PARTIAL
+ */
+ if ((err = dav_lock_query(lockdb, resource, &lock_list)) != NULL) {
+ return dav_push_error(p,
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "The locks could not be queried for "
+ "verification against a possible \"If:\" "
+ "header.",
+ err);
+ }
+
+ /* lock_list now determines whether we're in State 1, 2, or 3. */
}
/*
** else, do not require a token to be seen.
*/
if (flags & DAV_LOCKSCOPE_EXCLUSIVE) {
- if (lock_list != NULL) {
- return dav_new_error(p, HTTP_LOCKED, 0,
- "Existing lock(s) on the requested resource "
- "prevent an exclusive lock.");
- }
-
- /*
- ** There are no locks, so we can pretend that we've already met
- ** any requirement to find the resource's locks in an If: header.
- */
- seen_locktoken = 1;
+ if (lock_list != NULL) {
+ return dav_new_error(p, HTTP_LOCKED, 0,
+ "Existing lock(s) on the requested resource "
+ "prevent an exclusive lock.");
+ }
+
+ /*
+ ** There are no locks, so we can pretend that we've already met
+ ** any requirement to find the resource's locks in an If: header.
+ */
+ seen_locktoken = 1;
}
else if (flags & DAV_LOCKSCOPE_SHARED) {
- /*
- ** Strictly speaking, we don't need this loop. Either the first
- ** (and only) lock will be EXCLUSIVE, or none of them will be.
- */
+ /*
+ ** Strictly speaking, we don't need this loop. Either the first
+ ** (and only) lock will be EXCLUSIVE, or none of them will be.
+ */
for (lock = lock_list; lock != NULL; lock = lock->next) {
if (lock->scope == DAV_LOCKSCOPE_EXCLUSIVE) {
- return dav_new_error(p, HTTP_LOCKED, 0,
- "The requested resource is already "
- "locked exclusively.");
+ return dav_new_error(p, HTTP_LOCKED, 0,
+ "The requested resource is already "
+ "locked exclusively.");
}
}
- /*
- ** The locks on the resource (if any) are all shared. Set the
- ** <seen_locktoken> flag to indicate that we do not need to find
- ** the locks in an If: header.
- */
+ /*
+ ** The locks on the resource (if any) are all shared. Set the
+ ** <seen_locktoken> flag to indicate that we do not need to find
+ ** the locks in an If: header.
+ */
seen_locktoken = 1;
}
else {
- /*
- ** For methods other than LOCK:
- **
- ** If we have no locks, then <seen_locktoken> can be set to true --
- ** pretending that we've already met the requirement of seeing one
- ** of the resource's locks in the If: header.
- **
- ** Otherwise, it must be cleared and we'll look for one.
- */
+ /*
+ ** For methods other than LOCK:
+ **
+ ** If we have no locks, then <seen_locktoken> can be set to true --
+ ** pretending that we've already met the requirement of seeing one
+ ** of the resource's locks in the If: header.
+ **
+ ** Otherwise, it must be cleared and we'll look for one.
+ */
seen_locktoken = (lock_list == NULL);
}
** we fail.
*/
if (if_header == NULL) {
- if (seen_locktoken)
- return NULL;
+ if (seen_locktoken)
+ return NULL;
- return dav_new_error(p, HTTP_LOCKED, 0,
- "This resource is locked and an \"If:\" header "
- "was not supplied to allow access to the "
- "resource.");
+ return dav_new_error(p, HTTP_LOCKED, 0,
+ "This resource is locked and an \"If:\" header "
+ "was not supplied to allow access to the "
+ "resource.");
}
/* the If: header is present */
if (lock_list == NULL && if_header->dummy_header) {
if (flags & DAV_VALIDATE_IS_PARENT)
return NULL;
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "The locktoken specified in the \"Lock-Token:\" "
- "header is invalid because this resource has no "
- "outstanding locks.");
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "The locktoken specified in the \"Lock-Token:\" "
+ "header is invalid because this resource has no "
+ "outstanding locks.");
}
/*
uri = resource->uri;
uri_len = strlen(uri);
if (uri[uri_len - 1] == '/') {
- dav_set_bufsize(p, pbuf, uri_len);
- memcpy(pbuf->buf, uri, uri_len);
- pbuf->buf[--uri_len] = '\0';
- uri = pbuf->buf;
+ dav_set_bufsize(p, pbuf, uri_len);
+ memcpy(pbuf->buf, uri, uri_len);
+ pbuf->buf[--uri_len] = '\0';
+ uri = pbuf->buf;
}
/* get the resource's etag; we may need it during the checks */
* does not match at least one state_list.
*/
for (ifhdr_scan = if_header;
- ifhdr_scan != NULL;
- ifhdr_scan = ifhdr_scan->next) {
-
- /* DBG2("uri=<%s> if_uri=<%s>", uri, ifhdr_scan->uri ? ifhdr_scan->uri : "(no uri)"); */
-
- if (ifhdr_scan->uri != NULL
- && (uri_len != ifhdr_scan->uri_len
- || memcmp(uri, ifhdr_scan->uri, uri_len) != 0)) {
- /*
- ** A tagged-list's URI doesn't match this resource's URI.
- ** Skip to the next state_list to see if it will match.
- */
- continue;
- }
-
- /* this state_list applies to this resource */
-
- /*
- ** ### only one state_list should ever apply! a no-tag, or a tagged
- ** ### where S9.4.2 states only one can match.
- **
- ** ### revamp this code to loop thru ifhdr_scan until we find the
- ** ### matching state_list. process it. stop.
- */
- ++num_that_apply;
-
- /* To succeed, resource must match *all* of the states
- * specified in the state_list.
- */
- for (state_list = ifhdr_scan->state;
- state_list != NULL;
- state_list = state_list->next) {
-
- switch(state_list->type) {
- case dav_if_etag:
- {
- int mismatch = strcmp(state_list->etag, etag);
-
- if (state_list->condition == DAV_IF_COND_NORMAL && mismatch) {
- /*
- ** The specified entity-tag does not match the
- ** entity-tag on the resource. This state_list is
- ** not going to match. Bust outta here.
- */
- reason =
- "an entity-tag was specified, but the resource's "
- "actual ETag does not match.";
- goto state_list_failed;
- }
- else if (state_list->condition == DAV_IF_COND_NOT
- && !mismatch) {
- /*
- ** The specified entity-tag DOES match the
- ** entity-tag on the resource. This state_list is
- ** not going to match. Bust outta here.
- */
- reason =
- "an entity-tag was specified using the \"Not\" form, "
- "but the resource's actual ETag matches the provided "
- "entity-tag.";
- goto state_list_failed;
- }
- break;
- }
-
- case dav_if_opaquelock:
- if (lockdb == NULL) {
- if (state_list->condition == DAV_IF_COND_NOT) {
- /* the locktoken is definitely not there! (success) */
- continue;
- }
-
- /* condition == DAV_IF_COND_NORMAL */
-
- /*
- ** If no lockdb is provided, then validation fails for
- ** this state_list (NORMAL means we were supposed to
- ** find the token, which we obviously cannot do without
- ** a lock database).
- **
- ** Go and try the next state list.
- */
- reason =
- "a State-token was supplied, but a lock database "
- "is not available for to provide the required lock.";
- goto state_list_failed;
- }
-
- /* Resource validation 'fails' if:
- * ANY of the lock->locktokens match
- * a NOT state_list->locktoken,
- * OR
- * NONE of the lock->locktokens match
- * a NORMAL state_list->locktoken.
- */
- num_matched = 0;
- for (lock = lock_list; lock != NULL; lock = lock->next) {
-
- /*
- DBG2("compare: rsrc=%s ifhdr=%s",
- (*locks_hooks->format_locktoken)(p, lock->locktoken),
- (*locks_hooks->format_locktoken)(p, state_list->locktoken));
- */
-
- /* nothing to do if the locktokens do not match. */
- if ((*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) {
- continue;
- }
-
- /*
- ** We have now matched up one of the resource's locktokens
- ** to a locktoken in a State-token in the If: header.
- ** Note this fact, so that we can pass the overall
- ** requirement of seeing at least one of the resource's
- ** locktokens.
- */
- seen_locktoken = 1;
-
- if (state_list->condition == DAV_IF_COND_NOT) {
- /*
- ** This state requires that the specified locktoken
- ** is NOT present on the resource. But we just found
- ** it. There is no way this state-list can now
- ** succeed, so go try another one.
- */
- reason =
- "a State-token was supplied, which used a "
- "\"Not\" condition. The State-token was found "
- "in the locks on this resource";
- goto state_list_failed;
- }
-
- /* condition == DAV_IF_COND_NORMAL */
+ ifhdr_scan != NULL;
+ ifhdr_scan = ifhdr_scan->next) {
+
+ /* DBG2("uri=<%s> if_uri=<%s>", uri, ifhdr_scan->uri ? ifhdr_scan->uri : "(no uri)"); */
+
+ if (ifhdr_scan->uri != NULL
+ && (uri_len != ifhdr_scan->uri_len
+ || memcmp(uri, ifhdr_scan->uri, uri_len) != 0)) {
+ /*
+ ** A tagged-list's URI doesn't match this resource's URI.
+ ** Skip to the next state_list to see if it will match.
+ */
+ continue;
+ }
+
+ /* this state_list applies to this resource */
+
+ /*
+ ** ### only one state_list should ever apply! a no-tag, or a tagged
+ ** ### where S9.4.2 states only one can match.
+ **
+ ** ### revamp this code to loop thru ifhdr_scan until we find the
+ ** ### matching state_list. process it. stop.
+ */
+ ++num_that_apply;
+
+ /* To succeed, resource must match *all* of the states
+ * specified in the state_list.
+ */
+ for (state_list = ifhdr_scan->state;
+ state_list != NULL;
+ state_list = state_list->next) {
+
+ switch(state_list->type) {
+ case dav_if_etag:
+ {
+ int mismatch = strcmp(state_list->etag, etag);
+
+ if (state_list->condition == DAV_IF_COND_NORMAL && mismatch) {
+ /*
+ ** The specified entity-tag does not match the
+ ** entity-tag on the resource. This state_list is
+ ** not going to match. Bust outta here.
+ */
+ reason =
+ "an entity-tag was specified, but the resource's "
+ "actual ETag does not match.";
+ goto state_list_failed;
+ }
+ else if (state_list->condition == DAV_IF_COND_NOT
+ && !mismatch) {
+ /*
+ ** The specified entity-tag DOES match the
+ ** entity-tag on the resource. This state_list is
+ ** not going to match. Bust outta here.
+ */
+ reason =
+ "an entity-tag was specified using the \"Not\" form, "
+ "but the resource's actual ETag matches the provided "
+ "entity-tag.";
+ goto state_list_failed;
+ }
+ break;
+ }
+
+ case dav_if_opaquelock:
+ if (lockdb == NULL) {
+ if (state_list->condition == DAV_IF_COND_NOT) {
+ /* the locktoken is definitely not there! (success) */
+ continue;
+ }
+
+ /* condition == DAV_IF_COND_NORMAL */
+
+ /*
+ ** If no lockdb is provided, then validation fails for
+ ** this state_list (NORMAL means we were supposed to
+ ** find the token, which we obviously cannot do without
+ ** a lock database).
+ **
+ ** Go and try the next state list.
+ */
+ reason =
+ "a State-token was supplied, but a lock database "
+ "is not available for to provide the required lock.";
+ goto state_list_failed;
+ }
+
+ /* Resource validation 'fails' if:
+ * ANY of the lock->locktokens match
+ * a NOT state_list->locktoken,
+ * OR
+ * NONE of the lock->locktokens match
+ * a NORMAL state_list->locktoken.
+ */
+ num_matched = 0;
+ for (lock = lock_list; lock != NULL; lock = lock->next) {
+
+ /*
+ DBG2("compare: rsrc=%s ifhdr=%s",
+ (*locks_hooks->format_locktoken)(p, lock->locktoken),
+ (*locks_hooks->format_locktoken)(p, state_list->locktoken));
+ */
+
+ /* nothing to do if the locktokens do not match. */
+ if ((*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) {
+ continue;
+ }
+
+ /*
+ ** We have now matched up one of the resource's locktokens
+ ** to a locktoken in a State-token in the If: header.
+ ** Note this fact, so that we can pass the overall
+ ** requirement of seeing at least one of the resource's
+ ** locktokens.
+ */
+ seen_locktoken = 1;
+
+ if (state_list->condition == DAV_IF_COND_NOT) {
+ /*
+ ** This state requires that the specified locktoken
+ ** is NOT present on the resource. But we just found
+ ** it. There is no way this state-list can now
+ ** succeed, so go try another one.
+ */
+ reason =
+ "a State-token was supplied, which used a "
+ "\"Not\" condition. The State-token was found "
+ "in the locks on this resource";
+ goto state_list_failed;
+ }
+
+ /* condition == DAV_IF_COND_NORMAL */
/* Validate auth_user: If an authenticated user created
** the lock, only the same user may submit that locktoken
return dav_new_error(p, HTTP_UNAUTHORIZED, 0, errmsg);
}
- /*
- ** We just matched a specified State-Token to one of the
- ** resource's locktokens.
- **
- ** Break out of the lock scan -- we only needed to find
- ** one match (actually, there shouldn't be any other
- ** matches in the lock list).
- */
- num_matched = 1;
- break;
- }
-
- if (num_matched == 0
- && state_list->condition == DAV_IF_COND_NORMAL) {
- /*
- ** We had a NORMAL state, meaning that we should have
- ** found the State-Token within the locks on this
- ** resource. We didn't, so this state_list must fail.
- */
- reason =
- "a State-token was supplied, but it was not found "
- "in the locks on this resource.";
- goto state_list_failed;
- }
-
- break;
-
- } /* switch */
- } /* foreach ( state_list ) */
-
- /*
- ** We've checked every state in this state_list and none of them
- ** have failed. Since all of them succeeded, then we have a matching
- ** state list and we may be done.
- **
- ** The next requirement is that we have seen one of the resource's
- ** locktokens (if any). If we have, then we can just exit. If we
- ** haven't, then we need to keep looking.
- */
- if (seen_locktoken) {
- /* woo hoo! */
- return NULL;
- }
-
- /*
- ** Haven't seen one. Let's break out of the search and just look
- ** for a matching locktoken.
- */
- break;
-
- /*
- ** This label is used when we detect that a state_list is not
- ** going to match this resource. We bust out and try the next
- ** state_list.
- */
+ /*
+ ** We just matched a specified State-Token to one of the
+ ** resource's locktokens.
+ **
+ ** Break out of the lock scan -- we only needed to find
+ ** one match (actually, there shouldn't be any other
+ ** matches in the lock list).
+ */
+ num_matched = 1;
+ break;
+ }
+
+ if (num_matched == 0
+ && state_list->condition == DAV_IF_COND_NORMAL) {
+ /*
+ ** We had a NORMAL state, meaning that we should have
+ ** found the State-Token within the locks on this
+ ** resource. We didn't, so this state_list must fail.
+ */
+ reason =
+ "a State-token was supplied, but it was not found "
+ "in the locks on this resource.";
+ goto state_list_failed;
+ }
+
+ break;
+
+ } /* switch */
+ } /* foreach ( state_list ) */
+
+ /*
+ ** We've checked every state in this state_list and none of them
+ ** have failed. Since all of them succeeded, then we have a matching
+ ** state list and we may be done.
+ **
+ ** The next requirement is that we have seen one of the resource's
+ ** locktokens (if any). If we have, then we can just exit. If we
+ ** haven't, then we need to keep looking.
+ */
+ if (seen_locktoken) {
+ /* woo hoo! */
+ return NULL;
+ }
+
+ /*
+ ** Haven't seen one. Let's break out of the search and just look
+ ** for a matching locktoken.
+ */
+ break;
+
+ /*
+ ** This label is used when we detect that a state_list is not
+ ** going to match this resource. We bust out and try the next
+ ** state_list.
+ */
state_list_failed:
- ;
+ ;
} /* foreach ( ifhdr_scan ) */
*/
if (ifhdr_scan == NULL) {
- /*
- ** We finished the loop without finding any matching state lists.
- */
-
- /*
- ** If none of the state_lists apply to this resource, then we
- ** may have succeeded. Note that this scenario implies a
- ** tagged-list with no matching state_lists. If the If: header
- ** was a no-tag-list, then it would have applied to this resource.
- **
- ** S9.4.2 states that when no state_lists apply, then the header
- ** should be ignored.
- **
- ** If we saw one of the resource's locktokens, then we're done.
- ** If we did not see a locktoken, then we fail.
- */
- if (num_that_apply == 0) {
- if (seen_locktoken)
- return NULL;
-
- /*
- ** We may have aborted the scan before seeing the locktoken.
- ** Rescan the If: header to see if we can find the locktoken
- ** somewhere.
+ /*
+ ** We finished the loop without finding any matching state lists.
+ */
+
+ /*
+ ** If none of the state_lists apply to this resource, then we
+ ** may have succeeded. Note that this scenario implies a
+ ** tagged-list with no matching state_lists. If the If: header
+ ** was a no-tag-list, then it would have applied to this resource.
+ **
+ ** S9.4.2 states that when no state_lists apply, then the header
+ ** should be ignored.
+ **
+ ** If we saw one of the resource's locktokens, then we're done.
+ ** If we did not see a locktoken, then we fail.
+ */
+ if (num_that_apply == 0) {
+ if (seen_locktoken)
+ return NULL;
+
+ /*
+ ** We may have aborted the scan before seeing the locktoken.
+ ** Rescan the If: header to see if we can find the locktoken
+ ** somewhere.
**
** Note that seen_locktoken == 0 implies lock_list != NULL
** which implies locks_hooks != NULL.
- */
- if (dav_find_submitted_locktoken(if_header, lock_list,
- locks_hooks)) {
- /*
- ** We found a match! We're set... none of the If: header
- ** assertions apply (implicit success), and the If: header
- ** specified the locktoken somewhere. We're done.
- */
- return NULL;
- }
-
- return dav_new_error(p, HTTP_LOCKED, 0 /* error_id */,
- "This resource is locked and the \"If:\" "
- "header did not specify one of the "
- "locktokens for this resource's lock(s).");
- }
- /* else: one or more state_lists were applicable, but failed. */
-
- /*
- ** If the dummy_header did not match, then they specified an
- ** incorrect token in the Lock-Token header. Forget whether the
- ** If: statement matched or not... we'll tell them about the
- ** bad Lock-Token first. That is considered a 400 (Bad Request).
- */
- if (if_header->dummy_header) {
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "The locktoken specified in the "
- "\"Lock-Token:\" header did not specify one "
- "of this resource's locktoken(s).");
- }
-
- if (reason == NULL) {
- return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
- "The preconditions specified by the \"If:\" "
- "header did not match this resource.");
- }
-
- return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
- apr_psprintf(p,
- "The precondition(s) specified by "
- "the \"If:\" header did not match "
- "this resource. At least one "
- "failure is because: %s", reason));
+ */
+ if (dav_find_submitted_locktoken(if_header, lock_list,
+ locks_hooks)) {
+ /*
+ ** We found a match! We're set... none of the If: header
+ ** assertions apply (implicit success), and the If: header
+ ** specified the locktoken somewhere. We're done.
+ */
+ return NULL;
+ }
+
+ return dav_new_error(p, HTTP_LOCKED, 0 /* error_id */,
+ "This resource is locked and the \"If:\" "
+ "header did not specify one of the "
+ "locktokens for this resource's lock(s).");
+ }
+ /* else: one or more state_lists were applicable, but failed. */
+
+ /*
+ ** If the dummy_header did not match, then they specified an
+ ** incorrect token in the Lock-Token header. Forget whether the
+ ** If: statement matched or not... we'll tell them about the
+ ** bad Lock-Token first. That is considered a 400 (Bad Request).
+ */
+ if (if_header->dummy_header) {
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "The locktoken specified in the "
+ "\"Lock-Token:\" header did not specify one "
+ "of this resource's locktoken(s).");
+ }
+
+ if (reason == NULL) {
+ return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
+ "The preconditions specified by the \"If:\" "
+ "header did not match this resource.");
+ }
+
+ return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
+ apr_psprintf(p,
+ "The precondition(s) specified by "
+ "the \"If:\" header did not match "
+ "this resource. At least one "
+ "failure is because: %s", reason));
}
/* assert seen_locktoken == 0 */
** locks_hooks != NULL.
*/
if (dav_find_submitted_locktoken(if_header, lock_list, locks_hooks)) {
- /*
- ** We found a match! We're set... we have a matching state list,
- ** and the If: header specified the locktoken somewhere. We're done.
- */
- return NULL;
+ /*
+ ** We found a match! We're set... we have a matching state list,
+ ** and the If: header specified the locktoken somewhere. We're done.
+ */
+ return NULL;
}
/*
** We want to note the 400 (Bad Request) in favor of a 423 (Locked).
*/
if (if_header->dummy_header) {
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "The locktoken specified in the "
- "\"Lock-Token:\" header did not specify one "
- "of this resource's locktoken(s).");
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "The locktoken specified in the "
+ "\"Lock-Token:\" header did not specify one "
+ "of this resource's locktoken(s).");
}
return dav_new_error(p, HTTP_LOCKED, 1 /* error_id */,
- "This resource is locked and the \"If:\" header "
- "did not specify one of the "
- "locktokens for this resource's lock(s).");
+ "This resource is locked and the \"If:\" header "
+ "did not specify one of the "
+ "locktokens for this resource's lock(s).");
}
/* dav_validate_walker: Walker callback function to validate resource state */
dav_error *err;
if ((err = dav_validate_resource_state(ctx->w.pool, wres->resource,
- ctx->w.lockdb,
- ctx->if_header, ctx->flags,
- &ctx->work_buf, ctx->r)) == NULL) {
- /* There was no error, so just bug out. */
- return NULL;
+ ctx->w.lockdb,
+ ctx->if_header, ctx->flags,
+ &ctx->work_buf, ctx->r)) == NULL) {
+ /* There was no error, so just bug out. */
+ return NULL;
}
/*
if (ap_is_HTTP_SERVER_ERROR(err->status)
|| (*wres->resource->hooks->is_same_resource)(wres->resource,
ctx->w.root)) {
- /* ### maybe push a higher-level description? */
- return err;
+ /* ### maybe push a higher-level description? */
+ return err;
}
/* associate the error with the current URI */
** error is necessary, response will point to it, else NULL.
*/
dav_error * dav_validate_request(request_rec *r, dav_resource *resource,
- int depth, dav_locktoken *locktoken,
- dav_response **response, int flags,
+ int depth, dav_locktoken *locktoken,
+ dav_response **response, int flags,
dav_lockdb *lockdb)
{
dav_error *err;
#if DAV_DEBUG
if (depth && response == NULL) {
- /*
- ** ### bleck. we can't return errors for other URIs unless we have
+ /*
+ ** ### bleck. we can't return errors for other URIs unless we have
** ### a "response" ptr.
- */
- return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "DESIGN ERROR: dav_validate_request called "
+ */
+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "DESIGN ERROR: dav_validate_request called "
"with depth>0, but no response ptr.");
}
#endif
if (response != NULL)
- *response = NULL;
+ *response = NULL;
/* Do the standard checks for conditional requests using
* If-..-Since, If-Match etc */
if ((result = ap_meets_conditions(r)) != OK) {
- /* ### fix this up... how? */
- return dav_new_error(r->pool, result, 0, NULL);
+ /* ### fix this up... how? */
+ return dav_new_error(r->pool, result, 0, NULL);
}
/* always parse (and later process) the If: header */
if ((err = dav_process_if_header(r, &if_header)) != NULL) {
- /* ### maybe add higher-level description */
- return err;
+ /* ### maybe add higher-level description */
+ return err;
}
/* If a locktoken was specified, create a dummy if_header with which
* locks, but a Lock-Token header without an if-header to remove them.
*/
if (locktoken != NULL) {
- dav_if_header *ifhdr_new;
+ dav_if_header *ifhdr_new;
- ifhdr_new = apr_pcalloc(r->pool, sizeof(*ifhdr_new));
- ifhdr_new->uri = resource->uri;
- ifhdr_new->uri_len = strlen(resource->uri);
- ifhdr_new->dummy_header = 1;
+ ifhdr_new = apr_pcalloc(r->pool, sizeof(*ifhdr_new));
+ ifhdr_new->uri = resource->uri;
+ ifhdr_new->uri_len = strlen(resource->uri);
+ ifhdr_new->dummy_header = 1;
- ifhdr_new->state = apr_pcalloc(r->pool, sizeof(*ifhdr_new->state));
- ifhdr_new->state->type = dav_if_opaquelock;
- ifhdr_new->state->condition = DAV_IF_COND_NORMAL;
- ifhdr_new->state->locktoken = locktoken;
+ ifhdr_new->state = apr_pcalloc(r->pool, sizeof(*ifhdr_new->state));
+ ifhdr_new->state->type = dav_if_opaquelock;
+ ifhdr_new->state->condition = DAV_IF_COND_NORMAL;
+ ifhdr_new->state->locktoken = locktoken;
- ifhdr_new->next = if_header;
- if_header = ifhdr_new;
+ ifhdr_new->next = if_header;
+ if_header = ifhdr_new;
}
/*
if (lockdb == NULL) {
if (locks_hooks != NULL) {
if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) {
- /* ### maybe insert higher-level comment */
- return err;
+ /* ### maybe insert higher-level comment */
+ return err;
}
lock_db_opened_locally = 1;
}
dav_walker_ctx ctx = { { 0 } };
dav_response *multi_status;
- ctx.w.walk_type = DAV_WALKTYPE_NORMAL;
- ctx.w.func = dav_validate_walker;
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL;
+ ctx.w.func = dav_validate_walker;
ctx.w.walk_ctx = &ctx;
- ctx.w.pool = r->pool;
+ ctx.w.pool = r->pool;
ctx.w.root = resource;
- ctx.if_header = if_header;
- ctx.r = r;
+ ctx.if_header = if_header;
+ ctx.r = r;
ctx.flags = flags;
- if (lockdb != NULL) {
- ctx.w.lockdb = lockdb;
- ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL;
- }
+ if (lockdb != NULL) {
+ ctx.w.lockdb = lockdb;
+ ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL;
+ }
- err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
- if (err == NULL) {
+ err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
+ if (err == NULL) {
*response = multi_status;;
- }
+ }
/* else: implies a 5xx status code occurred. */
}
else {
- err = dav_validate_resource_state(r->pool, resource, lockdb,
- if_header, flags, &work_buf, r);
+ err = dav_validate_resource_state(r->pool, resource, lockdb,
+ if_header, flags, &work_buf, r);
}
/* (2) Validate the parent resource if requested */
err = (*repos_hooks->get_parent_resource)(resource, &parent_resource);
- if (err == NULL && parent_resource == NULL) {
- err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0,
- "Cannot access parent of repository root.");
- }
- else if (err == NULL) {
- err = dav_validate_resource_state(r->pool, parent_resource, lockdb,
- if_header,
+ if (err == NULL && parent_resource == NULL) {
+ err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0,
+ "Cannot access parent of repository root.");
+ }
+ else if (err == NULL) {
+ err = dav_validate_resource_state(r->pool, parent_resource, lockdb,
+ if_header,
flags | DAV_VALIDATE_IS_PARENT,
&work_buf, r);
-
- /*
- ** This error occurred on the parent resource. This implies that
- ** we have to create a multistatus response (to report the error
- ** against a URI other than the Request-URI). "Convert" this error
- ** into a multistatus response.
- */
- if (err != NULL) {
- new_response = apr_pcalloc(r->pool, sizeof(*new_response));
-
- new_response->href = parent_resource->uri;
- new_response->status = err->status;
- new_response->desc =
- "A validation error has occurred on the parent resource, "
- "preventing the operation on the resource specified by "
- "the Request-URI.";
+
+ /*
+ ** This error occurred on the parent resource. This implies that
+ ** we have to create a multistatus response (to report the error
+ ** against a URI other than the Request-URI). "Convert" this error
+ ** into a multistatus response.
+ */
+ if (err != NULL) {
+ new_response = apr_pcalloc(r->pool, sizeof(*new_response));
+
+ new_response->href = parent_resource->uri;
+ new_response->status = err->status;
+ new_response->desc =
+ "A validation error has occurred on the parent resource, "
+ "preventing the operation on the resource specified by "
+ "the Request-URI.";
if (err->desc != NULL) {
new_response->desc = apr_pstrcat(r->pool,
new_response->desc,
" The error was: ",
err->desc, NULL);
}
-
- /* assert: DAV_VALIDATE_PARENT implies response != NULL */
- new_response->next = *response;
- *response = new_response;
-
- err = NULL;
- }
- }
+
+ /* assert: DAV_VALIDATE_PARENT implies response != NULL */
+ new_response->next = *response;
+ *response = new_response;
+
+ err = NULL;
+ }
+ }
}
if (lock_db_opened_locally)
dav_error *err;
dav_if_header *if_header;
dav_if_state_list *if_state;
- dav_locktoken_list *lock_token = NULL;
-
+ dav_locktoken_list *lock_token = NULL;
+
*ltl = NULL;
if ((err = dav_process_if_header(r, &if_header)) != NULL) {
- /* ### add a higher-level description? */
- return err;
+ /* ### add a higher-level description? */
+ return err;
}
-
+
while (if_header != NULL) {
- if_state = if_header->state; /* Begining of the if_state linked list */
- while (if_state != NULL) {
- if (if_state->condition == DAV_IF_COND_NORMAL
- && if_state->type == dav_if_opaquelock) {
- lock_token = apr_pcalloc(r->pool, sizeof(dav_locktoken_list));
- lock_token->locktoken = if_state->locktoken;
- lock_token->next = *ltl;
- *ltl = lock_token;
- }
- if_state = if_state->next;
- }
- if_header = if_header->next;
+ if_state = if_header->state; /* Begining of the if_state linked list */
+ while (if_state != NULL) {
+ if (if_state->condition == DAV_IF_COND_NORMAL
+ && if_state->type == dav_if_opaquelock) {
+ lock_token = apr_pcalloc(r->pool, sizeof(dav_locktoken_list));
+ lock_token->locktoken = if_state->locktoken;
+ lock_token->next = *ltl;
+ *ltl = lock_token;
+ }
+ if_state = if_state->next;
+ }
+ if_header = if_header->next;
}
if (*ltl == NULL) {
- /* No nodes added */
- return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_ABSENT,
- "No locktokens were specified in the \"If:\" "
- "header, so the refresh could not be performed.");
+ /* No nodes added */
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_ABSENT,
+ "No locktokens were specified in the \"If:\" "
+ "header, so the refresh could not be performed.");
}
return NULL;
* in the response, add it.
*/
void dav_add_vary_header(request_rec *in_req,
- request_rec *out_req,
- const dav_resource *resource)
+ request_rec *out_req,
+ const dav_resource *resource)
{
const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(in_req);
/* Only versioning headers require a Vary response header,
* so only do this check if there is a versioning provider */
if (vsn_hooks != NULL) {
- const char *target = apr_table_get(in_req->headers_in, DAV_LABEL_HDR);
- const char *vary = apr_table_get(out_req->headers_out, "Vary");
+ const char *target = apr_table_get(in_req->headers_in, DAV_LABEL_HDR);
+ const char *vary = apr_table_get(out_req->headers_out, "Vary");
/* If Target-Selector specified, add it to the Vary header */
- if (target != NULL) {
- if (vary == NULL)
- vary = DAV_LABEL_HDR;
- else
- vary = apr_pstrcat(out_req->pool, vary, "," DAV_LABEL_HDR,
+ if (target != NULL) {
+ if (vary == NULL)
+ vary = DAV_LABEL_HDR;
+ else
+ vary = apr_pstrcat(out_req->pool, vary, "," DAV_LABEL_HDR,
NULL);
- apr_table_setn(out_req->headers_out, "Vary", vary);
- }
+ apr_table_setn(out_req->headers_out, "Vary", vary);
+ }
}
}
}
if ((err = dav_lock_query(*lockdb, resource, &lock_list)) != NULL) {
- return dav_push_error(r->pool,
- HTTP_INTERNAL_SERVER_ERROR, 0,
- "The locks could not be queried for "
- "determining auto-versioning behavior.",
- err);
+ return dav_push_error(r->pool,
+ HTTP_INTERNAL_SERVER_ERROR, 0,
+ "The locks could not be queried for "
+ "determining auto-versioning behavior.",
+ err);
}
if (lock_list != NULL)
/* check parent resource if requested or if resource must be created */
if (!resource->exists || parent_only) {
- dav_resource *parent;
+ dav_resource *parent;
if ((err = (*resource->hooks->get_parent_resource)(resource,
&parent)) != NULL)
goto done;
if (parent == NULL || !parent->exists) {
- err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
- apr_psprintf(r->pool,
- "Missing one or more intermediate "
+ err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
+ apr_psprintf(r->pool,
+ "Missing one or more intermediate "
"collections. Cannot create resource %s.",
- ap_escape_html(r->pool, resource->uri)));
+ ap_escape_html(r->pool, resource->uri)));
goto done;
}
av_info->parent_resource = parent;
/* if parent versioned and not checked out, see if it can be */
- if (parent->versioned && !parent->working) {
+ if (parent->versioned && !parent->working) {
int checkout_parent;
if ((err = dav_can_auto_checkout(r, parent,
}
if (!checkout_parent) {
- err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
- "<DAV:cannot-modify-checked-in-parent>");
+ err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
+ "<DAV:cannot-modify-checked-in-parent>");
goto done;
}
* Note that auto-versioning can only be applied to a version selector,
* so no separate working resource will be created.
*/
- if ((err = (*vsn_hooks->checkout)(parent, 1 /*auto_checkout*/,
+ if ((err = (*vsn_hooks->checkout)(parent, 1 /*auto_checkout*/,
0, 0, 0, NULL, NULL))
!= NULL)
{
- err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
- apr_psprintf(r->pool,
- "Unable to auto-checkout parent collection. "
- "Cannot create resource %s.",
- ap_escape_html(r->pool, resource->uri)),
+ err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
+ apr_psprintf(r->pool,
+ "Unable to auto-checkout parent collection. "
+ "Cannot create resource %s.",
+ ap_escape_html(r->pool, resource->uri)),
err);
goto done;
- }
+ }
/* remember that parent was checked out */
av_info->parent_checkedout = 1;
- }
+ }
}
/* if only checking parent, we're done */
if (!resource->exists
&& (*vsn_hooks->auto_versionable)(resource) == DAV_AUTO_VERSION_ALWAYS) {
- if ((err = (*vsn_hooks->vsn_control)(resource, NULL)) != NULL) {
- err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
- apr_psprintf(r->pool,
- "Unable to create versioned resource %s.",
- ap_escape_html(r->pool, resource->uri)),
+ if ((err = (*vsn_hooks->vsn_control)(resource, NULL)) != NULL) {
+ err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
+ apr_psprintf(r->pool,
+ "Unable to create versioned resource %s.",
+ ap_escape_html(r->pool, resource->uri)),
err);
goto done;
- }
+ }
/* remember that resource was created */
av_info->resource_versioned = 1;
}
if (!checkout_resource) {
- err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
- "<DAV:cannot-modify-version-controlled-content>");
+ err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
+ "<DAV:cannot-modify-version-controlled-content>");
goto done;
}
/* Auto-versioning can only be applied to version selectors, so
* no separate working resource will be created. */
- if ((err = (*vsn_hooks->checkout)(resource, 1 /*auto_checkout*/,
+ if ((err = (*vsn_hooks->checkout)(resource, 1 /*auto_checkout*/,
0, 0, 0, NULL, NULL))
!= NULL)
{
err = dav_push_error(r->pool, HTTP_CONFLICT, 0,
- apr_psprintf(r->pool,
- "Unable to checkout resource %s.",
- ap_escape_html(r->pool, resource->uri)),
+ apr_psprintf(r->pool,
+ "Unable to checkout resource %s.",
+ ap_escape_html(r->pool, resource->uri)),
err);
goto done;
- }
+ }
/* remember that resource was checked out */
av_info->resource_checkedout = 1;
if (av_info->resource_checkedout) {
if ((err = (*vsn_hooks->uncheckout)(resource)) != NULL) {
return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- apr_psprintf(r->pool,
- "Unable to undo auto-checkout "
+ apr_psprintf(r->pool,
+ "Unable to undo auto-checkout "
"of resource %s.",
- ap_escape_html(r->pool, resource->uri)),
+ ap_escape_html(r->pool, resource->uri)),
err);
}
}
if (av_info->resource_versioned) {
- dav_response *response;
+ dav_response *response;
- /* ### should we do anything with the response? */
+ /* ### should we do anything with the response? */
if ((err = (*resource->hooks->remove_resource)(resource,
- &response)) != NULL) {
+ &response)) != NULL) {
return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- apr_psprintf(r->pool,
- "Unable to undo auto-version-control "
+ apr_psprintf(r->pool,
+ "Unable to undo auto-version-control "
"of resource %s.",
- ap_escape_html(r->pool, resource->uri)),
+ ap_escape_html(r->pool, resource->uri)),
err);
}
}
if (av_info->parent_resource != NULL && av_info->parent_checkedout) {
if ((err = (*vsn_hooks->uncheckout)(av_info->parent_resource)) != NULL) {
- return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- apr_psprintf(r->pool,
- "Unable to undo auto-checkout "
+ return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ apr_psprintf(r->pool,
+ "Unable to undo auto-checkout "
"of parent collection %s.",
- ap_escape_html(r->pool, av_info->parent_resource->uri)),
- err);
- }
+ ap_escape_html(r->pool, av_info->parent_resource->uri)),
+ err);
+ }
}
return NULL;
0 /*keep_checked_out*/, NULL))
!= NULL) {
return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- apr_psprintf(r->pool,
- "Unable to auto-checkin resource %s.",
- ap_escape_html(r->pool, resource->uri)),
- err);
+ apr_psprintf(r->pool,
+ "Unable to auto-checkin resource %s.",
+ ap_escape_html(r->pool, resource->uri)),
+ err);
}
}
}
if (auto_version == DAV_AUTO_VERSION_ALWAYS ||
(unlock && (auto_version == DAV_AUTO_VERSION_LOCKED))) {
- if ((err = (*vsn_hooks->checkin)(av_info->parent_resource,
+ if ((err = (*vsn_hooks->checkin)(av_info->parent_resource,
0 /*keep_checked_out*/, NULL))
!= NULL) {
- return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- apr_psprintf(r->pool,
- "Unable to auto-checkin parent collection %s.",
- ap_escape_html(r->pool, av_info->parent_resource->uri)),
- err);
- }
+ return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ apr_psprintf(r->pool,
+ "Unable to auto-checkin parent collection %s.",
+ ap_escape_html(r->pool, av_info->parent_resource->uri)),
+ err);
+ }
}
}
** an activelock element for every item in the lock_discovery tree
*/
const char *dav_lock_get_activelock(request_rec *r, dav_lock *lock,
- dav_buffer *pbuf)
+ dav_buffer *pbuf)
{
dav_lock *lock_scan;
const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);
/* If no locks or no lock provider, there are no locks */
if (lock == NULL || hooks == NULL) {
- /*
- ** Since resourcediscovery is defined with (activelock)*,
- ** <D:activelock/> shouldn't be necessary for an empty lock.
- */
- return "";
+ /*
+ ** Since resourcediscovery is defined with (activelock)*,
+ ** <D:activelock/> shouldn't be necessary for an empty lock.
+ */
+ return "";
}
/*
** locktoken strings could be relatively expensive.
*/
for (lock_scan = lock; lock_scan != NULL; lock_scan = lock_scan->next)
- count++;
+ count++;
/* if a buffer was not provided, then use an internal buffer */
if (pbuf == NULL)
- pbuf = &work_buf;
+ pbuf = &work_buf;
/* reset the length before we start appending stuff */
pbuf->cur_len = 0;
dav_check_bufsize(p, pbuf, count * 300);
for (; lock != NULL; lock = lock->next) {
- char tmp[100];
+ char tmp[100];
#if DAV_DEBUG
- if (lock->rectype == DAV_LOCKREC_INDIRECT_PARTIAL) {
- /* ### crap. design error */
- dav_buffer_append(p, pbuf,
- "DESIGN ERROR: attempted to product an "
- "activelock element from a partial, indirect "
- "lock record. Creating an XML parsing error "
- "to ease detection of this situation: <");
- }
+ if (lock->rectype == DAV_LOCKREC_INDIRECT_PARTIAL) {
+ /* ### crap. design error */
+ dav_buffer_append(p, pbuf,
+ "DESIGN ERROR: attempted to product an "
+ "activelock element from a partial, indirect "
+ "lock record. Creating an XML parsing error "
+ "to ease detection of this situation: <");
+ }
#endif
- dav_buffer_append(p, pbuf, "<D:activelock>" DEBUG_CR "<D:locktype>");
- switch (lock->type) {
- case DAV_LOCKTYPE_WRITE:
- dav_buffer_append(p, pbuf, "<D:write/>");
- break;
- default:
- /* ### internal error. log something? */
- break;
- }
- dav_buffer_append(p, pbuf, "</D:locktype>" DEBUG_CR "<D:lockscope>");
- switch (lock->scope) {
- case DAV_LOCKSCOPE_EXCLUSIVE:
- dav_buffer_append(p, pbuf, "<D:exclusive/>");
- break;
- case DAV_LOCKSCOPE_SHARED:
- dav_buffer_append(p, pbuf, "<D:shared/>");
- break;
- default:
- /* ### internal error. log something? */
- break;
- }
- dav_buffer_append(p, pbuf, "</D:lockscope>" DEBUG_CR);
- sprintf(tmp, "<D:depth>%s</D:depth>" DEBUG_CR,
- lock->depth == DAV_INFINITY ? "infinity" : "0");
- dav_buffer_append(p, pbuf, tmp);
-
- if (lock->owner) {
- /*
- ** This contains a complete, self-contained <DAV:owner> element,
- ** with namespace declarations and xml:lang handling. Just drop
- ** it in.
- */
- dav_buffer_append(p, pbuf, lock->owner);
- }
-
- dav_buffer_append(p, pbuf, "<D:timeout>");
- if (lock->timeout == DAV_TIMEOUT_INFINITE) {
- dav_buffer_append(p, pbuf, "Infinite");
- }
- else {
- time_t now = time(NULL);
- sprintf(tmp, "Second-%lu", (long unsigned int)(lock->timeout - now));
- dav_buffer_append(p, pbuf, tmp);
- }
-
- dav_buffer_append(p, pbuf,
- "</D:timeout>" DEBUG_CR
- "<D:locktoken>" DEBUG_CR
- "<D:href>");
- dav_buffer_append(p, pbuf,
- (*hooks->format_locktoken)(p, lock->locktoken));
- dav_buffer_append(p, pbuf,
- "</D:href>" DEBUG_CR
- "</D:locktoken>" DEBUG_CR
- "</D:activelock>" DEBUG_CR);
+ dav_buffer_append(p, pbuf, "<D:activelock>" DEBUG_CR "<D:locktype>");
+ switch (lock->type) {
+ case DAV_LOCKTYPE_WRITE:
+ dav_buffer_append(p, pbuf, "<D:write/>");
+ break;
+ default:
+ /* ### internal error. log something? */
+ break;
+ }
+ dav_buffer_append(p, pbuf, "</D:locktype>" DEBUG_CR "<D:lockscope>");
+ switch (lock->scope) {
+ case DAV_LOCKSCOPE_EXCLUSIVE:
+ dav_buffer_append(p, pbuf, "<D:exclusive/>");
+ break;
+ case DAV_LOCKSCOPE_SHARED:
+ dav_buffer_append(p, pbuf, "<D:shared/>");
+ break;
+ default:
+ /* ### internal error. log something? */
+ break;
+ }
+ dav_buffer_append(p, pbuf, "</D:lockscope>" DEBUG_CR);
+ sprintf(tmp, "<D:depth>%s</D:depth>" DEBUG_CR,
+ lock->depth == DAV_INFINITY ? "infinity" : "0");
+ dav_buffer_append(p, pbuf, tmp);
+
+ if (lock->owner) {
+ /*
+ ** This contains a complete, self-contained <DAV:owner> element,
+ ** with namespace declarations and xml:lang handling. Just drop
+ ** it in.
+ */
+ dav_buffer_append(p, pbuf, lock->owner);
+ }
+
+ dav_buffer_append(p, pbuf, "<D:timeout>");
+ if (lock->timeout == DAV_TIMEOUT_INFINITE) {
+ dav_buffer_append(p, pbuf, "Infinite");
+ }
+ else {
+ time_t now = time(NULL);
+ sprintf(tmp, "Second-%lu", (long unsigned int)(lock->timeout - now));
+ dav_buffer_append(p, pbuf, tmp);
+ }
+
+ dav_buffer_append(p, pbuf,
+ "</D:timeout>" DEBUG_CR
+ "<D:locktoken>" DEBUG_CR
+ "<D:href>");
+ dav_buffer_append(p, pbuf,
+ (*hooks->format_locktoken)(p, lock->locktoken));
+ dav_buffer_append(p, pbuf,
+ "</D:href>" DEBUG_CR
+ "</D:locktoken>" DEBUG_CR
+ "</D:activelock>" DEBUG_CR);
}
return pbuf->buf;
** with its contents.
*/
dav_error * dav_lock_parse_lockinfo(request_rec *r,
- const dav_resource *resource,
- dav_lockdb *lockdb,
- const apr_xml_doc *doc,
- dav_lock **lock_request)
+ const dav_resource *resource,
+ dav_lockdb *lockdb,
+ const apr_xml_doc *doc,
+ dav_lock **lock_request)
{
apr_pool_t *p = r->pool;
dav_error *err;
dav_lock *lock;
if (!dav_validate_root(doc, "lockinfo")) {
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "The request body contains an unexpected "
- "XML root element.");
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "The request body contains an unexpected "
+ "XML root element.");
}
if ((err = (*lockdb->hooks->create_lock)(lockdb, resource,
&lock)) != NULL) {
- return dav_push_error(p, err->status, 0,
- "Could not parse the lockinfo due to an "
- "internal problem creating a lock structure.",
- err);
+ return dav_push_error(p, err->status, 0,
+ "Could not parse the lockinfo due to an "
+ "internal problem creating a lock structure.",
+ err);
}
lock->depth = dav_get_depth(r, DAV_INFINITY);
if (lock->depth == -1) {
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "An invalid Depth header was specified.");
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "An invalid Depth header was specified.");
}
lock->timeout = dav_get_timeout(r);
/* Parse elements in the XML body */
for (child = doc->root->first_child; child; child = child->next) {
- if (strcmp(child->name, "locktype") == 0
- && child->first_child
- && lock->type == DAV_LOCKTYPE_UNKNOWN) {
- if (strcmp(child->first_child->name, "write") == 0) {
- lock->type = DAV_LOCKTYPE_WRITE;
- continue;
- }
- }
- if (strcmp(child->name, "lockscope") == 0
- && child->first_child
- && lock->scope == DAV_LOCKSCOPE_UNKNOWN) {
- if (strcmp(child->first_child->name, "exclusive") == 0)
- lock->scope = DAV_LOCKSCOPE_EXCLUSIVE;
- else if (strcmp(child->first_child->name, "shared") == 0)
- lock->scope = DAV_LOCKSCOPE_SHARED;
- if (lock->scope != DAV_LOCKSCOPE_UNKNOWN)
- continue;
- }
-
- if (strcmp(child->name, "owner") == 0 && lock->owner == NULL) {
- const char *text;
-
- /* quote all the values in the <DAV:owner> element */
- apr_xml_quote_elem(p, child);
-
- /*
- ** Store a full <DAV:owner> element with namespace definitions
- ** and an xml:lang definition, if applicable.
- */
- apr_xml_to_text(p, child, APR_XML_X2T_FULL_NS_LANG, doc->namespaces,
- NULL, &text, NULL);
- lock->owner = text;
-
- continue;
- }
-
- return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
- apr_psprintf(p,
- "The server cannot satisfy the "
- "LOCK request due to an unknown XML "
- "element (\"%s\") within the "
- "DAV:lockinfo element.",
- child->name));
+ if (strcmp(child->name, "locktype") == 0
+ && child->first_child
+ && lock->type == DAV_LOCKTYPE_UNKNOWN) {
+ if (strcmp(child->first_child->name, "write") == 0) {
+ lock->type = DAV_LOCKTYPE_WRITE;
+ continue;
+ }
+ }
+ if (strcmp(child->name, "lockscope") == 0
+ && child->first_child
+ && lock->scope == DAV_LOCKSCOPE_UNKNOWN) {
+ if (strcmp(child->first_child->name, "exclusive") == 0)
+ lock->scope = DAV_LOCKSCOPE_EXCLUSIVE;
+ else if (strcmp(child->first_child->name, "shared") == 0)
+ lock->scope = DAV_LOCKSCOPE_SHARED;
+ if (lock->scope != DAV_LOCKSCOPE_UNKNOWN)
+ continue;
+ }
+
+ if (strcmp(child->name, "owner") == 0 && lock->owner == NULL) {
+ const char *text;
+
+ /* quote all the values in the <DAV:owner> element */
+ apr_xml_quote_elem(p, child);
+
+ /*
+ ** Store a full <DAV:owner> element with namespace definitions
+ ** and an xml:lang definition, if applicable.
+ */
+ apr_xml_to_text(p, child, APR_XML_X2T_FULL_NS_LANG, doc->namespaces,
+ NULL, &text, NULL);
+ lock->owner = text;
+
+ continue;
+ }
+
+ return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0,
+ apr_psprintf(p,
+ "The server cannot satisfy the "
+ "LOCK request due to an unknown XML "
+ "element (\"%s\") within the "
+ "DAV:lockinfo element.",
+ child->name));
}
*lock_request = lock;
/* We don't want to set indirects on the target */
if ((*wres->resource->hooks->is_same_resource)(wres->resource,
ctx->w.root))
- return NULL;
+ return NULL;
if ((err = (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
wres->resource, 1,
ctx->lock)) != NULL) {
- if (ap_is_HTTP_SERVER_ERROR(err->status)) {
- /* ### add a higher-level description? */
- return err;
- }
-
- /* add to the multistatus response */
- dav_add_response(wres, err->status, NULL);
-
- /*
- ** ### actually, this is probably wrong: we want to fail the whole
- ** ### LOCK process if something goes bad. maybe the caller should
- ** ### do a dav_unlock() (e.g. a rollback) if any errors occurred.
- */
+ if (ap_is_HTTP_SERVER_ERROR(err->status)) {
+ /* ### add a higher-level description? */
+ return err;
+ }
+
+ /* add to the multistatus response */
+ dav_add_response(wres, err->status, NULL);
+
+ /*
+ ** ### actually, this is probably wrong: we want to fail the whole
+ ** ### LOCK process if something goes bad. maybe the caller should
+ ** ### do a dav_unlock() (e.g. a rollback) if any errors occurred.
+ */
}
return NULL;
** ### assume request only contains one lock
*/
dav_error * dav_add_lock(request_rec *r, const dav_resource *resource,
- dav_lockdb *lockdb, dav_lock *lock,
- dav_response **response)
+ dav_lockdb *lockdb, dav_lock *lock,
+ dav_response **response)
{
dav_error *err;
int depth = lock->depth;
** no internal children); pretend the client gave the correct depth.
*/
if (!resource->collection) {
- depth = 0;
+ depth = 0;
}
/* In all cases, first add direct entry in lockdb */
*/
if ((err = (*lockdb->hooks->append_locks)(lockdb, resource, 0,
lock)) != NULL) {
- /* ### maybe add a higher-level description */
- return err;
+ /* ### maybe add a higher-level description */
+ return err;
}
if (depth > 0) {
- /* Walk existing collection and set indirect locks */
+ /* Walk existing collection and set indirect locks */
dav_walker_ctx ctx = { { 0 } };
dav_response *multi_status;
- ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
- ctx.w.func = dav_lock_walker;
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
+ ctx.w.func = dav_lock_walker;
ctx.w.walk_ctx = &ctx;
- ctx.w.pool = r->pool;
+ ctx.w.pool = r->pool;
ctx.w.root = resource;
- ctx.w.lockdb = lockdb;
-
- ctx.r = r;
- ctx.lock = lock;
-
- err = (*resource->hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
- if (err != NULL) {
- /* implies a 5xx status code occurred. screw the multistatus */
- return err;
- }
-
- if (multi_status != NULL) {
- /* manufacture a 207 error for the multistatus response */
- *response = multi_status;
- return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0,
- "Error(s) occurred on resources during the "
- "addition of a depth lock.");
- }
+ ctx.w.lockdb = lockdb;
+
+ ctx.r = r;
+ ctx.lock = lock;
+
+ err = (*resource->hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
+ if (err != NULL) {
+ /* implies a 5xx status code occurred. screw the multistatus */
+ return err;
+ }
+
+ if (multi_status != NULL) {
+ /* manufacture a 207 error for the multistatus response */
+ *response = multi_status;
+ return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0,
+ "Error(s) occurred on resources during the "
+ "addition of a depth lock.");
+ }
}
return NULL;
/* ### insert a higher-level description? */
return (*lockdb->hooks->get_locks)(lockdb, resource,
- DAV_GETLOCKS_RESOLVED,
- locks);
+ DAV_GETLOCKS_RESOLVED,
+ locks);
}
/* dav_unlock_walker: Walker callback function to remove indirect locks */
if ((err = (*ctx->w.lockdb->hooks->remove_lock)(ctx->w.lockdb,
wres->resource,
ctx->locktoken)) != NULL) {
- /* ### should we stop or return a multistatus? looks like STOP */
- /* ### add a higher-level description? */
- return err;
+ /* ### should we stop or return a multistatus? looks like STOP */
+ /* ### add a higher-level description? */
+ return err;
}
return NULL;
** able to return this information with a traversal.
*/
static dav_error * dav_get_direct_resource(apr_pool_t *p,
- dav_lockdb *lockdb,
- const dav_locktoken *locktoken,
- const dav_resource *resource,
- const dav_resource **direct_resource)
+ dav_lockdb *lockdb,
+ const dav_locktoken *locktoken,
+ const dav_resource *resource,
+ const dav_resource **direct_resource)
{
if (lockdb->hooks->lookup_resource != NULL) {
- return (*lockdb->hooks->lookup_resource)(lockdb, locktoken,
- resource, direct_resource);
+ return (*lockdb->hooks->lookup_resource)(lockdb, locktoken,
+ resource, direct_resource);
}
*direct_resource = NULL;
* Else fail.
*/
while (resource != NULL) {
- dav_error *err;
- dav_lock *lock;
+ dav_error *err;
+ dav_lock *lock;
dav_resource *parent;
- /*
- ** Find the lock specified by <locktoken> on <resource>. If it is
- ** an indirect lock, then partial results are okay. We're just
- ** trying to find the thing and know whether it is a direct or
- ** an indirect lock.
- */
- if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken,
- 1, &lock)) != NULL) {
- /* ### add a higher-level desc? */
- return err;
- }
-
- /* not found! that's an error. */
- if (lock == NULL) {
- return dav_new_error(p, HTTP_BAD_REQUEST, 0,
- "The specified locktoken does not correspond "
- "to an existing lock on this resource.");
- }
-
- if (lock->rectype == DAV_LOCKREC_DIRECT) {
- /* we found the direct lock. return this resource. */
-
- *direct_resource = resource;
- return NULL;
- }
-
- /* the lock was indirect. move up a level in the URL namespace */
- if ((err = (*resource->hooks->get_parent_resource)(resource,
+ /*
+ ** Find the lock specified by <locktoken> on <resource>. If it is
+ ** an indirect lock, then partial results are okay. We're just
+ ** trying to find the thing and know whether it is a direct or
+ ** an indirect lock.
+ */
+ if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken,
+ 1, &lock)) != NULL) {
+ /* ### add a higher-level desc? */
+ return err;
+ }
+
+ /* not found! that's an error. */
+ if (lock == NULL) {
+ return dav_new_error(p, HTTP_BAD_REQUEST, 0,
+ "The specified locktoken does not correspond "
+ "to an existing lock on this resource.");
+ }
+
+ if (lock->rectype == DAV_LOCKREC_DIRECT) {
+ /* we found the direct lock. return this resource. */
+
+ *direct_resource = resource;
+ return NULL;
+ }
+
+ /* the lock was indirect. move up a level in the URL namespace */
+ if ((err = (*resource->hooks->get_parent_resource)(resource,
&parent)) != NULL) {
/* ### add a higher-level desc? */
return err;
}
return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
- "The lock database is corrupt. A direct lock could "
- "not be found for the corresponding indirect lock "
- "on this resource.");
+ "The lock database is corrupt. A direct lock could "
+ "not be found for the corresponding indirect lock "
+ "on this resource.");
}
/*
** by us; there should be no need to incorporate a rollback.
*/
int dav_unlock(request_rec *r, const dav_resource *resource,
- const dav_locktoken *locktoken)
+ const dav_locktoken *locktoken)
{
int result;
dav_lockdb *lockdb;
*/
if ((err = (*hooks->open_lockdb)(r, 0, 1, &lockdb)) != NULL) {
- /* ### return err! maybe add a higher-level desc */
- /* ### map result to something nice; log an error */
- return HTTP_INTERNAL_SERVER_ERROR;
+ /* ### return err! maybe add a higher-level desc */
+ /* ### map result to something nice; log an error */
+ return HTTP_INTERNAL_SERVER_ERROR;
}
if (locktoken != NULL
- && (err = dav_get_direct_resource(r->pool, lockdb,
- locktoken, resource,
- &lock_resource)) != NULL) {
- /* ### add a higher-level desc? */
- /* ### should return err! */
- return err->status;
+ && (err = dav_get_direct_resource(r->pool, lockdb,
+ locktoken, resource,
+ &lock_resource)) != NULL) {
+ /* ### add a higher-level desc? */
+ /* ### should return err! */
+ return err->status;
}
/* At this point, lock_resource/locktoken refers to a direct lock (key), ie
dav_walker_ctx *ctx = wres->walk_ctx;
if (ctx->skip_root
- && (*wres->resource->hooks->is_same_resource)(wres->resource,
+ && (*wres->resource->hooks->is_same_resource)(wres->resource,
ctx->w.root)) {
- return NULL;
+ return NULL;
}
/* ### maybe add a higher-level desc */
** parent of resource to resource and below.
*/
static dav_error * dav_inherit_locks(request_rec *r, dav_lockdb *lockdb,
- const dav_resource *resource,
- int use_parent)
+ const dav_resource *resource,
+ int use_parent)
{
dav_error *err;
const dav_resource *which_resource;
if (use_parent) {
dav_resource *parent;
- if ((err = (*repos_hooks->get_parent_resource)(resource,
+ if ((err = (*repos_hooks->get_parent_resource)(resource,
&parent)) != NULL) {
/* ### add a higher-level desc? */
return err;
}
- if (parent == NULL) {
- /* ### map result to something nice; log an error */
- return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
- "Could not fetch parent resource. Unable to "
- "inherit locks from the parent and apply "
- "them to this resource.");
- }
+ if (parent == NULL) {
+ /* ### map result to something nice; log an error */
+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not fetch parent resource. Unable to "
+ "inherit locks from the parent and apply "
+ "them to this resource.");
+ }
which_resource = parent;
}
else {
- which_resource = resource;
+ which_resource = resource;
}
if ((err = (*lockdb->hooks->get_locks)(lockdb, which_resource,
- DAV_GETLOCKS_PARTIAL,
- &locks)) != NULL) {
- /* ### maybe add a higher-level desc */
- return err;
+ DAV_GETLOCKS_PARTIAL,
+ &locks)) != NULL) {
+ /* ### maybe add a higher-level desc */
+ return err;
}
if (locks == NULL) {
- /* No locks to propagate, just return */
- return NULL;
+ /* No locks to propagate, just return */
+ return NULL;
}
/*
** depth "infinity".
*/
for (scan = locks, prev = NULL;
- scan != NULL;
- prev = scan, scan = scan->next) {
+ scan != NULL;
+ prev = scan, scan = scan->next) {
- if (scan->rectype == DAV_LOCKREC_DIRECT
- && scan->depth != DAV_INFINITY) {
+ if (scan->rectype == DAV_LOCKREC_DIRECT
+ && scan->depth != DAV_INFINITY) {
- if (prev == NULL)
- locks = scan->next;
- else
- prev->next = scan->next;
- }
+ if (prev == NULL)
+ locks = scan->next;
+ else
+ prev->next = scan->next;
+ }
}
/* <locks> has all our new locks. Walk down and propagate them. */
const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);
if (resource->exists)
- return DAV_RESOURCE_EXISTS;
+ return DAV_RESOURCE_EXISTS;
if (hooks != NULL) {
- dav_error *err;
- dav_lockdb *lockdb;
- int locks_present;
-
- /*
- ** A locknull resource has the form:
- **
- ** known-dir "/" locknull-file
- **
- ** It would be nice to look into <resource> to verify this form,
- ** but it does not have enough information for us. Instead, we
- ** can look at the path_info. If the form does not match, then
- ** there is no way we could have a locknull resource -- it must
- ** be a plain, null resource.
- **
- ** Apache sets r->filename to known-dir/unknown-file and r->path_info
- ** to "" for the "proper" case. If anything is in path_info, then
- ** it can't be a locknull resource.
- **
- ** ### I bet this path_info hack doesn't work for repositories.
- ** ### Need input from repository implementors! What kind of
- ** ### restructure do we need? New provider APIs?
- */
- if (r->path_info != NULL && *r->path_info != '\0') {
- return DAV_RESOURCE_NULL;
- }
-
+ dav_error *err;
+ dav_lockdb *lockdb;
+ int locks_present;
+
+ /*
+ ** A locknull resource has the form:
+ **
+ ** known-dir "/" locknull-file
+ **
+ ** It would be nice to look into <resource> to verify this form,
+ ** but it does not have enough information for us. Instead, we
+ ** can look at the path_info. If the form does not match, then
+ ** there is no way we could have a locknull resource -- it must
+ ** be a plain, null resource.
+ **
+ ** Apache sets r->filename to known-dir/unknown-file and r->path_info
+ ** to "" for the "proper" case. If anything is in path_info, then
+ ** it can't be a locknull resource.
+ **
+ ** ### I bet this path_info hack doesn't work for repositories.
+ ** ### Need input from repository implementors! What kind of
+ ** ### restructure do we need? New provider APIs?
+ */
+ if (r->path_info != NULL && *r->path_info != '\0') {
+ return DAV_RESOURCE_NULL;
+ }
+
if ((err = (*hooks->open_lockdb)(r, 1, 1, &lockdb)) == NULL) {
- /* note that we might see some expired locks... *shrug* */
- err = (*hooks->has_locks)(lockdb, resource, &locks_present);
- (*hooks->close_lockdb)(lockdb);
+ /* note that we might see some expired locks... *shrug* */
+ err = (*hooks->has_locks)(lockdb, resource, &locks_present);
+ (*hooks->close_lockdb)(lockdb);
}
if (err != NULL) {
- /* ### don't log an error. return err. add higher-level desc. */
+ /* ### don't log an error. return err. add higher-level desc. */
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Failed to query lock-null status for %s",
- r->filename);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Failed to query lock-null status for %s",
+ r->filename);
- return DAV_RESOURCE_ERROR;
+ return DAV_RESOURCE_ERROR;
}
- if (locks_present)
- return DAV_RESOURCE_LOCK_NULL;
+ if (locks_present)
+ return DAV_RESOURCE_LOCK_NULL;
}
return DAV_RESOURCE_NULL;
}
dav_error * dav_notify_created(request_rec *r,
- dav_lockdb *lockdb,
- const dav_resource *resource,
- int resource_state,
- int depth)
+ dav_lockdb *lockdb,
+ const dav_resource *resource,
+ int resource_state,
+ int depth)
{
dav_error *err;
if (resource_state == DAV_RESOURCE_LOCK_NULL) {
- /*
- ** The resource is no longer a locknull resource. This will remove
- ** the special marker.
- **
- ** Note that a locknull resource has already inherited all of the
- ** locks from the parent. We do not need to call dav_inherit_locks.
- **
- ** NOTE: some lock providers record locks for locknull resources using
- ** a different key than for regular resources. this will shift
- ** the lock information between the two key types.
- */
- (void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource);
-
- /*
- ** There are resources under this one, which are new. We must
- ** propagate the locks down to the new resources.
- */
- if (depth > 0 &&
- (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) {
- /* ### add a higher level desc? */
- return err;
- }
+ /*
+ ** The resource is no longer a locknull resource. This will remove
+ ** the special marker.
+ **
+ ** Note that a locknull resource has already inherited all of the
+ ** locks from the parent. We do not need to call dav_inherit_locks.
+ **
+ ** NOTE: some lock providers record locks for locknull resources using
+ ** a different key than for regular resources. this will shift
+ ** the lock information between the two key types.
+ */
+ (void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource);
+
+ /*
+ ** There are resources under this one, which are new. We must
+ ** propagate the locks down to the new resources.
+ */
+ if (depth > 0 &&
+ (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) {
+ /* ### add a higher level desc? */
+ return err;
+ }
}
else if (resource_state == DAV_RESOURCE_NULL) {
- /* ### should pass depth to dav_inherit_locks so that it can
- ** ### optimize for the depth==0 case.
- */
+ /* ### should pass depth to dav_inherit_locks so that it can
+ ** ### optimize for the depth==0 case.
+ */
- /* this resource should inherit locks from its parent */
- if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) {
+ /* this resource should inherit locks from its parent */
+ if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) {
- err = dav_push_error(r->pool, err->status, 0,
- "The resource was created successfully, but "
- "there was a problem inheriting locks from "
- "the parent resource.",
- err);
- return err;
- }
+ err = dav_push_error(r->pool, err->status, 0,
+ "The resource was created successfully, but "
+ "there was a problem inheriting locks from "
+ "the parent resource.",
+ err);
+ return err;
+ }
}
/* else the resource already exists and its locks are correct. */