Author: julianfoad
Date: Mon Oct 10 15:52:23 2011
New Revision: 1181040
URL: http://svn.apache.org/viewvc?rev=1181040&view=rev
Log:
On the 'tree-read-api' branch: Implement svn_ra_get_symlink() and make
svn_ra_check_path2() support symlinks.
* subversion/include/svn_ra.h
(svn_ra_get_symlink): New function.
* subversion/libsvn_ra/ra_loader.c
(svn_ra_get_symlink): New function.
(svn_ra_check_path2): Use svn_ra_get_symlink() to detect symlinks.
Modified:
subversion/branches/tree-read-api/subversion/include/svn_ra.h
subversion/branches/tree-read-api/subversion/libsvn_ra/ra_loader.c
Modified: subversion/branches/tree-read-api/subversion/include/svn_ra.h
URL:
http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/include/svn_ra.h?rev=1181040&r1=1181039&r2=1181040&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/include/svn_ra.h (original)
+++ subversion/branches/tree-read-api/subversion/include/svn_ra.h Mon Oct 10
15:52:23 2011
@@ -990,6 +990,27 @@ svn_ra_get_dir2(svn_ra_session_t *sessio
apr_pool_t *pool);
/**
+ * If @a link_target is non @c NULL, set @a *link_target to the target of
+ * the symbolic link at @a path at @a revision.
+ *
+ * If @a props is non @c NULL, set @a *props to contain the properties of
+ * the link. This means @em all properties: not just ones controlled by
+ * the user and stored in the repository fs, but non-tweakable ones
+ * generated by the SCM system itself (e.g. 'wcprops', 'entryprops',
+ * etc.) The keys are <tt>const char *</tt>, values are
+ * <tt>@c svn_string_t *</tt>.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *svn_ra_get_symlink(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ const char **link_target,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props,
+ apr_pool_t *pool);
+
+/**
* Similar to @c svn_ra_get_dir2, but with @c SVN_DIRENT_ALL for the
* @a dirent_fields parameter.
*
Modified: subversion/branches/tree-read-api/subversion/libsvn_ra/ra_loader.c
URL:
http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_ra/ra_loader.c?rev=1181040&r1=1181039&r2=1181040&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_ra/ra_loader.c
(original)
+++ subversion/branches/tree-read-api/subversion/libsvn_ra/ra_loader.c Mon Oct
10 15:52:23 2011
@@ -44,6 +44,7 @@
#include "svn_path.h"
#include "svn_dso.h"
#include "svn_config.h"
+#include "svn_props.h"
#include "ra_loader.h"
#include "private/svn_ra_private.h"
@@ -757,6 +758,39 @@ svn_error_t *svn_ra_get_dir2(svn_ra_sess
path, revision, dirent_fields, pool);
}
+#define SVN_SUBST__SPECIAL_LINK_STR "link"
+
+svn_error_t *svn_ra_get_symlink(svn_ra_session_t *session,
+ const char *path,
+ svn_revnum_t revision,
+ const char **link_target,
+ svn_revnum_t *fetched_rev,
+ apr_hash_t **props_p,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *str = svn_stringbuf_create("", pool);
+ svn_stream_t *stream = svn_stream_from_stringbuf(str, pool);
+ apr_hash_t *props;
+ svn_string_t *special;
+
+ SVN_ERR_ASSERT(*path != '/');
+ SVN_ERR(svn_ra_get_file(session, path, revision,
+ stream, fetched_rev, &props, pool));
+ special = apr_hash_get(props, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING);
+ if (special == NULL
+ || strncmp(special->data, SVN_SUBST__SPECIAL_LINK_STR " ",
+ strlen(SVN_SUBST__SPECIAL_LINK_STR " ")) != 0)
+ return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+ _("not a symlink: '%s' at r%ld"), path, revision);
+
+ if (link_target)
+ *link_target = apr_pstrdup(pool, special->data +
+ strlen(SVN_SUBST__SPECIAL_LINK_STR " "));
+ if (props_p)
+ *props_p = props;
+ return SVN_NO_ERROR;
+}
+
svn_error_t *svn_ra_get_mergeinfo(svn_ra_session_t *session,
svn_mergeinfo_catalog_t *catalog,
const apr_array_header_t *paths,
@@ -916,11 +950,23 @@ svn_ra_check_path2(svn_ra_session_t *ses
switch (node_kind)
{
case svn_node_file:
- if (FALSE /* ### special */)
- *kind = svn_kind_symlink;
+ {
+ const char *target;
+ svn_error_t *err;
+
+ err = svn_ra_get_symlink(session, path, revision, &target, NULL, NULL,
+ scratch_pool);
+ if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
+ {
+ svn_error_clear(err);
+ *kind = svn_kind_file;
+ }
+ else if (err)
+ return svn_error_trace(err);
else
- *kind = svn_kind_file;
+ *kind = svn_kind_symlink;
break;
+ }
case svn_node_dir:
*kind = svn_kind_dir;
break;