You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2010/08/05 17:07:25 UTC

svn commit: r982653 [2/4] - in /subversion/branches/issue-2779-dev: ./ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ subversion/bindings/swig/ subversion/bindings/swig...

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocationsegments.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocationsegments.c Thu Aug  5 15:07:22 2010
@@ -126,8 +126,10 @@ end_gls(svn_ra_serf__xml_parser_t *parse
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t *
-create_gls_body(void *baton,
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_gls_body(serf_bucket_t **body_bkt,
+                void *baton,
                 serf_bucket_alloc_t *alloc,
                 apr_pool_t *pool)
 {
@@ -163,7 +165,8 @@ create_gls_body(void *baton,
   svn_ra_serf__add_close_tag_buckets(buckets, alloc,
                                      "S:get-location-segments");
 
-  return buckets;
+  *body_bkt = buckets;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocks.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/getlocks.c Thu Aug  5 15:07:22 2010
@@ -295,8 +295,10 @@ cdata_getlocks(svn_ra_serf__xml_parser_t
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t*
-create_getlocks_body(void *baton,
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_getlocks_body(serf_bucket_t **body_bkt,
+                     void *baton,
                      serf_bucket_alloc_t *alloc,
                      apr_pool_t *pool)
 {
@@ -310,7 +312,8 @@ create_getlocks_body(void *baton,
     "depth", svn_depth_to_word(lock_ctx->requested_depth), NULL);
   svn_ra_serf__add_close_tag_buckets(buckets, alloc, "S:get-locks-report");
 
-  return buckets;
+  *body_bkt = buckets;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/locks.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/locks.c Thu Aug  5 15:07:22 2010
@@ -321,7 +321,7 @@ static const svn_ra_serf__dav_props_t lo
   { NULL }
 };
 
-static apr_status_t
+static svn_error_t *
 set_lock_headers(serf_bucket_t *headers,
                  void *baton,
                  apr_pool_t *pool)
@@ -430,8 +430,10 @@ handle_lock(serf_request_t *request,
                                         handler_baton, pool);
 }
 
-static serf_bucket_t*
-create_getlock_body(void *baton,
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_getlock_body(serf_bucket_t **body_bkt,
+                    void *baton,
                     serf_bucket_alloc_t *alloc,
                     apr_pool_t *pool)
 {
@@ -448,21 +450,24 @@ create_getlock_body(void *baton,
   svn_ra_serf__add_close_tag_buckets(buckets, alloc, "prop");
   svn_ra_serf__add_close_tag_buckets(buckets, alloc, "propfind");
 
-  return buckets;
+  *body_bkt = buckets;
+  return SVN_NO_ERROR;
 }
 
-static apr_status_t
+static svn_error_t*
 setup_getlock_headers(serf_bucket_t *headers,
                       void *baton,
                       apr_pool_t *pool)
 {
   serf_bucket_headers_set(headers, "Depth", "0");
 
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
-static serf_bucket_t*
-create_lock_body(void *baton,
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_lock_body(serf_bucket_t **body_bkt,
+                 void *baton,
                  serf_bucket_alloc_t *alloc,
                  apr_pool_t *pool)
 {
@@ -492,7 +497,8 @@ create_lock_body(void *baton,
 
   svn_ra_serf__add_close_tag_buckets(buckets, alloc, "lockinfo");
 
-  return buckets;
+  *body_bkt = buckets;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -651,7 +657,7 @@ struct unlock_context_t {
   svn_boolean_t force;
 };
 
-static apr_status_t
+static svn_error_t *
 set_unlock_headers(serf_bucket_t *headers,
                    void *baton,
                    apr_pool_t *pool)
@@ -665,7 +671,7 @@ set_unlock_headers(serf_bucket_t *header
                               SVN_DAV_OPTION_LOCK_BREAK);
     }
 
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/log.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/log.c Thu Aug  5 15:07:22 2010
@@ -459,8 +459,9 @@ cdata_log(svn_ra_serf__xml_parser_t *par
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t *
-create_log_body(void *baton,
+static svn_error_t *
+create_log_body(serf_bucket_t **body_bkt,
+                void *baton,
                 serf_bucket_alloc_t *alloc,
                 apr_pool_t *pool)
 {
@@ -550,7 +551,8 @@ create_log_body(void *baton,
   svn_ra_serf__add_close_tag_buckets(buckets, alloc,
                                      "S:log-report");
 
-  return buckets;
+  *body_bkt = buckets;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/merge.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/merge.c Thu Aug  5 15:07:22 2010
@@ -405,7 +405,7 @@ cdata_merge(svn_ra_serf__xml_parser_t *p
   return SVN_NO_ERROR;
 }
 
-static apr_status_t
+static svn_error_t *
 setup_merge_headers(serf_bucket_t *headers,
                     void *baton,
                     apr_pool_t *pool)
@@ -418,7 +418,7 @@ setup_merge_headers(serf_bucket_t *heade
                               SVN_DAV_OPTION_RELEASE_LOCKS);
     }
 
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
 void
@@ -469,8 +469,9 @@ svn_ra_serf__merge_lock_token_list(apr_h
   svn_ra_serf__add_close_tag_buckets(body, alloc, "S:lock-token-list");
 }
 
-static serf_bucket_t*
-create_merge_body(void *baton,
+static svn_error_t*
+create_merge_body(serf_bucket_t **bkt,
+                  void *baton,
                   serf_bucket_alloc_t *alloc,
                   apr_pool_t *pool)
 {
@@ -508,7 +509,9 @@ create_merge_body(void *baton,
 
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:merge");
 
-  return body_bkt;
+  *bkt = body_bkt;
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/mergeinfo.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/mergeinfo.c Thu Aug  5 15:07:22 2010
@@ -176,8 +176,9 @@ cdata_handler(svn_ra_serf__xml_parser_t 
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t *
-create_mergeinfo_body(void *baton,
+static svn_error_t *
+create_mergeinfo_body(serf_bucket_t **bkt,
+                      void *baton,
                       serf_bucket_alloc_t *alloc,
                       apr_pool_t *pool)
 {
@@ -221,7 +222,8 @@ create_mergeinfo_body(void *baton,
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc,
                                      "S:" SVN_DAV__MERGEINFO_REPORT);
 
-  return body_bkt;
+  *bkt = body_bkt;
+  return SVN_NO_ERROR;
 }
 
 /* Request a mergeinfo-report from the URL attached to SESSION,

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/options.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/options.c Thu Aug  5 15:07:22 2010
@@ -210,8 +210,9 @@ cdata_options(svn_ra_serf__xml_parser_t 
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t*
-create_options_body(void *baton,
+static svn_error_t *
+create_options_body(serf_bucket_t **body_bkt,
+                    void *baton,
                     serf_bucket_alloc_t *alloc,
                     apr_pool_t *pool)
 {
@@ -224,7 +225,8 @@ create_options_body(void *baton,
   svn_ra_serf__add_tag_buckets(body, "D:activity-collection-set", NULL, alloc);
   svn_ra_serf__add_close_tag_buckets(body, alloc, "D:options");
 
-  return body;
+  *body_bkt = body;
+  return SVN_NO_ERROR;
 }
 
 svn_boolean_t*

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/property.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/property.c Thu Aug  5 15:07:22 2010
@@ -420,7 +420,7 @@ cdata_propfind(svn_ra_serf__xml_parser_t
   return SVN_NO_ERROR;
 }
 
-static apr_status_t
+static svn_error_t *
 setup_propfind_headers(serf_bucket_t *headers,
                         void *setup_baton,
                         apr_pool_t *pool)
@@ -437,14 +437,15 @@ setup_propfind_headers(serf_bucket_t *he
       serf_bucket_headers_setn(headers, "Label", ctx->label);
     }
 
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
 #define PROPFIND_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\">"
 #define PROPFIND_TRAILER "</propfind>"
 
-static serf_bucket_t*
-create_propfind_body(void *setup_baton,
+static svn_error_t *
+create_propfind_body(serf_bucket_t **bkt,
+                     void *setup_baton,
                      serf_bucket_alloc_t *alloc,
                      apr_pool_t *pool)
 {
@@ -515,7 +516,8 @@ create_propfind_body(void *setup_baton,
                                       alloc);
   serf_bucket_aggregate_append(body_bkt, tmp);
 
-  return body_bkt;
+  *bkt = body_bkt;
+  return SVN_NO_ERROR;
 }
 
 static svn_boolean_t
@@ -736,7 +738,7 @@ svn_ra_serf__retrieve_props(apr_hash_t *
   return SVN_NO_ERROR;
 }
 
-void
+svn_error_t *
 svn_ra_serf__walk_all_props(apr_hash_t *props,
                             const char *name,
                             svn_revnum_t rev,
@@ -751,14 +753,14 @@ svn_ra_serf__walk_all_props(apr_hash_t *
 
   if (!ver_props)
     {
-      return;
+      return SVN_NO_ERROR;
     }
 
   path_props = apr_hash_get(ver_props, name, strlen(name));
 
   if (!path_props)
     {
-      return;
+      return SVN_NO_ERROR;
     }
 
   for (ns_hi = apr_hash_first(pool, path_props); ns_hi;
@@ -778,9 +780,12 @@ svn_ra_serf__walk_all_props(apr_hash_t *
 
           apr_hash_this(name_hi, &prop_name, &prop_len, &prop_val);
           /* use a subpool? */
-          walker(baton, ns_name, ns_len, prop_name, prop_len, prop_val, pool);
+          SVN_ERR(walker(baton, ns_name, ns_len, prop_name, prop_len,
+                         prop_val, pool));
         }
     }
+
+  return SVN_NO_ERROR;
 }
 
 void

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/ra_serf.h?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/ra_serf.h Thu Aug  5 15:07:22 2010
@@ -408,7 +408,7 @@ svn_ra_serf__handle_client_cert_pw(void 
  *
  * If CONTENT_TYPE is not-NULL, it will be sent as the Content-Type header.
  */
-void
+svn_error_t *
 svn_ra_serf__setup_serf_req(serf_request_t *request,
                             serf_bucket_t **req_bkt, serf_bucket_t **hdrs_bkt,
                             svn_ra_serf__connection_t *conn,
@@ -444,19 +444,20 @@ typedef svn_error_t *
                                 apr_pool_t *pool);
 
 /* Callback for when a request body is needed. */
-typedef serf_bucket_t*
-(*svn_ra_serf__request_body_delegate_t)(void *baton,
+typedef svn_error_t *
+(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
+                                        void *baton,
                                         serf_bucket_alloc_t *alloc,
                                         apr_pool_t *pool);
 
 /* Callback for when request headers are needed. */
-typedef apr_status_t
+typedef svn_error_t *
 (*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
                                           void *baton,
                                           apr_pool_t *pool);
 
 /* Callback for when a response has an error. */
-typedef apr_status_t
+typedef svn_error_t *
 (*svn_ra_serf__response_error_t)(serf_request_t *request,
                                  serf_bucket_t *response,
                                  int status_code,
@@ -978,7 +979,7 @@ typedef svn_error_t *
                                  const svn_string_t *val,
                                  apr_pool_t *pool);
 
-void
+svn_error_t *
 svn_ra_serf__walk_all_props(apr_hash_t *props,
                             const char *name,
                             svn_revnum_t rev,

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/replay.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/replay.c Thu Aug  5 15:07:22 2010
@@ -183,9 +183,10 @@ start_replay(svn_ra_serf__xml_parser_t *
       /* Create a pool for the commit editor. */
       ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
       ctx->props = apr_hash_make(ctx->dst_rev_pool);
-      svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
-                                  ctx->revision, svn_ra_serf__set_bare_props,
-                                  ctx->props, ctx->dst_rev_pool);
+      SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
+                                          ctx->revision,
+                                          svn_ra_serf__set_bare_props,
+                                          ctx->props, ctx->dst_rev_pool));
       if (ctx->revstart_func)
         {
           SVN_ERR(ctx->revstart_func(ctx->revision, ctx->replay_baton,
@@ -563,8 +564,9 @@ cdata_replay(svn_ra_serf__xml_parser_t *
   return SVN_NO_ERROR;
 }
 
-static serf_bucket_t *
-create_replay_body(void *baton,
+static svn_error_t *
+create_replay_body(serf_bucket_t **bkt,
+                   void *baton,
                    serf_bucket_alloc_t *alloc,
                    apr_pool_t *pool)
 {
@@ -594,7 +596,8 @@ create_replay_body(void *baton,
 
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "S:replay-report");
 
-  return body_bkt;
+  *bkt = body_bkt;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/serf.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/serf.c Thu Aug  5 15:07:22 2010
@@ -545,8 +545,9 @@ svn_ra_serf__rev_proplist(svn_ra_session
                                       propfind_path, rev, "0", all_props,
                                       pool));
 
-  svn_ra_serf__walk_all_props(props, propfind_path, rev,
-                              svn_ra_serf__set_bare_props, *ret_props, pool);
+  SVN_ERR(svn_ra_serf__walk_all_props(props, propfind_path, rev,
+                                      svn_ra_serf__set_bare_props, *ret_props,
+                                      pool));
 
   return SVN_NO_ERROR;
 }
@@ -805,13 +806,13 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
           return SVN_NO_ERROR;
         }
       else
-        return err;
+        return svn_error_return(err);
     }
 
   entry = apr_pcalloc(pool, sizeof(*entry));
 
-  svn_ra_serf__walk_all_props(props, path, fetched_rev, dirent_walker, entry,
-                              pool);
+  SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev, dirent_walker,
+                                      entry, pool));
 
   *dirent = entry;
 
@@ -924,9 +925,9 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       /* Check if the path is really a directory. */
       SVN_ERR(resource_is_directory (props, path, revision));
 
-      svn_ra_serf__walk_all_props(props, path, revision,
-                                  svn_ra_serf__set_flat_props,
-                                  *ret_props, pool);
+      SVN_ERR(svn_ra_serf__walk_all_props(props, path, revision,
+                                          svn_ra_serf__set_flat_props,
+                                          *ret_props, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/update.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/update.c Thu Aug  5 15:07:22 2010
@@ -563,17 +563,21 @@ close_dir(report_dir_t *dir)
 
   SVN_ERR_ASSERT(! dir->ref_count);
 
-  svn_ra_serf__walk_all_props(dir->props, dir->base_name, dir->base_rev,
-                              set_dir_props, dir, dir->dir_baton_pool);
-
-  svn_ra_serf__walk_all_props(dir->removed_props, dir->base_name,
-                              dir->base_rev, remove_dir_props, dir,
-                              dir->dir_baton_pool);
+  SVN_ERR(svn_ra_serf__walk_all_props(dir->props, dir->base_name,
+                                      dir->base_rev,
+                                      set_dir_props, dir,
+                                      dir->dir_baton_pool));
+
+  SVN_ERR(svn_ra_serf__walk_all_props(dir->removed_props, dir->base_name,
+                                      dir->base_rev, remove_dir_props, dir,
+                                      dir->dir_baton_pool));
 
   if (dir->fetch_props)
     {
-      svn_ra_serf__walk_all_props(dir->props, dir->url, dir->target_rev,
-                                  set_dir_props, dir, dir->dir_baton_pool);
+      SVN_ERR(svn_ra_serf__walk_all_props(dir->props, dir->url,
+                                          dir->target_rev,
+                                          set_dir_props, dir,
+                                          dir->dir_baton_pool));
     }
 
   SVN_ERR(dir->update_editor->close_directory(dir->dir_baton,
@@ -664,7 +668,7 @@ check_lock(report_info_t *info)
     }
 }
 
-static apr_status_t
+static svn_error_t *
 headers_fetch(serf_bucket_t *headers,
               void *baton,
               apr_pool_t *pool)
@@ -685,10 +689,10 @@ headers_fetch(serf_bucket_t *headers,
       serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip");
     }
 
-  return APR_SUCCESS;
+  return SVN_NO_ERROR;
 }
 
-static apr_status_t
+static svn_error_t *
 cancel_fetch(serf_request_t *request,
              serf_bucket_t *response,
              int status_code,
@@ -721,7 +725,7 @@ cancel_fetch(serf_request_t *request,
     }
 
   /* We have no idea what went wrong. */
-  SVN_ERR_MALFUNCTION_NO_RETURN();
+  SVN_ERR_MALFUNCTION();
 }
 
 static svn_error_t *
@@ -937,28 +941,31 @@ handle_fetch(serf_request_t *request,
             check_lock(info);
 
           /* set all of the properties we received */
-          svn_ra_serf__walk_all_props(info->props,
-                                      info->base_name,
-                                      info->base_rev,
-                                      set_file_props,
-                                      info, info->editor_pool);
-          svn_ra_serf__walk_all_props(info->dir->removed_props,
-                                      info->base_name,
-                                      info->base_rev,
-                                      remove_file_props,
-                                      info, info->editor_pool);
-          if (info->fetch_props)
+          err = svn_ra_serf__walk_all_props(info->props,
+                                            info->base_name,
+                                            info->base_rev,
+                                            set_file_props,
+                                            info, info->editor_pool);
+
+          if (!err)
+            err = svn_ra_serf__walk_all_props(info->dir->removed_props,
+                                              info->base_name,
+                                              info->base_rev,
+                                              remove_file_props,
+                                              info, info->editor_pool);
+          if (!err && info->fetch_props)
             {
-              svn_ra_serf__walk_all_props(info->props,
-                                          info->url,
-                                          info->target_rev,
-                                          set_file_props,
-                                          info, info->editor_pool);
+              err = svn_ra_serf__walk_all_props(info->props,
+                                                info->url,
+                                                info->target_rev,
+                                                set_file_props,
+                                                info, info->editor_pool);
             }
 
-          err = info->dir->update_editor->close_file(info->file_baton,
-                                                     info->final_checksum,
-                                                     info->editor_pool);
+          if (!err)
+            err = info->dir->update_editor->close_file(info->file_baton,
+                                                       info->final_checksum,
+                                                       info->editor_pool);
 
           if (err)
             {
@@ -1122,16 +1129,19 @@ handle_propchange_only(report_info_t *in
     check_lock(info);
 
   /* set all of the properties we received */
-  svn_ra_serf__walk_all_props(info->props,
-                              info->base_name, info->base_rev,
-                              set_file_props, info, info->editor_pool);
-  svn_ra_serf__walk_all_props(info->dir->removed_props,
-                              info->base_name, info->base_rev,
-                              remove_file_props, info, info->editor_pool);
+  SVN_ERR(svn_ra_serf__walk_all_props(info->props,
+                                      info->base_name, info->base_rev,
+                                      set_file_props, info,
+                                      info->editor_pool));
+  SVN_ERR(svn_ra_serf__walk_all_props(info->dir->removed_props,
+                                      info->base_name, info->base_rev,
+                                      remove_file_props, info,
+                                      info->editor_pool));
   if (info->fetch_props)
     {
-      svn_ra_serf__walk_all_props(info->props, info->url, info->target_rev,
-                                  set_file_props, info, info->editor_pool);
+      SVN_ERR(svn_ra_serf__walk_all_props(info->props, info->url,
+                                          info->target_rev, set_file_props,
+                                          info, info->editor_pool));
     }
 
   SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
@@ -2203,8 +2213,9 @@ open_connection_if_needed(svn_ra_serf__s
 }
 
 /* Serf callback to create update request body bucket. */
-static serf_bucket_t *
-create_update_report_body(void *baton,
+static svn_error_t *
+create_update_report_body(serf_bucket_t **body_bkt,
+                          void *baton,
                           serf_bucket_alloc_t *alloc,
                           apr_pool_t *pool)
 {
@@ -2214,7 +2225,9 @@ create_update_report_body(void *baton,
   offset = 0;
   apr_file_seek(report->body_file, APR_SET, &offset);
 
-  return serf_bucket_file_create(report->body_file, alloc);
+  *body_bkt = serf_bucket_file_create(report->body_file, alloc);
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -2453,7 +2466,10 @@ abort_report(void *report_baton,
 #if 0
   report_context_t *report = report_baton;
 #endif
-  SVN_ERR_MALFUNCTION();
+
+  /* Should we perform some cleanup here? */
+
+  return SVN_NO_ERROR;
 }
 
 static const svn_ra_reporter3_t ra_serf_reporter = {
@@ -2715,8 +2731,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
       SVN_ERR(svn_ra_serf__retrieve_props(fetch_props, session, conn, fetch_url,
                                           revision, "0", all_props, pool));
 
-      svn_ra_serf__walk_all_props(fetch_props, fetch_url, revision,
-                                  svn_ra_serf__set_flat_props, *props, pool);
+      SVN_ERR(svn_ra_serf__walk_all_props(fetch_props, fetch_url, revision,
+                                          svn_ra_serf__set_flat_props, *props, pool));
     }
 
   if (stream)

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/util.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_ra_serf/util.c Thu Aug  5 15:07:22 2010
@@ -126,25 +126,23 @@ convert_organisation_to_str(apr_hash_t *
                       (char*)apr_hash_get(org, "E", APR_HASH_KEY_STRING));
 }
 
-/* Callback that implements serf_ssl_need_server_cert_t. This function is
-   called on receiving a ssl certificate of a server when opening a https
-   connection. It allows Subversion to override the initial validation done
-   by serf.
+/* This function is called on receiving a ssl certificate of a server when
+   opening a https connection. It allows Subversion to override the initial
+   validation done by serf.
    Serf provides us the @a baton as provided in the call to
    serf_ssl_server_cert_callback_set. The result of serf's initial validation
    of the certificate @a CERT is returned as a bitmask in FAILURES. */
-static apr_status_t
+static svn_error_t *
 ssl_server_cert(void *baton, int failures,
-                const serf_ssl_certificate_t *cert)
+                const serf_ssl_certificate_t *cert,
+                apr_pool_t *scratch_pool)
 {
   svn_ra_serf__connection_t *conn = baton;
-  apr_pool_t *subpool;
   svn_auth_ssl_server_cert_info_t cert_info;
   svn_auth_cred_ssl_server_trust_t *server_creds = NULL;
   svn_auth_iterstate_t *state;
   const char *realmstring;
   apr_uint32_t svn_failures;
-  svn_error_t *err;
   apr_hash_t *issuer, *subject, *serf_cert;
   void *creds;
 
@@ -154,27 +152,25 @@ ssl_server_cert(void *baton, int failure
       return APR_SUCCESS;
     }
 
-  subpool = svn_pool_create(conn->session->pool);
-
   /* Extract the info from the certificate */
-  subject = serf_ssl_cert_subject(cert, subpool);
-  issuer = serf_ssl_cert_issuer(cert, subpool);
-  serf_cert = serf_ssl_cert_certificate(cert, subpool);
+  subject = serf_ssl_cert_subject(cert, scratch_pool);
+  issuer = serf_ssl_cert_issuer(cert, scratch_pool);
+  serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
 
   cert_info.hostname = apr_hash_get(subject, "CN", APR_HASH_KEY_STRING);
   cert_info.fingerprint = apr_hash_get(serf_cert, "sha1", APR_HASH_KEY_STRING);
   if (! cert_info.fingerprint)
-    cert_info.fingerprint = apr_pstrdup(subpool, "<unknown>");
+    cert_info.fingerprint = apr_pstrdup(scratch_pool, "<unknown>");
   cert_info.valid_from = apr_hash_get(serf_cert, "notBefore",
                          APR_HASH_KEY_STRING);
   if (! cert_info.valid_from)
-    cert_info.valid_from = apr_pstrdup(subpool, "[invalid date]");
+    cert_info.valid_from = apr_pstrdup(scratch_pool, "[invalid date]");
   cert_info.valid_until = apr_hash_get(serf_cert, "notAfter",
                           APR_HASH_KEY_STRING);
   if (! cert_info.valid_until)
-    cert_info.valid_until = apr_pstrdup(subpool, "[invalid date]");
-  cert_info.issuer_dname = convert_organisation_to_str(issuer, subpool);
-  cert_info.ascii_cert = serf_ssl_cert_export(cert, subpool);
+    cert_info.valid_until = apr_pstrdup(scratch_pool, "[invalid date]");
+  cert_info.issuer_dname = convert_organisation_to_str(issuer, scratch_pool);
+  cert_info.ascii_cert = serf_ssl_cert_export(cert, scratch_pool);
 
   svn_failures = ssl_convert_serf_failures(failures);
 
@@ -198,32 +194,52 @@ ssl_server_cert(void *baton, int failure
 
   realmstring = construct_realm(conn->session, conn->session->pool);
 
-  err = svn_auth_first_credentials(&creds, &state,
-                                   SVN_AUTH_CRED_SSL_SERVER_TRUST,
-                                   realmstring,
-                                   conn->session->wc_callbacks->auth_baton,
-                                   subpool);
-  if (err || ! creds)
-    {
-      svn_error_clear(err);
-    }
-  else
+  SVN_ERR(svn_auth_first_credentials(&creds, &state,
+                                     SVN_AUTH_CRED_SSL_SERVER_TRUST,
+                                     realmstring,
+                                     conn->session->wc_callbacks->auth_baton,
+                                     scratch_pool));
+  if (creds)
     {
       server_creds = creds;
-      err = svn_auth_save_credentials(state, subpool);
-      if (err)
-        {
-          /* It would be nice to show the error to the user somehow... */
-          svn_error_clear(err);
-        }
+      SVN_ERR(svn_auth_save_credentials(state, scratch_pool));
     }
 
   svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
                          SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO, NULL);
 
+  if (!server_creds)
+    return svn_error_create(SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED, NULL, NULL);
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements serf_ssl_need_server_cert_t for ssl_server_cert */
+static apr_status_t
+ssl_server_cert_cb(void *baton, int failures,
+                const serf_ssl_certificate_t *cert)
+{
+  svn_ra_serf__connection_t *conn = baton;
+  svn_ra_serf__session_t *session = conn->session;
+  apr_pool_t *subpool;
+  svn_error_t *err;
+
+  subpool = svn_pool_create(session->pool);
+  err = ssl_server_cert(baton, failures, cert, subpool);
+
   svn_pool_destroy(subpool);
 
-  return server_creds ? APR_SUCCESS : SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED;
+  if (err || session->pending_error)
+    {
+      session->pending_error = svn_error_compose_create(
+                                                    session->pending_error,
+                                                    err);
+
+      return session->pending_error->apr_err;
+    }
+
+  return APR_SUCCESS;
+
 }
 
 static svn_error_t *
@@ -253,43 +269,28 @@ load_authorities(svn_ra_serf__connection
   return SVN_NO_ERROR;
 }
 
-#if SERF_VERSION_AT_LEAST(0, 4, 0)
-/* This ugly ifdef construction can be cleaned up as soon as serf >= 0.4
-   gets the minimum supported serf version! */
-
-/* svn_ra_serf__conn_setup is a callback for serf. This function
-   creates a read bucket and will wrap the write bucket if SSL
-   is needed. */
-apr_status_t
-svn_ra_serf__conn_setup(apr_socket_t *sock,
-                        serf_bucket_t **read_bkt,
-                        serf_bucket_t **write_bkt,
-                        void *baton,
-                        apr_pool_t *pool)
-{
-#else
-/* This is the old API, for compatibility with serf
-   versions <= 0.3. */
-serf_bucket_t *
-svn_ra_serf__conn_setup(apr_socket_t *sock,
-                        void *baton,
-                        apr_pool_t *pool)
+static svn_error_t *
+conn_setup(apr_socket_t *sock,
+           serf_bucket_t **read_bkt,
+           serf_bucket_t **write_bkt,
+           void *baton,
+           apr_pool_t *pool)
 {
-#endif
-  serf_bucket_t *rb = NULL;
   svn_ra_serf__connection_t *conn = baton;
 
-  rb = serf_context_bucket_socket_create(conn->session->context,
-                                         sock, conn->bkt_alloc);
+  /* While serf < 0.4.0 is supported we should set read_bkt even when
+     we have an error. See svn_ra_serf__conn_setup() */
+  *read_bkt = serf_context_bucket_socket_create(conn->session->context,
+                                               sock, conn->bkt_alloc);
 
   if (conn->using_ssl)
     {
       /* input stream */
-      rb = serf_bucket_ssl_decrypt_create(rb, conn->ssl_context,
-                                          conn->bkt_alloc);
+      *read_bkt = serf_bucket_ssl_decrypt_create(*read_bkt, conn->ssl_context,
+                                                 conn->bkt_alloc);
       if (!conn->ssl_context)
         {
-          conn->ssl_context = serf_bucket_ssl_encrypt_context_get(rb);
+          conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*read_bkt);
 
           serf_ssl_client_cert_provider_set(conn->ssl_context,
                                             svn_ra_serf__handle_client_cert,
@@ -298,7 +299,7 @@ svn_ra_serf__conn_setup(apr_socket_t *so
                                             svn_ra_serf__handle_client_cert_pw,
                                             conn, conn->session->pool);
           serf_ssl_server_cert_callback_set(conn->ssl_context,
-                                            ssl_server_cert,
+                                            ssl_server_cert_cb,
                                             conn);
 
           /* See if the user wants us to trust "default" openssl CAs. */
@@ -309,34 +310,72 @@ svn_ra_serf__conn_setup(apr_socket_t *so
           /* Are there custom CAs to load? */
           if (conn->session->ssl_authorities)
             {
-              svn_error_t *err;
-              err = load_authorities(conn, conn->session->ssl_authorities,
-                                     conn->session->pool);
-              if (err)
-                {
-                  /* TODO: we need a way to pass this error back to the
-                     caller */
-                  svn_error_clear(err);
-                }
+              SVN_ERR(load_authorities(conn, conn->session->ssl_authorities,
+                                       conn->session->pool));
             }
         }
-#if SERF_VERSION_AT_LEAST(0, 4, 0)
+
+    if (write_bkt) /* = Serf >= 0.4.0, see svn_ra_serf__conn_setup() */
       /* output stream */
       *write_bkt = serf_bucket_ssl_encrypt_create(*write_bkt, conn->ssl_context,
                                                   conn->bkt_alloc);
-#endif
-
     }
 
+  return SVN_NO_ERROR;
+}
+
 #if SERF_VERSION_AT_LEAST(0, 4, 0)
-  *read_bkt = rb;
+/* This ugly ifdef construction can be cleaned up as soon as serf >= 0.4
+   gets the minimum supported serf version! */
 
-  return APR_SUCCESS;
-}
+/* svn_ra_serf__conn_setup is a callback for serf. This function
+   creates a read bucket and will wrap the write bucket if SSL
+   is needed. */
+apr_status_t
+svn_ra_serf__conn_setup(apr_socket_t *sock,
+                        serf_bucket_t **read_bkt,
+                        serf_bucket_t **write_bkt,
+                        void *baton,
+                        apr_pool_t *pool)
+{
 #else
+/* This is the old API, for compatibility with serf
+   versions <= 0.3. */
+serf_bucket_t *
+svn_ra_serf__conn_setup(apr_socket_t *sock,
+                        void *baton,
+                        apr_pool_t *pool)
+{
+  serf_bucket_t **write_bkt = NULL;
+  serf_bucket_t *rb = NULL;
+  serf_bucket_t **read_bkt = &rb;
+#endif
+  svn_ra_serf__connection_t *conn = baton;
+  svn_ra_serf__session_t *session = conn->session;
+  apr_status_t status = SVN_NO_ERROR;
+
+  svn_error_t *err = conn_setup(sock,
+                                read_bkt,
+                                write_bkt,
+                                baton,
+                                pool);
+
+  if (err || session->pending_error)
+    {
+      session->pending_error = svn_error_compose_create(
+                                          session->pending_error,
+                                          err);
+
+      status = session->pending_error->apr_err;
+    }
+
+#if ! SERF_VERSION_AT_LEAST(0, 4, 0)
+  SVN_ERR_ASSERT_NO_RETURN(rb != NULL);
   return rb;
-}
+#else
+  return status;
 #endif
+}
 
 serf_bucket_t*
 svn_ra_serf__accept_response(serf_request_t *request,
@@ -370,30 +409,44 @@ accept_head(serf_request_t *request,
   return response;
 }
 
+static svn_error_t *
+connection_closed(serf_connection_t *conn,
+                  svn_ra_serf__connection_t *sc,
+                  apr_status_t why,
+                  apr_pool_t *pool)
+{
+  if (why)
+    {
+      SVN_ERR_MALFUNCTION();
+    }
+
+  if (sc->using_ssl)
+      sc->ssl_context = NULL;
+
+  /* Restart the authentication phase on this new connection. */
+  if (sc->session->auth_protocol)
+    SVN_ERR(sc->session->auth_protocol->init_conn_func(sc->session,
+                                                       sc,
+                                                       sc->session->pool));
+
+  return SVN_NO_ERROR;
+}
+
 void
 svn_ra_serf__conn_closed(serf_connection_t *conn,
                          void *closed_baton,
                          apr_status_t why,
                          apr_pool_t *pool)
 {
-  svn_ra_serf__connection_t *our_conn = closed_baton;
+  svn_ra_serf__connection_t *sc = closed_baton;
+  svn_error_t *err;
 
-  if (why)
-    {
-      SVN_ERR_MALFUNCTION_NO_RETURN();
-    }
+  err = connection_closed(conn, sc, why, pool);
 
-  if (our_conn->using_ssl)
-    {
-      our_conn->ssl_context = NULL;
-    }
-  /* Restart the authentication phase on this new connection. */
-  if (our_conn->session->auth_protocol)
-    {
-      our_conn->session->auth_protocol->init_conn_func(our_conn->session,
-                                                       our_conn,
-                                                       our_conn->session->pool);
-    }
+  if (err)
+    sc->session->pending_error = svn_error_compose_create(
+                                            sc->session->pending_error,
+                                            err);
 }
 
 apr_status_t
@@ -406,13 +459,15 @@ svn_ra_serf__cleanup_serf_session(void *
   return APR_SUCCESS;
 }
 
-apr_status_t svn_ra_serf__handle_client_cert(void *data,
-                                             const char **cert_path)
+/* Implementation of svn_ra_serf__handle_client_cert */
+static svn_error_t *
+handle_client_cert(void *data,
+                   const char **cert_path,
+                   apr_pool_t *pool)
 {
     svn_ra_serf__connection_t *conn = data;
     svn_ra_serf__session_t *session = conn->session;
     const char *realm;
-    svn_error_t *err;
     void *creds;
 
     *cert_path = NULL;
@@ -421,24 +476,18 @@ apr_status_t svn_ra_serf__handle_client_
 
     if (!conn->ssl_client_auth_state)
       {
-        err = svn_auth_first_credentials(&creds,
-                                         &conn->ssl_client_auth_state,
-                                         SVN_AUTH_CRED_SSL_CLIENT_CERT,
-                                         realm,
-                                         session->wc_callbacks->auth_baton,
-                                         session->pool);
+        SVN_ERR(svn_auth_first_credentials(&creds,
+                                           &conn->ssl_client_auth_state,
+                                           SVN_AUTH_CRED_SSL_CLIENT_CERT,
+                                           realm,
+                                           session->wc_callbacks->auth_baton,
+                                           pool));
       }
     else
       {
-        err = svn_auth_next_credentials(&creds,
-                                        conn->ssl_client_auth_state,
-                                        session->pool);
-      }
-
-    if (err)
-      {
-        session->pending_error = err;
-        return err->apr_err;
+        SVN_ERR(svn_auth_next_credentials(&creds,
+                                          conn->ssl_client_auth_state,
+                                          session->pool));
       }
 
     if (creds)
@@ -448,40 +497,58 @@ apr_status_t svn_ra_serf__handle_client_
         *cert_path = client_creds->cert_file;
       }
 
-    return APR_SUCCESS;
+    return SVN_NO_ERROR;
 }
 
-apr_status_t svn_ra_serf__handle_client_cert_pw(void *data,
-                                                const char *cert_path,
-                                                const char **password)
+/* Implements serf_ssl_need_client_cert_t for handle_client_cert */
+apr_status_t svn_ra_serf__handle_client_cert(void *data,
+                                             const char **cert_path)
+{
+  svn_ra_serf__connection_t *conn = data;
+  svn_ra_serf__session_t *session = conn->session;
+  svn_error_t *err = handle_client_cert(data,
+                                        cert_path,
+                                        session->pool);
+
+  if (err || session->pending_error)
+    {
+      session->pending_error = svn_error_compose_create(
+                                                    session->pending_error,
+                                                    err);
+
+      return session->pending_error->apr_err;
+    }
+
+  return APR_SUCCESS;
+}
+
+/* Implementation for svn_ra_serf__handle_client_cert_pw */
+static svn_error_t *
+handle_client_cert_pw(void *data,
+                      const char *cert_path,
+                      const char **password,
+                      apr_pool_t *pool)
 {
     svn_ra_serf__connection_t *conn = data;
     svn_ra_serf__session_t *session = conn->session;
-    svn_error_t *err;
     void *creds;
 
     *password = NULL;
 
     if (!conn->ssl_client_pw_auth_state)
       {
-        err = svn_auth_first_credentials(&creds,
-                                         &conn->ssl_client_pw_auth_state,
-                                         SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
-                                         cert_path,
-                                         session->wc_callbacks->auth_baton,
-                                         session->pool);
+        SVN_ERR(svn_auth_first_credentials(&creds,
+                                           &conn->ssl_client_pw_auth_state,
+                                           SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
+                                           cert_path,
+                                           session->wc_callbacks->auth_baton,
+                                           pool));
       }
     else
       {
-        err = svn_auth_next_credentials(&creds,
-                                        conn->ssl_client_pw_auth_state,
-                                        session->pool);
-      }
-
-    if (err)
-      {
-        session->pending_error = err;
-        return err->apr_err;
+        SVN_ERR(svn_auth_next_credentials(&creds,
+                                          conn->ssl_client_pw_auth_state,
+                                          pool));
       }
 
     if (creds)
@@ -494,7 +561,32 @@ apr_status_t svn_ra_serf__handle_client_
     return APR_SUCCESS;
 }
 
-void
+/* Implements serf_ssl_need_client_cert_pw_t for handle_client_cert_pw */
+apr_status_t svn_ra_serf__handle_client_cert_pw(void *data,
+                                                const char *cert_path,
+                                                const char **password)
+{
+  svn_ra_serf__connection_t *conn = data;
+  svn_ra_serf__session_t *session = conn->session;
+  svn_error_t *err = handle_client_cert_pw(data,
+                                           cert_path,
+                                           password,
+                                           session->pool);
+
+  if (err || session->pending_error)
+    {
+      session->pending_error = svn_error_compose_create(
+                                          session->pending_error,
+                                          err);
+
+      return session->pending_error->apr_err;
+    }
+
+  return APR_SUCCESS;
+}
+
+
+svn_error_t *
 svn_ra_serf__setup_serf_req(serf_request_t *request,
                             serf_bucket_t **req_bkt,
                             serf_bucket_t **ret_hdrs_bkt,
@@ -527,13 +619,15 @@ svn_ra_serf__setup_serf_req(serf_request
 
   /* Setup server authorization headers */
   if (conn->session->auth_protocol)
-    conn->session->auth_protocol->setup_request_func(conn, method, url,
-                                                     hdrs_bkt);
+    SVN_ERR(conn->session->auth_protocol->setup_request_func(conn, method, url,
+                                                             hdrs_bkt));
 
   /* Setup proxy authorization headers */
   if (conn->session->proxy_auth_protocol)
-    conn->session->proxy_auth_protocol->setup_request_func(conn, method,
-                                                           url, hdrs_bkt);
+    SVN_ERR(conn->session->proxy_auth_protocol->setup_request_func(conn,
+                                                                   method,
+                                                                   url,
+                                                                   hdrs_bkt));
 
 #if ! SERF_VERSION_AT_LEAST(0, 4, 0)
   /* Set up SSL if we need to */
@@ -559,6 +653,8 @@ svn_ra_serf__setup_serf_req(serf_request
     {
       *ret_hdrs_bkt = hdrs_bkt;
     }
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -1269,18 +1365,20 @@ svn_ra_serf__credentials_callback(char *
   return APR_SUCCESS;
 }
 
-/* Implements the serf_response_handler_t interface.  Wait for HTTP
-   response status and headers, and invoke CTX->response_handler() to
-   carry out operation-specific processing.  Afterwards, check for
-   connection close.
+/* Wait for HTTP response status and headers, and invoke CTX->
+   response_handler() to carry out operation-specific processing.
+   Afterwards, check for connection close.
+
+   SERF_STATUS allows returning errors to serf without creating a
+   subversion error object.
    */
-static apr_status_t
+static svn_error_t *
 handle_response(serf_request_t *request,
                 serf_bucket_t *response,
-                void *baton,
+                svn_ra_serf__handler_t *ctx,
+                apr_status_t *serf_status,
                 apr_pool_t *pool)
 {
-  svn_ra_serf__handler_t *ctx = baton;
   serf_status_line sl;
   apr_status_t status;
 
@@ -1288,14 +1386,8 @@ handle_response(serf_request_t *request,
     {
       /* Uh-oh.  Our connection died.  Requeue. */
       if (ctx->response_error)
-        {
-          status = ctx->response_error(request, response, 0,
-                                       ctx->response_error_baton);
-          if (status)
-            {
-              goto cleanup;
-            }
-        }
+        SVN_ERR(ctx->response_error(request, response, 0,
+                                    ctx->response_error_baton));
 
       svn_ra_serf__request_create(ctx);
 
@@ -1305,12 +1397,14 @@ handle_response(serf_request_t *request,
   status = serf_bucket_response_status(response, &sl);
   if (SERF_BUCKET_READ_ERROR(status))
     {
-      return status;
+      *serf_status = status;
+      return SVN_NO_ERROR; /* Handled by serf */
     }
   if (!sl.version && (APR_STATUS_IS_EOF(status) ||
                       APR_STATUS_IS_EAGAIN(status)))
     {
-      goto cleanup;
+      *serf_status = status;
+      return SVN_NO_ERROR; /* Handled by serf */
     }
 
   status = serf_bucket_response_wait_for_headers(response);
@@ -1318,7 +1412,8 @@ handle_response(serf_request_t *request,
     {
       if (!APR_STATUS_IS_EOF(status))
         {
-          goto cleanup;
+          *serf_status = status;
+          return SVN_NO_ERROR;
         }
 
       /* Cases where a lack of a response body (via EOF) is okay:
@@ -1331,7 +1426,7 @@ handle_response(serf_request_t *request,
        */
       if (strcmp(ctx->method, "HEAD") != 0 && sl.code != 204 && sl.code != 304)
         {
-          ctx->session->pending_error =
+          svn_error_t *err =
               svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
                                 svn_error_compose_create(
                                            ctx->session->pending_error,
@@ -1341,16 +1436,14 @@ handle_response(serf_request_t *request,
           /* This discard may be no-op, but let's preserve the algorithm
              used elsewhere in this function for clarity's sake. */
           svn_ra_serf__response_discard_handler(request, response, NULL, pool);
-          status = ctx->session->pending_error->apr_err;
-          goto cleanup;
+          return err;
         }
     }
 
   if (ctx->conn->last_status_code == 401 && sl.code < 400)
     {
-      svn_error_clear(
-           svn_auth_save_credentials(ctx->session->auth_state,
-                                     ctx->session->pool));
+      SVN_ERR(svn_auth_save_credentials(ctx->session->auth_state,
+                                        ctx->session->pool));
       ctx->session->auth_attempts = 0;
       ctx->session->auth_state = NULL;
       ctx->session->realm = NULL;
@@ -1361,49 +1454,38 @@ handle_response(serf_request_t *request,
   if (sl.code == 401 || sl.code == 407)
     {
       /* 401 Authorization or 407 Proxy-Authentication required */
-      svn_error_t *err;
       status = svn_ra_serf__response_discard_handler(request, response, NULL, pool);
 
       /* Don't bother handling the authentication request if the response
          wasn't received completely yet. Serf will call handle_response
          again when more data is received. */
-      if (! APR_STATUS_IS_EAGAIN(status))
-        {
-          err = svn_ra_serf__handle_auth(sl.code, ctx,
-                                         request, response, pool);
-          if (err)
-            {
-              ctx->session->pending_error = svn_error_compose_create(
-                                                  err,
-                                                  ctx->session->pending_error);
-              status = ctx->session->pending_error->apr_err;
-              goto cleanup;
-            }
-
-          svn_ra_serf__priority_request_create(ctx);
-          return status;
-        }
-      else
+      if (APR_STATUS_IS_EAGAIN(status))
         {
-          return status;
+          *serf_status = status;
+          return SVN_NO_ERROR;
         }
+
+      SVN_ERR(svn_ra_serf__handle_auth(sl.code, ctx,
+                                       request, response, pool));
+
+      svn_ra_serf__priority_request_create(ctx);
+
+      return SVN_NO_ERROR;
     }
   else if (sl.code == 409 || sl.code >= 500)
     {
       /* 409 Conflict: can indicate a hook error.
          5xx (Internal) Server error. */
-      ctx->session->pending_error = svn_error_compose_create(
-                 svn_ra_serf__handle_server_error(request, response, pool),
-                 ctx->session->pending_error);
+      SVN_ERR(svn_ra_serf__handle_server_error(request, response, pool));
 
       if (!ctx->session->pending_error)
         {
-          ctx->session->pending_error =
+          return
               svn_error_createf(APR_EGENERAL, NULL,
               _("Unspecified error message: %d %s"), sl.code, sl.reason);
         }
-      status = ctx->session->pending_error->apr_err;
-      goto cleanup;
+
+      return SVN_NO_ERROR; /* Error is set in caller */
     }
   else
     {
@@ -1425,56 +1507,72 @@ handle_response(serf_request_t *request,
             {
               svn_ra_serf__response_discard_handler(request, response, NULL,
                                                     pool);
-              ctx->session->pending_error = err;
-              status = ctx->session->pending_error->apr_err;
-              goto cleanup;
+              /* Ignore serf status code, just return the real error */
+
+              return svn_error_return(err);
             }
         }
 
       err = ctx->response_handler(request,response, ctx->response_baton, pool);
 
-      if (err)
-        {
-          status = err->apr_err;
-          if (!SERF_BUCKET_READ_ERROR(err->apr_err))
-            {
-              /* These errors are special cased in serf
-                 ### We hope no handler returns these by accident. */
-              svn_error_clear(err);
-            }
-          else
-            {
-              ctx->session->pending_error =
-                       svn_error_return(svn_error_compose_create(
-                                                       err,
-                                                       ctx->session->pending_error));
-            }
+      if (err
+          && (!SERF_BUCKET_READ_ERROR(err->apr_err)
+               || APR_STATUS_IS_ECONNRESET(err->apr_err)))
+        {
+          /* These errors are special cased in serf
+             ### We hope no handler returns these by accident. */
+          *serf_status = err->apr_err;
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
         }
+
+      return svn_error_return(err);
     }
+}
 
-cleanup:
 
-  return status;
+/* Implements serf_response_handler_t for handle_response. Storing
+   errors in ctx->session->pending_error if appropriate. */
+static apr_status_t
+handle_response_cb(serf_request_t *request,
+                   serf_bucket_t *response,
+                   void *baton,
+                   apr_pool_t *pool)
+{
+  svn_ra_serf__handler_t *ctx = baton;
+  svn_ra_serf__session_t *session = ctx->session;
+  svn_error_t *err;
+  apr_status_t serf_status = APR_SUCCESS;
+
+  err = svn_error_return(
+          handle_response(request, response, ctx, &serf_status, pool));
+
+  if (err || session->pending_error)
+    {
+      session->pending_error = svn_error_compose_create(session->pending_error,
+                                                        err);
+
+      serf_status = session->pending_error->apr_err;
+    }
+
+  return serf_status;
 }
 
-/* Implements the serf_request_setup_t interface (which sets up both a
-   request and its response handler callback).  If the CTX->setup()
-   callback is non-NULL, invoke it to carry out the majority of the
-   serf_request_setup_t implementation.  Otherwise, perform default
-   setup, with special handling for HEAD requests, and finer-grained
+/* If the CTX->setup() callback is non-NULL, invoke it to carry out the
+   majority of the serf_request_setup_t implementation.  Otherwise, perform
+   default setup, with special handling for HEAD requests, and finer-grained
    callbacks invoked (if non-NULL) to produce the request headers and
    body. */
-static apr_status_t
+static svn_error_t *
 setup_request(serf_request_t *request,
-              void *setup_baton,
-              serf_bucket_t **req_bkt,
-              serf_response_acceptor_t *acceptor,
-              void **acceptor_baton,
-              serf_response_handler_t *handler,
-              void **handler_baton,
-              apr_pool_t *pool)
+                 svn_ra_serf__handler_t *ctx,
+                 serf_bucket_t **req_bkt,
+                 serf_response_acceptor_t *acceptor,
+                 void **acceptor_baton,
+                 serf_response_handler_t *handler,
+                 void **handler_baton,
+                 apr_pool_t *pool)
 {
-  svn_ra_serf__handler_t *ctx = setup_baton;
   serf_bucket_t *headers_bkt;
 
   *acceptor = svn_ra_serf__accept_response;
@@ -1484,17 +1582,11 @@ setup_request(serf_request_t *request,
     {
       svn_ra_serf__response_handler_t response_handler;
       void *response_baton;
-      svn_error_t *error;
 
-      error = ctx->setup(request, ctx->setup_baton, req_bkt,
-                          acceptor, acceptor_baton,
-                          &response_handler, &response_baton,
-                          pool);
-      if (error)
-        {
-          ctx->session->pending_error = error;
-          return error->apr_err;
-        }
+      SVN_ERR(ctx->setup(request, ctx->setup_baton, req_bkt,
+                         acceptor, acceptor_baton,
+                         &response_handler, &response_baton,
+                         pool));
 
       ctx->response_handler = response_handler;
       ctx->response_baton = response_baton;
@@ -1511,42 +1603,77 @@ setup_request(serf_request_t *request,
 
       if (ctx->body_delegate)
         {
-          body_bkt =
-              ctx->body_delegate(ctx->body_delegate_baton, bkt_alloc, pool);
+          SVN_ERR(ctx->body_delegate(&body_bkt, 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,
-                                  body_bkt, ctx->body_type);
+      SVN_ERR(svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt,
+                                          ctx->conn, ctx->method, ctx->path,
+                                          body_bkt, ctx->body_type));
 
       if (ctx->header_delegate)
         {
-          ctx->header_delegate(headers_bkt, ctx->header_delegate_baton, pool);
+          SVN_ERR(ctx->header_delegate(headers_bkt, ctx->header_delegate_baton,
+                                       pool));
         }
     }
 
-  *handler = handle_response;
+  *handler = handle_response_cb;
   *handler_baton = ctx;
 
   return APR_SUCCESS;
 }
 
+/* Implements the serf_request_setup_t interface (which sets up both a
+   request and its response handler callback). Handles errors for
+   setup_request_cb */
+static apr_status_t
+setup_request_cb(serf_request_t *request,
+              void *setup_baton,
+              serf_bucket_t **req_bkt,
+              serf_response_acceptor_t *acceptor,
+              void **acceptor_baton,
+              serf_response_handler_t *handler,
+              void **handler_baton,
+              apr_pool_t *pool)
+{
+  svn_ra_serf__handler_t *ctx = setup_baton;
+  svn_error_t *err;
+
+  err = setup_request(request, ctx,
+                      req_bkt,
+                      acceptor, acceptor_baton,
+                      handler, handler_baton,
+                      pool);
+
+  if (err)
+    {
+      ctx->session->pending_error 
+                = svn_error_compose_create(ctx->session->pending_error,
+                                           err);
+
+      return err->apr_err;
+    }
+
+  return APR_SUCCESS;
+}
+
 serf_request_t *
 svn_ra_serf__request_create(svn_ra_serf__handler_t *handler)
 {
   return serf_connection_request_create(handler->conn->conn,
-                                        setup_request, handler);
+                                        setup_request_cb, handler);
 }
 
 serf_request_t *
 svn_ra_serf__priority_request_create(svn_ra_serf__handler_t *handler)
 {
   return serf_connection_priority_request_create(handler->conn->conn,
-                                                 setup_request, handler);
+                                                 setup_request_cb, handler);
 }
 
 svn_error_t *

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_crawler.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_crawler.c Thu Aug  5 15:07:22 2010
@@ -60,12 +60,16 @@
    last-commit-time.  Either way, set entry-timestamp to match that of
    the working file when all is finished.
 
+   If REMOVE_TEXT_CONFLICT is TRUE, remove an existing text conflict
+   from LOCAL_ABSPATH.
+
    Not that a valid access baton with a write lock to the directory of
    LOCAL_ABSPATH must be available in DB.*/
 static svn_error_t *
 restore_file(svn_wc__db_t *db,
              const char *local_abspath,
              svn_boolean_t use_commit_times,
+             svn_boolean_t remove_text_conflicts,
              apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_item;
@@ -87,8 +91,77 @@ restore_file(svn_wc__db_t *db,
                          scratch_pool));
 
   /* Remove any text conflict */
-  return svn_error_return(svn_wc__resolve_text_conflict(db, local_abspath,
+  if (remove_text_conflicts)
+    SVN_ERR(svn_wc__resolve_text_conflict(db, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_restore(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_boolean_t use_commit_times,
+               apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
+  svn_node_kind_t disk_kind;
+
+  SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
+
+  if (disk_kind != svn_node_none)
+    return svn_error_createf(SVN_ERR_WC_PATH_FOUND, NULL,
+                             _("The existing node '%s' can not be restored."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+
+
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  switch (status)
+    {
+      case svn_wc__db_status_added:
+        SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL,
+                                         wc_ctx->db, local_abspath,
+                                         scratch_pool, scratch_pool));
+        if (status != svn_wc__db_status_added)
+          break; /* Has pristine version */
+      case svn_wc__db_status_deleted:
+      case svn_wc__db_status_not_present:
+      case svn_wc__db_status_absent:
+      case svn_wc__db_status_excluded:
+#ifndef SVN_WC__SINGLE_DB
+      case svn_wc__db_status_obstructed:
+      case svn_wc__db_status_obstructed_add:
+      case svn_wc__db_status_obstructed_delete:
+#endif
+        return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                 _("The node '%s' can not be restored."),
+                                 svn_dirent_local_style(local_abspath,
                                                         scratch_pool));
+    }
+
+  if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
+    SVN_ERR(restore_file(wc_ctx->db, local_abspath, use_commit_times, FALSE,
+                         scratch_pool));
+  else
+#ifdef SVN_WC__SINGLE_DB
+    SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
+#else
+     return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                 _("The node '%s' can not be restored."),
+                                 svn_dirent_local_style(local_abspath,
+                                                        scratch_pool));
+#endif
+
+  return SVN_NO_ERROR;
 }
 
 /* Try to restore LOCAL_ABSPATH of node type KIND and if successfull,
@@ -116,7 +189,7 @@ restore_node(svn_boolean_t *restored,
   if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
     {
       /* Recreate file from text-base */
-      SVN_ERR(restore_file(db, local_abspath, use_commit_times,
+      SVN_ERR(restore_file(db, local_abspath, use_commit_times, TRUE,
                            scratch_pool));
 
       *restored = TRUE;

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_files.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_files.c Thu Aug  5 15:07:22 2010
@@ -609,7 +609,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
   SVN_ERR_ASSERT(repos_uuid != NULL);
   SVN_ERR_ASSERT(svn_uri_is_ancestor(repos_root_url, url));
 
-  SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__internal_check_wc(&format, db, local_abspath, TRUE,
+                                    scratch_pool));
 
   repos_relpath = svn_uri_is_child(repos_root_url, url, scratch_pool);
   if (repos_relpath == NULL)

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_ops.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/adm_ops.c Thu Aug  5 15:07:22 2010
@@ -1021,7 +1021,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
       {
         return
           svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, err,
-                            _("Can't find parent directory's entry while"
+                            _("Can't find parent directory's node while"
                               " trying to add '%s'"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
@@ -1534,6 +1534,9 @@ revert_entry(svn_depth_t *depth,
         }
       else if (kind == svn_wc__db_kind_dir)
         {
+#ifndef SVN_WC__SINGLE_DB
+          /* Before single-db we didn't have to perform a recursive delete
+             here. With single-db we really must delete missing nodes */
           if (disk_kind == svn_node_none
               || svn_wc__adm_missing(db, local_abspath, pool))
             {
@@ -1547,6 +1550,7 @@ revert_entry(svn_depth_t *depth,
                                                       pool));
             }
           else
+#endif
             {
               SVN_ERR(svn_wc__internal_remove_from_revision_control(
                                            db,
@@ -2045,15 +2049,16 @@ svn_wc__internal_remove_from_revision_co
         }
 
     }  /* done with file case */
+#ifndef SVN_WC__SINGLE_DB
   else if (svn_wc__adm_missing(db, local_abspath, scratch_pool))
     {
-      /* The directory is missing  so don't try to recurse,
-         just delete the entry in the parent directory.
-
-         ### This case disappears after we move to one DB. */
+      /* The directory is missing  so don't try to recurse, in
+         not existing administrative data, just delete the
+         entry in the parent directory. */
       SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
                                               scratch_pool));
     }
+#endif
   else /* looking at THIS_DIR */
     {
       apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -2076,7 +2081,10 @@ svn_wc__internal_remove_from_revision_co
 
           entry_abspath = svn_dirent_join(local_abspath, entry_name, iterpool);
 
-          /* ### where did the adm_missing and depth_exclude test go?!?  */
+          /* ### where did the adm_missing and depth_exclude test go?!? 
+
+             ### BH: depth exclude is handled by hidden and missing is ok
+                     for this temp_op. */
 
           SVN_ERR(svn_wc__db_node_hidden(&hidden, db, entry_abspath,
                                          iterpool));

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/ambient_depth_filter_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/ambient_depth_filter_editor.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/ambient_depth_filter_editor.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/ambient_depth_filter_editor.c Thu Aug  5 15:07:22 2010
@@ -96,6 +96,7 @@ struct edit_baton
   svn_wc__db_t *db;
   const char *anchor_abspath;
   const char *target;
+  svn_boolean_t read_base;
 };
 
 struct file_baton
@@ -114,6 +115,72 @@ struct dir_baton
   void *wrapped_baton;
 };
 
+/* Helper to call either svn_wc__db_base_get_info or svn_wc__db_read_info for
+   obtaining information for the ambient depth editor */
+static svn_error_t *
+ambient_read_info(svn_boolean_t *hidden,
+                  svn_wc__db_status_t *status,
+                  svn_wc__db_kind_t *kind,
+                  svn_depth_t *depth,
+                  svn_wc__db_t *db,
+                  const char *local_abspath,
+                  svn_boolean_t read_base,
+                  apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+  svn_wc__db_status_t status_p;
+
+  SVN_ERR_ASSERT(kind != NULL);
+
+  if (hidden)
+    {
+      *hidden = FALSE;
+
+      if (!status)
+        status = &status_p;
+    }
+
+  if (read_base)
+    err = svn_wc__db_base_get_info(status, kind, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, depth, NULL, NULL,
+                                   NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool);
+  else
+    err = svn_wc__db_read_info(status, kind, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, depth, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL,
+                               db, local_abspath, scratch_pool, scratch_pool);
+
+
+  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+    {
+      svn_error_clear(err);
+
+      *kind = svn_wc__db_kind_unknown;
+      if (status)
+        *status = svn_wc__db_status_normal;
+      if (depth)
+        *depth = svn_depth_unknown;
+
+      return SVN_NO_ERROR;
+    }
+  else
+    SVN_ERR(err);
+
+  if (hidden)
+    switch (*status)
+      {
+        case svn_wc__db_status_not_present:
+        case svn_wc__db_status_absent:
+        case svn_wc__db_status_excluded:
+          *hidden = TRUE;
+      }
+
+  return SVN_NO_ERROR;
+}
+
 /* */
 static svn_error_t *
 make_dir_baton(struct dir_baton **d_p,
@@ -148,8 +215,8 @@ make_dir_baton(struct dir_baton **d_p,
     {
       const char *abspath;
       svn_boolean_t exclude;
-      svn_error_t *err;
       svn_wc__db_status_t status;
+      svn_wc__db_kind_t kind;
       svn_boolean_t exists = TRUE;
 
       abspath = svn_dirent_join(eb->anchor_abspath,
@@ -157,19 +224,10 @@ make_dir_baton(struct dir_baton **d_p,
                                                          path),
                                 pool);
 
-      err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL,
-                                 eb->db, abspath, pool, pool);
+      SVN_ERR(ambient_read_info(NULL, &status, &kind, NULL,
+                                eb->db, abspath, eb->read_base, pool));
 
-      if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        {
-          svn_error_clear(err);
-          exists = FALSE;
-        }
-      else
-        SVN_ERR(err);
+      exists = (kind != svn_wc__db_kind_unknown);
 
       if (pb->ambient_depth == svn_depth_empty
           || pb->ambient_depth == svn_depth_files)
@@ -213,6 +271,10 @@ make_file_baton(struct file_baton **f_p,
 {
   struct file_baton *f = apr_pcalloc(pool, sizeof(*f));
   struct edit_baton *eb = pb->edit_baton;
+  svn_wc__db_status_t status;
+  svn_wc__db_kind_t kind;
+  svn_boolean_t hidden;
+  const char *abspath;
 
   SVN_ERR_ASSERT(path);
 
@@ -223,31 +285,22 @@ make_file_baton(struct file_baton **f_p,
       return SVN_NO_ERROR;
     }
 
+  abspath = svn_dirent_join(eb->anchor_abspath,
+                            svn_dirent_skip_ancestor(eb->anchor_abspath,
+                                                     path),
+                            pool);
+
+  SVN_ERR(ambient_read_info(&hidden, &status, &kind, NULL,
+                            eb->db, abspath, eb->read_base, pool));
+
   if (pb->ambient_depth == svn_depth_empty)
     {
       /* This is not a depth upgrade, and the parent directory is
          depth==empty.  So if the parent doesn't
          already have an entry for the file, then the parent
          doesn't want to hear about the file at all. */
-      svn_wc__db_kind_t kind;
-      svn_boolean_t unavailable = FALSE;
-      const char *abspath;
-
-      abspath = svn_dirent_join(eb->anchor_abspath,
-                                svn_dirent_skip_ancestor(eb->anchor_abspath,
-                                                         path),
-                                pool);
-
-      SVN_ERR(svn_wc__db_read_kind(&kind, pb->edit_baton->db, abspath, TRUE,
-                                   pool));
-
-      if (kind == svn_wc__db_kind_unknown)
-        unavailable = TRUE;
-      else
-        SVN_ERR(svn_wc__db_node_hidden(&unavailable, pb->edit_baton->db,
-                                       abspath, pool));
-
-      if (unavailable)
+      
+      if (hidden || kind == svn_wc__db_kind_unknown)
         {
           f->ambiently_excluded = TRUE;
           *f_p = f;
@@ -255,6 +308,16 @@ make_file_baton(struct file_baton **f_p,
         }
     }
 
+  /* If pb->ambient_depth == svn_depth_unknown we are pulling
+     in new nodes */
+  if (pb->ambient_depth != svn_depth_unknown
+      && status == svn_wc__db_status_excluded)
+    {
+      f->ambiently_excluded = TRUE;
+      *f_p = f;
+      return SVN_NO_ERROR;
+    }
+
   f->edit_baton = pb->edit_baton;
 
   *f_p = f;
@@ -296,28 +359,17 @@ open_root(void *edit_baton,
   if (! *eb->target)
     {
       /* For an update with a NULL target, this is equivalent to open_dir(): */
+      svn_wc__db_kind_t kind;
       svn_boolean_t hidden;
-      svn_error_t *err;
+      svn_depth_t depth;
 
       /* Read the depth from the entry. */
-      err = svn_wc__db_node_hidden(&hidden, eb->db, eb->anchor_abspath, pool);
-
-      if (!err && !hidden)
-        {
-          svn_depth_t depth;
-          SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, &depth, NULL,
-                                       NULL, NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL, NULL,
-                                       eb->db, eb->anchor_abspath,
-                                       pool, pool));
+      SVN_ERR(ambient_read_info(&hidden, NULL, &kind, &depth,
+                                eb->db, eb->anchor_abspath, eb->read_base,
+                                pool));
 
+      if (kind != svn_wc__db_kind_unknown && !hidden)
           b->ambient_depth = depth;
-        }
-      else if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        svn_error_clear(err);
-      else
-        SVN_ERR(err);
     }
 
   return eb->wrapped_editor->open_root(eb->wrapped_edit_baton, base_revision,
@@ -351,13 +403,11 @@ delete_entry(const char *path,
                                                          path),
                                 pool);
 
-      SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, abspath, TRUE, pool));
+      SVN_ERR(ambient_read_info(&hidden, NULL, &kind, NULL,
+                                eb->db, abspath, eb->read_base, pool));
 
-      if (kind == svn_wc__db_kind_unknown)
-        return SVN_NO_ERROR;
-
-      SVN_ERR(svn_wc__db_node_hidden(&hidden, eb->db, abspath, pool));
-      if (hidden)
+      if (kind == svn_wc__db_kind_unknown
+          || hidden)
         return SVN_NO_ERROR;
     }
 
@@ -423,8 +473,9 @@ open_directory(const char *path,
   struct edit_baton *eb = pb->edit_baton;
   struct dir_baton *b;
   const char *local_abspath;
+  svn_wc__db_kind_t kind;
   svn_boolean_t hidden;
-  svn_error_t *err;
+  svn_depth_t depth;
 
   SVN_ERR(make_dir_baton(&b, path, eb, pb, pool));
   *child_baton = b;
@@ -445,22 +496,14 @@ open_directory(const char *path,
                                   pool);
 
 
-  err = svn_wc__db_node_hidden(&hidden, eb->db, local_abspath, pool);
+  SVN_ERR(ambient_read_info(&hidden, NULL, &kind, &depth,
+                            eb->db, local_abspath, eb->read_base, pool));
 
-  if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) ||
-      hidden)
+  if (kind != svn_wc__db_kind_unknown
+      && !hidden)
     {
-      svn_error_clear(err);
-      return SVN_NO_ERROR;
+      b->ambient_depth = depth;
     }
-  else
-    SVN_ERR(err);
-
-  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, &b->ambient_depth, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               eb->db, local_abspath, pool, pool));
 
   return SVN_NO_ERROR;
 }
@@ -642,19 +685,20 @@ close_edit(void *edit_baton,
 svn_error_t *
 svn_wc__ambient_depth_filter_editor(const svn_delta_editor_t **editor,
                                     void **edit_baton,
-                                    const svn_delta_editor_t *wrapped_editor,
-                                    void *wrapped_edit_baton,
+                                    svn_wc__db_t *db,
                                     const char *anchor_abspath,
                                     const char *target,
-                                    svn_wc__db_t *db,
-                                    apr_pool_t *pool)
+                                    svn_boolean_t read_base,
+                                    const svn_delta_editor_t *wrapped_editor,
+                                    void *wrapped_edit_baton,
+                                    apr_pool_t *result_pool)
 {
   svn_delta_editor_t *depth_filter_editor;
   struct edit_baton *eb;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
 
-  depth_filter_editor = svn_delta_default_editor(pool);
+  depth_filter_editor = svn_delta_default_editor(result_pool);
   depth_filter_editor->set_target_revision = set_target_revision;
   depth_filter_editor->open_root = open_root;
   depth_filter_editor->delete_entry = delete_entry;
@@ -671,12 +715,13 @@ svn_wc__ambient_depth_filter_editor(cons
   depth_filter_editor->absent_file = absent_file;
   depth_filter_editor->close_edit = close_edit;
 
-  eb = apr_palloc(pool, sizeof(*eb));
+  eb = apr_pcalloc(result_pool, sizeof(*eb));
   eb->wrapped_editor = wrapped_editor;
   eb->wrapped_edit_baton = wrapped_edit_baton;
   eb->db = db;
   eb->anchor_abspath = anchor_abspath;
   eb->target = target;
+  eb->read_base = read_base;
 
   *editor = depth_filter_editor;
   *edit_baton = eb;

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/deprecated.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/deprecated.c Thu Aug  5 15:07:22 2010
@@ -2330,12 +2330,29 @@ svn_wc_props_modified_p(svn_boolean_t *m
                         svn_wc_adm_access_t *adm_access,
                         apr_pool_t *pool)
 {
-  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
+  svn_wc_context_t *wc_ctx;
   const char *local_abspath;
+  svn_error_t *err;
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+  SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
+                                         svn_wc__adm_get_db(adm_access), pool));
+
+  err = svn_wc_props_modified_p2(modified_p,
+                                 wc_ctx,
+                                 local_abspath,
+                                 pool);
 
-  return svn_wc__props_modified(modified_p, db, local_abspath, pool);
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_return(err);
+
+      svn_error_clear(err);
+      *modified_p = FALSE;
+    }
+
+  return svn_error_return(svn_wc_context_destroy(wc_ctx));
 }
 
 

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/diff.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/diff.c Thu Aug  5 15:07:22 2010
@@ -1864,11 +1864,12 @@ svn_wc_get_diff_editor6(const svn_delta_
   if (depth == svn_depth_unknown)
     SVN_ERR(svn_wc__ambient_depth_filter_editor(&inner_editor,
                                                 &inner_baton,
-                                                inner_editor,
-                                                inner_baton,
+                                                wc_ctx->db,
                                                 anchor_abspath,
                                                 target,
-                                                wc_ctx->db,
+                                                FALSE /* read_base */,
+                                                inner_editor,
+                                                inner_baton,
                                                 result_pool));
 
   return svn_delta_get_cancellation_editor(cancel_func,

Modified: subversion/branches/issue-2779-dev/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-2779-dev/subversion/libsvn_wc/lock.c?rev=982653&r1=982652&r2=982653&view=diff
==============================================================================
--- subversion/branches/issue-2779-dev/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/issue-2779-dev/subversion/libsvn_wc/lock.c Thu Aug  5 15:07:22 2010
@@ -109,6 +109,7 @@ svn_error_t *
 svn_wc__internal_check_wc(int *wc_format,
                           svn_wc__db_t *db,
                           const char *local_abspath,
+                          svn_boolean_t check_path,
                           apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
@@ -143,6 +144,68 @@ svn_wc__internal_check_wc(int *wc_format
         }
     }
 
+#ifdef SVN_WC__SINGLE_DB
+    if (*wc_format >= SVN_WC__WC_NG_VERSION)
+      {
+        svn_error_t *err;
+        svn_wc__db_status_t db_status;
+        svn_wc__db_kind_t db_kind;
+
+        if (check_path)
+          {
+            /* If a node is not a directory, it is not a working copy directory.
+               This allows creating new working copies as a path below an existing
+               working copy.
+             */
+            svn_node_kind_t wc_kind;
+
+            SVN_ERR(svn_io_check_path(local_abspath, &wc_kind, scratch_pool));
+            if (wc_kind != svn_node_dir)
+              {
+                *wc_format = 0; /* Not a directory, so not a wc-directory */
+                return SVN_NO_ERROR;
+              }
+          }
+      
+        err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool);
+      
+        if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+          {
+            svn_error_clear(err);
+            *wc_format = 0;
+            return SVN_NO_ERROR; 
+          }
+        else
+          SVN_ERR(err);
+
+        if (db_kind != svn_wc__db_kind_dir)
+          {
+            /* The WC thinks there must be a file, so this is not
+               a wc-directory */
+            *wc_format = 0;
+            return SVN_NO_ERROR;
+          }
+
+        switch (db_status)
+          {
+            case svn_wc__db_status_not_present:
+            case svn_wc__db_status_absent:
+            case svn_wc__db_status_excluded:
+              /* If there is a directory here, it is not related to the parent
+                 working copy: Obstruction */
+              *wc_format = 0;
+              return SVN_NO_ERROR;
+            default:
+              break;
+          }
+      }
+#endif
+
   return SVN_NO_ERROR;
 }
 
@@ -151,10 +214,13 @@ svn_error_t *
 svn_wc_check_wc2(int *wc_format,
                  svn_wc_context_t *wc_ctx,
                  const char *local_abspath,
-                 apr_pool_t *pool)
+                 apr_pool_t *scratch_pool)
 {
+  /* ### Should we pass TRUE for check_path to find obstructions and
+         missing directories? */
   return svn_error_return(
-    svn_wc__internal_check_wc(wc_format, wc_ctx->db, local_abspath, pool));
+    svn_wc__internal_check_wc(wc_format, wc_ctx->db, local_abspath, FALSE,
+                              scratch_pool));
 }
 
 
@@ -422,7 +488,8 @@ probe(svn_wc__db_t *db,
       const char *local_abspath;
 
       SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-      SVN_ERR(svn_wc__internal_check_wc(&wc_format, db, local_abspath, pool));
+      SVN_ERR(svn_wc__internal_check_wc(&wc_format, db, local_abspath,
+                                        FALSE, pool));
     }
 
   /* a "version" of 0 means a non-wc directory */
@@ -469,7 +536,8 @@ open_single(svn_wc_adm_access_t **adm_ac
   svn_wc_adm_access_t *lock;
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-  err = svn_wc__internal_check_wc(&wc_format, db, local_abspath, scratch_pool);
+  err = svn_wc__internal_check_wc(&wc_format, db, local_abspath, FALSE,
+                                  scratch_pool);
   if (wc_format == 0 || (err && APR_STATUS_IS_ENOENT(err->apr_err)))
     {
       return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, err,
@@ -1599,7 +1667,7 @@ acquire_locks_recursively(svn_wc_context
     {
       /* We don't want to try and lock an unversioned directory that
          obstructs a versioned directory. */
-      err = svn_wc__internal_check_wc(&format, wc_ctx->db, local_abspath,
+      err = svn_wc__internal_check_wc(&format, wc_ctx->db, local_abspath, FALSE,
                                       iterpool);
 
       if (!err && format)