svn_error_t *svn_ra_get_locks(svn_ra_session_t *session, apr_hash_t **locks, const char *path, apr_pool_t *pool) { return svn_ra_get_locks2(session, locks, path, svn_depth_infinity, pool); }
/* Implements svn_ra_reporter3_t->finish_report. */ static svn_error_t * reporter_finish_report(void *report_baton, apr_pool_t *pool) { report_baton_t *rb = report_baton; svn_ra_session_t *ras; apr_hash_t *locks; const char *repos_root; apr_pool_t *subpool = svn_pool_create(pool); svn_error_t *err = SVN_NO_ERROR; /* Open an RA session to our common ancestor and grab the locks under it. */ SVN_ERR(svn_client_open_ra_session2(&ras, rb->ancestor, NULL, rb->ctx, subpool, subpool)); /* The locks need to live throughout the edit. Note that if the server doesn't support lock discovery, we'll just not do locky stuff. */ err = svn_ra_get_locks2(ras, &locks, "", rb->depth, rb->pool); if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED) { svn_error_clear(err); err = SVN_NO_ERROR; locks = apr_hash_make(rb->pool); } SVN_ERR(err); SVN_ERR(svn_ra_get_repos_root2(ras, &repos_root, rb->pool)); /* Close the RA session. */ svn_pool_destroy(subpool); SVN_ERR(svn_wc_status_set_repos_locks(rb->set_locks_baton, locks, repos_root, rb->pool)); return rb->wrapped_reporter->finish_report(rb->wrapped_report_baton, pool); }
svn_error_t * svn_client_info3(const char *abspath_or_url, const svn_opt_revision_t *peg_revision, const svn_opt_revision_t *revision, svn_depth_t depth, svn_boolean_t fetch_excluded, svn_boolean_t fetch_actual_only, const apr_array_header_t *changelists, svn_client_info_receiver2_t receiver, void *receiver_baton, svn_client_ctx_t *ctx, apr_pool_t *pool) { svn_ra_session_t *ra_session; svn_client__pathrev_t *pathrev; svn_lock_t *lock; svn_boolean_t related; const char *base_name; svn_dirent_t *the_ent; svn_client_info2_t *info; svn_error_t *err; if (depth == svn_depth_unknown) depth = svn_depth_empty; if ((revision == NULL || revision->kind == svn_opt_revision_unspecified) && (peg_revision == NULL || peg_revision->kind == svn_opt_revision_unspecified)) { /* Do all digging in the working copy. */ wc_info_receiver_baton_t b; b.client_receiver_func = receiver; b.client_receiver_baton = receiver_baton; return svn_error_trace( svn_wc__get_info(ctx->wc_ctx, abspath_or_url, depth, fetch_excluded, fetch_actual_only, changelists, wc_info_receiver, &b, ctx->cancel_func, ctx->cancel_baton, pool)); } /* Go repository digging instead. */ /* Trace rename history (starting at path_or_url@peg_revision) and return RA session to the possibly-renamed URL as it exists in REVISION. The ra_session returned will be anchored on this "final" URL. */ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &pathrev, abspath_or_url, NULL, peg_revision, revision, ctx, pool)); svn_uri_split(NULL, &base_name, pathrev->url, pool); /* Get the dirent for the URL itself. */ err = ra_stat_compatible(ra_session, pathrev->rev, &the_ent, DIRENT_FIELDS, ctx, pool); if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED) { svn_error_clear(err); /* If we're recursing, degrade gracefully: rather than throw an error, return no information about the repos root. */ if (depth > svn_depth_empty) goto pre_1_2_recurse; /* Otherwise, we really are stuck. Better tell the user what's going on. */ return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL, _("Server does not support retrieving " "information about the repository root")); } else if (err) { return svn_error_trace(err); } if (! the_ent) return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL, _("URL '%s' non-existent in revision %ld"), pathrev->url, pathrev->rev); /* Check if the URL exists in HEAD and refers to the same resource. In this case, we check the repository for a lock on this URL. ### There is a possible race here, since HEAD might have changed since ### we checked it. A solution to this problem could be to do the below ### check in a loop which only terminates if the HEAD revision is the same ### before and after this check. That could, however, lead to a ### starvation situation instead. */ SVN_ERR(same_resource_in_head(&related, pathrev->url, pathrev->rev, ra_session, ctx, pool)); if (related) { err = svn_ra_get_lock(ra_session, &lock, "", pool); /* An old mod_dav_svn will always work; there's nothing wrong with doing a PROPFIND for a property named "DAV:supportedlock". But an old svnserve will error. */ if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED) { svn_error_clear(err); lock = NULL; } else if (err) return svn_error_trace(err); } else lock = NULL; /* Push the URL's dirent (and lock) at the callback.*/ SVN_ERR(build_info_from_dirent(&info, the_ent, lock, pathrev, pool)); SVN_ERR(receiver(receiver_baton, base_name, info, pool)); /* Possibly recurse, using the original RA session. */ if (depth > svn_depth_empty && (the_ent->kind == svn_node_dir)) { apr_hash_t *locks; pre_1_2_recurse: if (peg_revision->kind == svn_opt_revision_head) { err = svn_ra_get_locks2(ra_session, &locks, "", depth, pool); /* Catch specific errors thrown by old mod_dav_svn or svnserve. */ if (err && (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED || err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)) { svn_error_clear(err); locks = apr_hash_make(pool); /* use an empty hash */ } else if (err) return svn_error_trace(err); } else locks = apr_hash_make(pool); /* use an empty hash */ SVN_ERR(push_dir_info(ra_session, pathrev, "", receiver, receiver_baton, depth, ctx, locks, pool)); } return SVN_NO_ERROR; }