You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/03/27 00:29:55 UTC
svn commit: r1305641 - in /subversion/branches/inheritable-props/subversion:
libsvn_ra_svn/client.c libsvn_ra_svn/protocol svnserve/serve.c
Author: pburba
Date: Mon Mar 26 22:29:55 2012
New Revision: 1305641
URL: http://svn.apache.org/viewvc?rev=1305641&view=rev
Log:
On the inheritable-props branch: Implement getting inherited props over
ra_svn.
* subversion/libsvn_client/prop_commands.c
(remote_proplist): Raise an error if we insist on asking a server for
inherited props if that server isn't advertising the
SVN_RA_CAPABILITY_INHERITED_PROPS capability.
* subversion/libsvn_ra_svn/client.c
(parse_iproplist): New.
(ra_svn_get_file,
ra_svn_get_dir): Implement the client-side stuffs for getting inherited
props over ra_svn.
* subversion/libsvn_ra_svn/protocol
(get-file,
get-dir): Document the new protocol options.
* subversion/svnserve/serve.c
(get_props): Support getting inherited props via svn_fs_node_proplist2.
(get_file,
get_dir): Implement the server-side stuffs for getting inherited props
over ra_svn.
Modified:
subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c
subversion/branches/inheritable-props/subversion/libsvn_ra_svn/protocol
subversion/branches/inheritable-props/subversion/svnserve/serve.c
Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c?rev=1305641&r1=1305640&r2=1305641&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_svn/client.c Mon Mar 26 22:29:55 2012
@@ -1009,6 +1009,82 @@ static svn_error_t *ra_svn_commit(svn_ra
return SVN_NO_ERROR;
}
+/* Parse IPROPLIST, an array of svn_ra_svn_item_t structures, as a list of
+ const char * repos relative paths and properties for those paths, storing
+ the result as an array of svn_prop_inherited_item_t *items. */
+static svn_error_t *
+parse_iproplist(apr_array_header_t **inherited_props,
+ const apr_array_header_t *iproplist,
+ svn_ra_session_t *session,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+
+{
+ int i;
+ const char *repos_root_url;
+ apr_pool_t *iterpool;
+
+ if (iproplist == NULL)
+ {
+ /* If the server doesn't have the SVN_RA_CAPABILITY_INHERITED_PROPS
+ capability we shouldn't be asking for inherited props, but if we
+ did and the server sent back nothing then we'll want to handle
+ that. */
+ *inherited_props = NULL;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, scratch_pool));
+
+ *inherited_props = apr_array_make(
+ result_pool, iproplist->nelts, sizeof(svn_prop_inherited_item_t *));
+
+ iterpool = svn_pool_create(scratch_pool);
+
+ /* Iterate backwards over the array to preserve the depth-first ordering
+ of the parent paths as we create *INHERITED_PROPS. */
+ for (i = iproplist->nelts - 1; i >= 0; i--)
+ {
+ apr_array_header_t *iprop_list;
+ char *parent_rel_path;
+ apr_hash_t *iprops;
+ apr_hash_index_t *hi;
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(result_pool, sizeof(*new_iprop));
+ svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(iproplist, i,
+ svn_ra_svn_item_t);
+ if (elt->kind != SVN_RA_SVN_LIST)
+ return svn_error_create(
+ SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ _("Inherited proplist element not a list"));
+
+ svn_pool_clear(iterpool);
+
+ SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, iterpool, "cl",
+ &parent_rel_path, &iprop_list));
+ SVN_ERR(svn_ra_svn_parse_proplist(iprop_list, iterpool, &iprops));
+ 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);
+ for (hi = apr_hash_first(iterpool, iprops);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const char *name = svn__apr_hash_index_key(hi);
+ svn_string_t *value = svn__apr_hash_index_val(hi);
+ apr_hash_set(new_iprop->prop_hash,
+ apr_pstrdup(result_pool, name),
+ APR_HASH_KEY_STRING,
+ svn_string_dup(value, result_pool));
+ }
+ APR_ARRAY_PUSH(*inherited_props, svn_prop_inherited_item_t *) =
+ new_iprop;
+ }
+ svn_pool_destroy(iterpool);
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *ra_svn_get_file(svn_ra_session_t *session, const char *path,
svn_revnum_t rev, svn_stream_t *stream,
svn_revnum_t *fetched_rev,
@@ -1019,22 +1095,26 @@ static svn_error_t *ra_svn_get_file(svn_
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
apr_array_header_t *proplist;
+ apr_array_header_t *iproplist;
const char *expected_digest;
svn_checksum_t *expected_checksum = NULL;
svn_checksum_ctx_t *checksum_ctx;
apr_pool_t *iterpool;
- SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-file", "c(?r)bb", path,
- rev, (props != NULL), (stream != NULL)));
+ SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-file", "c(?r)bbb", path,
+ rev, (props != NULL), (stream != NULL),
+ (inherited_props != NULL)));
SVN_ERR(handle_auth_request(sess_baton, pool));
- SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "(?c)rl",
+ SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "(?c)rl?l",
&expected_digest,
- &rev, &proplist));
+ &rev, &proplist, &iproplist));
if (fetched_rev)
*fetched_rev = rev;
if (props)
SVN_ERR(svn_ra_svn_parse_proplist(proplist, pool, props));
+ if (inherited_props)
+ SVN_ERR(parse_iproplist(inherited_props, iproplist, session, pool, pool));
/* We're done if the contents weren't wanted. */
if (!stream)
@@ -1098,7 +1178,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
{
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
- apr_array_header_t *proplist, *dirlist;
+ apr_array_header_t *proplist, *dirlist, *iproplist;
int i;
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(c(?r)bb(!", "get-dir", path,
@@ -1116,16 +1196,20 @@ static svn_error_t *ra_svn_get_dir(svn_r
if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_LAST_AUTHOR));
- SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))"));
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)b)",
+ (inherited_props != NULL)));
SVN_ERR(handle_auth_request(sess_baton, pool));
- SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "rll", &rev, &proplist,
- &dirlist));
+ SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "rll?l", &rev, &proplist,
+ &dirlist, &iproplist));
if (fetched_rev)
*fetched_rev = rev;
if (props)
SVN_ERR(svn_ra_svn_parse_proplist(proplist, pool, props));
+ if (inherited_props)
+ SVN_ERR(parse_iproplist(inherited_props, iproplist, session, pool,
+ pool));
/* We're done if dirents aren't wanted. */
if (!dirents)
Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_svn/protocol
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_svn/protocol?rev=1305641&r1=1305640&r2=1305641&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_svn/protocol (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_svn/protocol Mon Mar 26 22:29:55 2012
@@ -222,6 +222,7 @@ responds.
Here are some miscellaneous prototypes used by the command sets:
proplist: ( ( name:string value:string ) ... )
+ iproplist: ( ( name:string proplist ) ... )
propdelta: ( ( name:string [ value:string ] ) ... )
node-kind: none|file|dir|unknown
bool: true|false
@@ -293,8 +294,10 @@ second place for auth-request point as n
? ( post-commit-err:string ) )
get-file
- params: ( path:string [ rev:number ] want-props:bool want-contents:bool )
- response: ( [ checksum:string ] rev:number props:proplist )
+ params: ( path:string [ rev:number ] want-props:bool want-contents:bool
+ [ want-iprops:bool ] )
+ response: ( [ checksum:string ] rev:number props:proplist
+ [ inherited-props:iproplist ] )
If want-contents is specified, then after sending response, server
sends file contents as a series of strings, terminated by the empty
string, followed by a second empty command response to indicate
@@ -302,8 +305,9 @@ second place for auth-request point as n
get-dir
params: ( path:string [ rev:number ] want-props:bool want-contents:bool
- ? ( field:dirent-field ... ) )
- response: ( rev:number props:proplist ( entry:dirent ... ) )]
+ ? ( field:dirent-field ... ) [ want-iprops:bool ] )
+ response: ( rev:number props:proplist ( entry:dirent ... )
+ [ inherited-props:iproplist ] )]
dirent: ( name:string kind:node-kind size:number has-props:bool
created-rev:number [ created-date:string ]
[ last-author:string ] )
Modified: subversion/branches/inheritable-props/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/svnserve/serve.c?rev=1305641&r1=1305640&r2=1305641&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/svnserve/serve.c (original)
+++ subversion/branches/inheritable-props/subversion/svnserve/serve.c Mon Mar 26 22:29:55 2012
@@ -963,15 +963,19 @@ static svn_error_t *write_lock(svn_ra_sv
/* ### This really belongs in libsvn_repos. */
/* Get the properties for a path, with hardcoded committed-info values. */
-static svn_error_t *get_props(apr_hash_t **props, svn_fs_root_t *root,
- const char *path, apr_pool_t *pool)
+static svn_error_t *
+get_props(apr_hash_t **props,
+ apr_array_header_t **iprops,
+ svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *pool)
{
svn_string_t *str;
svn_revnum_t crev;
const char *cdate, *cauthor, *uuid;
/* Get the properties. */
- SVN_ERR(svn_fs_node_proplist(props, root, path, pool));
+ SVN_ERR(svn_fs_node_proplist2(props, iprops, root, path, pool, pool));
/* Hardcode the values for the committed revision, date, and author. */
SVN_ERR(svn_repos_get_committed_info(&crev, &cdate, &cauthor, root,
@@ -1390,16 +1394,20 @@ static svn_error_t *get_file(svn_ra_svn_
svn_fs_root_t *root;
svn_stream_t *contents;
apr_hash_t *props = NULL;
+ apr_array_header_t *inherited_props;
svn_string_t write_str;
char buf[4096];
apr_size_t len;
svn_boolean_t want_props, want_contents;
+ apr_uint64_t wants_inherited_props;
svn_checksum_t *checksum;
svn_error_t *err, *write_err;
+ int i;
/* Parse arguments. */
- SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb", &path, &rev,
- &want_props, &want_contents));
+ SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?B", &path, &rev,
+ &want_props, &want_contents,
+ &wants_inherited_props));
full_path = svn_fspath__join(b->fs_path->data,
svn_relpath_canonicalize(path, pool), pool);
@@ -1420,8 +1428,8 @@ static svn_error_t *get_file(svn_ra_svn_
SVN_CMD_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, root,
full_path, TRUE, pool));
hex_digest = svn_checksum_to_cstring_display(checksum, pool);
- if (want_props)
- SVN_CMD_ERR(get_props(&props, root, full_path, pool));
+ if (want_props || wants_inherited_props)
+ SVN_CMD_ERR(get_props(&props, &inherited_props, root, full_path, pool));
if (want_contents)
SVN_CMD_ERR(svn_fs_file_contents(&contents, root, full_path, pool));
@@ -1429,6 +1437,23 @@ static svn_error_t *get_file(svn_ra_svn_
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((?c)r(!", "success",
hex_digest, rev));
SVN_ERR(svn_ra_svn_write_proplist(conn, pool, props));
+
+ if (wants_inherited_props)
+ {
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)(?!"));
+ for (i = 0; i < inherited_props->nelts; i++)
+ {
+ svn_prop_inherited_item_t *iprop =
+ APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
+
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!(c(!",
+ iprop->path_or_url));
+ SVN_ERR(svn_ra_svn_write_proplist(conn, pool, iprop->prop_hash));
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))!",
+ iprop->path_or_url));
+ }
+ }
+
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))"));
/* Now send the file's contents. */
@@ -1473,17 +1498,21 @@ static svn_error_t *get_dir(svn_ra_svn_c
const char *path, *full_path, *file_path, *cdate;
svn_revnum_t rev;
apr_hash_t *entries, *props = NULL, *file_props;
+ apr_array_header_t *inherited_props;
apr_hash_index_t *hi;
svn_fs_root_t *root;
apr_pool_t *subpool;
svn_boolean_t want_props, want_contents;
+ apr_uint64_t wants_inherited_props;
apr_uint64_t dirent_fields;
apr_array_header_t *dirent_fields_list = NULL;
svn_ra_svn_item_t *elt;
+ int i;
- SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?l", &path, &rev,
+ SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?l?B", &path, &rev,
&want_props, &want_contents,
- &dirent_fields_list));
+ &dirent_fields_list,
+ &wants_inherited_props));
if (! dirent_fields_list)
{
@@ -1491,8 +1520,6 @@ static svn_error_t *get_dir(svn_ra_svn_c
}
else
{
- int i;
-
dirent_fields = 0;
for (i = 0; i < dirent_fields_list->nelts; ++i)
@@ -1536,9 +1563,10 @@ static svn_error_t *get_dir(svn_ra_svn_c
/* Fetch the root of the appropriate revision. */
SVN_CMD_ERR(svn_fs_revision_root(&root, b->fs, rev, pool));
- /* Fetch the directory properties if requested. */
- if (want_props)
- SVN_CMD_ERR(get_props(&props, root, full_path, pool));
+ /* Fetch the directory's explicit and/or inherited properties
+ if requested. */
+ if (want_props || wants_inherited_props)
+ SVN_CMD_ERR(get_props(&props, &inherited_props, root, full_path, pool));
/* Begin response ... */
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(r(!", "success", rev));
@@ -1612,6 +1640,22 @@ static svn_error_t *get_dir(svn_ra_svn_c
svn_pool_destroy(subpool);
}
+ if (wants_inherited_props)
+ {
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)(?!"));
+ for (i = 0; i < inherited_props->nelts; i++)
+ {
+ svn_prop_inherited_item_t *iprop =
+ APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
+
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!(c(!",
+ iprop->path_or_url));
+ SVN_ERR(svn_ra_svn_write_proplist(conn, pool, iprop->prop_hash));
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))!",
+ iprop->path_or_url));
+ }
+ }
+
/* Finish response. */
return svn_ra_svn_write_tuple(conn, pool, "!))");
}
Re: svn commit: r1305641 - in
/subversion/branches/inheritable-props/subversion: libsvn_ra_svn/client.c
libsvn_ra_svn/protocol svnserve/serve.c
Posted by Daniel Shahaf <da...@elego.de>.
pburba@apache.org wrote on Mon, Mar 26, 2012 at 22:29:55 -0000:
> Author: pburba
> Date: Mon Mar 26 22:29:55 2012
> New Revision: 1305641
>
> URL: http://svn.apache.org/viewvc?rev=1305641&view=rev
> Log:
> On the inheritable-props branch: Implement getting inherited props over
> ra_svn.
>
> * subversion/libsvn_ra_svn/protocol
> (get-file,
> get-dir): Document the new protocol options.
>
The protocol document doesn't mention the new capability (which an
earlier commit added).
> +++ subversion/branches/inheritable-props/subversion/svnserve/serve.c Mon Mar 26 22:29:55 2012
> +static svn_error_t *
> +get_props(apr_hash_t **props,
> + apr_array_header_t **iprops,
> + svn_fs_root_t *root,
> + const char *path,
> + apr_pool_t *pool)
> {
> /* Get the properties. */
> - SVN_ERR(svn_fs_node_proplist(props, root, path, pool));
> + SVN_ERR(svn_fs_node_proplist2(props, iprops, root, path, pool, pool));
>
Don't you need an svn_repos_* wrapper here, where (eventually) authz
checks on the parents will be done?
Re: svn commit: r1305641 - in
/subversion/branches/inheritable-props/subversion: libsvn_ra_svn/client.c
libsvn_ra_svn/protocol svnserve/serve.c
Posted by Daniel Shahaf <da...@elego.de>.
pburba@apache.org wrote on Mon, Mar 26, 2012 at 22:29:55 -0000:
> Author: pburba
> Date: Mon Mar 26 22:29:55 2012
> New Revision: 1305641
>
> URL: http://svn.apache.org/viewvc?rev=1305641&view=rev
> Log:
> On the inheritable-props branch: Implement getting inherited props over
> ra_svn.
>
> * subversion/libsvn_ra_svn/protocol
> (get-file,
> get-dir): Document the new protocol options.
>
The protocol document doesn't mention the new capability (which an
earlier commit added).
> +++ subversion/branches/inheritable-props/subversion/svnserve/serve.c Mon Mar 26 22:29:55 2012
> +static svn_error_t *
> +get_props(apr_hash_t **props,
> + apr_array_header_t **iprops,
> + svn_fs_root_t *root,
> + const char *path,
> + apr_pool_t *pool)
> {
> /* Get the properties. */
> - SVN_ERR(svn_fs_node_proplist(props, root, path, pool));
> + SVN_ERR(svn_fs_node_proplist2(props, iprops, root, path, pool, pool));
>
Don't you need an svn_repos_* wrapper here, where (eventually) authz
checks on the parents will be done?