You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/11 00:07:31 UTC
svn commit: r984234 [7/20] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/ac-macros/ build/generator/ notes/ notes/api-errata/
notes/obliterate/ notes/obliterate/fspec-cc1/ notes/rename-tracking/
notes/svnpatch/ notes/tree-conflicts/ notes...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c Tue Aug 10 22:07:24 2010
@@ -1255,10 +1255,6 @@ svn_ra_serf__credentials_callback(char *
response status and headers, and invoke CTX->response_handler() to
carry out operation-specific processing. Afterwards, check for
connection close.
-
- If during the setup of the request we set a snapshot on the body buckets,
- handle_response has to make sure these buckets get destroyed iff the
- request doesn't have to be resent.
*/
static apr_status_t
handle_response(serf_request_t *request,
@@ -1439,15 +1435,6 @@ handle_response(serf_request_t *request,
}
cleanup:
- /* If a snapshot was set on the body bucket, it wasn't destroyed when the
- request was sent, we have to destroy it now upon successful handling of
- the response. */
- if (ctx->body_snapshot_set && ctx->body_buckets)
- {
- serf_bucket_destroy(ctx->body_buckets);
- ctx->body_buckets = NULL;
- ctx->body_snapshot_set = FALSE;
- }
return status;
}
@@ -1496,7 +1483,8 @@ setup_request(serf_request_t *request,
}
else
{
- serf_bucket_t *body_bkt = ctx->body_buckets;
+ serf_bucket_t *body_bkt;
+ serf_bucket_alloc_t *bkt_alloc = serf_request_get_alloc(request);
if (strcmp(ctx->method, "HEAD") == 0)
{
@@ -1505,49 +1493,13 @@ setup_request(serf_request_t *request,
if (ctx->body_delegate)
{
- body_bkt = ctx->body_buckets =
- ctx->body_delegate(ctx->body_delegate_baton,
- serf_request_get_alloc(request),
- pool);
- }
- /* If this is a request that has to be retried, we might be able to reuse
- the existing body buckets if a snapshot was set. */
- else if (ctx->body_buckets)
- {
- /* Wrap the body bucket in a barrier bucket if a snapshot was set.
- After the request is sent serf will destroy the request bucket
- (req_bkt) including this barrier bucket, but this way our
- body_buckets bucket will not be destroyed and we can reuse it
- later.
- This does put ownership of body_buckets in our own hands though,
- so we have to make sure it gets destroyed when handling the
- response. */
- /* TODO: for now we assume restoring a snapshot on a bucket that
- hasn't been read yet is a cheap operation. We need a way to find
- out if we really need to restore a snapshot, or if we still are
- in the initial state. */
- apr_status_t status;
- if (ctx->body_snapshot_set)
- {
- /* If restoring a snapshot doesn't work, we have to fall back
- on current behavior (ie. retrying a request fails). */
- status = serf_bucket_restore_snapshot(ctx->body_buckets);
- }
- status = serf_bucket_snapshot(ctx->body_buckets);
- if (status == APR_SUCCESS)
- {
- ctx->body_snapshot_set = TRUE;
- body_bkt = serf_bucket_barrier_create(ctx->body_buckets,
- serf_request_get_alloc(request));
- }
- else
- {
- /* If the snapshot wasn't successful (maybe because the caller
- used a bucket that doesn't support the snapshot feature),
- fall back to non-snapshot behavior and hope that the request
- is handled the first time. */
- }
- }
+ body_bkt =
+ ctx->body_delegate(ctx->body_delegate_baton, bkt_alloc, pool);
+ }
+ else
+ {
+ body_bkt = NULL;
+ }
svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt, ctx->conn,
ctx->method, ctx->path,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c Tue Aug 10 22:07:24 2010
@@ -2207,17 +2207,52 @@ static svn_error_t *ra_svn_get_lock(svn_
return SVN_NO_ERROR;
}
+/* Copied from svn_ra_get_path_relative_to_root() and de-vtable-ized
+ to prevent a dependency cycle. */
+static svn_error_t *path_relative_to_root(svn_ra_session_t *session,
+ const char **rel_path,
+ const char *url,
+ apr_pool_t *pool)
+{
+ const char *root_url;
+
+ SVN_ERR(ra_svn_get_repos_root(session, &root_url, pool));
+ if (strcmp(root_url, url) == 0)
+ {
+ *rel_path = "";
+ }
+ else
+ {
+ *rel_path = svn_uri_is_child(root_url, url, pool);
+ if (! *rel_path)
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ _("'%s' isn't a child of repository root "
+ "URL '%s'"),
+ url, root_url);
+ *rel_path = svn_path_uri_decode(*rel_path, pool);
+ }
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *ra_svn_get_locks(svn_ra_session_t *session,
apr_hash_t **locks,
const char *path,
+ svn_depth_t depth,
apr_pool_t *pool)
{
svn_ra_svn__session_baton_t *sess = session->priv;
svn_ra_svn_conn_t* conn = sess->conn;
apr_array_header_t *list;
+ const char *abs_path;
int i;
- SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-locks", "c", path));
+ /* Figure out the repository abspath from PATH. */
+ abs_path = svn_path_url_add_component2(sess->url, path, pool);
+ SVN_ERR(path_relative_to_root(session, &abs_path, abs_path, pool));
+ abs_path = apr_pstrcat(pool, "/", abs_path, NULL);
+
+ SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-locks", "c(w)", path,
+ svn_depth_to_word(depth)));
/* Servers before 1.2 doesn't support locking. Check this here. */
SVN_ERR(handle_unsupported_cmd(handle_auth_request(sess, pool),
@@ -2237,7 +2272,27 @@ static svn_error_t *ra_svn_get_locks(svn
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Lock element not a list"));
SVN_ERR(parse_lock(elt->u.list, pool, &lock));
- apr_hash_set(*locks, lock->path, APR_HASH_KEY_STRING, lock);
+
+ /* Filter out unwanted paths. Since Subversion only allows
+ locks on files, we can treat depth=immediates the same as
+ depth=files for filtering purposes. Meaning, we'll keep
+ this lock if:
+
+ a) its path is the very path we queried, or
+ b) we've asked for a fully recursive answer, or
+ c) we've asked for depth=files or depth=immediates, and this
+ lock is on an immediate child of our query path.
+ */
+ if ((strcmp(abs_path, lock->path) == 0) || (depth == svn_depth_infinity))
+ {
+ apr_hash_set(*locks, lock->path, APR_HASH_KEY_STRING, lock);
+ }
+ else if ((depth == svn_depth_files) || (depth == svn_depth_immediates))
+ {
+ const char *rel_uri = svn_uri_is_child(abs_path, lock->path, pool);
+ if (rel_uri && (svn_path_component_count(rel_uri) == 1))
+ apr_hash_set(*locks, lock->path, APR_HASH_KEY_STRING, lock);
+ }
}
return SVN_NO_ERROR;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/protocol
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/protocol?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/protocol (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/protocol Tue Aug 10 22:07:24 2010
@@ -427,7 +427,7 @@ second place for auth-request point as n
response: ( [ lock:lockdesc ] )
get-locks
- params: ( path:string )
+ params: ( path:string ? [ depth:word ] )
response ( ( lock:lockdesc ... ) )
replay
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/deprecated.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/deprecated.c Tue Aug 10 22:07:24 2010
@@ -137,6 +137,41 @@ svn_repos_get_commit_editor(const svn_de
}
/*** From repos.c ***/
+struct recover_baton
+{
+ svn_error_t *(*start_callback)(void *baton);
+ void *start_callback_baton;
+ apr_pool_t *pool;
+};
+
+static void
+recovery_started(void *baton,
+ const svn_repos_notify_t *notify,
+ apr_pool_t *scratch_pool)
+{
+ struct recover_baton *rb = baton;
+
+ if (notify->action == svn_repos_notify_mutex_acquired)
+ svn_error_clear(rb->start_callback(rb->start_callback_baton));
+}
+
+svn_error_t *
+svn_repos_recover3(const char *path,
+ svn_boolean_t nonblocking,
+ svn_error_t *(*start_callback)(void *baton),
+ void *start_callback_baton,
+ svn_cancel_func_t cancel_func, void *cancel_baton,
+ apr_pool_t *pool)
+{
+ struct recover_baton rb;
+
+ rb.start_callback = start_callback;
+ rb.start_callback_baton = start_callback_baton;
+
+ return svn_repos_recover4(path, nonblocking, recovery_started, &rb,
+ cancel_func, cancel_baton, pool);
+}
+
svn_error_t *
svn_repos_recover2(const char *path,
svn_boolean_t nonblocking,
@@ -157,6 +192,21 @@ svn_repos_recover(const char *path,
return svn_repos_recover2(path, FALSE, NULL, NULL, pool);
}
+svn_error_t *
+svn_repos_upgrade(const char *path,
+ svn_boolean_t nonblocking,
+ svn_error_t *(*start_callback)(void *baton),
+ void *start_callback_baton,
+ apr_pool_t *pool)
+{
+ struct recover_baton rb;
+
+ rb.start_callback = start_callback;
+ rb.start_callback_baton = start_callback_baton;
+
+ return svn_repos_upgrade2(path, nonblocking, recovery_started, &rb, pool);
+}
+
/*** From reporter.c ***/
svn_error_t *
svn_repos_begin_report(void **report_baton,
@@ -306,6 +356,56 @@ svn_repos_fs_change_rev_prop(svn_repos_t
NULL, NULL, pool);
}
+struct pack_notify_wrapper_baton
+{
+ svn_fs_pack_notify_t notify_func;
+ void *notify_baton;
+};
+
+static void
+pack_notify_wrapper_func(void *baton,
+ const svn_repos_notify_t *notify,
+ apr_pool_t *scratch_pool)
+{
+ struct pack_notify_wrapper_baton *pnwb = baton;
+
+ svn_error_clear(pnwb->notify_func(pnwb->notify_baton, notify->shard,
+ notify->action - 3, scratch_pool));
+}
+
+svn_error_t *
+svn_repos_fs_pack(svn_repos_t *repos,
+ svn_fs_pack_notify_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ struct pack_notify_wrapper_baton pnwb;
+
+ pnwb.notify_func = notify_func;
+ pnwb.notify_baton = notify_baton;
+
+ return svn_repos_fs_pack2(repos, pack_notify_wrapper_func, &pnwb,
+ cancel_func, cancel_baton, pool);
+}
+
+
+svn_error_t *
+svn_repos_fs_get_locks(apr_hash_t **locks,
+ svn_repos_t *repos,
+ const char *path,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *pool)
+{
+ return svn_error_return(svn_repos_fs_get_locks2(locks, repos, path,
+ svn_depth_infinity,
+ authz_read_func,
+ authz_read_baton, pool));
+}
+
+
/*** From logs.c ***/
svn_error_t *
svn_repos_get_logs3(svn_repos_t *repos,
@@ -428,36 +528,110 @@ svn_repos_dump_fs(svn_repos_t *repos,
cancel_baton, pool);
}
-/* Baton for repos_progress_handler */
-struct notify_baton
-{
- svn_boolean_t dumping;
- svn_stream_t *feedback_stream;
-};
-
/* Implementation of svn_repos_notify_func_t to wrap the output to a
response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
-static svn_error_t *
-repos_progress_handler(void * baton,
- svn_revnum_t revision,
- const char *warning_text,
- apr_pool_t *scratch_pool)
-{
- struct notify_baton *nb = baton;
-
- if (warning_text != NULL)
- {
- apr_size_t len = strlen(warning_text);
- SVN_ERR(svn_stream_write(nb->feedback_stream, warning_text, &len));
- }
- else
- SVN_ERR(svn_stream_printf(nb->feedback_stream, scratch_pool,
- nb->dumping
- ? _("* Dumped revision %ld.\n")
- : _("* Verified revision %ld.\n"),
- revision));
-
- return SVN_NO_ERROR;
+static void
+repos_notify_handler(void *baton,
+ const svn_repos_notify_t *notify,
+ apr_pool_t *scratch_pool)
+{
+ svn_stream_t *feedback_stream = baton;
+ apr_size_t len;
+
+ switch (notify->action)
+ {
+ case svn_repos_notify_warning:
+ len = strlen(notify->warning);
+ svn_error_clear(svn_stream_write(feedback_stream, notify->warning, &len));
+ return;
+
+ case svn_repos_notify_dump_rev_end:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("* Dumped revision %ld.\n"),
+ notify->revision));
+ return;
+
+ case svn_repos_notify_verify_rev_end:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("* Verified revision %ld.\n"),
+ notify->revision));
+ return;
+
+ case svn_repos_notify_load_txn_committed:
+ if (notify->old_revision == SVN_INVALID_REVNUM)
+ {
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("\n------- Committed revision %ld >>>\n\n"),
+ notify->new_revision));
+ }
+ else
+ {
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("\n------- Committed new rev %ld"
+ " (loaded from original rev %ld"
+ ") >>>\n\n"), notify->new_revision,
+ notify->old_revision));
+ }
+ return;
+
+ case svn_repos_notify_load_node_start:
+ {
+ switch (notify->node_action)
+ {
+ case svn_node_action_change:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * editing path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_delete:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * deleting path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_add:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * adding path : %s ..."),
+ notify->path));
+ break;
+
+ case svn_node_action_replace:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" * replacing path : %s ..."),
+ notify->path));
+ break;
+
+ }
+ }
+ return;
+
+ case svn_repos_notify_load_node_done:
+ len = 7;
+ svn_error_clear(svn_stream_write(feedback_stream, _(" done.\n"), &len));
+ return;
+
+ case svn_repos_notify_load_copied_node:
+ len = 9;
+ svn_error_clear(svn_stream_write(feedback_stream, "COPIED...", &len));
+ return;
+
+ case svn_repos_notify_load_txn_start:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("<<< Started new transaction, based on "
+ "original revision %ld\n"),
+ notify->old_revision));
+ return;
+
+ case svn_repos_notify_load_normalized_mergeinfo:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _(" removing '\\r' from %s ..."),
+ SVN_PROP_MERGEINFO));
+ return;
+
+ default:
+ return;
+ }
}
@@ -473,10 +647,6 @@ svn_repos_dump_fs2(svn_repos_t *repos,
void *cancel_baton,
apr_pool_t *pool)
{
- struct notify_baton nb;
- nb.dumping = (stream != NULL); /* Show verify messages if stream is NULL */
- nb.feedback_stream = feedback_stream;
-
return svn_error_return(svn_repos_dump_fs3(repos,
stream,
start_rev,
@@ -484,9 +654,9 @@ svn_repos_dump_fs2(svn_repos_t *repos,
incremental,
use_deltas,
feedback_stream
- ? repos_progress_handler
+ ? repos_notify_handler
: NULL,
- &nb,
+ feedback_stream,
cancel_func,
cancel_baton,
pool));
@@ -501,23 +671,39 @@ svn_repos_verify_fs(svn_repos_t *repos,
void *cancel_baton,
apr_pool_t *pool)
{
- struct notify_baton nb;
- nb.dumping = FALSE;
- nb.feedback_stream = feedback_stream;
-
return svn_error_return(svn_repos_verify_fs2(repos,
start_rev,
end_rev,
feedback_stream
- ? repos_progress_handler
+ ? repos_notify_handler
: NULL,
- &nb,
+ feedback_stream,
cancel_func,
cancel_baton,
pool));
}
/*** From load.c ***/
+
+svn_error_t *
+svn_repos_load_fs2(svn_repos_t *repos,
+ svn_stream_t *dumpstream,
+ svn_stream_t *feedback_stream,
+ enum svn_repos_load_uuid uuid_action,
+ const char *parent_dir,
+ svn_boolean_t use_pre_commit_hook,
+ svn_boolean_t use_post_commit_hook,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ return svn_repos_load_fs3(repos, dumpstream, uuid_action, parent_dir,
+ use_pre_commit_hook, use_post_commit_hook,
+ feedback_stream ? repos_notify_handler : NULL,
+ feedback_stream, cancel_func, cancel_baton, pool);
+}
+
+
static svn_repos_parser_fns_t *
fns_from_fns2(const svn_repos_parse_fns2_t *fns2,
apr_pool_t *pool)
@@ -536,6 +722,7 @@ fns_from_fns2(const svn_repos_parse_fns2
fns->close_revision = fns2->close_revision;
return fns;
}
+
static svn_repos_parse_fns2_t *
fns2_from_fns(const svn_repos_parser_fns_t *fns,
apr_pool_t *pool)
@@ -587,6 +774,22 @@ svn_repos_load_fs(svn_repos_t *repos,
}
svn_error_t *
+svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **parser,
+ void **parse_baton,
+ svn_repos_t *repos,
+ svn_boolean_t use_history,
+ enum svn_repos_load_uuid uuid_action,
+ svn_stream_t *outstream,
+ const char *parent_dir,
+ apr_pool_t *pool)
+{
+ return svn_repos_get_fs_build_parser3(parser, parse_baton, repos, use_history,
+ uuid_action, parent_dir,
+ outstream ? repos_notify_handler : NULL,
+ outstream, pool);
+}
+
+svn_error_t *
svn_repos_get_fs_build_parser(const svn_repos_parser_fns_t **parser_callbacks,
void **parse_baton,
svn_repos_t *repos,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c Tue Aug 10 22:07:24 2010
@@ -429,7 +429,10 @@ dump_node(struct edit_baton *eb,
if (!eb->verify && cmp_rev < eb->oldest_dumped_rev
&& eb->notify_func)
{
- const char *warning = apr_psprintf(
+ svn_repos_notify_t *notify =
+ svn_repos_notify_create(svn_repos_notify_warning, pool);
+
+ notify->warning = apr_psprintf(
pool,
_("WARNING: Referencing data in revision %ld,"
" which is older than the oldest\n"
@@ -438,8 +441,7 @@ dump_node(struct edit_baton *eb,
"WARNING: will fail.\n"),
cmp_rev, eb->oldest_dumped_rev);
eb->found_old_reference = TRUE;
- SVN_ERR(eb->notify_func(eb->notify_baton,
- eb->oldest_dumped_rev, warning, pool));
+ eb->notify_func(eb->notify_baton, notify, pool);
}
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -530,7 +532,10 @@ dump_node(struct edit_baton *eb,
TRUE, pool, pool));
if (apr_hash_count(old_mergeinfo))
{
- const char *warning = apr_psprintf(
+ svn_repos_notify_t *notify =
+ svn_repos_notify_create(svn_repos_notify_warning, pool);
+
+ notify->warning = apr_psprintf(
pool,
_("WARNING: Mergeinfo referencing revision(s) prior "
"to the oldest dumped revision (%ld).\n"
@@ -539,9 +544,7 @@ dump_node(struct edit_baton *eb,
eb->oldest_dumped_rev);
eb->found_old_mergeinfo = TRUE;
- SVN_ERR(eb->notify_func(eb->notify_baton,
- SVN_INVALID_REVNUM,
- warning, pool));
+ eb->notify_func(eb->notify_baton, notify, pool);
}
}
}
@@ -1030,6 +1033,7 @@ svn_repos_dump_fs3(svn_repos_t *repos,
int version;
svn_boolean_t found_old_reference = FALSE;
svn_boolean_t found_old_mergeinfo = FALSE;
+ svn_repos_notify_t *notify;
/* Determine the current youngest revision of the filesystem. */
SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
@@ -1075,6 +1079,11 @@ svn_repos_dump_fs3(svn_repos_t *repos,
SVN_ERR(svn_stream_printf(stream, pool, SVN_REPOS_DUMPFILE_UUID
": %s\n\n", uuid));
+ /* Create a notify object that we can reuse in the loop. */
+ if (notify_func)
+ notify = svn_repos_notify_create(svn_repos_notify_dump_rev_end,
+ pool);
+
/* Main loop: we're going to dump revision i. */
for (i = start_rev; i <= end_rev; i++)
{
@@ -1156,7 +1165,10 @@ svn_repos_dump_fs3(svn_repos_t *repos,
loop_end:
if (notify_func)
- SVN_ERR(notify_func(notify_baton, to_rev, NULL, subpool));
+ {
+ notify->revision = to_rev;
+ notify_func(notify_baton, notify, subpool);
+ }
if (dump_edit_baton) /* We never get an edit baton for r0. */
{
@@ -1173,23 +1185,28 @@ svn_repos_dump_fs3(svn_repos_t *repos,
the oldest dumped revision? If so, then issue a final generic
warning, since the inline warnings already issued might easily be
missed. */
+
+ notify = svn_repos_notify_create(svn_repos_notify_warning, subpool);
+
if (found_old_reference)
- SVN_ERR(notify_func(notify_baton, SVN_INVALID_REVNUM,
- _("WARNING: The range of revisions dumped "
- "contained references to\n"
- "WARNING: copy sources outside that "
- "range.\n"),
- subpool));
+ {
+ notify->warning = _("WARNING: The range of revisions dumped "
+ "contained references to\n"
+ "WARNING: copy sources outside that "
+ "range.\n");
+ notify_func(notify_baton, notify, subpool);
+ }
/* Ditto if we issued any warnings about old revisions referenced
in dumped mergeinfo. */
if (found_old_mergeinfo)
- SVN_ERR(notify_func(notify_baton, SVN_INVALID_REVNUM,
- _("WARNING: The range of revisions dumped "
- "contained mergeinfo\n"
- "WARNING: which reference revisions outside "
- "that range.\n"),
- subpool));
+ {
+ notify->warning = _("WARNING: The range of revisions dumped "
+ "contained mergeinfo\n"
+ "WARNING: which reference revisions outside "
+ "that range.\n");
+ notify_func(notify_baton, notify, subpool);
+ }
}
svn_pool_destroy(subpool);
@@ -1274,6 +1291,7 @@ svn_repos_verify_fs2(svn_repos_t *repos,
svn_revnum_t youngest;
svn_revnum_t rev;
apr_pool_t *iterpool = svn_pool_create(pool);
+ svn_repos_notify_t *notify;
/* Determine the current youngest revision of the filesystem. */
SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
@@ -1296,6 +1314,11 @@ svn_repos_verify_fs2(svn_repos_t *repos,
"(youngest revision is %ld)"),
end_rev, youngest);
+ /* Create a notify object that we can reuse within the loop. */
+ if (notify_func)
+ notify = svn_repos_notify_create(svn_repos_notify_verify_rev_end,
+ pool);
+
for (rev = start_rev; rev <= end_rev; rev++)
{
svn_delta_editor_t *dump_editor;
@@ -1329,7 +1352,10 @@ svn_repos_verify_fs2(svn_repos_t *repos,
SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool));
if (notify_func)
- SVN_ERR(notify_func(notify_baton, rev, NULL, iterpool));
+ {
+ notify->revision = rev;
+ notify_func(notify_baton, notify, iterpool);
+ }
}
svn_pool_destroy(iterpool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/fs-wrap.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/fs-wrap.c Tue Aug 10 22:07:24 2010
@@ -298,7 +298,8 @@ svn_repos_fs_change_rev_prop3(svn_repos_
SVN_ERR(svn_repos__hooks_pre_revprop_change(repos, rev, author, name,
new_value, action, pool));
- SVN_ERR(svn_fs_change_rev_prop(repos->fs, rev, name, new_value, pool));
+ SVN_ERR(svn_fs_change_rev_prop2(repos->fs, rev, name, NULL,
+ new_value, pool));
if (use_post_revprop_change_hook)
SVN_ERR(svn_repos__hooks_post_revprop_change(repos, rev, author, name,
@@ -528,10 +529,8 @@ get_locks_callback(void *baton,
/* If there's auth to deal with, deal with it. */
if (b->authz_read_func)
- {
- SVN_ERR(b->authz_read_func(&readable, b->head_root, lock->path,
- b->authz_read_baton, pool));
- }
+ SVN_ERR(b->authz_read_func(&readable, b->head_root, lock->path,
+ b->authz_read_baton, pool));
/* If we can read this lock path, add the lock to the return hash. */
if (readable)
@@ -543,19 +542,23 @@ get_locks_callback(void *baton,
svn_error_t *
-svn_repos_fs_get_locks(apr_hash_t **locks,
- svn_repos_t *repos,
- const char *path,
- svn_repos_authz_func_t authz_read_func,
- void *authz_read_baton,
- apr_pool_t *pool)
+svn_repos_fs_get_locks2(apr_hash_t **locks,
+ svn_repos_t *repos,
+ const char *path,
+ svn_depth_t depth,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *pool)
{
apr_hash_t *all_locks = apr_hash_make(pool);
svn_revnum_t head_rev;
struct get_locks_baton_t baton;
- /* Locks are always said to apply to HEAD revision, so we'll check
- to see if locked-paths are readable in HEAD as well. */
+ SVN_ERR_ASSERT((depth == svn_depth_empty) ||
+ (depth == svn_depth_files) ||
+ (depth == svn_depth_immediates) ||
+ (depth == svn_depth_infinity));
+
SVN_ERR(svn_fs_youngest_rev(&head_rev, repos->fs, pool));
/* Populate our callback baton. */
@@ -567,8 +570,8 @@ svn_repos_fs_get_locks(apr_hash_t **lock
head_rev, pool));
/* Get all the locks. */
- SVN_ERR(svn_fs_get_locks(repos->fs, path, get_locks_callback,
- &baton, pool));
+ SVN_ERR(svn_fs_get_locks2(repos->fs, path, depth,
+ get_locks_callback, &baton, pool));
*locks = baton.locks;
return SVN_NO_ERROR;
@@ -640,22 +643,52 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
return SVN_NO_ERROR;
}
+struct pack_notify_baton
+{
+ svn_repos_notify_func_t notify_func;
+ void *notify_baton;
+};
+
+/* Implements svn_fs_pack_notify_t. */
+static svn_error_t *
+pack_notify_func(void *baton,
+ apr_int64_t shard,
+ svn_fs_pack_notify_action_t pack_action,
+ apr_pool_t *pool)
+{
+ struct pack_notify_baton *pnb = baton;
+ svn_repos_notify_t *notify;
+
+ notify = svn_repos_notify_create(pack_action + 3, pool);
+ notify->shard = shard;
+ pnb->notify_func(pnb->notify_baton, notify, pool);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
-svn_repos_fs_pack(svn_repos_t *repos,
- svn_fs_pack_notify_t notify_func,
- void *notify_baton,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *pool)
+svn_repos_fs_pack2(svn_repos_t *repos,
+ 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_fs_pack(repos->db_path, notify_func, notify_baton,
+ struct pack_notify_baton pnb;
+
+ pnb.notify_func = notify_func;
+ pnb.notify_baton = notify_baton;
+
+ return svn_fs_pack(repos->db_path,
+ notify_func ? pack_notify_func : NULL,
+ notify_func ? &pnb : NULL,
cancel_func, cancel_baton, pool);
}
/*
- * vim:ts=4:sw=4:expandtab:tw=80:fo=tcroq
+ * vim:ts=4:sw=2:expandtab:tw=80:fo=tcroq
* vim:isk=a-z,A-Z,48-57,_,.,-,>
* vim:cino=>1s,e0,n0,f0,{.5s,}0,^-.5s,=.5s,t0,+1s,c3,(0,u0,\:0
*/
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c Tue Aug 10 22:07:24 2010
@@ -51,9 +51,11 @@ struct parse_baton
svn_boolean_t use_history;
svn_boolean_t use_pre_commit_hook;
svn_boolean_t use_post_commit_hook;
- svn_stream_t *outstream;
enum svn_repos_load_uuid uuid_action;
const char *parent_dir;
+ svn_repos_notify_func_t notify_func;
+ void *notify_baton;
+ svn_repos_notify_t *notify;
apr_pool_t *pool;
/* A hash mapping copy-from revisions and mergeinfo range revisions
@@ -465,12 +467,13 @@ parse_property_block(svn_stream_t *strea
propstring.data = prop_eol_normalized;
propstring.len = strlen(prop_eol_normalized);
- if (pb->outstream)
- SVN_ERR(svn_stream_printf(
- pb->outstream,
- proppool,
- _(" removing '\\r' from %s ..."),
- SVN_PROP_MERGEINFO));
+ if (pb->notify_func)
+ {
+ pb->notify->action =
+ svn_repos_notify_load_normalized_mergeinfo;
+ pb->notify_func(pb->notify_baton, pb->notify,
+ proppool);
+ }
}
SVN_ERR(parse_fns->set_node_property(record_baton,
@@ -1050,9 +1053,12 @@ new_revision_record(void **revision_bato
SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
SVN_ERR(svn_fs_txn_root(&(rb->txn_root), rb->txn, pool));
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _("<<< Started new transaction, based on "
- "original revision %ld\n"), rb->rev));
+ if (pb->notify_func)
+ {
+ pb->notify->action = svn_repos_notify_load_txn_start;
+ pb->notify->old_revision = rb->rev;
+ pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ }
}
/* If we're parsing revision 0, only the revision are (possibly)
@@ -1073,7 +1079,6 @@ maybe_add_with_history(struct node_baton
apr_pool_t *pool)
{
struct parse_baton *pb = rb->pb;
- apr_size_t len;
if ((nb->copyfrom_path == NULL) || (! pb->use_history))
{
@@ -1125,8 +1130,11 @@ maybe_add_with_history(struct node_baton
SVN_ERR(svn_fs_copy(copy_root, nb->copyfrom_path,
rb->txn_root, nb->path, pool));
- len = 9;
- SVN_ERR(svn_stream_write(pb->outstream, "COPIED...", &len));
+ if (pb->notify_func)
+ {
+ pb->notify->action = svn_repos_notify_load_copied_node;
+ pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ }
}
return SVN_NO_ERROR;
@@ -1171,47 +1179,38 @@ new_node_record(void **node_baton,
nb = make_node_baton(headers, rb, pool);
+ /* Make sure we have an action we recognize. */
+ if (nb->action < svn_node_action_change
+ || nb->action > svn_node_action_replace)
+ return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
+ _("Unrecognized node-action on node '%s'"),
+ nb->path);
+
+ if (pb->notify_func)
+ {
+ pb->notify->action = svn_repos_notify_load_node_start;
+ pb->notify->node_action = nb->action;
+ pb->notify->path = nb->path;
+ pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ }
+
switch (nb->action)
{
case svn_node_action_change:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * editing path : %s ..."),
- nb->path));
- break;
- }
+ break;
+
case svn_node_action_delete:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * deleting path : %s ..."),
- nb->path));
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
- break;
- }
+ SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
+ break;
+
case svn_node_action_add:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * adding path : %s ..."),
- nb->path));
-
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
- }
+ SVN_ERR(maybe_add_with_history(nb, rb, pool));
+ break;
+
case svn_node_action_replace:
- {
- SVN_ERR(svn_stream_printf(pb->outstream, pool,
- _(" * replacing path : %s ..."),
- nb->path));
-
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
-
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
- }
- default:
- return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
- _("Unrecognized node-action on node '%s'"),
- nb->path);
+ SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
+ SVN_ERR(maybe_add_with_history(nb, rb, pool));
+ break;
}
*node_baton = nb;
@@ -1245,7 +1244,8 @@ set_revision_property(void *baton,
SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
if (youngest_rev == 0)
- SVN_ERR(svn_fs_change_rev_prop(pb->fs, 0, name, value, rb->pool));
+ SVN_ERR(svn_fs_change_rev_prop2(pb->fs, 0, name, NULL, value,
+ rb->pool));
}
return SVN_NO_ERROR;
@@ -1364,9 +1364,14 @@ close_node(void *baton)
struct node_baton *nb = baton;
struct revision_baton *rb = nb->rb;
struct parse_baton *pb = rb->pb;
- apr_size_t len = 7;
- return svn_stream_write(pb->outstream, _(" done.\n"), &len);
+ if (pb->notify_func)
+ {
+ pb->notify->action = svn_repos_notify_load_node_done;
+ pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
+ }
+
+ return SVN_NO_ERROR;
}
@@ -1437,7 +1442,7 @@ close_revision(void *baton)
if (pb->last_rev_mapped != SVN_INVALID_REVNUM
&& *old_rev != pb->last_rev_mapped + 1)
{
- int i;
+ svn_revnum_t i;
/* Map all dropped revisions between PB->LAST_REV_MAPPED and OLD_REV. */
for (i = pb->last_rev_mapped + 1; i < *old_rev; i++)
@@ -1467,19 +1472,17 @@ close_revision(void *baton)
SVN_PROP_REVISION_DATE, rb->datestamp,
rb->pool));
- if (*new_rev == rb->rev)
- {
- return svn_stream_printf(pb->outstream, rb->pool,
- _("\n------- Committed revision %ld"
- " >>>\n\n"), *new_rev);
- }
- else
+ if (pb->notify_func)
{
- return svn_stream_printf(pb->outstream, rb->pool,
- _("\n------- Committed new rev %ld"
- " (loaded from original rev %ld"
- ") >>>\n\n"), *new_rev, rb->rev);
+ pb->notify->action = svn_repos_notify_load_txn_committed;
+ pb->notify->new_revision = *new_rev;
+ pb->notify->old_revision = ((*new_rev == rb->rev)
+ ? SVN_INVALID_REVNUM
+ : rb->rev);
+ pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
}
+
+ return SVN_NO_ERROR;
}
@@ -1489,13 +1492,14 @@ close_revision(void *baton)
svn_error_t *
-svn_repos_get_fs_build_parser2(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
void **parse_baton,
svn_repos_t *repos,
svn_boolean_t use_history,
enum svn_repos_load_uuid uuid_action,
- svn_stream_t *outstream,
const char *parent_dir,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
apr_pool_t *pool)
{
svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
@@ -1516,7 +1520,9 @@ svn_repos_get_fs_build_parser2(const svn
pb->repos = repos;
pb->fs = svn_repos_fs(repos);
pb->use_history = use_history;
- pb->outstream = outstream ? outstream : svn_stream_empty(pool);
+ pb->notify_func = notify_func;
+ pb->notify_baton = notify_baton;
+ pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
pb->uuid_action = uuid_action;
pb->parent_dir = parent_dir;
pb->pool = pool;
@@ -1531,13 +1537,14 @@ svn_repos_get_fs_build_parser2(const svn
svn_error_t *
-svn_repos_load_fs2(svn_repos_t *repos,
+svn_repos_load_fs3(svn_repos_t *repos,
svn_stream_t *dumpstream,
- svn_stream_t *feedback_stream,
enum svn_repos_load_uuid uuid_action,
const char *parent_dir,
svn_boolean_t use_pre_commit_hook,
svn_boolean_t use_post_commit_hook,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool)
@@ -1548,12 +1555,13 @@ svn_repos_load_fs2(svn_repos_t *repos,
/* This is really simple. */
- SVN_ERR(svn_repos_get_fs_build_parser2(&parser, &parse_baton,
+ SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
repos,
TRUE, /* look for copyfrom revs */
uuid_action,
- feedback_stream,
parent_dir,
+ notify_func,
+ notify_baton,
pool));
/* Heh. We know this is a parse_baton. This file made it. So
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c Tue Aug 10 22:07:24 2010
@@ -1553,11 +1553,11 @@ svn_repos_open(svn_repos_t **repos_p,
svn_error_t *
-svn_repos_upgrade(const char *path,
- svn_boolean_t nonblocking,
- svn_error_t *(*start_callback)(void *baton),
- void *start_callback_baton,
- apr_pool_t *pool)
+svn_repos_upgrade2(const char *path,
+ svn_boolean_t nonblocking,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ apr_pool_t *pool)
{
svn_repos_t *repos;
const char *format_path;
@@ -1571,8 +1571,17 @@ svn_repos_upgrade(const char *path,
lock_repos.) */
SVN_ERR(get_repos(&repos, path, TRUE, nonblocking, FALSE, subpool));
- if (start_callback)
- SVN_ERR(start_callback(start_callback_baton));
+ if (notify_func)
+ {
+ /* We notify *twice* here, because there are two different logistical
+ actions occuring. */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_mutex_acquired, subpool);
+ notify_func(notify_baton, notify, subpool);
+
+ notify->action = svn_repos_notify_upgrade_start;
+ notify_func(notify_baton, notify, subpool);
+ }
/* Try to overwrite with its own contents. We do this only to
verify that we can, because we don't want to actually bump the
@@ -1721,11 +1730,12 @@ svn_repos_fs(svn_repos_t *repos)
*/
svn_error_t *
-svn_repos_recover3(const char *path,
+svn_repos_recover4(const char *path,
svn_boolean_t nonblocking,
- svn_error_t *(*start_callback)(void *baton),
- void *start_callback_baton,
- svn_cancel_func_t cancel_func, void *cancel_baton,
+ svn_repos_notify_func_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void * cancel_baton,
apr_pool_t *pool)
{
svn_repos_t *repos;
@@ -1740,8 +1750,17 @@ svn_repos_recover3(const char *path,
FALSE, /* don't try to open the db yet. */
subpool));
- if (start_callback)
- SVN_ERR(start_callback(start_callback_baton));
+ if (notify_func)
+ {
+ /* We notify *twice* here, because there are two different logistical
+ actions occuring. */
+ svn_repos_notify_t *notify = svn_repos_notify_create(
+ svn_repos_notify_mutex_acquired, subpool);
+ notify_func(notify_baton, notify, subpool);
+
+ notify->action = svn_repos_notify_recover_start;
+ notify_func(notify_baton, notify, subpool);
+ }
/* Recover the database to a consistent state. */
SVN_ERR(svn_fs_recover(repos->db_path, cancel_func, cancel_baton, subpool));
@@ -1837,6 +1856,8 @@ static svn_error_t *hotcopy_structure(vo
return create_repos_dir(target, pool);
else if (finfo->filetype == APR_REG)
return svn_io_copy_file(path, target, TRUE, pool);
+ else if (finfo->filetype == APR_LNK)
+ return svn_io_copy_link(path, target, pool);
else
return SVN_NO_ERROR;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c Tue Aug 10 22:07:24 2010
@@ -979,6 +979,10 @@ svn_config_ensure(const char *config_dir
"### This will override the compile-time default, which is to use" NL
"### Subversion's internal diff implementation." NL
"# diff-cmd = diff_program (diff, gdiff, etc.)" NL
+ "### Diff-extensions are arguments passed to an external diff" NL
+ "### program or to Subversion's internal diff implementation." NL
+ "### Set diff-extensions to override the default arguments ('-u')." NL
+ "# diff-extensions = -u -p" NL
"### Set diff3-cmd to the absolute path of your 'diff3' program." NL
"### This will override the compile-time default, which is to use" NL
"### Subversion's internal diff3 implementation." NL
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/deprecated.c Tue Aug 10 22:07:24 2010
@@ -722,6 +722,14 @@ svn_io_remove_file(const char *path,
return svn_error_return(svn_io_remove_file2(path, FALSE, scratch_pool));
}
+svn_error_t *svn_io_file_lock(const char *lock_file,
+ svn_boolean_t exclusive,
+ apr_pool_t *pool)
+{
+ return svn_io_file_lock2(lock_file, exclusive, FALSE, pool);
+}
+
+
/*** From constructors.c ***/
svn_log_changed_path_t *
svn_log_changed_path_dup(const svn_log_changed_path_t *changed_path,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/dirent_uri.c Tue Aug 10 22:07:24 2010
@@ -50,6 +50,11 @@
the OS! */
#define SVN_PATH_IS_PLATFORM_EMPTY(s,n) ((n) == 1 && (s)[0] == '.')
+/* This check must match the check on top of dirent_uri-tests.c */
+#if defined(WIN32) || defined(__CYGWIN__) || defined(__OS2__)
+#define SVN_USE_DOS_PATHS
+#endif
+
/* Path type definition. Used only by internal functions. */
typedef enum {
type_uri,
@@ -169,7 +174,7 @@ canonicalize_to_upper(char c)
static apr_size_t
dirent_root_length(const char *dirent, apr_size_t len)
{
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (len >= 2 && dirent[1] == ':' &&
((dirent[0] >= 'A' && dirent[0] <= 'Z') ||
(dirent[0] >= 'a' && dirent[0] <= 'z')))
@@ -194,7 +199,7 @@ dirent_root_length(const char *dirent, a
return i;
}
-#endif
+#endif /* SVN_USE_DOS_PATHS */
if (len >= 1 && dirent[0] == '/')
return 1;
@@ -218,9 +223,9 @@ dirent_previous_segment(const char *dire
--len;
while (len > 0 && dirent[len] != '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
&& (dirent[len] != ':' || len != 1)
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
)
--len;
@@ -277,12 +282,12 @@ dirent_is_rooted(const char *dirent)
/* On Windows, dirent is also absolute when it starts with 'H:' or 'H:/'
where 'H' is any letter. */
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (((dirent[0] >= 'A' && dirent[0] <= 'Z') ||
(dirent[0] >= 'a' && dirent[0] <= 'z')) &&
(dirent[1] == ':'))
return TRUE;
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
return FALSE;
}
@@ -429,14 +434,14 @@ canonicalize(path_type_t type, const cha
{
*(dst++) = *(src++);
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* On Windows permit two leading separator characters which means an
* UNC path. */
if ((type == type_dirent) && *src == '/')
*(dst++) = *(src++);
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
}
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* On Windows the first segment can be a drive letter, which we normalize
to upper case. */
else if (type == type_dirent &&
@@ -449,7 +454,7 @@ canonicalize(path_type_t type, const cha
by the following code block, so we need not care whether it has
a slash after it. */
}
-#endif
+#endif /* SVN_USE_DOS_PATHS */
}
while (*src)
@@ -465,7 +470,7 @@ canonicalize(path_type_t type, const cha
{
/* Noop segment, so do nothing. */
}
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* If this is the first path segment of a file:// URI and it contains a
windows drive letter, convert the drive letter to upper case. */
else if (url && canon_segments == 1 && seglen == 2 &&
@@ -478,7 +483,7 @@ canonicalize(path_type_t type, const cha
*(dst++) = *next;
canon_segments++;
}
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
else
{
/* An actual segment, append it to the destination path */
@@ -509,7 +514,7 @@ canonicalize(path_type_t type, const cha
*dst = '\0';
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* Skip leading double slashes when there are less than 2
* canon segments. UNC paths *MUST* have two segments. */
if ((type == type_dirent) && canon[0] == '/' && canon[1] == '/')
@@ -529,7 +534,7 @@ canonicalize(path_type_t type, const cha
*(dst++) = canonicalize_to_lower(*dst);
}
}
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
/* Check the normalization of characters in a uri */
if (schema_data)
@@ -642,7 +647,7 @@ get_longest_ancestor_length(path_type_t
apr_size_t path1_len, path2_len;
apr_size_t i = 0;
apr_size_t last_dirsep = 0;
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
svn_boolean_t unc = FALSE;
#endif
@@ -675,7 +680,7 @@ get_longest_ancestor_length(path_type_t
return 0;
/* Handle some windows specific cases */
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (types == type_dirent)
{
/* don't count the '//' from UNC paths */
@@ -703,7 +708,7 @@ get_longest_ancestor_length(path_type_t
if (path1[i - 1] == ':' || path2[i - 1] == ':')
return i;
}
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
/* last_dirsep is now the offset of the last directory separator we
crossed before reaching a non-matching byte. i is the offset of
@@ -718,7 +723,7 @@ get_longest_ancestor_length(path_type_t
{
/* Nothing in common but the root folder '/' or 'X:/' for Windows
dirents. */
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (! unc)
{
/* X:/foo and X:/bar returns X:/ */
@@ -726,10 +731,10 @@ get_longest_ancestor_length(path_type_t
last_dirsep == 2 && path1[1] == ':' && path1[2] == '/'
&& path2[1] == ':' && path2[2] == '/')
return 3;
-#endif
+#endif /* SVN_USE_DOS_PATHS */
if (last_dirsep == 0 && path1[0] == '/' && path2[0] == '/')
return 1;
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
}
#endif
}
@@ -807,9 +812,9 @@ is_child(path_type_t type, const char *p
if (path1[i] == '\0' && path2[i])
{
if (path1[i - 1] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
|| ((type == type_dirent) && path1[i - 1] == ':')
-#endif /* WIN32 or Cygwin */
+#endif
)
{
if (path2[i] == '/')
@@ -870,9 +875,9 @@ is_ancestor(path_type_t type, const char
path1_len = strlen(path1);
if (strncmp(path1, path2, path1_len) == 0)
return path1[path1_len - 1] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
|| ((type == type_dirent) && path1[path1_len - 1] == ':')
-#endif /* WIN32 or Cygwin */
+#endif
|| (path2[path1_len] == '/' || path2[path1_len] == '\0');
return FALSE;
@@ -913,7 +918,7 @@ svn_relpath_local_style(const char *dire
svn_boolean_t
svn_dirent_is_root(const char *dirent, apr_size_t len)
{
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* On Windows and Cygwin, 'H:' or 'H:/' (where 'H' is any letter)
are also root directories */
if ((len == 2 || ((len == 3) && (dirent[2] == '/'))) &&
@@ -987,7 +992,7 @@ char *svn_dirent_join(const char *base,
if (SVN_PATH_IS_EMPTY(component))
return apr_pmemdup(pool, base, blen + 1);
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (component[0] == '/')
{
/* '/' is drive relative on Windows, not absolute like on Posix */
@@ -1015,14 +1020,14 @@ char *svn_dirent_join(const char *base,
}
else if (dirent_is_rooted(component))
return apr_pmemdup(pool, component, clen + 1);
-#endif
+#endif /* SVN_USE_DOS_PATHS */
/* if last character of base is already a separator, don't add a '/' */
add_separator = 1;
if (base[blen - 1] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
|| base[blen - 1] == ':'
-#endif /* WIN32 or Cygwin */
+#endif
)
add_separator = 0;
@@ -1058,9 +1063,9 @@ char *svn_dirent_join_many(apr_pool_t *p
add_separator = 1;
if (total_len == 0
|| base[total_len - 1] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
|| base[total_len - 1] == ':'
-#endif /* WIN32 or Cygwin */
+#endif
)
add_separator = 0;
@@ -1087,7 +1092,7 @@ char *svn_dirent_join_many(apr_pool_t *p
total_len = len;
base_arg = nargs;
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (!svn_dirent_is_absolute(s)) /* Handle non absolute roots */
{
/* Set new base and skip the current argument */
@@ -1096,7 +1101,7 @@ char *svn_dirent_join_many(apr_pool_t *p
saved_lengths[0] = total_len = len = strlen(s);
}
else
-#endif
+#endif /* SVN_USE_DOS_PATHS */
{
base = ""; /* Don't add base */
saved_lengths[0] = 0;
@@ -1104,9 +1109,9 @@ char *svn_dirent_join_many(apr_pool_t *p
add_separator = 1;
if (s[len - 1] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
|| s[len - 1] == ':'
-#endif /* WIN32 or Cygwin */
+#endif
)
add_separator = 0;
}
@@ -1274,9 +1279,9 @@ svn_dirent_basename(const char *dirent,
{
start = len;
while (start > 0 && dirent[start - 1] != '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
&& dirent[start - 1] != ':'
-#endif /* WIN32 or Cygwin */
+#endif
)
--start;
}
@@ -1288,9 +1293,9 @@ svn_dirent_basename(const char *dirent,
}
void
-svn_dirent_split(const char *dirent,
- const char **dirpath,
+svn_dirent_split(const char **dirpath,
const char **base_name,
+ const char *dirent,
apr_pool_t *pool)
{
assert(dirpath != base_name);
@@ -1334,9 +1339,9 @@ svn_relpath_basename(const char *relpath
}
void
-svn_relpath_split(const char *relpath,
- const char **dirpath,
+svn_relpath_split(const char **dirpath,
const char **base_name,
+ const char *relpath,
apr_pool_t *pool)
{
assert(dirpath != base_name);
@@ -1385,9 +1390,9 @@ svn_uri_basename(const char *uri, apr_po
}
void
-svn_uri_split(const char *uri,
- const char **dirpath,
+svn_uri_split(const char **dirpath,
const char **base_name,
+ const char *uri,
apr_pool_t *pool)
{
assert(dirpath != base_name);
@@ -1541,7 +1546,7 @@ svn_dirent_skip_ancestor(const char *dir
if (dirent2[len] == '/')
return dirent2 + len + 1;
-#ifdef WIN32
+#ifdef SVN_USE_DOS_PATHS
if (root_len == len && len > 0 && dirent2[len-1])
return dirent2 + len;
#endif
@@ -1601,7 +1606,7 @@ svn_dirent_is_absolute(const char *diren
/* dirent is absolute if it starts with '/' on non-Windows platforms
or with '//' on Windows platforms */
if (dirent[0] == '/'
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
&& dirent[1] == '/' /* Single '/' depends on current drive */
#endif
)
@@ -1609,11 +1614,11 @@ svn_dirent_is_absolute(const char *diren
/* On Windows, dirent is also absolute when it starts with 'H:/'
where 'H' is any letter. */
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (((dirent[0] >= 'A' && dirent[0] <= 'Z')) &&
(dirent[1] == ':') && (dirent[2] == '/'))
return TRUE;
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
return FALSE;
}
@@ -1675,7 +1680,7 @@ svn_dirent_canonicalize(const char *dire
{
const char *dst = canonicalize(type_dirent, dirent, pool);
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* Handle a specific case on Windows where path == "X:/". Here we have to
append the final '/', as svn_path_canonicalize will chop this of. */
if (((dirent[0] >= 'A' && dirent[0] <= 'Z') ||
@@ -1691,7 +1696,7 @@ svn_dirent_canonicalize(const char *dire
return dst_slash;
}
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
return dst;
}
@@ -1703,7 +1708,7 @@ svn_dirent_is_canonical(const char *dire
if (*ptr == '/')
{
ptr++;
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
/* Check for UNC paths */
if (*ptr == '/')
{
@@ -1712,9 +1717,9 @@ svn_dirent_is_canonical(const char *dire
/* ### Fall back to old implementation */
return (strcmp(dirent, svn_dirent_canonicalize(dirent, pool)) == 0);
}
-#endif
+#endif /* SVN_USE_DOS_PATHS */
}
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
else if (((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z')) &&
(ptr[1] == ':'))
{
@@ -1727,7 +1732,7 @@ svn_dirent_is_canonical(const char *dire
if (*ptr == '/')
ptr++;
}
-#endif
+#endif /* SVN_USE_DOS_PATHS */
return svn_relpath_is_canonical(ptr, pool);
}
@@ -1844,7 +1849,7 @@ svn_uri_is_canonical(const char *uri, ap
}
}
-#if defined(WIN32) || defined(__CYGWIN__)
+#ifdef SVN_USE_DOS_PATHS
if (schema_data && *ptr == '/')
{
/* If this is a file url, ptr now points to the third '/' in
@@ -1855,7 +1860,7 @@ svn_uri_is_canonical(const char *uri, ap
*(ptr+2) == ':')
return FALSE;
}
-#endif /* WIN32 or Cygwin */
+#endif /* SVN_USE_DOS_PATHS */
/* Now validate the rest of the URI. */
while(1)
@@ -2265,3 +2270,147 @@ svn_dirent_is_under_root(char **full_pat
return status == APR_SUCCESS ? TRUE : FALSE;
}
+
+svn_error_t *
+svn_uri_get_dirent_from_file_url(const char **dirent,
+ const char *url,
+ apr_pool_t *pool)
+{
+ const char *hostname, *path;
+
+ SVN_ERR_ASSERT(svn_uri_is_canonical(url, pool));
+ SVN_ERR_ASSERT(svn_path_is_url(url));
+
+ /* Verify that the URL is well-formed (loosely) */
+
+ /* First, check for the "file://" prefix. */
+ if (strncmp(url, "file://", 7) != 0)
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ _("Local URL '%s' does not contain 'file://' "
+ "prefix"), url);
+
+ /* Find the HOSTNAME portion and the PATH portion of the URL. The host
+ name is between the "file://" prefix and the next occurence of '/'. We
+ are considering everything from that '/' until the end of the URL to be
+ the absolute path portion of the URL.
+ If we got just "file://", treat it the same as "file:///". */
+ hostname = url + 7;
+ path = strchr(hostname, '/');
+ if (path)
+ hostname = apr_pstrmemdup(pool, hostname, path - hostname);
+ else
+ path = "/";
+
+ /* URI-decode HOSTNAME, and set it to NULL if it is "" or "localhost". */
+ if (*hostname == '\0')
+ hostname = NULL;
+ else
+ {
+ hostname = svn_path_uri_decode(hostname, pool);
+ if (strcmp(hostname, "localhost") == 0)
+ hostname = NULL;
+ }
+
+ /* Duplicate the URL, starting at the top of the path.
+ At the same time, we URI-decode the path. */
+#ifdef SVN_USE_DOS_PATHS
+ /* On Windows, we'll typically have to skip the leading / if the
+ path starts with a drive letter. Like most Web browsers, We
+ support two variants of this scheme:
+
+ file:///X:/path and
+ file:///X|/path
+
+ Note that, at least on WinNT and above, file:////./X:/path will
+ also work, so we must make sure the transformation doesn't break
+ that, and file:///path (that looks within the current drive
+ only) should also keep working.
+ If we got a non-empty hostname other than localhost, we convert this
+ into an UNC path. In this case, we obviously don't strip the slash
+ even if the path looks like it starts with a drive letter.
+ */
+ {
+ static const char valid_drive_letters[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ /* Casting away const! */
+ char *dup_path = (char *)svn_path_uri_decode(path, pool);
+
+ /* This check assumes ':' and '|' are already decoded! */
+ if (!hostname && dup_path[1] && strchr(valid_drive_letters, dup_path[1])
+ && (dup_path[2] == ':' || dup_path[2] == '|'))
+ {
+ /* Skip the leading slash. */
+ ++dup_path;
+
+ if (dup_path[1] == '|')
+ dup_path[1] = ':';
+
+ if (dup_path[2] == '/' || dup_path[2] == '\0')
+ {
+ if (dup_path[2] == '\0')
+ {
+ /* A valid dirent for the driveroot must be like "C:/" instead of
+ just "C:" or svn_dirent_join() will use the current directory
+ on the drive instead */
+ char *new_path = apr_pcalloc(pool, 4);
+ new_path[0] = dup_path[0];
+ new_path[1] = ':';
+ new_path[2] = '/';
+ new_path[3] = '\0';
+ dup_path = new_path;
+ }
+ }
+ }
+ if (hostname)
+ {
+ if (dup_path[0] == '/' && dup_path[1] == '\0')
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ _("Local URL '%s' contains only a hostname, "
+ "no path"), url);
+
+ /* We still know that the path starts with a slash. */
+ *dirent = apr_pstrcat(pool, "//", hostname, dup_path, NULL);
+ }
+ else
+ *dirent = dup_path;
+ }
+#else /* !SVN_USE_DOS_PATHS */
+ /* Currently, the only hostnames we are allowing on non-Win32 platforms
+ are the empty string and 'localhost'. */
+ if (hostname)
+ return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+ _("Local URL '%s' contains unsupported hostname"),
+ url);
+
+ *dirent = svn_path_uri_decode(path, pool);
+#endif /* SVN_USE_DOS_PATHS */
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_uri_get_file_url_from_dirent(const char **url,
+ const char *dirent,
+ apr_pool_t *pool)
+{
+ assert(svn_dirent_is_canonical(dirent, pool));
+
+ SVN_ERR(svn_dirent_get_absolute(&dirent, dirent, pool));
+
+ dirent = svn_path_uri_encode(dirent, pool);
+
+#ifndef SVN_USE_DOS_PATHS
+ *url = apr_pstrcat(pool, "file://", dirent, NULL);
+#else
+ if (dirent[0] == '/')
+ {
+ /* Handle UNC paths */
+ assert(dirent[1] != '/'); /* Not absolute! */
+
+ *url = apr_pstrcat(pool, "file://", dirent+1, NULL);
+ }
+ else
+ *url = apr_pstrcat(pool, "file:///", dirent, NULL);
+#endif
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/io.c Tue Aug 10 22:07:24 2010
@@ -243,20 +243,20 @@ io_check_path(const char *path,
}
-/* Wrapper for apr_file_open(). */
+/* Wrapper for apr_file_open(), taking an APR-encoded filename. */
static apr_status_t
file_open(apr_file_t **f,
- const char *fname,
+ const char *fname_apr,
apr_int32_t flag,
apr_fileperms_t perm,
svn_boolean_t retry_on_failure,
apr_pool_t *pool)
{
- apr_status_t status = apr_file_open(f, fname, flag, perm, pool);
+ apr_status_t status = apr_file_open(f, fname_apr, flag, perm, pool);
if (retry_on_failure)
{
- WIN32_RETRY_LOOP(status, apr_file_open(f, fname, flag, perm, pool));
+ WIN32_RETRY_LOOP(status, apr_file_open(f, fname_apr, flag, perm, pool));
}
return status;
}
@@ -292,7 +292,9 @@ svn_io_check_special_path(const char *pa
struct temp_file_cleanup_s
{
apr_pool_t *pool;
- const char *name;
+ /* The (APR-encoded) full path of the file to be removed, or NULL if
+ * nothing to do. */
+ const char *fname_apr;
};
@@ -302,10 +304,10 @@ temp_file_plain_cleanup_handler(void *ba
struct temp_file_cleanup_s *b = baton;
apr_status_t apr_err = APR_SUCCESS;
- if (b->name)
+ if (b->fname_apr)
{
- apr_err = apr_file_remove(b->name, b->pool);
- WIN32_RETRY_LOOP(apr_err, apr_file_remove(b->name, b->pool));
+ apr_err = apr_file_remove(b->fname_apr, b->pool);
+ WIN32_RETRY_LOOP(apr_err, apr_file_remove(b->fname_apr, b->pool));
}
return apr_err;
@@ -354,7 +356,7 @@ svn_io_open_uniquely_named(apr_file_t **
baton = apr_palloc(result_pool, sizeof(*baton));
baton->pool = result_pool;
- baton->name = NULL;
+ baton->fname_apr = NULL;
/* Because cleanups are run LIFO, we need to make sure to register
our cleanup before the apr_file_close cleanup:
@@ -447,7 +449,7 @@ svn_io_open_uniquely_named(apr_file_t **
else
{
if (delete_when == svn_io_file_del_on_pool_cleanup)
- baton->name = apr_pstrdup(result_pool, unique_name_apr);
+ baton->fname_apr = apr_pstrdup(result_pool, unique_name_apr);
if (file)
*file = try_file;
@@ -786,7 +788,8 @@ svn_io_copy_file(const char *src,
return svn_error_return(svn_io_file_rename(dst_tmp, dst, pool));
}
-/* Wrapper for apr_file_perms_set(). */
+#if !defined(WIN32) && !defined(__OS2__)
+/* Wrapper for apr_file_perms_set(), taking a UTF8-encoded filename. */
static svn_error_t *
file_perms_set(const char *fname, apr_fileperms_t perms,
apr_pool_t *pool)
@@ -803,35 +806,32 @@ file_perms_set(const char *fname, apr_fi
else
return SVN_NO_ERROR;
}
+#endif /* !WIN32 && !__OS2__ */
svn_error_t *
svn_io_copy_perms(const char *src,
const char *dst,
apr_pool_t *pool)
{
- /* ### On Windows, apr_file_perms_set always returns APR_ENOTIMPL,
+ /* ### On Windows or OS/2, apr_file_perms_set always returns APR_ENOTIMPL,
and the path passed to apr_file_perms_set must be encoded
in the platform-specific path encoding; not necessary UTF-8.
We need a platform-specific implementation to get the
permissions right. */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
{
- apr_file_t *src_file;
- apr_file_t *dst_file;
apr_finfo_t finfo;
+ svn_node_kind_t kind;
+ svn_boolean_t is_special;
svn_error_t *err;
/* If DST is a symlink, don't bother copying permissions. */
- SVN_ERR(svn_io_file_open(&dst_file, dst, APR_READ, APR_OS_DEFAULT, pool));
- SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_TYPE, dst_file, pool));
- SVN_ERR(svn_io_file_close(dst_file, pool));
- if (finfo.filetype == APR_LNK)
+ SVN_ERR(svn_io_check_special_path(dst, &kind, &is_special, pool));
+ if (is_special)
return SVN_NO_ERROR;
- SVN_ERR(svn_io_file_open(&src_file, src, APR_READ, APR_OS_DEFAULT, pool));
- SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, src_file, pool));
- SVN_ERR(svn_io_file_close(src_file, pool));
+ SVN_ERR(svn_io_stat(&finfo, src, APR_FINFO_PROT, pool));
err = file_perms_set(dst, finfo.protection, pool);
if (err)
{
@@ -852,7 +852,7 @@ svn_io_copy_perms(const char *src,
}
}
}
-#endif /* ! WIN32 */
+#endif /* !WIN32 && !__OS2__ */
return SVN_NO_ERROR;
}
@@ -1239,7 +1239,7 @@ svn_io_file_checksum(unsigned char diges
/*** Permissions and modes. ***/
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
/* Given the file specified by PATH, attempt to create an
identical version of it owned by the current user. This is done by
moving it to a temporary location, copying the file back to its old
@@ -1454,7 +1454,7 @@ io_set_file_perms(const char *path,
_("Can't change perms of file '%s'"),
svn_dirent_local_style(path, pool));
}
-#endif /* !WIN32 */
+#endif /* !WIN32 && !__OS2__ */
svn_error_t *
@@ -1473,9 +1473,9 @@ svn_io_set_file_read_only(const char *pa
svn_boolean_t ignore_enoent,
apr_pool_t *pool)
{
- /* On Windows, just set the file attributes -- on unix call
+ /* On Windows and OS/2, just set the file attributes -- on unix call
our internal function which attempts to honor the umask. */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
return io_set_file_perms(path, TRUE, FALSE, FALSE, FALSE,
ignore_enoent, pool);
#else
@@ -1505,9 +1505,9 @@ svn_io_set_file_read_write(const char *p
svn_boolean_t ignore_enoent,
apr_pool_t *pool)
{
- /* On Windows, just set the file attributes -- on unix call
+ /* On Windows and OS/2, just set the file attributes -- on unix call
our internal function which attempts to honor the umask. */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
return io_set_file_perms(path, TRUE, TRUE, FALSE, FALSE,
ignore_enoent, pool);
#else
@@ -1537,9 +1537,9 @@ svn_io_set_file_executable(const char *p
svn_boolean_t ignore_enoent,
apr_pool_t *pool)
{
- /* On Windows, just exit -- on unix call our internal function
+ /* On Windows and OS/2, just exit -- on unix call our internal function
which attempts to honor the umask. */
-#ifndef WIN32
+#if (!defined(WIN32) && !defined(__OS2__))
return io_set_file_perms(path, FALSE, FALSE, TRUE, executable,
ignore_enoent, pool);
#else
@@ -1553,7 +1553,7 @@ svn_io_is_file_executable(svn_boolean_t
const char *path,
apr_pool_t *pool)
{
-#if defined(APR_HAS_USER) && !defined(WIN32)
+#if defined(APR_HAS_USER) && !defined(WIN32) &&!defined(__OS2__)
apr_finfo_t file_info;
apr_status_t apr_err;
apr_uid_t uid;
@@ -1580,7 +1580,7 @@ svn_io_is_file_executable(svn_boolean_t
else
*executable = (file_info.protection & APR_WEXECUTE);
-#else /* defined(WIN32) || !defined(APR_HAS_USER) */
+#else /* WIN32 || __OS2__ || !APR_HAS_USER */
*executable = FALSE;
#endif
@@ -1589,9 +1589,10 @@ svn_io_is_file_executable(svn_boolean_t
/*** File locking. ***/
+#if !defined(WIN32) && !defined(__OS2__)
/* Clear all outstanding locks on ARG, an open apr_file_t *. */
static apr_status_t
-svn_io__file_clear_and_close(void *arg)
+file_clear_locks(void *arg)
{
apr_status_t apr_err;
apr_file_t *f = arg;
@@ -1601,26 +1602,15 @@ svn_io__file_clear_and_close(void *arg)
if (apr_err)
return apr_err;
- /* Close the file. */
- apr_err = apr_file_close(f);
- if (apr_err)
- return apr_err;
-
return 0;
}
+#endif
-
-svn_error_t *svn_io_file_lock(const char *lock_file,
- svn_boolean_t exclusive,
- apr_pool_t *pool)
-{
- return svn_io_file_lock2(lock_file, exclusive, FALSE, pool);
-}
-
-svn_error_t *svn_io_file_lock2(const char *lock_file,
- svn_boolean_t exclusive,
- svn_boolean_t nonblocking,
- apr_pool_t *pool)
+svn_error_t *
+svn_io_file_lock2(const char *lock_file,
+ svn_boolean_t exclusive,
+ svn_boolean_t nonblocking,
+ apr_pool_t *pool)
{
int locktype = APR_FLOCK_SHARED;
apr_file_t *lockfile_handle;
@@ -1660,9 +1650,13 @@ svn_error_t *svn_io_file_lock2(const cha
}
}
+/* On Windows and OS/2 file locks are automatically released when
+ the file handle closes */
+#if !defined(WIN32) && !defined(__OS2__)
apr_pool_cleanup_register(pool, lockfile_handle,
- svn_io__file_clear_and_close,
+ file_clear_locks,
apr_pool_cleanup_null);
+#endif
return SVN_NO_ERROR;
}
@@ -1849,8 +1843,8 @@ svn_io_remove_file2(const char *path,
apr_status_t apr_err;
const char *path_apr;
-#ifdef WIN32
- /* Set the file writable but only on Windows, because Windows
+#if defined(WIN32) || defined(__OS2__)
+ /* Set the file writable but only on Windows & OS/2, because Windows and OS/2
will not allow us to remove files that are read-only. */
SVN_ERR(svn_io_set_file_read_write(path, TRUE, scratch_pool));
#endif /* WIN32 */
@@ -2949,7 +2943,7 @@ svn_io_file_rename(const char *from_path
status = apr_file_rename(from_path_apr, to_path_apr, pool);
-#ifdef WIN32
+#if defined(WIN32) || defined(__OS2__)
/* If the target file is read only NTFS reports EACCESS and
FAT/FAT32 reports EEXIST */
if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
@@ -2962,7 +2956,7 @@ svn_io_file_rename(const char *from_path
status = apr_file_rename(from_path_apr, to_path_apr, pool);
}
WIN32_RETRY_LOOP(status, apr_file_rename(from_path_apr, to_path_apr, pool));
-#endif /* WIN32 */
+#endif /* WIN32 || __OS2__ */
if (status)
return svn_error_wrap_apr(status, _("Can't move '%s' to '%s'"),
@@ -3255,7 +3249,7 @@ svn_io_dir_walk(const char *dirname,
walk_baton,
subpool));
}
- else if (finfo.filetype == APR_REG)
+ else if (finfo.filetype == APR_REG || finfo.filetype == APR_LNK)
{
/* some other directory. pass it to the callback. */
SVN_ERR(entry_name_to_utf8(&name_utf8, finfo.name, dirname,
@@ -3382,11 +3376,11 @@ svn_io_write_version_file(const char *pa
format_contents, strlen(format_contents),
svn_io_file_del_none, pool));
-#ifdef WIN32
+#if defined(WIN32) || defined(__OS2__)
/* make the destination writable, but only on Windows, because
Windows does not let us replace read-only files. */
SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
-#endif /* WIN32 */
+#endif /* WIN32 || __OS2__ */
/* rename the temp file as the real destination */
SVN_ERR(svn_io_file_rename(path_tmp, path, pool));
@@ -3594,8 +3588,10 @@ temp_file_create(apr_file_t **new_file,
disk io) */
unique_nr = baseNr + 3 * i;
- unique_name = apr_psprintf(scratch_pool, "%s/svn-%X", directory,
- unique_nr);
+ unique_name = svn_dirent_join(directory,
+ apr_psprintf(scratch_pool, "svn-%X",
+ unique_nr),
+ scratch_pool);
SVN_ERR(cstring_from_utf8(&unique_name_apr, unique_name, scratch_pool));
@@ -3663,7 +3659,7 @@ temp_file_create(apr_file_t **new_file,
#endif
}
-/* Wrapper for apr_file_name_get(). */
+/* Wrapper for apr_file_name_get(), passing out a UTF8-encoded filename. */
svn_error_t *
svn_io_file_name_get(const char **filename,
apr_file_t *file,
@@ -3716,7 +3712,7 @@ svn_io_open_unique_file3(apr_file_t **fi
case svn_io_file_del_on_pool_cleanup:
baton = apr_palloc(result_pool, sizeof(*baton));
baton->pool = result_pool;
- baton->name = NULL;
+ baton->fname_apr = NULL;
/* Because cleanups are run LIFO, we need to make sure to register
our cleanup before the apr_file_close cleanup:
@@ -3738,9 +3734,9 @@ svn_io_open_unique_file3(apr_file_t **fi
SVN_ERR(temp_file_create(&tempfile, &tempname, dirpath, flags,
result_pool, scratch_pool));
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
/* ### file_mktemp() creates files with mode 0600.
- * ### As of r40264, tempfiles created by svn_io_open_unique_file3()
+ * ### As of r880338, tempfiles created by svn_io_open_unique_file3()
* ### often end up being copied or renamed into the working copy.
* ### This will cause working files having mode 0600 while users might
* ### expect to see 644 or 664. Ideally, permissions should be tweaked
@@ -3761,12 +3757,7 @@ svn_io_open_unique_file3(apr_file_t **fi
*unique_path = tempname; /* Was allocated in result_pool */
if (baton)
- {
- if (unique_path)
- baton->name = *unique_path;
- else
- baton->name = tempname; /* Was allocated in result_pool */
- }
+ SVN_ERR(cstring_from_utf8(&baton->fname_apr, tempname, result_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c Tue Aug 10 22:07:24 2010
@@ -1064,46 +1064,3 @@ svn_opt_print_help3(apr_getopt_t *os,
return SVN_NO_ERROR;
}
-
-/* svn_opt__eat_peg_revisions was added to the 1.6 branch and, despite
- its double underscore name, it is called from the application
- layer. So to remain ABI compatibilty with 1.6 the name must
- continue to exist. Adding this name is sufficient for the 1.6
- client to link against the 1.7 libraries. */
-svn_error_t *
-svn_opt__eat_peg_revisions(apr_array_header_t **true_targets_p,
- const apr_array_header_t *targets,
- apr_pool_t *pool);
-svn_error_t *
-svn_opt__eat_peg_revisions(apr_array_header_t **true_targets_p,
- const apr_array_header_t *targets,
- apr_pool_t *pool)
-{
- return svn_opt_eat_peg_revisions(true_targets_p, targets, pool);
-}
-
-svn_error_t *
-svn_opt_eat_peg_revisions(apr_array_header_t **true_targets_p,
- const apr_array_header_t *targets,
- apr_pool_t *pool)
-{
- int i;
- apr_array_header_t *true_targets;
-
- true_targets = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
-
- for (i = 0; i < targets->nelts; i++)
- {
- const char *target = APR_ARRAY_IDX(targets, i, const char *);
- const char *true_target;
-
- SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, NULL,
- target, pool));
- APR_ARRAY_PUSH(true_targets, const char *) = true_target;
- }
-
- SVN_ERR_ASSERT(true_targets_p);
- *true_targets_p = true_targets;
-
- return SVN_NO_ERROR;
-}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c Tue Aug 10 22:07:24 2010
@@ -40,7 +40,7 @@
HANDLE dbghelp_dll = INVALID_HANDLE_VALUE;
/* Email address where the crash reports should be sent too. */
-#define CRASHREPORT_EMAIL "notifications@subversion.apache.org"
+#define CRASHREPORT_EMAIL "users@subversion.apache.org"
#define DBGHELP_DLL "dbghelp.dll"