** dav_unlock: Removes all direct and indirect locks for r->filename, ** with given locktoken. If locktoken == null_locktoken, all locks ** are removed. If r->filename represents an indirect lock, ** we must unlock the appropriate direct lock. ** Returns OK or appropriate HTTP_* response and logs any errors. ** ** ### We've already crawled the tree to ensure everything was locked **
| 495 | ** by us; there should be no need to incorporate a rollback. |
| 496 | */ |
| 497 | DAV_DECLARE(int) dav_unlock(request_rec *r, const dav_resource *resource, |
| 498 | const dav_locktoken *locktoken) |
| 499 | { |
| 500 | int result; |
| 501 | dav_lockdb *lockdb; |
| 502 | const dav_resource *lock_resource = resource; |
| 503 | const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); |
| 504 | const dav_hooks_repository *repos_hooks = resource->hooks; |
| 505 | dav_walker_ctx ctx = { { 0 } }; |
| 506 | dav_response *multi_status; |
| 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 */ |
| 529 | return HTTP_INTERNAL_SERVER_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 | */ |
| 544 | ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL; |
| 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); |
no test coverage detected