📄 session.c
字号:
err = shim_svn_ra_dav__lock(session, &lock, path, comment, force, *revnum, iterpool); if (err && !SVN_ERR_IS_LOCK_ERROR(err)) { ret_err = err; goto departure; } if (lock_func) callback_err = lock_func(lock_baton, path, TRUE, err ? NULL : lock, err, iterpool); svn_error_clear(err); if (callback_err) { ret_err = callback_err; goto departure; } } svn_pool_destroy(iterpool); departure: return svn_ra_dav__maybe_store_auth_info_after_result(ret_err, ras, pool);}/* ###TODO for 1.3: Send all lock tokens to the server at once. */static svn_error_t *shim_svn_ra_dav__unlock(svn_ra_session_t *session, const char *path, const char *token, svn_boolean_t force, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; int rv; const char *url; struct ne_lock *nlock; /* Make a neon lock structure containing token and full URL to unlock. */ nlock = ne_lock_create(); url = svn_path_url_add_component(ras->url->data, path, pool); if ((rv = ne_uri_parse(url, &(nlock->uri)))) { ne_lock_destroy(nlock); return svn_ra_dav__convert_error(ras->sess, _("Failed to parse URI"), rv, pool); } /* In the case of 'force', we might not have a token at all. Unfortunately, ne_unlock() insists on sending one, and mod_dav insists on having a valid token for UNLOCK requests. That means we need to fetch the token. */ if (! token) { svn_lock_t *lock; SVN_ERR(svn_ra_dav__get_lock(session, &lock, path, pool)); if (! lock) return svn_error_createf(SVN_ERR_RA_NOT_LOCKED, NULL, _("'%s' is not locked in the repository"), path); nlock->token = ne_strdup(lock->token); } else { nlock->token = ne_strdup(token); } /* Clear out the lrb... */ memset((ras->lrb), 0, sizeof(*ras->lrb)); /* ...and load it up again. */ ras->lrb->pool = pool; ras->lrb->force = force; /* Issue UNLOCK request. */ rv = ne_unlock(ras->sess, nlock); /* Did we get a <D:error> response? */ if (ras->lrb->err) { ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return ras->lrb->err; } /* Did we get some other sort of neon error? */ if (rv) { ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return svn_ra_dav__convert_error(ras->sess, _("Unlock request failed"), rv, pool); } /* Free neon things. */ ne_lock_destroy(nlock); if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return SVN_NO_ERROR;}static svn_error_t *svn_ra_dav__unlock(svn_ra_session_t *session, apr_hash_t *path_tokens, svn_boolean_t force, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(pool); svn_ra_dav__session_t *ras = session->priv; svn_error_t *ret_err = NULL; setup_neon_request_hook(ras); /* ### TODO for 1.3: Send all the lock tokens over the wire at once. This loop is just a temporary shim. */ for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi)) { const void *key; const char *path; void *val; const char *token; svn_error_t *err, *callback_err = NULL; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); path = key; /* Since we can't store NULL values in a hash, we turn "" to NULL here. */ if (strcmp(val, "") != 0) token = val; else token = NULL; err = shim_svn_ra_dav__unlock(session, path, token, force, iterpool); if (err && !SVN_ERR_IS_UNLOCK_ERROR(err)) { ret_err = err; goto departure; } if (lock_func) callback_err = lock_func(lock_baton, path, FALSE, NULL, err, iterpool); svn_error_clear(err); if (callback_err) { ret_err = callback_err; goto departure; } } svn_pool_destroy(iterpool); departure: return svn_ra_dav__maybe_store_auth_info_after_result(ret_err, ras, pool);}/* A context for lock_receiver(). */struct receiver_baton{ /* Set this if something goes wrong. */ svn_error_t *err; /* The thing being retrieved and assembled. */ svn_lock_t *lock; /* Our RA session. */ svn_ra_dav__session_t *ras; /* The baton used by the handle_creation_date() callback */ struct lock_request_baton *lrb; /* The absolute FS path that we're querying. */ const char *fs_path; /* A place to allocate the lock. */ apr_pool_t *pool;};/* A callback of type ne_lock_result; called by ne_lock_discover(). */static voidlock_receiver(void *userdata, const struct ne_lock *lock,#ifdef SVN_NEON_0_26 const ne_uri *uri,#else const char *uri,#endif const ne_status *status){ struct receiver_baton *rb = userdata; if (lock) {#ifdef SVN_NEON_0_25 /* The post_send hook has not run at this stage; so grab the response headers early. As Joe Orton explains in Issue #2297: "post_send hooks run much later than the name might suggest. I've noted another API change for a future neon release to make that easier." */ if (post_send_hook(rb->lrb->request, rb->lrb, ne_get_status(rb->lrb->request))) { return; }#endif /* SVN_NEON_0_25 */ if (!rb->lrb->lock_owner || !rb->lrb->creation_date) { rb->err = svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Incomplete lock data returned")); return; } /* Convert the ne_lock into an svn_lock_t. */ rb->lock = svn_lock_create(rb->pool); rb->lock->token = apr_pstrdup(rb->pool, lock->token); rb->lock->path = rb->fs_path; if (lock->owner) rb->lock->comment = apr_pstrdup(rb->pool, lock->owner); rb->lock->owner = apr_pstrdup(rb->pool, rb->lrb->lock_owner); rb->lock->creation_date = rb->lrb->creation_date; if (lock->timeout == NE_TIMEOUT_INFINITE) rb->lock->expiration_date = 0; else if (lock->timeout > 0) rb->lock->expiration_date = rb->lock->creation_date + apr_time_from_sec(lock->timeout); } else { /* There's no lock... is that because the path isn't locked? Or because of a real error? */ if (status->code != 404) rb->err = svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL, status->reason_phrase); }}svn_error_t *svn_ra_dav__get_lock(svn_ra_session_t *session, svn_lock_t **lock, const char *path, apr_pool_t *pool){ svn_ra_dav__session_t *ras = session->priv; int rv; const char *url; struct receiver_baton *rb; svn_string_t fs_path; svn_error_t *err; ne_uri uri; /* To begin, we convert the incoming path into an absolute fs-path. */ url = svn_path_url_add_component(ras->url->data, path, pool); err = svn_ra_dav__get_baseline_info(NULL, NULL, &fs_path, NULL, ras->sess, url, SVN_INVALID_REVNUM, pool); SVN_ERR(svn_ra_dav__maybe_store_auth_info_after_result(err, ras, pool)); /* Build context for neon callbacks and then register them. */ setup_neon_request_hook(ras); memset((ras->lrb), 0, sizeof(*ras->lrb)); ras->lrb->pool = pool; /* Build context for the lock_receiver() callback. */ rb = apr_pcalloc(pool, sizeof(*rb)); rb->pool = pool; rb->ras = ras; rb->lrb = ras->lrb; rb->fs_path = fs_path.data; /* Ask neon to "discover" the lock (presumably by doing a PROPFIND for the DAV:supportedlock property). */ /* ne_lock_discover wants just the path, so parse it out of the url. */ if (ne_uri_parse(url, &uri) == 0) { url = apr_pstrdup(pool, uri.path); ne_uri_free(&uri); } rv = ne_lock_discover(ras->sess, url, lock_receiver, rb); /* Did we get a <D:error> response? */ if (ras->lrb->err) { if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return ras->lrb->err; } /* Did lock_receiver() generate an error? */ if (rb->err) { if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return rb->err; } /* Did we get some other sort of neon error? */ if (rv) { if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); return svn_ra_dav__convert_error(ras->sess, _("Failed to fetch lock information"), rv, pool); } /* Free neon things. */ if (ras->lrb->error_parser) ne_xml_destroy(ras->lrb->error_parser); *lock = rb->lock; return SVN_NO_ERROR;}static const svn_version_t *ra_dav_version(void){ SVN_VERSION_BODY;}static const svn_ra__vtable_t dav_vtable = { ra_dav_version, ra_dav_get_description, ra_dav_get_schemes, svn_ra_dav__open, svn_ra_dav__reparent, svn_ra_dav__get_latest_revnum, svn_ra_dav__get_dated_revision, svn_ra_dav__change_rev_prop, svn_ra_dav__rev_proplist, svn_ra_dav__rev_prop, svn_ra_dav__get_commit_editor, svn_ra_dav__get_file, svn_ra_dav__get_dir, svn_ra_dav__do_update, svn_ra_dav__do_switch, svn_ra_dav__do_status, svn_ra_dav__do_diff, svn_ra_dav__get_log, svn_ra_dav__do_check_path, svn_ra_dav__do_stat, svn_ra_dav__do_get_uuid, svn_ra_dav__get_repos_root, svn_ra_dav__get_locations, svn_ra_dav__get_file_revs, svn_ra_dav__lock, svn_ra_dav__unlock, svn_ra_dav__get_lock, svn_ra_dav__get_locks, svn_ra_dav__replay,};svn_error_t *svn_ra_dav__init(const svn_version_t *loader_version, const svn_ra__vtable_t **vtable, apr_pool_t *pool){ static const svn_version_checklist_t checklist[] = { { "svn_subr", svn_subr_version }, { "svn_delta", svn_delta_version }, { NULL, NULL } }; SVN_ERR(svn_ver_check_list(ra_dav_version(), checklist)); /* Simplified version check to make sure we can safely use the VTABLE parameter. The RA loader does a more exhaustive check. */ if (loader_version->major != SVN_VER_MAJOR) { return svn_error_createf (SVN_ERR_VERSION_MISMATCH, NULL, _("Unsupported RA loader version (%d) for ra_dav"), loader_version->major); } *vtable = &dav_vtable; return SVN_NO_ERROR;}/* Compatibility wrapper for the 1.1 and before API. */#define NAME "ra_dav"#define DESCRIPTION RA_DAV_DESCRIPTION#define VTBL dav_vtable#define INITFUNC svn_ra_dav__init#define COMPAT_INITFUNC svn_ra_dav_init#include "../libsvn_ra/wrapper_template.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -