diff options
| author | Peter Wemm <peter@FreeBSD.org> | 2015-10-12 08:54:49 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 2015-10-12 08:54:49 +0000 | 
| commit | dc5d469d6574e9fb03bdd793658bb371315b306a (patch) | |
| tree | 013c2e6845398e5a9ca4901dcc077769c7520e1d /subversion/libsvn_ra | |
| parent | 58218291fa73a17020ef0447398e9e8a78f9e8c7 (diff) | |
Diffstat (limited to 'subversion/libsvn_ra')
| -rw-r--r-- | subversion/libsvn_ra/compat.c | 26 | ||||
| -rw-r--r-- | subversion/libsvn_ra/libsvn_ra.pc.in | 12 | ||||
| -rw-r--r-- | subversion/libsvn_ra/ra_loader.c | 418 | ||||
| -rw-r--r-- | subversion/libsvn_ra/ra_loader.h | 10 | ||||
| -rw-r--r-- | subversion/libsvn_ra/wrapper_template.h | 4 | 
5 files changed, 235 insertions, 235 deletions
diff --git a/subversion/libsvn_ra/compat.c b/subversion/libsvn_ra/compat.c index b16bbefe9a46..f7307bf557a5 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 000000000000..b7ef131365e5 --- /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 d9cb96b9efe3..3a782f239f9b 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 227730aec230..f371f273feca 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 cee3fb3fe00a..0585deda87db 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)      {  | 
