summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-08-05 16:22:51 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-08-05 16:22:51 +0000
commitcf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch)
treeda27775a2161723ef342e91af41a8b51fedef405 /subversion/libsvn_ra
parentbb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff)
downloadsubversion-tarball-master.tar.gz
Diffstat (limited to 'subversion/libsvn_ra')
-rw-r--r--subversion/libsvn_ra/compat.c26
-rw-r--r--subversion/libsvn_ra/libsvn_ra.pc.in12
-rw-r--r--subversion/libsvn_ra/ra_loader.c418
-rw-r--r--subversion/libsvn_ra/ra_loader.h10
-rw-r--r--subversion/libsvn_ra/wrapper_template.h4
5 files changed, 235 insertions, 235 deletions
diff --git a/subversion/libsvn_ra/compat.c b/subversion/libsvn_ra/compat.c
index b16bbef..f7307bf 100644
--- a/subversion/libsvn_ra/compat.c
+++ b/subversion/libsvn_ra/compat.c
@@ -35,6 +35,7 @@
#include "svn_props.h"
#include "private/svn_fspath.h"
+#include "private/svn_sorts_private.h"
#include "ra_loader.h"
#include "svn_private_config.h"
@@ -315,6 +316,7 @@ svn_ra__locations_from_log(svn_ra_session_t *session,
svn_revnum_t youngest_requested, oldest_requested, youngest, oldest;
svn_node_kind_t kind;
const char *fs_path;
+ apr_array_header_t *sorted_location_revisions;
/* Fetch the absolute FS path associated with PATH. */
SVN_ERR(get_fs_path(&fs_path, session, path, pool));
@@ -336,11 +338,11 @@ svn_ra__locations_from_log(svn_ra_session_t *session,
/* Figure out the youngest and oldest revs (amongst the set of
requested revisions + the peg revision) so we can avoid
unnecessary log parsing. */
- qsort(location_revisions->elts, location_revisions->nelts,
- location_revisions->elt_size, compare_revisions);
- oldest_requested = APR_ARRAY_IDX(location_revisions, 0, svn_revnum_t);
- youngest_requested = APR_ARRAY_IDX(location_revisions,
- location_revisions->nelts - 1,
+ sorted_location_revisions = apr_array_copy(pool, location_revisions);
+ svn_sort__array(sorted_location_revisions, compare_revisions);
+ oldest_requested = APR_ARRAY_IDX(sorted_location_revisions, 0, svn_revnum_t);
+ youngest_requested = APR_ARRAY_IDX(sorted_location_revisions,
+ sorted_location_revisions->nelts - 1,
svn_revnum_t);
youngest = peg_revision;
youngest = (oldest_requested > youngest) ? oldest_requested : youngest;
@@ -352,7 +354,7 @@ svn_ra__locations_from_log(svn_ra_session_t *session,
/* Populate most of our log receiver baton structure. */
lrb.kind = kind;
lrb.last_path = fs_path;
- lrb.location_revisions = apr_array_copy(pool, location_revisions);
+ lrb.location_revisions = apr_array_copy(pool, sorted_location_revisions);
lrb.peg_revision = peg_revision;
lrb.peg_path = NULL;
lrb.locations = locations;
@@ -378,9 +380,9 @@ svn_ra__locations_from_log(svn_ra_session_t *session,
if (lrb.last_path)
{
int i;
- for (i = 0; i < location_revisions->nelts; i++)
+ for (i = 0; i < sorted_location_revisions->nelts; i++)
{
- svn_revnum_t rev = APR_ARRAY_IDX(location_revisions, i,
+ svn_revnum_t rev = APR_ARRAY_IDX(sorted_location_revisions, i,
svn_revnum_t);
if (! apr_hash_get(locations, &rev, sizeof(rev)))
apr_hash_set(locations, apr_pmemdup(pool, &rev, sizeof(rev)),
@@ -920,9 +922,9 @@ svn_ra__get_inherited_props_walk(svn_ra_session_t *session,
hi;
hi = apr_hash_next(hi))
{
- const char *name = svn__apr_hash_index_key(hi);
- apr_ssize_t klen = svn__apr_hash_index_klen(hi);
- svn_string_t *value = svn__apr_hash_index_val(hi);
+ const char *name = apr_hash_this_key(hi);
+ apr_ssize_t klen = apr_hash_this_key_len(hi);
+ svn_string_t *value = apr_hash_this_val(hi);
if (svn_property_kind2(name) == svn_prop_regular_kind)
{
@@ -940,7 +942,7 @@ svn_ra__get_inherited_props_walk(svn_ra_session_t *session,
parent_url,
result_pool);
new_iprop->prop_hash = final_hash;
- svn_sort__array_insert(&new_iprop, *inherited_props, 0);
+ svn_sort__array_insert(*inherited_props, &new_iprop, 0);
}
}
diff --git a/subversion/libsvn_ra/libsvn_ra.pc.in b/subversion/libsvn_ra/libsvn_ra.pc.in
new file mode 100644
index 0000000..b7ef131
--- /dev/null
+++ b/subversion/libsvn_ra/libsvn_ra.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libsvn_ra
+Description: Subversion General Repository Access Library
+Version: @PACKAGE_VERSION@
+Requires: apr-@SVN_APR_MAJOR_VERSION@
+Requires.private: libsvn_delta libsvn_subr
+Libs: -L${libdir} -lsvn_ra
+Cflags: -I${includedir}
diff --git a/subversion/libsvn_ra/ra_loader.c b/subversion/libsvn_ra/ra_loader.c
index d9cb96b..3a782f2 100644
--- a/subversion/libsvn_ra/ra_loader.c
+++ b/subversion/libsvn_ra/ra_loader.c
@@ -35,6 +35,7 @@
#include "svn_hash.h"
#include "svn_version.h"
+#include "svn_time.h"
#include "svn_types.h"
#include "svn_error.h"
#include "svn_error_codes.h"
@@ -51,6 +52,7 @@
#include "ra_loader.h"
#include "deprecated.h"
+#include "private/svn_auth_private.h"
#include "private/svn_ra_private.h"
#include "svn_private_config.h"
@@ -230,6 +232,11 @@ check_ra_version(const svn_version_t *ra_version, const char *scheme)
svn_error_t *svn_ra_initialize(apr_pool_t *pool)
{
+#if defined(SVN_USE_DSO) && APR_HAS_DSO
+ /* Ensure that DSO subsystem is initialized early as possible if
+ we're going to use it. */
+ SVN_ERR(svn_dso_initialize2());
+#endif
return SVN_NO_ERROR;
}
@@ -259,25 +266,17 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
apr_pool_t *pool)
{
apr_pool_t *sesspool = svn_pool_create(pool);
+ apr_pool_t *scratch_pool = svn_pool_create(sesspool);
svn_ra_session_t *session;
const struct ra_lib_defn *defn;
const svn_ra__vtable_t *vtable = NULL;
- svn_config_t *servers = NULL;
- const char *server_group;
apr_uri_t repos_URI;
apr_status_t apr_err;
+ svn_error_t *err;
#ifdef CHOOSABLE_DAV_MODULE
const char *http_library = DEFAULT_HTTP_LIBRARY;
#endif
- /* Auth caching parameters. */
- svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
- svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
- const char *store_plaintext_passwords
- = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS;
- svn_boolean_t store_pp = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP;
- const char *store_pp_plaintext
- = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT;
- const char *corrected_url;
+ svn_auth_baton_t *auth_baton;
/* Initialize the return variable. */
*session_p = NULL;
@@ -293,100 +292,31 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
repos_URL);
if (callbacks->auth_baton)
- {
- /* The 'store-passwords' and 'store-auth-creds' parameters used to
- * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
- * if values for these parameters have already been set by our
- * callers, we use those values as defaults.
- *
- * Note that we can only catch the case where users explicitly set
- * "store-passwords = no" or 'store-auth-creds = no".
- *
- * However, since the default value for both these options is
- * currently (and has always been) "yes", users won't know
- * the difference if they set "store-passwords = yes" or
- * "store-auth-creds = yes" -- they'll get the expected behaviour.
- */
-
- if (svn_auth_get_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
- store_passwords = FALSE;
-
- if (svn_auth_get_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
- store_auth_creds = FALSE;
- }
+ SVN_ERR(svn_auth__make_session_auth(&auth_baton,
+ callbacks->auth_baton, config,
+ repos_URI.hostname,
+ sesspool, scratch_pool));
+ else
+ auth_baton = NULL;
+#ifdef CHOOSABLE_DAV_MODULE
if (config)
{
+ svn_config_t *servers = NULL;
+ const char *server_group = NULL;
+
/* Grab the 'servers' config. */
servers = svn_hash_gets(config, SVN_CONFIG_CATEGORY_SERVERS);
if (servers)
{
/* First, look in the global section. */
- SVN_ERR(svn_config_get_bool
- (servers, &store_passwords, SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_STORE_PASSWORDS,
- store_passwords));
-
- SVN_ERR(svn_config_get_yes_no_ask
- (servers, &store_plaintext_passwords, SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
- SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
-
- SVN_ERR(svn_config_get_bool
- (servers, &store_pp, SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
- store_pp));
-
- SVN_ERR(svn_config_get_yes_no_ask
- (servers, &store_pp_plaintext,
- SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
- SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT));
-
- SVN_ERR(svn_config_get_bool
- (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
- store_auth_creds));
-
/* Find out where we're about to connect to, and
* try to pick a server group based on the destination. */
server_group = svn_config_find_group(servers, repos_URI.hostname,
SVN_CONFIG_SECTION_GROUPS,
sesspool);
- if (server_group)
- {
- /* Override global auth caching parameters with the ones
- * for the server group, if any. */
- SVN_ERR(svn_config_get_bool(servers, &store_auth_creds,
- server_group,
- SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
- store_auth_creds));
-
- SVN_ERR(svn_config_get_bool(servers, &store_passwords,
- server_group,
- SVN_CONFIG_OPTION_STORE_PASSWORDS,
- store_passwords));
-
- SVN_ERR(svn_config_get_yes_no_ask
- (servers, &store_plaintext_passwords, server_group,
- SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
- store_plaintext_passwords));
-
- SVN_ERR(svn_config_get_bool
- (servers, &store_pp,
- server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
- store_pp));
-
- SVN_ERR(svn_config_get_yes_no_ask
- (servers, &store_pp_plaintext, server_group,
- SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
- store_pp_plaintext));
- }
-#ifdef CHOOSABLE_DAV_MODULE
/* Now, which DAV-based RA method do we want to use today? */
http_library
= svn_config_get_server_setting(servers,
@@ -399,34 +329,9 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
_("Invalid config: unknown HTTP library "
"'%s'"),
http_library);
-#endif
}
}
-
- if (callbacks->auth_baton)
- {
- /* Save auth caching parameters in the auth parameter hash. */
- if (! store_passwords)
- svn_auth_set_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
-
- svn_auth_set_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
- store_plaintext_passwords);
-
- if (! store_pp)
- svn_auth_set_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
- "");
-
- svn_auth_set_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
- store_pp_plaintext);
-
- if (! store_auth_creds)
- svn_auth_set_parameter(callbacks->auth_baton,
- SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
- }
+#endif
/* Find the library. */
for (defn = ra_libraries; defn->ra_name != NULL; ++defn)
@@ -445,16 +350,16 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
if (! initfunc)
SVN_ERR(load_ra_module(&initfunc, NULL, defn->ra_name,
- sesspool));
+ scratch_pool));
if (! initfunc)
/* Library not found. */
continue;
- SVN_ERR(initfunc(svn_ra_version(), &vtable, sesspool));
+ SVN_ERR(initfunc(svn_ra_version(), &vtable, scratch_pool));
SVN_ERR(check_ra_version(vtable->get_version(), scheme));
- if (! has_scheme_of(vtable->get_schemes(sesspool), repos_URL))
+ if (! has_scheme_of(vtable->get_schemes(scratch_pool), repos_URL))
/* Library doesn't support the scheme at runtime. */
continue;
@@ -476,31 +381,32 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
session->pool = sesspool;
/* Ask the library to open the session. */
- SVN_ERR_W(vtable->open_session(session, &corrected_url, repos_URL,
- callbacks, callback_baton, config, sesspool),
- apr_psprintf(pool, "Unable to connect to a repository at URL '%s'",
- repos_URL));
+ err = vtable->open_session(session, corrected_url_p,
+ repos_URL,
+ callbacks, callback_baton, auth_baton,
+ config, sesspool, scratch_pool);
+
+ if (err)
+ {
+ svn_pool_destroy(sesspool); /* Includes scratch_pool */
+ if (err->apr_err == SVN_ERR_RA_SESSION_URL_MISMATCH)
+ return svn_error_trace(err);
+
+ return svn_error_createf(
+ SVN_ERR_RA_CANNOT_CREATE_SESSION, err,
+ _("Unable to connect to a repository at URL '%s'"),
+ repos_URL);
+ }
/* If the session open stuff detected a server-provided URL
correction (a 301 or 302 redirect response during the initial
OPTIONS request), then kill the session so the caller can decide
what to do. */
- if (corrected_url_p && corrected_url)
+ if (corrected_url_p && *corrected_url_p)
{
- if (! svn_path_is_url(corrected_url))
- {
- /* RFC1945 and RFC2616 state that the Location header's
- value (from whence this CORRECTED_URL ultimately comes),
- if present, must be an absolute URI. But some Apache
- versions (those older than 2.2.11, it seems) transmit
- only the path portion of the URI. See issue #3775 for
- details. */
- apr_uri_t corrected_URI = repos_URI;
- corrected_URI.path = (char *)corrected_url;
- corrected_url = apr_uri_unparse(pool, &corrected_URI, 0);
- }
- *corrected_url_p = svn_uri_canonicalize(corrected_url, pool);
- svn_pool_destroy(sesspool);
+ /* *session_p = NULL; */
+ *corrected_url_p = apr_pstrdup(pool, *corrected_url_p);
+ svn_pool_destroy(sesspool); /* Includes scratch_pool */
return SVN_NO_ERROR;
}
@@ -514,7 +420,7 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
{
/* Duplicate the uuid as it is allocated in sesspool */
repository_uuid = apr_pstrdup(pool, repository_uuid);
- svn_pool_destroy(sesspool);
+ svn_pool_destroy(sesspool); /* includes scratch_pool */
return svn_error_createf(SVN_ERR_RA_UUID_MISMATCH, NULL,
_("Repository UUID '%s' doesn't match "
"expected UUID '%s'"),
@@ -522,10 +428,50 @@ svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
}
}
+ svn_pool_destroy(scratch_pool);
*session_p = session;
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_ra__dup_session(svn_ra_session_t **new_session,
+ svn_ra_session_t *old_session,
+ const char *session_url,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_session_t *session;
+
+ if (session_url)
+ {
+ const char *dummy;
+
+ /* This verifies in new_session_url is in the repository */
+ SVN_ERR(svn_ra_get_path_relative_to_root(old_session,
+ &dummy,
+ session_url,
+ scratch_pool));
+ }
+ else
+ SVN_ERR(svn_ra_get_session_url(old_session, &session_url, scratch_pool));
+
+ /* Create the session object. */
+ session = apr_pcalloc(result_pool, sizeof(*session));
+ session->cancel_func = old_session->cancel_func;
+ session->cancel_baton = old_session->cancel_baton;
+ session->vtable = old_session->vtable;
+ session->pool = result_pool;
+
+ SVN_ERR(old_session->vtable->dup_session(session,
+ old_session,
+ session_url,
+ result_pool,
+ scratch_pool));
+
+ *new_session = session;
+ return SVN_NO_ERROR;
+}
+
svn_error_t *svn_ra_reparent(svn_ra_session_t *session,
const char *url,
apr_pool_t *pool)
@@ -650,61 +596,6 @@ svn_error_t *svn_ra_rev_prop(svn_ra_session_t *session,
return session->vtable->rev_prop(session, rev, name, value, pool);
}
-struct ccw_baton
-{
- svn_commit_callback2_t original_callback;
- void *original_baton;
-
- svn_ra_session_t *session;
-};
-
-/* Wrapper which populates the repos_root field of the commit_info struct */
-static svn_error_t *
-commit_callback_wrapper(const svn_commit_info_t *commit_info,
- void *baton,
- apr_pool_t *pool)
-{
- struct ccw_baton *ccwb = baton;
- svn_commit_info_t *ci = svn_commit_info_dup(commit_info, pool);
-
- SVN_ERR(svn_ra_get_repos_root2(ccwb->session, &ci->repos_root, pool));
-
- return ccwb->original_callback(ci, ccwb->original_baton, pool);
-}
-
-
-/* Some RA layers do not correctly fill in REPOS_ROOT in commit_info, or
- they are third-party layers conforming to an older commit_info structure.
- Interpose a utility function to ensure the field is valid. */
-static void
-remap_commit_callback(svn_commit_callback2_t *callback,
- void **callback_baton,
- svn_ra_session_t *session,
- svn_commit_callback2_t original_callback,
- void *original_baton,
- apr_pool_t *result_pool)
-{
- if (original_callback == NULL)
- {
- *callback = NULL;
- *callback_baton = NULL;
- }
- else
- {
- /* Allocate this in RESULT_POOL, since the callback will be called
- long after this function has returned. */
- struct ccw_baton *ccwb = apr_palloc(result_pool, sizeof(*ccwb));
-
- ccwb->session = session;
- ccwb->original_callback = original_callback;
- ccwb->original_baton = original_baton;
-
- *callback = commit_callback_wrapper;
- *callback_baton = ccwb;
- }
-}
-
-
svn_error_t *svn_ra_get_commit_editor3(svn_ra_session_t *session,
const svn_delta_editor_t **editor,
void **edit_baton,
@@ -715,10 +606,6 @@ svn_error_t *svn_ra_get_commit_editor3(svn_ra_session_t *session,
svn_boolean_t keep_locks,
apr_pool_t *pool)
{
- remap_commit_callback(&commit_callback, &commit_baton,
- session, commit_callback, commit_baton,
- pool);
-
return session->vtable->get_commit_editor(session, editor, edit_baton,
revprop_table,
commit_callback, commit_baton,
@@ -925,8 +812,104 @@ svn_error_t *svn_ra_stat(svn_ra_session_t *session,
svn_dirent_t **dirent,
apr_pool_t *pool)
{
+ svn_error_t *err;
SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
- return session->vtable->stat(session, path, revision, dirent, pool);
+ err = session->vtable->stat(session, path, revision, dirent, pool);
+
+ /* svnserve before 1.2 doesn't support the above, so fall back on
+ a far less efficient, but still correct method. */
+ if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
+ {
+ /* ### TODO: Find out if we can somehow move this code in libsvn_ra_svn.
+ */
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
+ svn_node_kind_t kind;
+
+ svn_error_clear(err);
+
+ SVN_ERR(svn_ra_check_path(session, path, revision, &kind, scratch_pool));
+
+ if (kind != svn_node_none)
+ {
+ const char *repos_root_url;
+ const char *session_url;
+
+ SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url,
+ scratch_pool));
+ SVN_ERR(svn_ra_get_session_url(session, &session_url,
+ scratch_pool));
+
+ if (!svn_path_is_empty(path))
+ session_url = svn_path_url_add_component2(session_url, path,
+ scratch_pool);
+
+ if (strcmp(session_url, repos_root_url) != 0)
+ {
+ svn_ra_session_t *parent_session;
+ apr_hash_t *parent_ents;
+ const char *parent_url, *base_name;
+
+ /* Open another session to the path's parent. This server
+ doesn't support svn_ra_reparent anyway, so don't try it. */
+ svn_uri_split(&parent_url, &base_name, session_url,
+ scratch_pool);
+
+ SVN_ERR(svn_ra__dup_session(&parent_session, session, parent_url,
+ scratch_pool, scratch_pool));
+
+ /* Get all parent's entries, no props. */
+ SVN_ERR(svn_ra_get_dir2(parent_session, &parent_ents, NULL,
+ NULL, "", revision, SVN_DIRENT_ALL,
+ scratch_pool));
+
+ /* Get the relevant entry. */
+ *dirent = svn_hash_gets(parent_ents, base_name);
+
+ if (*dirent)
+ *dirent = svn_dirent_dup(*dirent, pool);
+ }
+ else
+ {
+ apr_hash_t *props;
+ const svn_string_t *val;
+
+ /* We can't get the directory entry for the repository root,
+ but we can still get the information we want.
+ The created-rev of the repository root must, by definition,
+ be rev. */
+ *dirent = apr_pcalloc(pool, sizeof(**dirent));
+ (*dirent)->kind = kind;
+ (*dirent)->size = SVN_INVALID_FILESIZE;
+
+ SVN_ERR(svn_ra_get_dir2(session, NULL, NULL, &props,
+ "", revision, 0 /* no dirent fields */,
+ scratch_pool));
+ (*dirent)->has_props = (apr_hash_count(props) != 0);
+
+ (*dirent)->created_rev = revision;
+
+ SVN_ERR(svn_ra_rev_proplist(session, revision, &props,
+ scratch_pool));
+
+ val = svn_hash_gets(props, SVN_PROP_REVISION_DATE);
+ if (val)
+ SVN_ERR(svn_time_from_cstring(&(*dirent)->time, val->data,
+ scratch_pool));
+
+ val = svn_hash_gets(props, SVN_PROP_REVISION_AUTHOR);
+ (*dirent)->last_author = val ? apr_pstrdup(pool, val->data)
+ : NULL;
+ }
+ }
+ else
+ *dirent = NULL;
+
+ svn_pool_clear(scratch_pool);
+ }
+ else
+ SVN_ERR(err);
+
+ return SVN_NO_ERROR;
}
svn_error_t *svn_ra_get_uuid2(svn_ra_session_t *session,
@@ -1030,7 +1013,7 @@ svn_error_t *svn_ra_get_file_revs2(svn_ra_session_t *session,
if (include_merged_revisions)
SVN_ERR(svn_ra__assert_mergeinfo_capable_server(session, NULL, pool));
- if (start > end)
+ if (start > end || !SVN_IS_VALID_REVNUM(start))
SVN_ERR(
svn_ra__assert_capable_server(session,
SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
@@ -1040,7 +1023,8 @@ svn_error_t *svn_ra_get_file_revs2(svn_ra_session_t *session,
err = session->vtable->get_file_revs(session, path, start, end,
include_merged_revisions,
handler, handler_baton, pool);
- if (err && (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED))
+ if (err && (err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
+ && !include_merged_revisions)
{
svn_error_clear(err);
@@ -1048,7 +1032,7 @@ svn_error_t *svn_ra_get_file_revs2(svn_ra_session_t *session,
err = svn_ra__file_revs_from_log(session, path, start, end,
handler, handler_baton, pool);
}
- return err;
+ return svn_error_trace(err);
}
svn_error_t *svn_ra_lock(svn_ra_session_t *session,
@@ -1063,7 +1047,7 @@ svn_error_t *svn_ra_lock(svn_ra_session_t *session,
for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
{
- const char *path = svn__apr_hash_index_key(hi);
+ const char *path = apr_hash_this_key(hi);
SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
}
@@ -1088,7 +1072,7 @@ svn_error_t *svn_ra_unlock(svn_ra_session_t *session,
for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
{
- const char *path = svn__apr_hash_index_key(hi);
+ const char *path = apr_hash_this_key(hi);
SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
}
@@ -1320,27 +1304,24 @@ svn_ra_get_inherited_props(svn_ra_session_t *session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_boolean_t iprop_capable;
-
+ svn_error_t *err;
/* Path must be relative. */
SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
- SVN_ERR(svn_ra_has_capability(session, &iprop_capable,
- SVN_RA_CAPABILITY_INHERITED_PROPS,
- scratch_pool));
+ err = session->vtable->get_inherited_props(session, iprops, path,
+ revision, result_pool,
+ scratch_pool);
- if (iprop_capable)
- {
- SVN_ERR(session->vtable->get_inherited_props(session, iprops, path,
- revision, result_pool,
- scratch_pool));
- }
- else
+ if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
{
+ svn_error_clear(err);
+
/* Fallback for legacy servers. */
SVN_ERR(svn_ra__get_inherited_props_walk(session, path, revision, iprops,
result_pool, scratch_pool));
}
+ else
+ SVN_ERR(err);
return SVN_NO_ERROR;
}
@@ -1365,11 +1346,6 @@ svn_ra__get_commit_ev2(svn_editor_t **editor,
/* The specific RA layer does not have an implementation. Use our
default shim over the normal commit editor. */
- /* Remap for RA layers exposing Ev1. */
- remap_commit_callback(&commit_callback, &commit_baton,
- session, commit_callback, commit_baton,
- result_pool);
-
return svn_error_trace(svn_ra__use_commit_shim(
editor,
session,
diff --git a/subversion/libsvn_ra/ra_loader.h b/subversion/libsvn_ra/ra_loader.h
index 227730a..f371f27 100644
--- a/subversion/libsvn_ra/ra_loader.h
+++ b/subversion/libsvn_ra/ra_loader.h
@@ -61,8 +61,16 @@ typedef struct svn_ra__vtable_t {
const char *session_URL,
const svn_ra_callbacks2_t *callbacks,
void *callback_baton,
+ svn_auth_baton_t *auth_baton,
apr_hash_t *config,
- apr_pool_t *pool);
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+ /* Backs svn_ra_dup_session */
+ svn_error_t * (*dup_session)(svn_ra_session_t *new_session,
+ svn_ra_session_t *old_session,
+ const char *new_session_url,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* See svn_ra_reparent(). */
/* URL is guaranteed to have what get_repos_root() returns as a prefix. */
svn_error_t *(*reparent)(svn_ra_session_t *session,
diff --git a/subversion/libsvn_ra/wrapper_template.h b/subversion/libsvn_ra/wrapper_template.h
index cee3fb3..0585ded 100644
--- a/subversion/libsvn_ra/wrapper_template.h
+++ b/subversion/libsvn_ra/wrapper_template.h
@@ -91,7 +91,9 @@ static svn_error_t *compat_open(void **session_baton,
callbacks2->progress_baton = NULL;
SVN_ERR(VTBL.open_session(sess, &session_url, repos_URL,
- callbacks2, callback_baton, config, sesspool));
+ callbacks2, callback_baton,
+ callbacks ? callbacks->auth_baton : NULL,
+ config, sesspool, sesspool));
if (strcmp(repos_URL, session_url) != 0)
{