Apache HTTPD
util_lock.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18** DAV repository-independent lock functions
19*/
20
21#include "apr.h"
22#include "apr_strings.h"
23
24#include "mod_dav.h"
25#include "http_log.h"
26#include "http_config.h"
27#include "http_protocol.h"
28#include "http_core.h"
29
31
32/* ---------------------------------------------------------------
33**
34** Property-related lock functions
35**
36*/
37
38/*
39** dav_lock_get_activelock: Returns a <lockdiscovery> containing
40** an activelock element for every item in the lock_discovery tree
41*/
45{
48 int count = 0;
49 dav_buffer work_buf = { 0 };
50 apr_pool_t *p = r->pool;
51
52 /* If no locks or no lock provider, there are no locks */
53 if (lock == NULL || hooks == NULL) {
54 /*
55 ** Since resourcediscovery is defined with (activelock)*,
56 ** <D:activelock/> shouldn't be necessary for an empty lock.
57 */
58 return "";
59 }
60
61 /*
62 ** Note: it could be interesting to sum the lengths of the owners
63 ** and locktokens during this loop. However, the buffer
64 ** mechanism provides some rough padding so that we don't
65 ** really need to have an exact size. Further, constructing
66 ** locktoken strings could be relatively expensive.
67 */
68 for (lock_scan = lock; lock_scan != NULL; lock_scan = lock_scan->next)
69 count++;
70
71 /* if a buffer was not provided, then use an internal buffer */
72 if (pbuf == NULL)
73 pbuf = &work_buf;
74
75 /* reset the length before we start appending stuff */
76 pbuf->cur_len = 0;
77
78 /* prep the buffer with a "good" size */
80
81 for (; lock != NULL; lock = lock->next) {
82 char tmp[100];
83
84#if DAV_DEBUG
85 if (lock->rectype == DAV_LOCKREC_INDIRECT_PARTIAL) {
86 /* ### crap. design error */
88 "DESIGN ERROR: attempted to product an "
89 "activelock element from a partial, indirect "
90 "lock record. Creating an XML parsing error "
91 "to ease detection of this situation: <");
92 }
93#endif
94
95 dav_buffer_append(p, pbuf, "<D:activelock>" DEBUG_CR "<D:locktype>");
96 switch (lock->type) {
98 dav_buffer_append(p, pbuf, "<D:write/>");
99 break;
100 default:
101 /* ### internal error. log something? */
102 break;
103 }
104 dav_buffer_append(p, pbuf, "</D:locktype>" DEBUG_CR "<D:lockscope>");
105 switch (lock->scope) {
107 dav_buffer_append(p, pbuf, "<D:exclusive/>");
108 break;
110 dav_buffer_append(p, pbuf, "<D:shared/>");
111 break;
112 default:
113 /* ### internal error. log something? */
114 break;
115 }
116 dav_buffer_append(p, pbuf, "</D:lockscope>" DEBUG_CR);
117 apr_snprintf(tmp, sizeof(tmp), "<D:depth>%s</D:depth>" DEBUG_CR,
118 lock->depth == DAV_INFINITY ? "infinity" : "0");
119 dav_buffer_append(p, pbuf, tmp);
120
121 if (lock->owner) {
122 /*
123 ** This contains a complete, self-contained <DAV:owner> element,
124 ** with namespace declarations and xml:lang handling. Just drop
125 ** it in.
126 */
127 dav_buffer_append(p, pbuf, lock->owner);
128 }
129
130 dav_buffer_append(p, pbuf, "<D:timeout>");
131 if (lock->timeout == DAV_TIMEOUT_INFINITE) {
132 dav_buffer_append(p, pbuf, "Infinite");
133 }
134 else {
135 time_t now = time(NULL);
136
137 /*
138 ** Check if the timeout is not, for any reason, already elapsed.
139 ** (e.g., because of a large collection, or disk under heavy load...)
140 */
141 if (now >= lock->timeout) {
142 dav_buffer_append(p, pbuf, "Second-0");
143 }
144 else {
145 apr_snprintf(tmp, sizeof(tmp), "Second-%lu", (long unsigned int)(lock->timeout - now));
146 dav_buffer_append(p, pbuf, tmp);
147 }
148 }
149
151 "</D:timeout>" DEBUG_CR
152 "<D:locktoken>" DEBUG_CR
153 "<D:href>");
155 (*hooks->format_locktoken)(p, lock->locktoken));
157 "</D:href>" DEBUG_CR
158 "</D:locktoken>" DEBUG_CR
159 "</D:activelock>" DEBUG_CR);
160 }
161
162 return pbuf->buf;
163}
164
165/*
166** dav_lock_parse_lockinfo: Validates the given xml_doc to contain a
167** lockinfo XML element, then populates a dav_lock structure
168** with its contents.
169*/
171 const dav_resource *resource,
172 dav_lockdb *lockdb,
173 const apr_xml_doc *doc,
175{
176 apr_pool_t *p = r->pool;
177 dav_error *err;
178 apr_xml_elem *child;
179 dav_lock *lock;
180
181 if (!dav_validate_root(doc, "lockinfo")) {
182 return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
183 "The request body contains an unexpected "
184 "XML root element.");
185 }
186
187 if ((err = (*lockdb->hooks->create_lock)(lockdb, resource,
188 &lock)) != NULL) {
189 return dav_push_error(p, err->status, 0,
190 "Could not parse the lockinfo due to an "
191 "internal problem creating a lock structure.",
192 err);
193 }
194
195 lock->depth = dav_get_depth(r, DAV_INFINITY);
196 if (lock->depth == -1) {
197 return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
198 "An invalid Depth header was specified.");
199 }
200 lock->timeout = dav_get_timeout(r);
201
202 /* Parse elements in the XML body */
203 for (child = doc->root->first_child; child; child = child->next) {
204 if (strcmp(child->name, "locktype") == 0
205 && child->first_child
206 && lock->type == DAV_LOCKTYPE_UNKNOWN) {
207 if (strcmp(child->first_child->name, "write") == 0) {
208 lock->type = DAV_LOCKTYPE_WRITE;
209 continue;
210 }
211 }
212 if (strcmp(child->name, "lockscope") == 0
213 && child->first_child
214 && lock->scope == DAV_LOCKSCOPE_UNKNOWN) {
215 if (strcmp(child->first_child->name, "exclusive") == 0)
217 else if (strcmp(child->first_child->name, "shared") == 0)
218 lock->scope = DAV_LOCKSCOPE_SHARED;
219 if (lock->scope != DAV_LOCKSCOPE_UNKNOWN)
220 continue;
221 }
222
223 if (strcmp(child->name, "owner") == 0 && lock->owner == NULL) {
224 const char *text;
225
226 /* quote all the values in the <DAV:owner> element */
227 apr_xml_quote_elem(p, child);
228
229 /*
230 ** Store a full <DAV:owner> element with namespace definitions
231 ** and an xml:lang definition, if applicable.
232 */
234 NULL, &text, NULL);
235 lock->owner = text;
236
237 continue;
238 }
239
242 "The server cannot satisfy the "
243 "LOCK request due to an unknown XML "
244 "element (\"%s\") within the "
245 "DAV:lockinfo element.",
246 child->name));
247 }
248
250 return NULL;
251}
252
253/* ---------------------------------------------------------------
254**
255** General lock functions
256**
257*/
258
259/* dav_lock_walker: Walker callback function to record indirect locks */
261{
262 dav_walker_ctx *ctx = wres->walk_ctx;
263 dav_error *err;
264
265 /* We don't want to set indirects on the target */
266 if ((*wres->resource->hooks->is_same_resource)(wres->resource,
267 ctx->w.root))
268 return NULL;
269
270 if ((err = (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
271 wres->resource, 1,
272 ctx->lock)) != NULL) {
273 if (ap_is_HTTP_SERVER_ERROR(err->status)) {
274 /* ### add a higher-level description? */
275 return err;
276 }
277
278 /* add to the multistatus response */
279 dav_add_response(wres, err->status, NULL);
280
281 /*
282 ** ### actually, this is probably wrong: we want to fail the whole
283 ** ### LOCK process if something goes bad. maybe the caller should
284 ** ### do a dav_unlock() (e.g. a rollback) if any errors occurred.
285 */
286 }
287
288 return NULL;
289}
290
291/*
292** dav_add_lock: Add a direct lock for resource, and indirect locks for
293** all children, bounded by depth.
294** ### assume request only contains one lock
295*/
297 const dav_resource *resource,
298 dav_lockdb *lockdb, dav_lock *lock,
299 dav_response **response)
300{
301 dav_error *err;
302 int depth = lock->depth;
303
304 *response = NULL;
305
306 /* Requested lock can be:
307 * Depth: 0 for null resource, existing resource, or existing collection
308 * Depth: Inf for existing collection
309 */
310
311 /*
312 ** 2518 9.2 says to ignore depth if target is not a collection (it has
313 ** no internal children); pretend the client gave the correct depth.
314 */
315 if (!resource->collection) {
316 depth = 0;
317 }
318
319 /* In all cases, first add direct entry in lockdb */
320
321 /*
322 ** Append the new (direct) lock to the resource's existing locks.
323 **
324 ** Note: this also handles locknull resources
325 */
326 if ((err = (*lockdb->hooks->append_locks)(lockdb, resource, 0,
327 lock)) != NULL) {
328 /* ### maybe add a higher-level description */
329 return err;
330 }
331
332 if (depth > 0) {
333 /* Walk existing collection and set indirect locks */
334 dav_walker_ctx ctx = { { 0 } };
336
338 ctx.w.func = dav_lock_walker;
339 ctx.w.walk_ctx = &ctx;
340 ctx.w.pool = r->pool;
341 ctx.w.root = resource;
342 ctx.w.lockdb = lockdb;
343
344 ctx.r = r;
345 ctx.lock = lock;
346
347 err = (*resource->hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
348 if (err != NULL) {
349 /* implies a 5xx status code occurred. screw the multistatus */
350 return err;
351 }
352
353 if (multi_status != NULL) {
354 /* manufacture a 207 error for the multistatus response */
355 *response = multi_status;
356 return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, 0,
357 "Error(s) occurred on resources during the "
358 "addition of a depth lock.");
359 }
360 }
361
362 return NULL;
363}
364
365/*
366** dav_lock_query: Opens the lock database. Returns a linked list of
367** dav_lock structures for all direct locks on path.
368*/
370 const dav_resource *resource,
371 dav_lock **locks)
372{
373 /* If no lock database, return empty result */
374 if (lockdb == NULL) {
375 *locks = NULL;
376 return NULL;
377 }
378
379 /* ### insert a higher-level description? */
380 return (*lockdb->hooks->get_locks)(lockdb, resource,
382 locks);
383}
384
385/* dav_unlock_walker: Walker callback function to remove indirect locks */
387{
388 dav_walker_ctx *ctx = wres->walk_ctx;
389 dav_error *err;
390
391 /* Before removing the lock, do any auto-checkin required */
392 if (wres->resource->working) {
393 /* ### get rid of this typecast */
394 if ((err = dav_auto_checkin(ctx->r, (dav_resource *) wres->resource,
395 0 /*undo*/, 1 /*unlock*/, NULL))
396 != NULL) {
397 return err;
398 }
399 }
400
401 if ((err = (*ctx->w.lockdb->hooks->remove_lock)(ctx->w.lockdb,
402 wres->resource,
403 ctx->locktoken)) != NULL) {
404 /* ### should we stop or return a multistatus? looks like STOP */
405 /* ### add a higher-level description? */
406 return err;
407 }
408
409 return NULL;
410}
411
412/*
413** dav_get_direct_resource:
414**
415** Find a lock on the specified resource, then return the resource the
416** lock was applied to (in other words, given a (possibly) indirect lock,
417** return the direct lock's corresponding resource).
418**
419** If the lock is an indirect lock, this usually means traversing up the
420** namespace [repository] hierarchy. Note that some lock providers may be
421** able to return this information with a traversal.
422*/
424 dav_lockdb *lockdb,
425 const dav_locktoken *locktoken,
426 const dav_resource *resource,
428{
429 if (lockdb->hooks->lookup_resource != NULL) {
430 return (*lockdb->hooks->lookup_resource)(lockdb, locktoken,
432 }
433
435
436 /* Find the top of this lock-
437 * If r->filename's direct locks include locktoken, use r->filename.
438 * If r->filename's indirect locks include locktoken, retry r->filename/..
439 * Else fail.
440 */
441 while (resource != NULL) {
442 dav_error *err;
443 dav_lock *lock;
445
446 /*
447 ** Find the lock specified by <locktoken> on <resource>. If it is
448 ** an indirect lock, then partial results are okay. We're just
449 ** trying to find the thing and know whether it is a direct or
450 ** an indirect lock.
451 */
452 if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken,
453 1, &lock)) != NULL) {
454 /* ### add a higher-level desc? */
455 return err;
456 }
457
458 /* not found! that's an error. */
459 if (lock == NULL) {
460 return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
461 "The specified locktoken does not correspond "
462 "to an existing lock on this resource.");
463 }
464
465 if (lock->rectype == DAV_LOCKREC_DIRECT) {
466 /* we found the direct lock. return this resource. */
467
469 return NULL;
470 }
471
472 /* the lock was indirect. move up a level in the URL namespace */
473 if ((err = (*resource->hooks->get_parent_resource)(resource,
474 &parent)) != NULL) {
475 /* ### add a higher-level desc? */
476 return err;
477 }
479 }
480
482 "The lock database is corrupt. A direct lock could "
483 "not be found for the corresponding indirect lock "
484 "on this resource.");
485}
486
487/*
488** dav_unlock: Removes all direct and indirect locks for r->filename,
489** with given locktoken. If locktoken == null_locktoken, all locks
490** are removed. If r->filename represents an indirect lock,
491** we must unlock the appropriate direct lock.
492** Returns OK or appropriate HTTP_* response and logs any errors.
493**
494** ### We've already crawled the tree to ensure everything was locked
495** by us; there should be no need to incorporate a rollback.
496*/
498 const dav_locktoken *locktoken)
499{
500 int result;
501 dav_lockdb *lockdb;
505 dav_walker_ctx ctx = { { 0 } };
507 dav_error *err;
508
509 /* If no locks provider, then there is nothing to unlock. */
510 if (hooks == NULL) {
511 return OK;
512 }
513
514 /* 2518 requires the entire lock to be removed if resource/locktoken
515 * point to an indirect lock. We need resource of the _direct_
516 * lock in order to walk down the tree and remove the locks. So,
517 * If locktoken != null_locktoken,
518 * Walk up the resource hierarchy until we see a direct lock.
519 * Or, we could get the direct lock's db/key, pick out the URL
520 * and do a subrequest. I think walking up is faster and will work
521 * all the time.
522 * Else
523 * Just start removing all locks at and below resource.
524 */
525
526 if ((err = (*hooks->open_lockdb)(r, 0, 1, &lockdb)) != NULL) {
527 /* ### return err! maybe add a higher-level desc */
528 /* ### map result to something nice; log an error */
530 }
531
532 if (locktoken != NULL
533 && (err = dav_get_direct_resource(r->pool, lockdb,
534 locktoken, resource,
535 &lock_resource)) != NULL) {
536 /* ### add a higher-level desc? */
537 /* ### should return err! */
538 return err->status;
539 }
540
541 /* At this point, lock_resource/locktoken refers to a direct lock (key), ie
542 * the root of a depth > 0 lock, or locktoken is null.
543 */
545 ctx.w.func = dav_unlock_walker;
546 ctx.w.walk_ctx = &ctx;
547 ctx.w.pool = r->pool;
548 ctx.w.root = lock_resource;
549 ctx.w.lockdb = lockdb;
550
551 ctx.r = r;
552 ctx.locktoken = locktoken;
553
554 err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
555
556 /* ### fix this! */
557 /* ### do something with multi_status */
558 result = err == NULL ? OK : err->status;
559
560 (*hooks->close_lockdb)(lockdb);
561
562 return result;
563}
564
565/* dav_inherit_walker: Walker callback function to inherit locks */
567{
568 dav_walker_ctx *ctx = wres->walk_ctx;
569
570 if (ctx->skip_root
571 && (*wres->resource->hooks->is_same_resource)(wres->resource,
572 ctx->w.root)) {
573 return NULL;
574 }
575
576 /* ### maybe add a higher-level desc */
577 return (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
578 wres->resource, 1,
579 ctx->lock);
580}
581
582/*
583** dav_inherit_locks: When a resource or collection is added to a collection,
584** locks on the collection should be inherited to the resource/collection.
585** (MOVE, MKCOL, etc) Here we propagate any direct or indirect locks from
586** parent of resource to resource and below.
587*/
589 const dav_resource *resource,
590 int use_parent)
591{
592 dav_error *err;
594 dav_lock *locks;
595 dav_lock *scan;
596 dav_lock *prev;
597 dav_walker_ctx ctx = { { 0 } };
600
601 if (use_parent) {
603 if ((err = (*repos_hooks->get_parent_resource)(resource,
604 &parent)) != NULL) {
605 /* ### add a higher-level desc? */
606 return err;
607 }
608 if (parent == NULL) {
609 /* ### map result to something nice; log an error */
611 "Could not fetch parent resource. Unable to "
612 "inherit locks from the parent and apply "
613 "them to this resource.");
614 }
616 }
617 else {
619 }
620
621 if ((err = (*lockdb->hooks->get_locks)(lockdb, which_resource,
623 &locks)) != NULL) {
624 /* ### maybe add a higher-level desc */
625 return err;
626 }
627
628 if (locks == NULL) {
629 /* No locks to propagate, just return */
630 return NULL;
631 }
632
633 /*
634 ** (1) Copy all indirect locks from our parent;
635 ** (2) Create indirect locks for the depth infinity, direct locks
636 ** in our parent.
637 **
638 ** The append_locks call in the walker callback will do the indirect
639 ** conversion, but we need to remove any direct locks that are NOT
640 ** depth "infinity".
641 */
642 for (scan = locks, prev = NULL;
643 scan != NULL;
644 prev = scan, scan = scan->next) {
645
646 if (scan->rectype == DAV_LOCKREC_DIRECT
647 && scan->depth != DAV_INFINITY) {
648
649 if (prev == NULL)
650 locks = scan->next;
651 else
652 prev->next = scan->next;
653 }
654 }
655
656 /* <locks> has all our new locks. Walk down and propagate them. */
657
659 ctx.w.func = dav_inherit_walker;
660 ctx.w.walk_ctx = &ctx;
661 ctx.w.pool = r->pool;
662 ctx.w.root = resource;
663 ctx.w.lockdb = lockdb;
664
665 ctx.r = r;
666 ctx.lock = locks;
667 ctx.skip_root = !use_parent;
668
669 /* ### do something with multi_status */
670 return (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
671}
672
673/* ---------------------------------------------------------------
674**
675** Functions dealing with lock-null resources
676**
677*/
678
679/*
680** dav_get_resource_state: Returns the state of the resource
681** r->filename: DAV_RESOURCE_NULL, DAV_RESOURCE_LOCK_NULL,
682** or DAV_RESOURCE_EXIST.
683**
684** Returns DAV_RESOURCE_ERROR if an error occurs.
685*/
687 const dav_resource *resource)
688{
690
691 if (resource->exists)
692 return DAV_RESOURCE_EXISTS;
693
694 if (hooks != NULL) {
695 dav_error *err;
696 dav_lockdb *lockdb;
697 int locks_present;
698
699 /*
700 ** A locknull resource has the form:
701 **
702 ** known-dir "/" locknull-file
703 **
704 ** It would be nice to look into <resource> to verify this form,
705 ** but it does not have enough information for us. Instead, we
706 ** can look at the path_info. If the form does not match, then
707 ** there is no way we could have a locknull resource -- it must
708 ** be a plain, null resource.
709 **
710 ** Apache sets r->filename to known-dir/unknown-file and r->path_info
711 ** to "" for the "proper" case. If anything is in path_info, then
712 ** it can't be a locknull resource.
713 **
714 ** ### I bet this path_info hack doesn't work for repositories.
715 ** ### Need input from repository implementors! What kind of
716 ** ### restructure do we need? New provider APIs?
717 */
718 if (r->path_info != NULL && *r->path_info != '\0') {
719 return DAV_RESOURCE_NULL;
720 }
721
722 if ((err = (*hooks->open_lockdb)(r, 1, 1, &lockdb)) == NULL) {
723 /* note that we might see some expired locks... *shrug* */
724 err = (*hooks->has_locks)(lockdb, resource, &locks_present);
725 (*hooks->close_lockdb)(lockdb);
726 }
727
728 if (err != NULL) {
729 /* ### don't log an error. return err. add higher-level desc. */
730
732 "Failed to query lock-null status for %s",
733 r->filename);
734
735 return DAV_RESOURCE_ERROR;
736 }
737
738 if (locks_present)
740 }
741
742 return DAV_RESOURCE_NULL;
743}
744
746 dav_lockdb *lockdb,
747 const dav_resource *resource,
748 int resource_state,
749 int depth)
750{
751 dav_error *err;
752
754
755 /*
756 ** The resource is no longer a locknull resource. This will remove
757 ** the special marker.
758 **
759 ** Note that a locknull resource has already inherited all of the
760 ** locks from the parent. We do not need to call dav_inherit_locks.
761 **
762 ** NOTE: some lock providers record locks for locknull resources using
763 ** a different key than for regular resources. this will shift
764 ** the lock information between the two key types.
765 */
766 (void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource);
767
768 /*
769 ** There are resources under this one, which are new. We must
770 ** propagate the locks down to the new resources.
771 */
772 if (depth > 0 &&
773 (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) {
774 /* ### add a higher level desc? */
775 return err;
776 }
777 }
778 else if (resource_state == DAV_RESOURCE_NULL) {
779
780 /* ### should pass depth to dav_inherit_locks so that it can
781 ** ### optimize for the depth==0 case.
782 */
783
784 /* this resource should inherit locks from its parent */
785 if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) {
786
787 err = dav_push_error(r->pool, err->status, 0,
788 "The resource was created successfully, but "
789 "there was a problem inheriting locks from "
790 "the parent resource.",
791 err);
792 return err;
793 }
794 }
795 /* else the resource already exists and its locks are correct. */
796
797 return NULL;
798}
APR Strings library.
static sem_id lock
Definition threadpriv.c:21
#define APLOG_USE_MODULE(foo)
request_rec * r
#define OK
Definition httpd.h:456
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
unsigned int count
Definition apr_md5.h:152
apr_brigade_flush void * ctx
void ** resource
apr_text_header const char * text
Definition apr_xml.h:78
#define APR_XML_X2T_FULL_NS_LANG
Definition apr_xml.h:295
const apr_xml_elem int apr_array_header_t int const char ** pbuf
Definition apr_xml.h:288
#define HTTP_BAD_REQUEST
Definition httpd.h:508
#define HTTP_MULTI_STATUS
Definition httpd.h:497
#define HTTP_PRECONDITION_FAILED
Definition httpd.h:520
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define ap_is_HTTP_SERVER_ERROR(x)
Definition httpd.h:558
#define DAV_GET_HOOKS_LOCKS(r)
Definition mod_dav.h:808
#define DAV_RESOURCE_LOCK_NULL
Definition mod_dav.h:1671
int dav_get_depth(request_rec *r, int def_depth)
Definition mod_dav.c:704
void dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, const char *str)
Definition util.c:152
const char * dav_lock_get_activelock(request_rec *r, dav_lock *lock, dav_buffer *pbuf)
Definition util_lock.c:42
#define DAV_RESOURCE_NULL
Definition mod_dav.h:1672
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)
Definition util_lock.c:170
int dav_unlock(request_rec *r, const dav_resource *resource, const dav_locktoken *locktoken)
Definition util_lock.c:497
dav_error * dav_auto_checkin(request_rec *r, dav_resource *resource, int undo, int unlock, dav_auto_version_info *av_info)
Definition util.c:2107
#define DEBUG_CR
Definition mod_dav.h:65
dav_error * dav_lock_query(dav_lockdb *lockdb, const dav_resource *resource, dav_lock **locks)
Definition util_lock.c:369
void dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf, apr_size_t extra_needed)
Definition util.c:107
dav_error * dav_add_lock(request_rec *r, const dav_resource *resource, dav_lockdb *lockdb, dav_lock *lock, dav_response **response)
Definition util_lock.c:296
#define DAV_INFINITY
Definition mod_dav.h:79
time_t dav_get_timeout(request_rec *r)
Definition util.c:542
int dav_validate_root(const apr_xml_doc *doc, const char *tagname)
Definition util.c:328
#define DAV_RESOURCE_ERROR
Definition mod_dav.h:1674
int dav_get_resource_state(request_rec *r, const dav_resource *resource)
Definition util_lock.c:686
dav_error * dav_push_error(apr_pool_t *p, int status, int error_id, const char *desc, dav_error *prev)
Definition util.c:66
dav_error * dav_notify_created(request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, int resource_state, int depth)
Definition util_lock.c:745
#define DAV_DECLARE(type)
Definition mod_dav.h:85
#define DAV_TIMEOUT_INFINITE
Definition mod_dav.h:1314
dav_error * dav_new_error(apr_pool_t *p, int status, int error_id, apr_status_t aprerr, const char *desc)
Definition util.c:36
#define DAV_RESOURCE_EXISTS
Definition mod_dav.h:1673
void dav_add_response(dav_walk_resource *wres, int status, dav_get_props_result *propstats)
Definition mod_dav.c:1245
@ DAV_LOCKREC_DIRECT
Definition mod_dav.h:1353
@ DAV_LOCKREC_INDIRECT_PARTIAL
Definition mod_dav.h:1355
@ DAV_LOCKSCOPE_UNKNOWN
Definition mod_dav.h:1342
@ DAV_LOCKSCOPE_SHARED
Definition mod_dav.h:1344
@ DAV_LOCKSCOPE_EXCLUSIVE
Definition mod_dav.h:1343
@ DAV_LOCKTYPE_UNKNOWN
Definition mod_dav.h:1348
@ DAV_LOCKTYPE_WRITE
Definition mod_dav.h:1349
apr_size_t size
apr_array_header_t ** result
apr_pool_t * parent
Definition apr_pools.h:197
apr_int32_t apr_int32_t apr_int32_t err
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
apr_pool_t * p
Definition md_event.c:32
DAV extension module for Apache 2.0.*.
#define DAV_WALKTYPE_AUTH
Definition mod_dav.h:1819
#define DAV_GETLOCKS_PARTIAL
Definition mod_dav.h:1567
#define DAV_GETLOCKS_RESOLVED
Definition mod_dav.h:1566
#define DAV_WALKTYPE_LOCKNULL
Definition mod_dav.h:1821
#define DAV_WALKTYPE_NORMAL
Definition mod_dav.h:1820
static const char *const hooks[]
return NULL
Definition mod_so.c:359
apr_array_header_t * namespaces
Definition apr_xml.h:204
apr_xml_elem * root
Definition apr_xml.h:202
const char * name
Definition apr_xml.h:164
struct apr_xml_elem * first_child
Definition apr_xml.h:180
struct apr_xml_elem * next
Definition apr_xml.h:178
int status
Definition mod_dav.h:122
dav_error *(* get_locks)(dav_lockdb *lockdb, const dav_resource *resource, int calltype, dav_lock **locks)
Definition mod_dav.h:1561
dav_error *(* find_lock)(dav_lockdb *lockdb, const dav_resource *resource, const dav_locktoken *locktoken, int partial_ok, dav_lock **lock)
Definition mod_dav.h:1582
dav_error *(* create_lock)(dav_lockdb *lockdb, const dav_resource *resource, dav_lock **lock)
Definition mod_dav.h:1547
dav_error *(* lookup_resource)(dav_lockdb *lockdb, const dav_locktoken *locktoken, const dav_resource *start_resource, const dav_resource **resource)
Definition mod_dav.h:1658
dav_error *(* append_locks)(dav_lockdb *lockdb, const dav_resource *resource, int make_indirect, const dav_lock *lock)
Definition mod_dav.h:1612
dav_error *(* remove_locknull_state)(dav_lockdb *lockdb, const dav_resource *resource)
Definition mod_dav.h:1536
int(* is_same_resource)(const dav_resource *res1, const dav_resource *res2)
Definition mod_dav.h:1968
struct dav_lock * next
Definition mod_dav.h:1407
const dav_hooks_locks * hooks
Definition mod_dav.h:1334
const dav_hooks_repository * hooks
Definition mod_dav.h:414
const dav_resource * resource
Definition mod_dav.h:1809
A structure that represents the current request.
Definition httpd.h:845
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
char * path_info
Definition httpd.h:1024
static apr_time_t now
Definition testtime.c:33
static dav_error * dav_unlock_walker(dav_walk_resource *wres, int calltype)
Definition util_lock.c:386
static dav_error * dav_inherit_locks(request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, int use_parent)
Definition util_lock.c:588
static dav_error * dav_lock_walker(dav_walk_resource *wres, int calltype)
Definition util_lock.c:260
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)
Definition util_lock.c:423
static dav_error * dav_inherit_walker(dav_walk_resource *wres, int calltype)
Definition util_lock.c:566