You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/10/15 10:52:18 UTC
svn commit: r1532250 [19/37] - in /subversion/branches/cache-server: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/
contrib/server-side/fsfsfixer/ contrib/se...
Modified: subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
#include <apr_uri.h>
#include <serf.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_ra.h"
@@ -36,7 +37,6 @@
#include "svn_delta.h"
#include "svn_path.h"
-#include "svn_private_config.h"
#include "private/svn_string_private.h"
#include "ra_serf.h"
@@ -57,6 +57,7 @@ struct svn_ra_serf__xml_context_t {
svn_ra_serf__xml_opened_t opened_cb;
svn_ra_serf__xml_closed_t closed_cb;
svn_ra_serf__xml_cdata_t cdata_cb;
+ svn_ra_serf__xml_done_t done_cb;
void *baton;
/* Linked list of free states. */
@@ -458,11 +459,58 @@ lazy_create_pool(void *baton)
return xes->state_pool;
}
-void
-svn_ra_serf__xml_context_destroy(
- svn_ra_serf__xml_context_t *xmlctx)
+svn_error_t *
+svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx)
{
+ if (xmlctx->current->prev)
+ {
+ /* Probably unreachable as this would be an xml parser error */
+ return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+ _("XML stream truncated: closing '%s' missing"),
+ xmlctx->current->tag.name);
+ }
+ else if (! xmlctx->free_states)
+ {
+ /* If we have no items on the free_states list, we didn't push anything,
+ which tells us that we found an empty xml body */
+ const svn_ra_serf__xml_transition_t *scan;
+ const svn_ra_serf__xml_transition_t *document = NULL;
+ const char *msg;
+
+ for (scan = xmlctx->ttable; scan->ns != NULL; ++scan)
+ {
+ if (scan->from_state == XML_STATE_INITIAL)
+ {
+ if (document != NULL)
+ {
+ document = NULL; /* Multiple document elements defined */
+ break;
+ }
+ document = scan;
+ }
+ }
+
+ if (document)
+ msg = apr_psprintf(xmlctx->scratch_pool, "'%s' element not found",
+ document->name);
+ else
+ msg = _("document element not found");
+
+ return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+ _("XML stream truncated: %s"),
+ msg);
+ }
+
+ if (xmlctx->done_cb != NULL)
+ {
+ START_CALLBACK(xmlctx);
+ SVN_ERR(xmlctx->done_cb(xmlctx->baton,
+ xmlctx->scratch_pool));
+ END_CALLBACK(xmlctx);
+ }
+
svn_pool_destroy(xmlctx->scratch_pool);
+ return SVN_NO_ERROR;
}
svn_ra_serf__xml_context_t *
@@ -471,6 +519,7 @@ svn_ra_serf__xml_context_create(
svn_ra_serf__xml_opened_t opened_cb,
svn_ra_serf__xml_closed_t closed_cb,
svn_ra_serf__xml_cdata_t cdata_cb,
+ svn_ra_serf__xml_done_t done_cb,
void *baton,
apr_pool_t *result_pool)
{
@@ -482,6 +531,7 @@ svn_ra_serf__xml_context_create(
xmlctx->opened_cb = opened_cb;
xmlctx->closed_cb = closed_cb;
xmlctx->cdata_cb = cdata_cb;
+ xmlctx->done_cb = done_cb;
xmlctx->baton = baton;
xmlctx->scratch_pool = svn_pool_create(result_pool);
@@ -615,6 +665,14 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
}
if (scan->ns == NULL)
{
+ if (current->state == XML_STATE_INITIAL)
+ {
+ return svn_error_createf(
+ SVN_ERR_XML_UNEXPECTED_ELEMENT, NULL,
+ _("XML Parsing failed: Unexpected root element '%s'"),
+ elemname.name);
+ }
+
xmlctx->waiting = elemname;
/* ### return? */
return SVN_NO_ERROR;
@@ -669,10 +727,11 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
name = *saveattr;
value = svn_xml_get_attr_value(name, attrs);
if (value == NULL)
- return svn_error_createf(SVN_ERR_XML_ATTRIB_NOT_FOUND,
- NULL,
- _("Missing XML attribute: '%s'"),
- name);
+ return svn_error_createf(
+ SVN_ERR_XML_ATTRIB_NOT_FOUND,
+ NULL,
+ _("Missing XML attribute '%s' on '%s' element"),
+ name, scan->name);
}
if (value)
Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c Tue Oct 15 08:52:06 2013
@@ -32,6 +32,7 @@
#include <apr_network_io.h>
#include <apr_uri.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
@@ -47,9 +48,8 @@
#include "svn_mergeinfo.h"
#include "svn_version.h"
-#include "svn_private_config.h"
-
#include "private/svn_fspath.h"
+#include "private/svn_subr_private.h"
#include "../libsvn_ra/ra_loader.h"
@@ -561,14 +561,42 @@ static svn_error_t *parse_url(const char
return SVN_NO_ERROR;
}
+/* This structure is used as a baton for the pool cleanup function to
+ store tunnel parameters used by the close-tunnel callback. */
+struct tunnel_data_t {
+ void *tunnel_context;
+ void *tunnel_baton;
+ const char *tunnel_name;
+ const char *user;
+ const char *hostname;
+ int port;
+ svn_ra_close_tunnel_func_t close_tunnel;
+};
+
+/* Pool cleanup function that invokes the close-tunel callback. */
+static apr_status_t close_tunnel_cleanup(void *baton)
+{
+ const struct tunnel_data_t *const td = baton;
+ svn_error_t *const err =
+ svn_error_root_cause(td->close_tunnel(td->tunnel_context, td->tunnel_baton,
+ td->tunnel_name, td->user,
+ td->hostname, td->port));
+ const apr_status_t ret = (err ? err->apr_err : 0);
+ svn_error_clear(err);
+ return ret;
+}
+
/* Open a session to URL, returning it in *SESS_P, allocating it in POOL.
URI is a parsed version of URL. CALLBACKS and CALLBACKS_BATON
- are provided by the caller of ra_svn_open. If tunnel_argv is non-null,
- it points to a program argument list to use when invoking the tunnel agent.
+ are provided by the caller of ra_svn_open. If TUNNEL_NAME is not NULL,
+ it is the name of the tunnel type parsed from the URL scheme.
+ If TUNNEL_ARGV is not NULL, it points to a program argument list to use
+ when invoking the tunnel agent.
*/
static svn_error_t *open_session(svn_ra_svn__session_baton_t **sess_p,
const char *url,
const apr_uri_t *uri,
+ const char *tunnel_name,
const char **tunnel_argv,
const svn_ra_callbacks2_t *callbacks,
void *callbacks_baton,
@@ -583,19 +611,52 @@ static svn_error_t *open_session(svn_ra_
sess = apr_palloc(pool, sizeof(*sess));
sess->pool = pool;
- sess->is_tunneled = (tunnel_argv != NULL);
+ sess->is_tunneled = (tunnel_name != NULL);
sess->url = apr_pstrdup(pool, url);
sess->user = uri->user;
sess->hostname = uri->hostname;
sess->realm_prefix = apr_psprintf(pool, "<svn://%s:%d>", uri->hostname,
uri->port);
+ sess->tunnel_name = tunnel_name;
sess->tunnel_argv = tunnel_argv;
sess->callbacks = callbacks;
sess->callbacks_baton = callbacks_baton;
sess->bytes_read = sess->bytes_written = 0;
- if (tunnel_argv)
- SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+ if (tunnel_name)
+ {
+ if (tunnel_argv)
+ SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+ else
+ {
+ void *tunnel_context;
+ apr_file_t *request;
+ apr_file_t *response;
+ SVN_ERR(callbacks->open_tunnel_func(
+ &request, &response, &tunnel_context,
+ callbacks->tunnel_baton, tunnel_name,
+ uri->user, uri->hostname, uri->port,
+ pool));
+ if (callbacks->close_tunnel_func)
+ {
+ struct tunnel_data_t *const td = apr_palloc(pool, sizeof(*td));
+ td->tunnel_context = tunnel_context;
+ td->tunnel_baton = callbacks->tunnel_baton;
+ td->tunnel_name = apr_pstrdup(pool, tunnel_name);
+ td->user = apr_pstrdup(pool, uri->user);
+ td->hostname = apr_pstrdup(pool, uri->hostname);
+ td->port = uri->port;
+ td->close_tunnel = callbacks->close_tunnel_func;
+ apr_pool_cleanup_register(pool, td, close_tunnel_cleanup,
+ apr_pool_cleanup_null);
+ }
+
+ conn = svn_ra_svn_create_conn3(NULL, response, request,
+ SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
+ 0, 0, pool);
+ SVN_ERR(svn_ra_svn__skip_leading_garbage(conn, pool));
+ }
+ }
else
{
SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));
@@ -701,7 +762,7 @@ static svn_error_t *open_session(svn_ra_
N_("Module for accessing a repository using the svn network protocol.")
#endif
-static const char *ra_svn_get_description(void)
+static const char *ra_svn_get_description(apr_pool_t *pool)
{
return _(RA_SVN_DESCRIPTION);
}
@@ -738,7 +799,14 @@ static svn_error_t *ra_svn_open(svn_ra_s
parse_tunnel(url, &tunnel, pool);
- if (tunnel)
+ /* Use the default tunnel implementation if we got a tunnel name,
+ but either do not have tunnel handler callbacks installed, or
+ the handlers don't like the tunnel name. */
+ if (tunnel
+ && (!callbacks->open_tunnel_func
+ || (callbacks->check_tunnel_func && callbacks->open_tunnel_func
+ && !callbacks->check_tunnel_func(callbacks->tunnel_baton,
+ tunnel))))
SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
pool));
else
@@ -755,7 +823,7 @@ static svn_error_t *ra_svn_open(svn_ra_s
/* We open the session in a subpool so we can get rid of it if we
reparent with a server that doesn't support reparenting. */
- SVN_ERR(open_session(&sess, url, &uri, tunnel_argv,
+ SVN_ERR(open_session(&sess, url, &uri, tunnel, tunnel_argv,
callbacks, callback_baton, sess_pool));
session->priv = sess;
@@ -791,7 +859,7 @@ static svn_error_t *ra_svn_reparent(svn_
sess_pool = svn_pool_create(ra_session->pool);
err = parse_url(url, &uri, sess_pool);
if (! err)
- err = open_session(&new_sess, url, &uri, sess->tunnel_argv,
+ err = open_session(&new_sess, url, &uri, sess->tunnel_name, sess->tunnel_argv,
sess->callbacks, sess->callbacks_baton, sess_pool);
/* We destroy the new session pool on error, since it is allocated in
the main session pool. */
@@ -977,6 +1045,28 @@ static svn_error_t *ra_svn_commit(svn_ra
const svn_string_t *log_msg = svn_hash_gets(revprop_table,
SVN_PROP_REVISION_LOG);
+ if (log_msg == NULL &&
+ ! svn_ra_svn_has_capability(conn, SVN_RA_SVN_CAP_COMMIT_REVPROPS))
+ {
+ return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+ _("ra_svn does not support not specifying "
+ "a log message with pre-1.5 servers; "
+ "consider passing an empty one, or upgrading "
+ "the server"));
+ }
+ else if (log_msg == NULL)
+ /* 1.5+ server. Set LOG_MSG to something, since the 'logmsg' argument
+ to the 'commit' protocol command is non-optional; on the server side,
+ only REVPROP_TABLE will be used, and LOG_MSG will be ignored. The
+ "svn:log" member of REVPROP_TABLE table is NULL, therefore the commit
+ will have a NULL log message (not just "", really NULL).
+
+ svnserve 1.5.x+ has always ignored LOG_MSG when REVPROP_TABLE was
+ present; this was elevated to a protocol promise in r1498550 (and
+ later documented in this comment) in order to fix the segmentation
+ fault bug described in the log message of r1498550.*/
+ log_msg = svn_string_create("", pool);
+
/* If we're sending revprops other than svn:log, make sure the server won't
silently ignore them. */
if (apr_hash_count(revprop_table) > 1 &&
@@ -1095,7 +1185,7 @@ parse_iproplist(apr_array_header_t **inh
new_iprop->path_or_url = svn_path_url_add_component2(repos_root_url,
parent_rel_path,
result_pool);
- new_iprop->prop_hash = apr_hash_make(result_pool);
+ new_iprop->prop_hash = svn_hash__make(result_pool);
for (hi = apr_hash_first(iterpool, iprops);
hi;
hi = apr_hash_next(hi))
@@ -1234,7 +1324,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
return SVN_NO_ERROR;
/* Interpret the directory list. */
- *dirents = apr_hash_make(pool);
+ *dirents = svn_hash__make(pool);
for (i = 0; i < dirlist->nelts; i++)
{
const char *name, *kind, *cdate, *cauthor;
@@ -1322,7 +1412,7 @@ static svn_error_t *ra_svn_get_mergeinfo
*catalog = NULL;
if (mergeinfo_tuple->nelts > 0)
{
- *catalog = apr_hash_make(pool);
+ *catalog = svn_hash__make(pool);
for (i = 0; i < mergeinfo_tuple->nelts; i++)
{
svn_mergeinfo_t for_path;
@@ -1456,16 +1546,20 @@ static svn_error_t *ra_svn_diff(svn_ra_s
}
-static svn_error_t *ra_svn_log(svn_ra_session_t *session,
- const apr_array_header_t *paths,
- svn_revnum_t start, svn_revnum_t end,
- int limit,
- svn_boolean_t discover_changed_paths,
- svn_boolean_t strict_node_history,
- svn_boolean_t include_merged_revisions,
- const apr_array_header_t *revprops,
- svn_log_entry_receiver_t receiver,
- void *receiver_baton, apr_pool_t *pool)
+static svn_error_t *
+perform_ra_svn_log(svn_error_t **outer_error,
+ svn_ra_session_t *session,
+ const apr_array_header_t *paths,
+ svn_revnum_t start, svn_revnum_t end,
+ int limit,
+ svn_boolean_t discover_changed_paths,
+ svn_boolean_t strict_node_history,
+ svn_boolean_t include_merged_revisions,
+ svn_move_behavior_t move_behavior,
+ const apr_array_header_t *revprops,
+ svn_log_entry_receiver_t receiver,
+ void *receiver_baton,
+ apr_pool_t *pool)
{
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -1475,6 +1569,10 @@ static svn_error_t *ra_svn_log(svn_ra_se
const char *path;
char *name;
svn_boolean_t want_custom_revprops;
+ svn_boolean_t want_author = FALSE;
+ svn_boolean_t want_message = FALSE;
+ svn_boolean_t want_date = FALSE;
+ int nreceived = 0;
SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "log"));
if (paths)
@@ -1497,17 +1595,27 @@ static svn_error_t *ra_svn_log(svn_ra_se
{
name = APR_ARRAY_IDX(revprops, i, char *);
SVN_ERR(svn_ra_svn__write_cstring(conn, pool, name));
- if (!want_custom_revprops
- && strcmp(name, SVN_PROP_REVISION_AUTHOR) != 0
- && strcmp(name, SVN_PROP_REVISION_DATE) != 0
- && strcmp(name, SVN_PROP_REVISION_LOG) != 0)
+
+ if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
+ want_author = TRUE;
+ else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
+ want_date = TRUE;
+ else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
+ want_message = TRUE;
+ else
want_custom_revprops = TRUE;
}
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)n)",
+ (apr_uint64_t) move_behavior));
}
else
{
- SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!w())", "all-revprops"));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!w()n)", "all-revprops",
+ (apr_uint64_t) move_behavior));
+
+ want_author = TRUE;
+ want_date = TRUE;
+ want_message = TRUE;
want_custom_revprops = TRUE;
}
@@ -1528,7 +1636,6 @@ static svn_error_t *ra_svn_log(svn_ra_se
svn_ra_svn_item_t *item;
apr_hash_t *cphash;
svn_revnum_t rev;
- int nreceived;
svn_pool_clear(iterpool);
SVN_ERR(svn_ra_svn__read_item(conn, iterpool, &item));
@@ -1571,11 +1678,12 @@ static svn_error_t *ra_svn_log(svn_ra_se
if (cplist->nelts > 0)
{
/* Interpret the changed-paths list. */
- cphash = apr_hash_make(iterpool);
+ cphash = svn_hash__make(iterpool);
for (i = 0; i < cplist->nelts; i++)
{
svn_log_changed_path2_t *change;
- const char *copy_path, *action, *cpath, *kind_str;
+ svn_string_t *cpath;
+ const char *copy_path, *action, *kind_str;
apr_uint64_t text_mods, prop_mods;
svn_revnum_t copy_rev;
svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(cplist, i,
@@ -1584,14 +1692,19 @@ static svn_error_t *ra_svn_log(svn_ra_se
if (elt->kind != SVN_RA_SVN_LIST)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Changed-path entry not a list"));
- SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool,
- "cw(?cr)?(?c?BB)",
+ SVN_ERR(svn_ra_svn__read_data_log_changed_entry(elt->u.list,
&cpath, &action, ©_path,
©_rev, &kind_str,
&text_mods, &prop_mods));
- cpath = svn_fspath__canonicalize(cpath, iterpool);
- if (copy_path)
+
+ if (!svn_fspath__is_canonical(cpath->data))
+ {
+ cpath->data = svn_fspath__canonicalize(cpath->data, iterpool);
+ cpath->len = strlen(cpath->data);
+ }
+ if (copy_path && !svn_fspath__is_canonical(copy_path))
copy_path = svn_fspath__canonicalize(copy_path, iterpool);
+
change = svn_log_changed_path2_create(iterpool);
change->action = *action;
change->copyfrom_path = copy_path;
@@ -1599,15 +1712,20 @@ static svn_error_t *ra_svn_log(svn_ra_se
change->node_kind = svn_node_kind_from_word(kind_str);
change->text_modified = optbool_to_tristate(text_mods);
change->props_modified = optbool_to_tristate(prop_mods);
- svn_hash_sets(cphash, cpath, change);
+ apr_hash_set(cphash, cpath->data, cpath->len, change);
}
}
else
cphash = NULL;
- nreceived = 0;
- if (! (limit && (nest_level == 0) && (++nreceived > limit)))
+ /* Invoke RECEIVER
+ - Except if the server sends more than a >= 1 limit top level items
+ - Or when the callback reported a SVN_ERR_CEASE_INVOCATION
+ in an earlier invocation. */
+ if (! (limit && (nest_level == 0) && (++nreceived > limit))
+ && ! *outer_error)
{
+ svn_error_t *err;
log_entry = svn_log_entry_create(iterpool);
log_entry->changed_paths = cphash;
@@ -1619,38 +1737,27 @@ static svn_error_t *ra_svn_log(svn_ra_se
SVN_ERR(svn_ra_svn__parse_proplist(rplist, iterpool,
&log_entry->revprops));
if (log_entry->revprops == NULL)
- log_entry->revprops = apr_hash_make(iterpool);
- if (revprops == NULL)
+ log_entry->revprops = svn_hash__make(iterpool);
+
+ if (author && want_author)
+ svn_hash_sets(log_entry->revprops,
+ SVN_PROP_REVISION_AUTHOR, author);
+ if (date && want_date)
+ svn_hash_sets(log_entry->revprops,
+ SVN_PROP_REVISION_DATE, date);
+ if (message && want_message)
+ svn_hash_sets(log_entry->revprops,
+ SVN_PROP_REVISION_LOG, message);
+
+ err = receiver(receiver_baton, log_entry, iterpool);
+ if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
{
- /* Caller requested all revprops; set author/date/log. */
- if (author)
- svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
- author);
- if (date)
- svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_DATE,
- date);
- if (message)
- svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_LOG,
- message);
+ *outer_error = svn_error_trace(
+ svn_error_compose_create(*outer_error, err));
}
else
- {
- /* Caller requested some; maybe set author/date/log. */
- for (i = 0; i < revprops->nelts; i++)
- {
- name = APR_ARRAY_IDX(revprops, i, char *);
- if (author && strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
- svn_hash_sets(log_entry->revprops,
- SVN_PROP_REVISION_AUTHOR, author);
- if (date && strcmp(name, SVN_PROP_REVISION_DATE) == 0)
- svn_hash_sets(log_entry->revprops,
- SVN_PROP_REVISION_DATE, date);
- if (message && strcmp(name, SVN_PROP_REVISION_LOG) == 0)
- svn_hash_sets(log_entry->revprops,
- SVN_PROP_REVISION_LOG, message);
- }
- }
- SVN_ERR(receiver(receiver_baton, log_entry, iterpool));
+ SVN_ERR(err);
+
if (log_entry->has_children)
{
nest_level++;
@@ -1665,10 +1772,42 @@ static svn_error_t *ra_svn_log(svn_ra_se
svn_pool_destroy(iterpool);
/* Read the response. */
- return svn_ra_svn__read_cmd_response(conn, pool, "");
+ return svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, ""));
+}
+
+static svn_error_t *
+ra_svn_log(svn_ra_session_t *session,
+ const apr_array_header_t *paths,
+ svn_revnum_t start, svn_revnum_t end,
+ int limit,
+ svn_boolean_t discover_changed_paths,
+ svn_boolean_t strict_node_history,
+ svn_boolean_t include_merged_revisions,
+ svn_move_behavior_t move_behavior,
+ const apr_array_header_t *revprops,
+ svn_log_entry_receiver_t receiver,
+ void *receiver_baton, apr_pool_t *pool)
+{
+ svn_error_t *outer_error = NULL;
+ svn_error_t *err;
+
+ err = svn_error_trace(perform_ra_svn_log(&outer_error,
+ session, paths,
+ start, end,
+ limit,
+ discover_changed_paths,
+ strict_node_history,
+ include_merged_revisions,
+ move_behavior, revprops,
+ receiver, receiver_baton,
+ pool));
+ return svn_error_trace(
+ svn_error_compose_create(outer_error,
+ err));
}
+
static svn_error_t *ra_svn_check_path(svn_ra_session_t *session,
const char *path, svn_revnum_t rev,
svn_node_kind_t *kind, apr_pool_t *pool)
@@ -1942,7 +2081,7 @@ static svn_error_t *ra_svn_get_file_revs
{
svn_stream_t *stream;
- if (d_handler)
+ if (d_handler && d_handler != svn_delta_noop_window_handler)
stream = svn_txdelta_parse_svndiff(d_handler, d_baton, TRUE,
rev_pool);
else
@@ -2709,7 +2848,7 @@ svn_ra_svn__init(const svn_version_t *lo
{ NULL, NULL }
};
- SVN_ERR(svn_ver_check_list(svn_ra_svn_version(), checklist));
+ SVN_ERR(svn_ver_check_list2(svn_ra_svn_version(), checklist, svn_ver_equal));
/* Simplified version check to make sure we can safely use the
VTABLE parameter. The RA loader does a more exhaustive check. */
Propchange: subversion/branches/cache-server/subversion/libsvn_ra_svn/deprecated.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c Tue Oct 15 08:52:06 2013
@@ -28,6 +28,7 @@
#include <apr_general.h>
#include <apr_strings.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
@@ -37,7 +38,6 @@
#include "svn_ra_svn.h"
#include "svn_path.h"
#include "svn_pools.h"
-#include "svn_private_config.h"
#include "private/svn_fspath.h"
#include "private/svn_editor.h"
Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c Tue Oct 15 08:52:06 2013
@@ -32,13 +32,13 @@
#include <apr_lib.h>
#include <apr_strings.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_ra_svn.h"
-#include "svn_private_config.h"
#include "svn_ctype.h"
#include "svn_time.h"
@@ -47,6 +47,7 @@
#include "private/svn_string_private.h"
#include "private/svn_dep_compat.h"
#include "private/svn_error_private.h"
+#include "private/svn_subr_private.h"
#define svn_iswhitespace(c) ((c) == ' ' || (c) == '\n')
@@ -56,6 +57,19 @@
#define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
+/* We don't use "words" longer than this in our protocol. The longest word
+ * we are currently using is only about 16 chars long but we leave room for
+ * longer future capability and command names.
+ */
+#define MAX_WORD_LENGTH 31
+
+/* The generic parsers will use the following value to limit the recursion
+ * depth to some reasonable value. The current protocol implementation
+ * actually uses only maximum item nesting level of around 5. So, there is
+ * plenty of headroom here.
+ */
+#define ITEM_NESTING_LIMIT 64
+
/* Return the APR socket timeout to be used for the connection depending
* on whether there is a blockage handler or zero copy has been activated. */
static apr_interval_time_t
@@ -397,7 +411,7 @@ static svn_error_t *readbuf_fill(svn_ra_
return SVN_NO_ERROR;
}
-static APR_INLINE svn_error_t *
+static SVN__FORCE_INLINE svn_error_t *
readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool, char *result)
{
if (conn->read_ptr == conn->read_end)
@@ -511,21 +525,32 @@ svn_ra_svn__write_number(svn_ra_svn_conn
return write_number(conn, pool, number, ' ');
}
-svn_error_t *
-svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool,
- const svn_string_t *str)
+static svn_error_t *
+svn_ra_svn__write_ncstring(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *s,
+ apr_size_t len)
{
- if (str->len < 10)
+ if (len < 10)
{
- SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
+ SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
SVN_ERR(writebuf_writechar(conn, pool, ':'));
}
else
- SVN_ERR(write_number(conn, pool, str->len, ':'));
+ SVN_ERR(write_number(conn, pool, len, ':'));
- SVN_ERR(writebuf_write(conn, pool, str->data, str->len));
+ SVN_ERR(writebuf_write(conn, pool, s, len));
SVN_ERR(writebuf_writechar(conn, pool, ' '));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const svn_string_t *str)
+{
+ svn_ra_svn__write_ncstring(conn, pool, str->data, str->len);
return SVN_NO_ERROR;
}
@@ -534,19 +559,7 @@ svn_ra_svn__write_cstring(svn_ra_svn_con
apr_pool_t *pool,
const char *s)
{
- apr_size_t len = strlen(s);
-
- if (len < 10)
- {
- SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
- SVN_ERR(writebuf_writechar(conn, pool, ':'));
- }
- else
- SVN_ERR(write_number(conn, pool, len, ':'));
-
- SVN_ERR(writebuf_write(conn, pool, s, len));
- SVN_ERR(writebuf_writechar(conn, pool, ' '));
-
+ svn_ra_svn__write_ncstring(conn, pool, s, strlen(s));
return SVN_NO_ERROR;
}
@@ -562,31 +575,45 @@ svn_ra_svn__write_word(svn_ra_svn_conn_t
}
svn_error_t *
+svn_ra_svn__write_boolean(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_boolean_t value)
+{
+ if (value)
+ SVN_ERR(writebuf_write_short_string(conn, pool, "true ", 5));
+ else
+ SVN_ERR(writebuf_write_short_string(conn, pool, "false ", 6));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_ra_svn__write_proplist(svn_ra_svn_conn_t *conn,
apr_pool_t *pool,
apr_hash_t *props)
{
- apr_pool_t *iterpool;
apr_hash_index_t *hi;
- const void *key;
- void *val;
const char *propname;
svn_string_t *propval;
+ apr_size_t len;
+ /* One might use an iterpool here but that would only be used when the
+ send buffer gets flushed and only by the CONN's progress callback.
+ That should happen at most once for typical prop lists and even then
+ use only a few bytes at best.
+ */
if (props)
- {
- iterpool = svn_pool_create(pool);
- for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
- {
- svn_pool_clear(iterpool);
- apr_hash_this(hi, &key, NULL, &val);
- propname = key;
- propval = val;
- SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "cs",
- propname, propval));
- }
- svn_pool_destroy(iterpool);
- }
+ for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
+ {
+ apr_hash_this(hi, (const void **)&propname,
+ (apr_ssize_t *)&len,
+ (void **)&propval);
+
+ SVN_ERR(svn_ra_svn__start_list(conn, pool));
+ SVN_ERR(svn_ra_svn__write_ncstring(conn, pool, propname, len));
+ SVN_ERR(svn_ra_svn__write_string(conn, pool, propval));
+ SVN_ERR(svn_ra_svn__end_list(conn, pool));
+ }
return SVN_NO_ERROR;
}
@@ -704,8 +731,7 @@ vwrite_tuple_number(svn_ra_svn_conn_t *c
static svn_error_t *
vwrite_tuple_boolean(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
{
- const char *cstr = va_arg(*ap, svn_boolean_t) ? "true" : "false";
- return svn_ra_svn__write_word(conn, pool, cstr);
+ return svn_ra_svn__write_boolean(conn, pool, va_arg(*ap, svn_boolean_t));
}
static svn_error_t *
@@ -780,8 +806,7 @@ write_tuple_boolean(svn_ra_svn_conn_t *c
apr_pool_t *pool,
svn_boolean_t value)
{
- const char *cstr = value ? "true" : "false";
- return svn_ra_svn__write_word(conn, pool, cstr);
+ return svn_ra_svn__write_boolean(conn, pool, value);
}
static svn_error_t *
@@ -929,7 +954,6 @@ svn_ra_svn__write_tuple(svn_ra_svn_conn_
static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
svn_ra_svn_item_t *item, apr_uint64_t len64)
{
- svn_stringbuf_t *stringbuf;
apr_size_t len = (apr_size_t)len64;
apr_size_t readbuf_len;
char *dest;
@@ -940,58 +964,60 @@ static svn_error_t *read_string(svn_ra_s
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("String length larger than maximum"));
- /* Read the string in chunks. The chunk size is large enough to avoid
- * re-allocation in typical cases, and small enough to ensure we do not
- * pre-allocate an unreasonable amount of memory if (perhaps due to
- * network data corruption or a DOS attack), we receive a bogus claim that
- * a very long string is going to follow. In that case, we start small
- * and wait for all that data to actually show up. This does not fully
- * prevent DOS attacks but makes them harder (you have to actually send
- * gigabytes of data). */
- readbuf_len = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
- ? len
- : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
- stringbuf = svn_stringbuf_create_ensure(readbuf_len, pool);
- dest = stringbuf->data;
-
- /* Read remaining string data directly into the string structure.
- * Do it iteratively, if necessary. */
- while (readbuf_len)
- {
- SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
-
- stringbuf->len += readbuf_len;
- len -= readbuf_len;
-
- /* Early exit. In most cases, strings can be read in the first
- * iteration. */
- if (len == 0)
- break;
-
- /* Prepare next iteration: determine length of chunk to read
- * and re-alloc the string buffer. */
- readbuf_len
- = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
- ? len
- : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
-
- svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
- dest = stringbuf->data + stringbuf->len;
- }
-
- /* zero-terminate the string */
- stringbuf->data[stringbuf->len] = '\0';
-
- /* Return the string properly wrapped into an RA_SVN item. */
- item->kind = SVN_RA_SVN_STRING;
- item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+ /* Shorter strings can be copied directly from the read buffer. */
+ if (conn->read_ptr + len <= conn->read_end)
+ {
+ item->kind = SVN_RA_SVN_STRING;
+ item->u.string = svn_string_ncreate(conn->read_ptr, len, pool);
+ conn->read_ptr += len;
+ }
+ else
+ {
+ /* Read the string in chunks. The chunk size is large enough to avoid
+ * re-allocation in typical cases, and small enough to ensure we do
+ * not pre-allocate an unreasonable amount of memory if (perhaps due
+ * to network data corruption or a DOS attack), we receive a bogus
+ * claim that a very long string is going to follow. In that case, we
+ * start small and wait for all that data to actually show up. This
+ * does not fully prevent DOS attacks but makes them harder (you have
+ * to actually send gigabytes of data). */
+ svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+
+ /* Read string data directly into the string structure.
+ * Do it iteratively. */
+ do
+ {
+ /* Determine length of chunk to read and re-alloc the buffer. */
+ readbuf_len
+ = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
+ ? len
+ : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
+
+ svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
+ dest = stringbuf->data + stringbuf->len;
+
+ /* read data & update length info */
+ SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
+
+ stringbuf->len += readbuf_len;
+ len -= readbuf_len;
+ }
+ while (len);
+
+ /* zero-terminate the string */
+ stringbuf->data[stringbuf->len] = '\0';
+
+ /* Return the string properly wrapped into an RA_SVN item. */
+ item->kind = SVN_RA_SVN_STRING;
+ item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+ }
return SVN_NO_ERROR;
}
/* Given the first non-whitespace character FIRST_CHAR, read an item
* into the already allocated structure ITEM. LEVEL should be set
- * to 0 for the first call and is used to enforce a recurssion limit
+ * to 0 for the first call and is used to enforce a recursion limit
* on the parser. */
static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
svn_ra_svn_item_t *item, char first_char,
@@ -999,12 +1025,11 @@ static svn_error_t *read_item(svn_ra_svn
{
char c = first_char;
apr_uint64_t val;
- svn_stringbuf_t *str;
svn_ra_svn_item_t *listitem;
- if (++level >= 64)
+ if (++level >= ITEM_NESTING_LIMIT)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
- _("Too many nested items"));
+ _("Items are nested too deeply"));
/* Determine the item type and read it in. Make sure that c is the
@@ -1022,7 +1047,8 @@ static svn_error_t *read_item(svn_ra_svn
break;
val = val * 10 + (c - '0');
/* val wrapped past maximum value? */
- if (prev_val >= (APR_UINT64_MAX / 10) && (val / 10) != prev_val)
+ if ((prev_val >= (APR_UINT64_MAX / 10))
+ && (val < APR_UINT64_MAX - 10))
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Number is larger than maximum"));
}
@@ -1041,31 +1067,72 @@ static svn_error_t *read_item(svn_ra_svn
}
else if (svn_ctype_isalpha(c))
{
- /* It's a word. */
- str = svn_stringbuf_create_ensure(16, pool);
- svn_stringbuf_appendbyte(str, c);
+ /* It's a word. Read it into a buffer of limited size. */
+ char *buffer = apr_palloc(pool, MAX_WORD_LENGTH + 1);
+ char *end = buffer + MAX_WORD_LENGTH;
+ char *p = buffer + 1;
+
+ buffer[0] = c;
while (1)
{
- SVN_ERR(readbuf_getchar(conn, pool, &c));
- if (!svn_ctype_isalnum(c) && c != '-')
+ SVN_ERR(readbuf_getchar(conn, pool, p));
+ if (!svn_ctype_isalnum(*p) && *p != '-')
break;
- svn_stringbuf_appendbyte(str, c);
+
+ if (++p == end)
+ return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ _("Word is too long"));
}
+
+ c = *p;
+ *p = '\0';
+
item->kind = SVN_RA_SVN_WORD;
- item->u.word = str->data;
+ item->u.word = buffer;
}
else if (c == '(')
{
- /* Read in the list items. */
+ /* Allocate an APR array with room for (initially) 4 items.
+ * We do this manually because lists are the most frequent protocol
+ * element, often used to frame a single, optional value. We save
+ * about 20% of total protocol handling time. */
+ char *buffer = apr_palloc(pool, sizeof(apr_array_header_t)
+ + 4 * sizeof(svn_ra_svn_item_t));
+ svn_ra_svn_item_t *data
+ = (svn_ra_svn_item_t *)(buffer + sizeof(apr_array_header_t));
+
item->kind = SVN_RA_SVN_LIST;
- item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
+ item->u.list = (apr_array_header_t *)buffer;
+ item->u.list->elts = (char *)data;
+ item->u.list->pool = pool;
+ item->u.list->elt_size = sizeof(*data);
+ item->u.list->nelts = 0;
+ item->u.list->nalloc = 4;
+
+ listitem = data;
+
+ /* Read in the list items. */
while (1)
{
SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
if (c == ')')
break;
- listitem = apr_array_push(item->u.list);
+
+ /* increase array capacity if necessary */
+ if (item->u.list->nelts == item->u.list->nalloc)
+ {
+ data = apr_palloc(pool, 2 * item->u.list->nelts * sizeof(*data));
+ memcpy(data, item->u.list->elts, item->u.list->nelts * sizeof(*data));
+ item->u.list->elts = (char *)data;
+ item->u.list->nalloc *= 2;
+ listitem = data + item->u.list->nelts;
+ }
+
+ /* read next protocol item */
SVN_ERR(read_item(conn, pool, listitem, c, level));
+
+ listitem++;
+ item->u.list->nelts++;
}
SVN_ERR(readbuf_getchar(conn, pool, &c));
}
@@ -1202,14 +1269,15 @@ static svn_error_t *vparse_tuple(const a
if (**fmt == '?')
(*fmt)++;
elt = &APR_ARRAY_IDX(items, count, svn_ra_svn_item_t);
- if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
- *va_arg(*ap, apr_uint64_t *) = elt->u.number;
- else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
- *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
- else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
- *va_arg(*ap, svn_string_t **) = elt->u.string;
+ if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
+ {
+ (*fmt)++;
+ SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
+ }
else if (**fmt == 'c' && elt->kind == SVN_RA_SVN_STRING)
*va_arg(*ap, const char **) = elt->u.string->data;
+ else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
+ *va_arg(*ap, svn_string_t **) = elt->u.string;
else if (**fmt == 'w' && elt->kind == SVN_RA_SVN_WORD)
*va_arg(*ap, const char **) = elt->u.word;
else if (**fmt == 'b' && elt->kind == SVN_RA_SVN_WORD)
@@ -1221,6 +1289,10 @@ static svn_error_t *vparse_tuple(const a
else
break;
}
+ else if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
+ *va_arg(*ap, apr_uint64_t *) = elt->u.number;
+ else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
+ *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
else if (**fmt == 'B' && elt->kind == SVN_RA_SVN_WORD)
{
if (strcmp(elt->u.word, "true") == 0)
@@ -1230,13 +1302,17 @@ static svn_error_t *vparse_tuple(const a
else
break;
}
- else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
- *va_arg(*ap, apr_array_header_t **) = elt->u.list;
- else if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
+ else if (**fmt == '3' && elt->kind == SVN_RA_SVN_WORD)
{
- (*fmt)++;
- SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
+ if (strcmp(elt->u.word, "true") == 0)
+ *va_arg(*ap, svn_tristate_t *) = svn_tristate_true;
+ else if (strcmp(elt->u.word, "false") == 0)
+ *va_arg(*ap, svn_tristate_t *) = svn_tristate_false;
+ else
+ break;
}
+ else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
+ *va_arg(*ap, apr_array_header_t **) = elt->u.list;
else if (**fmt == ')')
return SVN_NO_ERROR;
else
@@ -1268,6 +1344,9 @@ static svn_error_t *vparse_tuple(const a
case 'n':
*va_arg(*ap, apr_uint64_t *) = SVN_RA_SVN_UNSPECIFIED_NUMBER;
break;
+ case '3':
+ *va_arg(*ap, svn_tristate_t *) = svn_tristate_unknown;
+ break;
case '(':
nesting_level++;
break;
@@ -1342,7 +1421,7 @@ svn_ra_svn__parse_proplist(const apr_arr
svn_ra_svn_item_t *elt;
int i;
- *props = apr_hash_make(pool);
+ *props = svn_hash__make(pool);
for (i = 0; i < list->nelts; i++)
{
elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
@@ -1455,6 +1534,58 @@ svn_ra_svn__read_cmd_response(svn_ra_svn
status);
}
+static svn_error_t *
+svn_ra_svn__handle_command(svn_boolean_t *terminate,
+ apr_hash_t *cmd_hash,
+ void *baton,
+ svn_ra_svn_conn_t *conn,
+ svn_boolean_t error_on_disconnect,
+ apr_pool_t *iterpool)
+{
+ const char *cmdname;
+ svn_error_t *err, *write_err;
+ apr_array_header_t *params;
+ const svn_ra_svn_cmd_entry_t *command;
+
+ err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, ¶ms);
+ if (err)
+ {
+ if (!error_on_disconnect
+ && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
+ {
+ svn_error_clear(err);
+ *terminate = TRUE;
+ return SVN_NO_ERROR;
+ }
+ return err;
+ }
+ command = svn_hash_gets(cmd_hash, cmdname);
+
+ if (command)
+ err = (*command->handler)(conn, iterpool, params, baton);
+ else
+ {
+ err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
+ _("Unknown editor command '%s'"), cmdname);
+ err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
+ }
+
+ if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
+ {
+ write_err = svn_ra_svn__write_cmd_failure(
+ conn, iterpool,
+ svn_ra_svn__locate_real_error_child(err));
+ svn_error_clear(err);
+ if (write_err)
+ return write_err;
+ }
+ else if (err)
+ return err;
+
+ *terminate = (command && command->terminate);
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn,
apr_pool_t *pool,
@@ -1464,10 +1595,7 @@ svn_ra_svn__handle_commands2(svn_ra_svn_
{
apr_pool_t *subpool = svn_pool_create(pool);
apr_pool_t *iterpool = svn_pool_create(subpool);
- const char *cmdname;
const svn_ra_svn_cmd_entry_t *command;
- svn_error_t *err, *write_err;
- apr_array_header_t *params;
apr_hash_t *cmd_hash = apr_hash_make(subpool);
for (command = commands; command->cmdname; command++)
@@ -1475,43 +1603,18 @@ svn_ra_svn__handle_commands2(svn_ra_svn_
while (1)
{
+ svn_boolean_t terminate;
+ svn_error_t *err;
svn_pool_clear(iterpool);
- err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, ¶ms);
- if (err)
- {
- if (!error_on_disconnect
- && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
- {
- svn_error_clear(err);
- svn_pool_destroy(subpool);
- return SVN_NO_ERROR;
- }
- return err;
- }
- command = svn_hash_gets(cmd_hash, cmdname);
- if (command)
- err = (*command->handler)(conn, iterpool, params, baton);
- else
- {
- err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
- _("Unknown editor command '%s'"), cmdname);
- err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
- }
-
- if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
+ err = svn_ra_svn__handle_command(&terminate, cmd_hash, baton, conn,
+ error_on_disconnect, iterpool);
+ if (err)
{
- write_err = svn_ra_svn__write_cmd_failure(
- conn, iterpool,
- svn_ra_svn__locate_real_error_child(err));
- svn_error_clear(err);
- if (write_err)
- return write_err;
+ svn_pool_destroy(subpool);
+ return svn_error_trace(err);
}
- else if (err)
- return err;
-
- if (command && command->terminate)
+ if (terminate)
break;
}
svn_pool_destroy(iterpool);
@@ -2287,3 +2390,217 @@ svn_error_t *svn_ra_svn__write_cmd_failu
}
return writebuf_write_short_string(conn, pool, ") ) ", 4);
}
+
+svn_error_t *
+svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ char action,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_rev,
+ svn_node_kind_t node_kind,
+ svn_boolean_t text_modified,
+ svn_boolean_t props_modified)
+{
+ SVN_ERR(write_tuple_start_list(conn, pool));
+
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(writebuf_writechar(conn, pool, action));
+ SVN_ERR(writebuf_writechar(conn, pool, ' '));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, copyfrom_path));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, copyfrom_rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, svn_node_kind_to_word(node_kind)));
+ SVN_ERR(write_tuple_boolean(conn, pool, text_modified));
+ SVN_ERR(write_tuple_boolean(conn, pool, props_modified));
+
+ return writebuf_write_short_string(conn, pool, ") ) ", 4);
+}
+
+svn_error_t *
+svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t revision,
+ const svn_string_t *author,
+ const svn_string_t *date,
+ const svn_string_t *message,
+ svn_boolean_t has_children,
+ svn_boolean_t invalid_revnum,
+ unsigned revprop_count)
+{
+ SVN_ERR(write_tuple_revision(conn, pool, revision));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_string_opt(conn, pool, author));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_string_opt(conn, pool, date));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_string_opt(conn, pool, message));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, has_children));
+ SVN_ERR(write_tuple_boolean(conn, pool, invalid_revnum));
+ SVN_ERR(svn_ra_svn__write_number(conn, pool, revprop_count));
+
+ return SVN_NO_ERROR;
+}
+
+/* If condition COND is not met, return a "malformed network data" error.
+ */
+#define CHECK_PROTOCOL_COND(cond)\
+ if (!(cond)) \
+ return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, \
+ _("Malformed network data"));
+
+/* In *RESULT, return the SVN-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_string(const apr_array_header_t *items,
+ int idx,
+ svn_string_t **result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+ *result = elt->u.string;
+
+ return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the C-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_cstring(const apr_array_header_t *items,
+ int idx,
+ const char **result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+ *result = elt->u.string->data;
+
+ return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the word at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_word(const apr_array_header_t *items,
+ int idx,
+ const char **result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+ *result = elt->u.word;
+
+ return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the revision at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_revision(const apr_array_header_t *items,
+ int idx,
+ svn_revnum_t *result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_NUMBER);
+ *result = (svn_revnum_t)elt->u.number;
+
+ return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the boolean at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_boolean(const apr_array_header_t *items,
+ int idx,
+ apr_uint64_t *result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+ if (elt->u.word[0] == 't' && strcmp(elt->u.word, "true") == 0)
+ *result = TRUE;
+ else if (strcmp(elt->u.word, "false") == 0)
+ *result = FALSE;
+ else
+ CHECK_PROTOCOL_COND(FALSE);
+
+ return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the tuple at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_list(const apr_array_header_t *items,
+ int idx,
+ const apr_array_header_t **result)
+{
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+ CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_LIST);
+
+ *result = elt->u.list;
+ return SVN_NO_ERROR;
+}
+
+/* Verify the tuple ITEMS contains at least MIN and at most MAX elements.
+ */
+static svn_error_t *
+svn_ra_svn__read_check_array_size(const apr_array_header_t *items,
+ int min,
+ int max)
+{
+ CHECK_PROTOCOL_COND(items->nelts >= min && items->nelts <= max);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items,
+ svn_string_t **cpath,
+ const char **action,
+ const char **copy_path,
+ svn_revnum_t *copy_rev,
+ const char **kind_str,
+ apr_uint64_t *text_mods,
+ apr_uint64_t *prop_mods)
+{
+ const apr_array_header_t *sub_items;
+
+ /* initialize optional values */
+ *copy_path = NULL;
+ *copy_rev = SVN_INVALID_REVNUM;
+ *kind_str = NULL;
+ *text_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+ *prop_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+
+ /* top-level elements (mandatory) */
+ SVN_ERR(svn_ra_svn__read_check_array_size(items, 3, 4));
+ SVN_ERR(svn_ra_svn__read_string(items, 0, cpath));
+ SVN_ERR(svn_ra_svn__read_word(items, 1, action));
+
+ /* first sub-structure (mandatory) */
+ SVN_ERR(svn_ra_svn__read_list(items, 2, &sub_items));
+ if (sub_items->nelts)
+ {
+ SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 2, 2));
+ SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, copy_path));
+ SVN_ERR(svn_ra_svn__read_revision(sub_items, 1, copy_rev));
+ }
+
+ /* second sub-structure (optional) */
+ if (items->nelts == 4)
+ {
+ SVN_ERR(svn_ra_svn__read_list(items, 3, &sub_items));
+ SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 0, 3));
+
+ switch (sub_items->nelts)
+ {
+ case 3 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 2, prop_mods));
+ case 2 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 1, text_mods));
+ case 1 : SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, kind_str));
+ default: break;
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol Tue Oct 15 08:52:06 2013
@@ -294,8 +294,12 @@ second place for auth-request point as n
Upon receiving response, client switches to editor command set.
Upon successful completion of edit, server sends auth-request.
After auth exchange completes, server sends commit-info.
+ If rev-props is present, logmsg is ignored. Only the svn:log entry in
+ rev-props (if any) will be used.
commit-info: ( new-rev:number date:string author:string
? ( post-commit-err:string ) )
+ NOTE: when revving this, make 'logmsg' optional, or delete that parameter
+ and have the log message specified in 'rev-props'.
get-file
params: ( path:string [ rev:number ] want-props:bool want-contents:bool
@@ -378,11 +382,13 @@ second place for auth-request point as n
[ end-rev:number ] changed-paths:bool strict-node:bool
? limit:number
? include-merged-revisions:bool
- all-revprops | revprops ( revprop:string ... ) )
+ all-revprops | revprops ( revprop:string ... )
+ ? move-behavior:number )
Before sending response, server sends log entries, ending with "done".
If a client does not want to specify a limit, it should send 0 as the
limit parameter. rev-props excludes author, date, and log; they are
sent separately for backwards-compatibility.
+ Move-behavior is encoded like enum svn_move_behavior_t.
log-entry: ( ( change:changed-path-entry ... ) rev:number
[ author:string ] [ date:string ] [ message:string ]
? has-children:bool invalid-revnum:bool
@@ -591,7 +597,13 @@ desirability:
* The protocol version may be bumped. Clients and servers can then
choose to any range of protocol versions.
-4.1. Extending existing commands
+4.1. Limitations
+
+The current implementation limits the length of a word to 31 characters.
+Longer words, such as capability names, will be cause an error on the
+receiver side.
+
+4.2. Extending existing commands
Extending an existing command is normally done by indicating that its
tuple is allowed to end where it currently ends, for backwards
Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h Tue Oct 15 08:52:06 2013
@@ -127,6 +127,7 @@ struct svn_ra_svn__session_baton_t {
const char *user;
const char *hostname; /* The remote hostname. */
const char *realm_prefix;
+ const char *tunnel_name;
const char **tunnel_argv;
const svn_ra_callbacks2_t *callbacks;
void *callbacks_baton;
Modified: subversion/branches/cache-server/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/authz.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/authz.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
#include <apr_pools.h>
#include <apr_file_io.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_error.h"
@@ -853,23 +854,9 @@ authz_retrieve_config_repo(svn_config_t
return SVN_NO_ERROR;
}
-/* Given a PATH which might be a relative repo URL (^/), an absolute
- * local repo URL (file://), an absolute path outside of the repo
- * or a location in the Windows registry.
- *
- * Retrieve the configuration data that PATH points at and parse it into
- * CFG_P allocated in POOL.
- *
- * If PATH cannot be parsed as a config file then an error is returned. The
- * contents of CFG_P is then undefined. If MUST_EXIST is TRUE, a missing
- * authz file is also an error.
- *
- * REPOS_ROOT points at the root of the repos you are
- * going to apply the authz against, can be NULL if you are sure that you
- * don't have a repos relative URL in PATH. */
-static svn_error_t *
-authz_retrieve_config(svn_config_t **cfg_p, const char *path,
- svn_boolean_t must_exist, apr_pool_t *pool)
+svn_error_t *
+svn_repos__retrieve_config(svn_config_t **cfg_p, const char *path,
+ svn_boolean_t must_exist, apr_pool_t *pool)
{
if (svn_path_is_url(path))
{
@@ -942,7 +929,7 @@ svn_repos__authz_read(svn_authz_t **auth
/* Load the authz file */
if (accept_urls)
- SVN_ERR(authz_retrieve_config(&authz->cfg, path, must_exist, pool));
+ SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, pool));
else
SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
@@ -953,8 +940,8 @@ svn_repos__authz_read(svn_authz_t **auth
/* Load the groups file */
if (accept_urls)
- SVN_ERR(authz_retrieve_config(&groups_cfg, groups_path, must_exist,
- pool));
+ SVN_ERR(svn_repos__retrieve_config(&groups_cfg, groups_path,
+ must_exist, pool));
else
SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
TRUE, TRUE, pool));
Modified: subversion/branches/cache-server/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/commit.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/commit.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
#include <apr_pools.h>
#include <apr_file_io.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_compat.h"
#include "svn_pools.h"
@@ -39,7 +40,6 @@
#include "svn_ctype.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
-#include "svn_private_config.h"
#include "repos.h"
@@ -259,79 +259,6 @@ make_dir_baton(struct edit_baton *edit_b
return db;
}
-/* Return a copy of PATH, allocated from POOL, for which control
- characters have been escaped using the form \NNN (where NNN is the
- octal representation of the byte's ordinal value). */
-static const char *
-illegal_path_escape(const char *path, apr_pool_t *pool)
-{
- svn_stringbuf_t *retstr;
- apr_size_t i, copied = 0;
- int c;
-
- /* At least one control character:
- strlen - 1 (control) + \ + N + N + N + null . */
- retstr = svn_stringbuf_create_ensure(strlen(path) + 4, pool);
- for (i = 0; path[i]; i++)
- {
- c = (unsigned char)path[i];
- if (! svn_ctype_iscntrl(c))
- continue;
-
- /* If we got here, we're looking at a character that isn't
- supported by the (or at least, our) URI encoding scheme. We
- need to escape this character. */
-
- /* First things first, copy all the good stuff that we haven't
- yet copied into our output buffer. */
- if (i - copied)
- svn_stringbuf_appendbytes(retstr, path + copied,
- i - copied);
-
- /* Make sure buffer is big enough for '\' 'N' 'N' 'N' (and NUL) */
- svn_stringbuf_ensure(retstr, retstr->len + 4);
- /*### The backslash separator doesn't work too great with Windows,
- but it's what we'll use for consistency with invalid utf8
- formatting (until someone has a better idea) */
- apr_snprintf(retstr->data + retstr->len, 5, "\\%03o", (unsigned char)c);
- retstr->len += 4;
-
- /* Finally, update our copy counter. */
- copied = i + 1;
- }
-
- /* If we didn't encode anything, we don't need to duplicate the string. */
- if (retstr->len == 0)
- return path;
-
- /* Anything left to copy? */
- if (i - copied)
- svn_stringbuf_appendbytes(retstr, path + copied, i - copied);
-
- /* retstr is null-terminated either by apr_snprintf or the svn_stringbuf
- functions. */
-
- return retstr->data;
-}
-
-/* Reject paths which contain control characters (related to issue #4340). */
-static svn_error_t *
-check_valid_path(const char *path,
- apr_pool_t *pool)
-{
- const char *c;
-
- for (c = path; *c; c++)
- {
- if (svn_ctype_iscntrl(*c))
- return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
- _("Invalid control character '0x%02x' in path '%s'"),
- (unsigned char)*c, illegal_path_escape(path, pool));
- }
-
- return SVN_NO_ERROR;
-}
-
/* This function is the shared guts of add_file() and add_directory(),
which see for the meanings of the parameters. The only extra
parameter here is IS_DIR, which is TRUE when adding a directory,
@@ -351,7 +278,8 @@ add_file_or_directory(const char *path,
svn_boolean_t was_copied = FALSE;
const char *full_path;
- SVN_ERR(check_valid_path(path, pool));
+ /* Reject paths which contain control characters (related to issue #4340). */
+ SVN_ERR(svn_path_check_valid(path, pool));
full_path = svn_fspath__join(eb->base_path,
svn_relpath_canonicalize(path, pool), pool);
@@ -1192,15 +1120,15 @@ static svn_error_t *
alter_file_cb(void *baton,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
const svn_checksum_t *checksum,
svn_stream_t *contents,
+ apr_hash_t *props,
apr_pool_t *scratch_pool)
{
struct ev2_baton *eb = baton;
- SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision, props,
- checksum, contents));
+ SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision,
+ checksum, contents, props));
return SVN_NO_ERROR;
}
@@ -1210,14 +1138,14 @@ static svn_error_t *
alter_symlink_cb(void *baton,
const char *relpath,
svn_revnum_t revision,
- apr_hash_t *props,
const char *target,
+ apr_hash_t *props,
apr_pool_t *scratch_pool)
{
struct ev2_baton *eb = baton;
- SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision, props,
- target));
+ SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision,
+ target, props));
return SVN_NO_ERROR;
}
@@ -1270,20 +1198,6 @@ move_cb(void *baton,
}
-/* This implements svn_editor_cb_rotate_t */
-static svn_error_t *
-rotate_cb(void *baton,
- const apr_array_header_t *relpaths,
- const apr_array_header_t *revisions,
- apr_pool_t *scratch_pool)
-{
- struct ev2_baton *eb = baton;
-
- SVN_ERR(svn_editor_rotate(eb->inner, relpaths, revisions));
- return SVN_NO_ERROR;
-}
-
-
/* This implements svn_editor_cb_complete_t */
static svn_error_t *
complete_cb(void *baton,
@@ -1405,7 +1319,6 @@ svn_repos__get_commit_ev2(svn_editor_t *
delete_cb,
copy_cb,
move_cb,
- rotate_cb,
complete_cb,
abort_cb
};
Modified: subversion/branches/cache-server/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/delta.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
#include <apr_hash.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_delta.h"
@@ -33,7 +34,6 @@
#include "svn_repos.h"
#include "svn_pools.h"
#include "svn_props.h"
-#include "svn_private_config.h"
#include "repos.h"
@@ -196,17 +196,6 @@ authz_root_check(svn_fs_root_t *root,
}
-static svn_error_t *
-not_a_dir_error(const char *role,
- const char *path)
-{
- return svn_error_createf
- (SVN_ERR_FS_NOT_DIRECTORY, 0,
- "Invalid %s directory '%s'",
- role, path ? path : "(null)");
-}
-
-
/* Public interface to computing directory deltas. */
svn_error_t *
svn_repos_dir_delta2(svn_fs_root_t *src_root,
@@ -237,7 +226,8 @@ svn_repos_dir_delta2(svn_fs_root_t *src_
if (src_parent_dir)
src_parent_dir = svn_relpath_canonicalize(src_parent_dir, pool);
else
- return not_a_dir_error("source parent", src_parent_dir);
+ return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, 0,
+ "Invalid source parent directory '(null)'");
/* TGT_FULLPATH must be valid. */
if (tgt_fullpath)
Modified: subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c Tue Oct 15 08:52:06 2013
@@ -26,13 +26,12 @@
deprecated functions in this file. */
#define SVN_DEPRECATED
+#include "svn_private_config.h"
#include "svn_repos.h"
#include "svn_compat.h"
#include "svn_hash.h"
#include "svn_props.h"
-#include "svn_private_config.h"
-
#include "repos.h"
@@ -473,6 +472,30 @@ svn_repos_fs_get_locks(apr_hash_t **lock
/*** From logs.c ***/
svn_error_t *
+svn_repos_get_logs4(svn_repos_t *repos,
+ const apr_array_header_t *paths,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ int limit,
+ svn_boolean_t discover_changed_paths,
+ svn_boolean_t strict_node_history,
+ svn_boolean_t include_merged_revisions,
+ const apr_array_header_t *revprops,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ svn_log_entry_receiver_t receiver,
+ void *receiver_baton,
+ apr_pool_t *pool)
+{
+ return svn_repos_get_logs5(repos, paths, start, end, limit,
+ discover_changed_paths, strict_node_history,
+ include_merged_revisions,
+ svn_move_behavior_no_moves, revprops,
+ authz_read_func, authz_read_baton,
+ receiver, receiver_baton, pool);
+}
+
+svn_error_t *
svn_repos_get_logs3(svn_repos_t *repos,
const apr_array_header_t *paths,
svn_revnum_t start,
@@ -727,6 +750,27 @@ svn_repos_dump_fs2(svn_repos_t *repos,
}
svn_error_t *
+svn_repos_verify_fs2(svn_repos_t *repos,
+ svn_revnum_t start_rev,
+ svn_revnum_t end_rev,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ return svn_error_trace(svn_repos_verify_fs3(repos,
+ start_rev,
+ end_rev,
+ FALSE,
+ notify_func,
+ notify_baton,
+ cancel_func,
+ cancel_baton,
+ pool));
+}
+
+svn_error_t *
svn_repos_verify_fs(svn_repos_t *repos,
svn_stream_t *feedback_stream,
svn_revnum_t start_rev,