You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2010/11/11 23:58:50 UTC

svn commit: r1034191 [2/3] - in /subversion/branches/issue-3668-3669: ./ build/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ su...

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/dav_svn.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/dav_svn.h Thu Nov 11 22:58:49 2010
@@ -723,6 +723,19 @@ dav_svn__new_error_tag(apr_pool_t *pool,
                        const char *tagname);
 
 
+/* A wrapper around mod_dav's dav_new_error, mod_dav_svn uses this
+   instead of the mod_dav function to enable special mod_dav_svn specific
+   processing.  See dav_new_error for parameter documentation.
+   Note that DESC may be null (it's hard to track this down from
+   dav_new_error()'s documentation, but see the dav_error type,
+   which says that its desc field may be NULL). */
+dav_error *
+dav_svn__new_error(apr_pool_t *pool,
+                   int status,
+                   int errno_id,
+                   const char *desc);
+
+
 /* Convert an svn_error_t into a dav_error, pushing another error based on
    MESSAGE if MESSAGE is not NULL.  Use the provided HTTP status for the
    DAV errors.  Allocate new DAV errors from POOL.

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/deadprops.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/deadprops.c Thu Nov 11 22:58:49 2010
@@ -178,10 +178,10 @@ save_value(dav_db *db, const dav_prop_na
         /* ignore the unknown namespace of the incoming prop. */
         propname = name->name;
       else
-        return dav_new_error(db->p, HTTP_CONFLICT, 0,
-                             "Properties may only be defined in the "
-                             SVN_DAV_PROP_NS_SVN " and " SVN_DAV_PROP_NS_CUSTOM
-                             " namespaces.");
+        return dav_svn__new_error(db->p, HTTP_CONFLICT, 0,
+                                  "Properties may only be defined in the "
+                                  SVN_DAV_PROP_NS_SVN " and " 
+                                  SVN_DAV_PROP_NS_CUSTOM " namespaces.");
     }
 
   /* We've got three different types of properties (node, txn, and
@@ -300,9 +300,9 @@ db_open(apr_pool_t *p,
          changing unversioned rev props.  Remove this someday: see IZ #916. */
       if (! (resource->baselined
              && resource->type == DAV_RESOURCE_TYPE_VERSION))
-        return dav_new_error(p, HTTP_CONFLICT, 0,
-                             "Properties may only be changed on working "
-                             "resources.");
+        return dav_svn__new_error(p, HTTP_CONFLICT, 0,
+                                  "Properties may only be changed on working "
+                                  "resources.");
     }
 
   db = apr_pcalloc(p, sizeof(*db));
@@ -451,8 +451,8 @@ decode_property_value(const svn_string_t
             *out_propval_p = svn_base64_decode_string(maybe_encoded_propval,
                                                       pool);
           else
-            return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                 "Unknown property encoding");
+            return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                      "Unknown property encoding");
           break;
         }
 
@@ -498,11 +498,12 @@ db_store(dav_db *db,
 
   if (absent && ! elem->first_child)
     /* ### better error check */
-    return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                         apr_psprintf(pool, 
-                                      "'%s' cannot be specified on the value "
-                                      "without specifying an expectation",
-                                      SVN_DAV__OLD_VALUE__ABSENT));
+    return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              apr_psprintf(pool, 
+                                           "'%s' cannot be specified on the "
+                                           "value without specifying an "
+                                           "expectation",
+                                           SVN_DAV__OLD_VALUE__ABSENT));
 
   /* ### namespace check? */
   if (elem->first_child && !strcmp(elem->first_child->name, SVN_DAV__OLD_VALUE))

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/lock.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/lock.c Thu Nov 11 22:58:49 2010
@@ -143,8 +143,8 @@ unescape_xml(const char **output,
     {
       char errbuf[1024];
       (void)apr_xml_parser_geterror(xml_parser, errbuf, sizeof(errbuf));
-      return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
-                           DAV_ERR_LOCK_SAVE_LOCK, errbuf);
+      return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
+                                DAV_ERR_LOCK_SAVE_LOCK, errbuf);
     }
 
   apr_xml_to_text(pool, xml_doc->root, APR_XML_X2T_INNER,
@@ -166,14 +166,14 @@ dav_lock_to_svn_lock(svn_lock_t **slock,
 
   /* Sanity checks */
   if (dlock->type != DAV_LOCKTYPE_WRITE)
-    return dav_new_error(pool, HTTP_BAD_REQUEST,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Only 'write' locks are supported.");
+    return dav_svn__new_error(pool, HTTP_BAD_REQUEST,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Only 'write' locks are supported.");
 
   if (dlock->scope != DAV_LOCKSCOPE_EXCLUSIVE)
-    return dav_new_error(pool, HTTP_BAD_REQUEST,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Only exclusive locks are supported.");
+    return dav_svn__new_error(pool, HTTP_BAD_REQUEST,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Only exclusive locks are supported.");
 
   lock = svn_lock_create(pool);
   lock->path = apr_pstrdup(pool, path);
@@ -460,9 +460,9 @@ get_locks(dav_lockdb *lockdb,
      anything about locks attached to it.*/
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   serr = svn_fs_get_lock(&slock,
                          resource->info->repos->fs,
@@ -521,9 +521,9 @@ find_lock(dav_lockdb *lockdb,
      anything about locks attached to it.*/
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   serr = svn_fs_get_lock(&slock,
                          resource->info->repos->fs,
@@ -538,9 +538,10 @@ find_lock(dav_lockdb *lockdb,
     {
       /* Sanity check. */
       if (strcmp(locktoken->uuid_str, slock->token) != 0)
-        return dav_new_error(resource->pool, HTTP_BAD_REQUEST,
-                             DAV_ERR_LOCK_SAVE_LOCK,
-                             "Incoming token doesn't match existing lock.");
+        return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST,
+                                  DAV_ERR_LOCK_SAVE_LOCK,
+                                  "Incoming token doesn't match existing "
+                                  "lock.");
 
       svn_lock_to_dav_lock(&dlock, slock, FALSE,
                            resource->exists, resource->pool);
@@ -600,9 +601,9 @@ has_locks(dav_lockdb *lockdb, const dav_
      anything about locks attached to it.*/
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   serr = svn_fs_get_lock(&slock,
                          resource->info->repos->fs,
@@ -644,14 +645,14 @@ append_locks(dav_lockdb *lockdb,
      be created on it. */
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   if (lock->next)
-    return dav_new_error(resource->pool, HTTP_BAD_REQUEST,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Tried to attach multiple locks to a resource.");
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Tried to attach multiple locks to a resource.");
 
   /* RFC2518bis (section 7.4) doesn't require us to support
      'lock-null' resources at all.  Instead, it asks that we treat
@@ -669,16 +670,16 @@ append_locks(dav_lockdb *lockdb,
                                                           resource->pool));
 
       if (resource->info->repos->is_svn_client)
-        return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,
-                             DAV_ERR_LOCK_SAVE_LOCK,
-                             "Subversion clients may not lock "
-                             "nonexistent paths.");
+        return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,
+                                  DAV_ERR_LOCK_SAVE_LOCK,
+                                  "Subversion clients may not lock "
+                                  "nonexistent paths.");
 
       else if (! resource->info->repos->autoversioning)
-        return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,
-                             DAV_ERR_LOCK_SAVE_LOCK,
-                             "Attempted to lock non-existent path;"
-                             " turn on autoversioning first.");
+        return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,
+                                  DAV_ERR_LOCK_SAVE_LOCK,
+                                  "Attempted to lock non-existent path; "
+                                  "turn on autoversioning first.");
 
       /* Commit a 0-byte file: */
 
@@ -746,9 +747,9 @@ append_locks(dav_lockdb *lockdb,
   if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
     {
       svn_error_clear(serr);
-      return dav_new_error(resource->pool, HTTP_UNAUTHORIZED,
-                           DAV_ERR_LOCK_SAVE_LOCK,
-                           "Anonymous lock creation is not allowed.");
+      return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+                                DAV_ERR_LOCK_SAVE_LOCK,
+                                "Anonymous lock creation is not allowed.");
     }
   else if (serr)
     return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -812,9 +813,9 @@ remove_lock(dav_lockdb *lockdb,
      be removed from it. */
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   if (locktoken == NULL)
     {
@@ -849,9 +850,9 @@ remove_lock(dav_lockdb *lockdb,
       if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
         {
           svn_error_clear(serr);
-          return dav_new_error(resource->pool, HTTP_UNAUTHORIZED,
-                               DAV_ERR_LOCK_SAVE_LOCK,
-                               "Anonymous lock removal is not allowed.");
+          return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+                                    DAV_ERR_LOCK_SAVE_LOCK,
+                                    "Anonymous lock removal is not allowed.");
         }
       else if (serr)
         return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -898,9 +899,9 @@ refresh_locks(dav_lockdb *lockdb,
      anything about locks attached to it.*/
   if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
                                      resource->pool))
-    return dav_new_error(resource->pool, HTTP_FORBIDDEN,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Path is not accessible.");
+    return dav_svn__new_error(resource->pool, HTTP_FORBIDDEN,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Path is not accessible.");
 
   /* Convert the path into an svn_lock_t. */
   serr = svn_fs_get_lock(&slock,
@@ -916,9 +917,10 @@ refresh_locks(dav_lockdb *lockdb,
      current lock on the incoming resource? */
   if ((! slock)
       || (strcmp(token->uuid_str, slock->token) != 0))
-    return dav_new_error(resource->pool, HTTP_UNAUTHORIZED,
-                         DAV_ERR_LOCK_SAVE_LOCK,
-                         "Lock refresh request doesn't match existing lock.");
+    return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+                              DAV_ERR_LOCK_SAVE_LOCK,
+                              "Lock refresh request doesn't match existing "
+                              "lock.");
 
   /* Now use the tweaked svn_lock_t to 'refresh' the existing lock. */
   serr = svn_repos_fs_lock(&slock,
@@ -936,9 +938,9 @@ refresh_locks(dav_lockdb *lockdb,
   if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
     {
       svn_error_clear(serr);
-      return dav_new_error(resource->pool, HTTP_UNAUTHORIZED,
-                           DAV_ERR_LOCK_SAVE_LOCK,
-                           "Anonymous lock refreshing is not allowed.");
+      return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+                                DAV_ERR_LOCK_SAVE_LOCK,
+                                "Anonymous lock refreshing is not allowed.");
     }
   else if (serr)
     return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/dated-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/dated-rev.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/dated-rev.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/dated-rev.c Thu Nov 11 22:58:49 2010
@@ -80,9 +80,9 @@ dav_svn__dated_rev_report(const dav_reso
 
   if (tm == (apr_time_t) -1)
     {
-      return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                           "The request does not contain a valid "
-                           "'DAV:" SVN_DAV__CREATIONDATE "' element.");
+      return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                                "The request does not contain a valid "
+                                "'DAV:" SVN_DAV__CREATIONDATE "' element.");
     }
 
   /* Do the actual work of finding the revision by date. */
@@ -90,8 +90,8 @@ dav_svn__dated_rev_report(const dav_reso
                                       resource->pool)) != SVN_NO_ERROR)
     {
       svn_error_clear(err);
-      return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                           "Could not access revision times.");
+      return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                "Could not access revision times.");
     }
 
   bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/deleted-rev.c Thu Nov 11 22:58:49 2010
@@ -110,8 +110,8 @@ dav_svn__get_deleted_rev_report(const da
   if (err)
     {
       svn_error_clear(err);
-      return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                           "Could not find revision path was deleted.");
+      return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                "Could not find revision path was deleted.");
     }
 
   bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/get-locks.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/reports/get-locks.c Thu Nov 11 22:58:49 2010
@@ -192,9 +192,9 @@ dav_svn__get_locks_report(const dav_reso
   /* The request URI should be a public one representing an fs path. */
   if ((! resource->info->repos_path)
       || (! resource->info->repos->repos))
-    return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                         "get-locks-report run on resource which doesn't "
-                         "represent a path within a repository.");
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "get-locks-report run on resource which doesn't "
+                              "represent a path within a repository.");
 
   arb.r = resource->info->r;
   arb.repos = resource->info->repos;
@@ -209,9 +209,9 @@ dav_svn__get_locks_report(const dav_reso
               (depth != svn_depth_files) &&
               (depth != svn_depth_immediates) &&
               (depth != svn_depth_infinity))
-            return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                                 "Invalid 'depth' specified in "
-                                 "get-locks-report request.");
+            return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                                      "Invalid 'depth' specified in "
+                                      "get-locks-report request.");
           continue;
         }
     }

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/repos.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/repos.c Thu Nov 11 22:58:49 2010
@@ -880,10 +880,10 @@ prep_working(dav_resource_combined *comb
                                   comb->priv.root.activity_id);
       if (txn_name == NULL)
         {
-          return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                               "An unknown activity was specified in the URL. "
-                               "This is generally caused by a problem in the "
-                               "client software.");
+          return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                                    "An unknown activity was specified in the "
+                                    "URL. This is generally caused by a "
+                                    "problem in the client software.");
         }
       comb->priv.root.txn_name = txn_name;
     }
@@ -896,10 +896,10 @@ prep_working(dav_resource_combined *comb
       if (serr->apr_err == SVN_ERR_FS_NO_SUCH_TRANSACTION)
         {
           svn_error_clear(serr);
-          return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                               "An activity was specified and found, but the "
-                               "corresponding SVN FS transaction was not "
-                               "found.");
+          return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                    "An activity was specified and found, but "
+                                    "the corresponding SVN FS transaction was "
+                                    "not found.");
         }
       return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                   "Could not open the SVN FS transaction "
@@ -956,8 +956,8 @@ prep_working(dav_resource_combined *comb
         }
       else if (!svn_string_compare(current_author, &request_author))
         {
-          return dav_new_error(pool, HTTP_NOT_IMPLEMENTED, 0,
-                   "Multi-author commits not supported.");
+          return dav_svn__new_error(pool, HTTP_NOT_IMPLEMENTED, 0,
+                                    "Multi-author commits not supported.");
         }
     }
 
@@ -1011,8 +1011,9 @@ prep_private(dav_resource_combined *comb
       /* Open the named transaction. */
 
       if (comb->priv.root.txn_name == NULL)
-        return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                             "An unknown txn name was specified in the URL.");
+        return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                                  "An unknown txn name was specified in the "
+                                  "URL.");
 
       serr = svn_fs_open_txn(&comb->priv.root.txn,
                              comb->priv.repos->fs,
@@ -1023,8 +1024,8 @@ prep_private(dav_resource_combined *comb
             {
               svn_error_clear(serr);
               comb->res.exists = FALSE;
-              return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                   "Named transaction doesn't exist.");
+              return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                        "Named transaction doesn't exist.");
             }
           return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                       "Could not open specified transaction.",
@@ -1074,8 +1075,8 @@ prep_resource(dav_resource_combined *com
         return (*scan->prep)(comb);
     }
 
-  return dav_new_error(comb->res.pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                       "DESIGN FAILURE: unknown resource type");
+  return dav_svn__new_error(comb->res.pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                            "DESIGN FAILURE: unknown resource type");
 }
 
 
@@ -1158,12 +1159,12 @@ dav_svn_split_uri(request_rec *r,
   if ((fs_path == NULL) && (fs_parent_path == NULL))
     {
       /* ### are SVN_ERR_APMOD codes within the right numeric space? */
-      return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
-                           SVN_ERR_APMOD_MISSING_PATH_TO_FS,
-                           "The server is misconfigured: "
-                           "either an SVNPath or SVNParentPath "
-                           "directive is required to specify the location "
-                           "of this resource's repository.");
+      return dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                                SVN_ERR_APMOD_MISSING_PATH_TO_FS,
+                                "The server is misconfigured: "
+                                "either an SVNPath or SVNParentPath "
+                                "directive is required to specify the location "
+                                "of this resource's repository.");
     }
 
   /* make a copy so that we can do some work on it */
@@ -1241,10 +1242,10 @@ dav_svn_split_uri(request_rec *r,
       if (relative[1] == '\0')
         {
           /* ### are SVN_ERR_APMOD codes within the right numeric space? */
-          return dav_new_error(r->pool, HTTP_FORBIDDEN,
-                               SVN_ERR_APMOD_MALFORMED_URI,
-                               "The URI does not contain the name "
-                               "of a repository.");
+          return dav_svn__new_error(r->pool, HTTP_FORBIDDEN,
+                                    SVN_ERR_APMOD_MALFORMED_URI,
+                                    "The URI does not contain the name "
+                                    "of a repository.");
         }
 
       magic_end = ap_strchr_c(relative + 1, '/');
@@ -1289,9 +1290,9 @@ dav_svn_split_uri(request_rec *r,
         if (ch == '\0')
           {
             /* relative is just "!svn", which is malformed. */
-            return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                 SVN_ERR_APMOD_MALFORMED_URI,
-                                 "Nothing follows the svn special_uri.");
+            return dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                                      SVN_ERR_APMOD_MALFORMED_URI,
+                                      "Nothing follows the svn special_uri.");
           }
         else
           {
@@ -1315,10 +1316,10 @@ dav_svn_split_uri(request_rec *r,
                         if (defn->numcomponents == 0)
                           *repos_path = NULL;
                         else
-                          return
-                            dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
-                                          SVN_ERR_APMOD_MALFORMED_URI,
-                                          "Missing info after special_uri.");
+                          return dav_svn__new_error(
+                                     r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                                     SVN_ERR_APMOD_MALFORMED_URI,
+                                     "Missing info after special_uri.");
                       }
                     else if (relative[len3] == '/')
                       {
@@ -1339,12 +1340,11 @@ dav_svn_split_uri(request_rec *r,
                           {
                             /* Did we break from the loop prematurely? */
                             if (j != (defn->numcomponents - 1))
-                              return
-                                dav_new_error(r->pool,
-                                              HTTP_INTERNAL_SERVER_ERROR,
-                                              SVN_ERR_APMOD_MALFORMED_URI,
-                                              "Not enough components"
-                                              " after special_uri.");
+                              return dav_svn__new_error(
+                                         r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                                         SVN_ERR_APMOD_MALFORMED_URI,
+                                         "Not enough components after "
+                                         "special_uri.");
 
                             if (! defn->has_repos_path)
                               /* It's okay to not have found a slash. */
@@ -1361,7 +1361,7 @@ dav_svn_split_uri(request_rec *r,
                     else
                       {
                         return
-                          dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                          dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
                                         SVN_ERR_APMOD_MALFORMED_URI,
                                         "Unknown data after special_uri.");
                       }
@@ -1372,9 +1372,9 @@ dav_svn_split_uri(request_rec *r,
 
             if (defn->name == NULL)
               return
-                dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
-                              SVN_ERR_APMOD_MALFORMED_URI,
-                              "Couldn't match subdir after special_uri.");
+                dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                                   SVN_ERR_APMOD_MALFORMED_URI,
+                                   "Couldn't match subdir after special_uri.");
           }
       }
     else
@@ -1462,9 +1462,9 @@ get_parentpath_resource(request_rec *r,
                             "/", (char *)NULL);
       apr_table_setn(r->headers_out, "Location",
                      ap_construct_url(r->pool, new_uri, r));
-      return dav_new_error(r->pool, HTTP_MOVED_PERMANENTLY, 0,
-                           "Requests for a collection must have a "
-                           "trailing slash on the URI.");
+      return dav_svn__new_error(r->pool, HTTP_MOVED_PERMANENTLY, 0,
+                                "Requests for a collection must have a "
+                                "trailing slash on the URI.");
     }
 
   /* No other "prepping" of resource needs to happen -- no opening
@@ -1771,8 +1771,8 @@ parse_querystring(request_rec *r, const 
     {
       peg_rev = SVN_STR_TO_REV(prevstr);
       if (!SVN_IS_VALID_REVNUM(peg_rev))
-        return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                             "invalid peg rev in query string");
+        return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                                  "invalid peg rev in query string");
     }
   else
     {
@@ -1788,8 +1788,8 @@ parse_querystring(request_rec *r, const 
     {
       working_rev = SVN_STR_TO_REV(wrevstr);
       if (!SVN_IS_VALID_REVNUM(working_rev))
-        return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                             "invalid working rev in query string");
+        return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                                  "invalid working rev in query string");
     }
   else
     {
@@ -1802,8 +1802,8 @@ parse_querystring(request_rec *r, const 
      Our node-tracing algorithms can't handle that scenario, so we'll
      disallow it here. */
   if (working_rev > peg_rev)
-    return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                         "working rev greater than peg rev.");
+    return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                              "working rev greater than peg rev.");
 
   /* If WORKING_REV and PEG_REV are equivalent, we want to return the
      resource at the revision.  Otherwise, WORKING_REV is older than
@@ -1844,8 +1844,8 @@ parse_querystring(request_rec *r, const 
 
       newpath = apr_hash_get(locations, &working_rev, sizeof(svn_revnum_t));
       if (! newpath)
-        return dav_new_error(pool, HTTP_NOT_FOUND, 0,
-                             "path doesn't exist in that revision.");
+        return dav_svn__new_error(pool, HTTP_NOT_FOUND, 0,
+                                  "path doesn't exist in that revision.");
 
       /* Redirect folks to a canonical, peg-revision-only location.
          If they used a peg revision in this request, we can use a
@@ -1857,10 +1857,10 @@ parse_querystring(request_rec *r, const 
                                                    comb->priv.repos->root_path,
                                                    newpath, working_rev),
                                       r));
-      return dav_new_error(r->pool,
-                           prevstr ? HTTP_MOVED_PERMANENTLY
-                                   : HTTP_MOVED_TEMPORARILY,
-                           0, "redirecting to canonical location");
+      return dav_svn__new_error(r->pool,
+                                prevstr ? HTTP_MOVED_PERMANENTLY
+                                        : HTTP_MOVED_TEMPORARILY,
+                                0, "redirecting to canonical location");
     }
 
   return NULL;
@@ -2256,9 +2256,9 @@ get_resource(request_rec *r,
                                          (char *)NULL);
       apr_table_setn(r->headers_out, "Location",
                      ap_construct_url(r->pool, new_path, r));
-      return dav_new_error(r->pool, HTTP_MOVED_PERMANENTLY, 0,
-                           "Requests for a collection must have a "
-                           "trailing slash on the URI.");
+      return dav_svn__new_error(r->pool, HTTP_MOVED_PERMANENTLY, 0,
+                                "Requests for a collection must have a "
+                                "trailing slash on the URI.");
     }
 
   /* HTTPv2: for write-requests, out-of-dateness checks happen via
@@ -2280,12 +2280,12 @@ get_resource(request_rec *r,
      doofus typed it in manually or has a buggy client. */
   /* ### pick something other than HTTP_INTERNAL_SERVER_ERROR */
   /* ### are SVN_ERR_APMOD codes within the right numeric space? */
-  return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
-                       SVN_ERR_APMOD_MALFORMED_URI,
-                       "The URI indicated a resource within Subversion's "
-                       "special resource area, but does not exist. This is "
-                       "generally caused by a problem in the client "
-                       "software.");
+  return dav_svn__new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,
+                            SVN_ERR_APMOD_MALFORMED_URI,
+                            "The URI indicated a resource within Subversion's "
+                            "special resource area, but does not exist. This "
+                            "is generally caused by a problem in the client "
+                            "software.");
 }
 
 
@@ -2387,11 +2387,11 @@ get_parent_resource(const dav_resource *
 
   /* If we didn't create parent resource above, complain. */
   if (! *parent_resource)
-    return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                         apr_psprintf(resource->pool,
-                                      "get_parent_resource was called for "
-                                      "%s (type %d)",
-                                      resource->uri, resource->type));
+    return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              apr_psprintf(resource->pool,
+                                           "get_parent_resource was called for "
+                                           "%s (type %d)",
+                                           resource->uri, resource->type));
 
   return NULL;
 }
@@ -2610,18 +2610,18 @@ open_stream(const dav_resource *resource
     {
       if (resource->type != DAV_RESOURCE_TYPE_WORKING)
         {
-          return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                               "Resource body changes may only be made to "
-                               "working resources [at this time].");
+          return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                                    "Resource body changes may only be made to "
+                                    "working resources (at this time).");
         }
     }
 
 #if 1
   if (mode == DAV_MODE_WRITE_SEEKABLE)
     {
-      return dav_new_error(resource->pool, HTTP_NOT_IMPLEMENTED, 0,
-                           "Resource body writes cannot use ranges "
-                           "[at this time].");
+      return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED, 0,
+                                "Resource body writes cannot use ranges "
+                                "(at this time).");
     }
 #endif
 
@@ -2814,9 +2814,9 @@ seek_stream(dav_stream *stream, apr_off_
 {
   /* ### fill this in */
 
-  return dav_new_error(stream->res->pool, HTTP_NOT_IMPLEMENTED, 0,
-                       "Resource body read/write cannot use ranges "
-                       "(at this time)");
+  return dav_svn__new_error(stream->res->pool, HTTP_NOT_IMPLEMENTED, 0,
+                            "Resource body read/write cannot use ranges "
+                            "(at this time)");
 }
 
 /* Returns whether the DAV resource lacks potential for generation of
@@ -3110,8 +3110,8 @@ deliver(const dav_resource *resource, ap
       && resource->type != DAV_RESOURCE_TYPE_WORKING
       && resource->info->restype != DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
     {
-      return dav_new_error(resource->pool, HTTP_CONFLICT, 0,
-                           "Cannot GET this type of resource.");
+      return dav_svn__new_error(resource->pool, HTTP_CONFLICT, 0,
+                                "Cannot GET this type of resource.");
     }
 
   if (resource->collection)
@@ -3429,8 +3429,8 @@ deliver(const dav_resource *resource, ap
       bkt = apr_bucket_eos_create(output->c->bucket_alloc);
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
       if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS)
-        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Could not write EOS to filter.");
+        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Could not write EOS to filter.");
 
       return NULL;
     }
@@ -3476,8 +3476,9 @@ deliver(const dav_resource *resource, ap
                                         "is really a file",
                                         resource->pool);
           if (!is_file)
-            return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                                 "the delta base does not refer to a file");
+            return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                                      "the delta base does not refer to a "
+                                      "file");
 
           /* Okay. Let's open up a delta stream for the client to read. */
           serr = svn_fs_get_file_delta_stream(&txd_stream,
@@ -3563,8 +3564,9 @@ deliver(const dav_resource *resource, ap
         APR_BRIGADE_INSERT_TAIL(bb, bkt);
         if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
           /* ### what to do with status; and that HTTP code... */
-          return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                               "Could not write data to filter.");
+          return dav_svn__new_error(resource->pool,
+                                    HTTP_INTERNAL_SERVER_ERROR, 0,
+                                    "Could not write data to filter.");
         }
       }
 
@@ -3574,8 +3576,9 @@ deliver(const dav_resource *resource, ap
       APR_BRIGADE_INSERT_TAIL(bb, bkt);
       if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) {
         /* ### what to do with status; and that HTTP code... */
-        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Could not write EOS to filter.");
+        return dav_svn__new_error(resource->pool,
+                                  HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Could not write EOS to filter.");
       }
 
       return NULL;
@@ -3592,17 +3595,18 @@ create_collection(dav_resource *resource
   if (resource->type != DAV_RESOURCE_TYPE_WORKING
       && resource->type != DAV_RESOURCE_TYPE_REGULAR)
     {
-      return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                           "Collections can only be created within a working "
-                           "or regular collection [at this time].");
+      return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                                "Collections can only be created within a "
+                                "working or regular collection (at this "
+                                "time).");
     }
 
   /* ...regular resources allowed only if autoversioning is turned on. */
   if (resource->type == DAV_RESOURCE_TYPE_REGULAR
       && ! (resource->info->repos->autoversioning))
-    return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                         "MKCOL called on regular resource, but "
-                         "autoversioning is not active.");
+    return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                              "MKCOL called on regular resource, but "
+                              "autoversioning is not active.");
 
   /* ### note that the parent was checked out at some point, and this
      ### is being preformed relative to the working rsrc for that parent */
@@ -3664,7 +3668,7 @@ copy_resource(const dav_resource *src,
       (src->pool, "Got a COPY request with src arg '%s' and dst arg '%s'",
       src->uri, dst->uri);
 
-      return dav_new_error(src->pool, HTTP_NOT_IMPLEMENTED, 0, msg);
+      return dav_svn__new_error(src->pool, HTTP_NOT_IMPLEMENTED, 0, msg);
   */
 
   /* ### Safeguard: see issue #916, whereby we're allowing an
@@ -3672,14 +3676,14 @@ copy_resource(const dav_resource *src,
      a new baseline afterwards.  We need to safeguard here that nobody
      is calling COPY with the baseline as a Destination! */
   if (dst->baselined && dst->type == DAV_RESOURCE_TYPE_VERSION)
-    return dav_new_error(src->pool, HTTP_PRECONDITION_FAILED, 0,
-                         "Illegal: COPY Destination is a baseline.");
+    return dav_svn__new_error(src->pool, HTTP_PRECONDITION_FAILED, 0,
+                              "Illegal: COPY Destination is a baseline.");
 
   if (dst->type == DAV_RESOURCE_TYPE_REGULAR
       && !(dst->info->repos->autoversioning))
-    return dav_new_error(dst->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                         "COPY called on regular resource, but "
-                         "autoversioning is not active.");
+    return dav_svn__new_error(dst->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                              "COPY called on regular resource, but "
+                              "autoversioning is not active.");
 
   /* Auto-versioning copy of regular resource: */
   if (dst->type == DAV_RESOURCE_TYPE_REGULAR)
@@ -3748,15 +3752,15 @@ remove_resource(dav_resource *resource, 
          || resource->type == DAV_RESOURCE_TYPE_ACTIVITY
          || (resource->type == DAV_RESOURCE_TYPE_PRIVATE
              && resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)))
-    return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                           "DELETE called on invalid resource type.");
+    return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                              "DELETE called on invalid resource type.");
 
   /* ...and regular resources only if autoversioning is turned on. */
   if (resource->type == DAV_RESOURCE_TYPE_REGULAR
       && ! (resource->info->repos->autoversioning))
-    return dav_new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                         "DELETE called on regular resource, but "
-                         "autoversioning is not active.");
+    return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                              "DELETE called on regular resource, but "
+                              "autoversioning is not active.");
 
   /* Handle activity deletions (early exit). */
   if (resource->type == DAV_RESOURCE_TYPE_ACTIVITY)
@@ -3889,9 +3893,9 @@ move_resource(dav_resource *src,
   if (src->type != DAV_RESOURCE_TYPE_REGULAR
       || dst->type != DAV_RESOURCE_TYPE_REGULAR
       || !(src->info->repos->autoversioning))
-    return dav_new_error(dst->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                         "MOVE only allowed on two public URIs, and "
-                         "autoversioning must be active.");
+    return dav_svn__new_error(dst->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                              "MOVE only allowed on two public URIs, and "
+                              "autoversioning must be active.");
 
   /* Change the dst VCR into a WR, in place.  This creates a txn and
      changes dst->info->root from a rev-root into a txn-root. */
@@ -3984,9 +3988,9 @@ do_walk(walker_ctx_t *ctx, int depth)
   /* ### need to allow more walking in the future */
   if (params->root->type != DAV_RESOURCE_TYPE_REGULAR)
     {
-      return dav_new_error(params->pool, HTTP_METHOD_NOT_ALLOWED, 0,
-                           "Walking the resource hierarchy can only be done "
-                           "on 'regular' resources [at this time].");
+      return dav_svn__new_error(params->pool, HTTP_METHOD_NOT_ALLOWED, 0,
+                                "Walking the resource hierarchy can only be "
+                                "done on 'regular' resources [at this time].");
     }
 
   /* assert: collection resource. isdir == TRUE. repos_path != NULL. */
@@ -4119,6 +4123,12 @@ walk(const dav_walk_params *params, int 
   walker_ctx_t ctx = { 0 };
   dav_error *err;
 
+  if (params->root->info->restype == DAV_SVN_RESTYPE_PARENTPATH_COLLECTION)
+    {
+      /* Cannot walk an SVNParentPath collection, there is no repository. */
+      return NULL;
+    }
+
   ctx.params = params;
 
   ctx.wres.walk_ctx = params->walk_ctx;
@@ -4292,8 +4302,8 @@ dav_svn__create_version_resource(dav_res
 
   result = parse_version_uri(comb, uri, NULL, 0);
   if (result != 0)
-    return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                         "Could not parse version resource uri.");
+    return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Could not parse version resource uri.");
 
   err = prep_version(comb);
   if (err)
@@ -4320,12 +4330,12 @@ handle_post_request(request_rec *r,
   status = dav_svn__parse_request_skel(&request_skel, r, pool);
 
   if (status != OK)
-    return dav_new_error(pool, status, 0,
-                         "Error parsing skel POST request body.");
+    return dav_svn__new_error(pool, status, 0,
+                              "Error parsing skel POST request body.");
 
   if (svn_skel__list_length(request_skel) < 1)
-    return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                         "Unable to identify skel POST request flavor.");
+    return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                              "Unable to identify skel POST request flavor.");
 
   if (svn_skel__matches_atom(request_skel->children, "create-txn"))
     {
@@ -4333,8 +4343,8 @@ handle_post_request(request_rec *r,
     }
   else
     {
-      return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
-                           "Unsupported skel POST request flavor.");
+      return dav_svn__new_error(pool, HTTP_BAD_REQUEST, 0,
+                                "Unsupported skel POST request flavor.");
     }
   /* NOTREACHED */
 }
@@ -4362,8 +4372,8 @@ int dav_svn__method_post(request_rec *r)
     }
   else
     {
-      derr = dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                           "Unsupported POST request type.");
+      derr = dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                                "Unsupported POST request type.");
     }
 
   /* If something went wrong above, we'll generate a response back to

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/util.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/util.c Thu Nov 11 22:58:49 2010
@@ -39,6 +39,27 @@
 
 
 dav_error *
+dav_svn__new_error(apr_pool_t *pool,
+                   int status,
+                   int error_id,
+                   const char *desc)
+{
+/*
+ * Note: dav_new_error() in httpd 2.0/2.2 always treated
+ * the errno field in dav_error as an apr_status_t when
+ * logging; on some platforms errno and apr_status_t
+ * aren't directly interchangeable.  The code for httpd
+ * > 2.2 below perpetuates this.
+ */
+#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
+  /* old code assumed errno was valid; keep assuming */
+  return dav_new_error(pool, status, error_id, errno, desc);
+#else
+  return dav_new_error(pool, status, error_id, desc);
+#endif
+}
+
+dav_error *
 dav_svn__new_error_tag(apr_pool_t *pool,
                        int status,
                        int error_id,
@@ -46,6 +67,10 @@ dav_svn__new_error_tag(apr_pool_t *pool,
                        const char *namespace,
                        const char *tagname)
 {
+#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
+  return dav_new_error_tag(pool, status, error_id, 0,
+                           desc, namespace, tagname);
+#else
   /* dav_new_error_tag will record errno but Subversion makes no attempt
      to ensure that it is valid.  We reset it to avoid putting incorrect
      information into the error log, at the expense of possibly removing
@@ -53,6 +78,7 @@ dav_svn__new_error_tag(apr_pool_t *pool,
   errno = 0;
 
   return dav_new_error_tag(pool, status, error_id, desc, namespace, tagname);
+#endif
 }
 
 
@@ -573,8 +599,8 @@ dav_svn__final_flush_or_error(request_re
     {
       apr_status_t apr_err = ap_fflush(output, bb);
       if (apr_err && (! derr))
-        derr = dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Error flushing brigade.");
+        derr = dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Error flushing brigade.");
     }
   return derr;
 }

Modified: subversion/branches/issue-3668-3669/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/mod_dav_svn/version.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/issue-3668-3669/subversion/mod_dav_svn/version.c Thu Nov 11 22:58:49 2010
@@ -83,8 +83,8 @@ set_auto_revprops(dav_resource *resource
 
   if (! (resource->type == DAV_RESOURCE_TYPE_WORKING
          && resource->info->auto_checked_out))
-    return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                         "Set_auto_revprops called on invalid resource.");
+    return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Set_auto_revprops called on invalid resource.");
 
   if ((serr = dav_svn__attach_auto_revprops(resource->info->root.txn,
                                             resource->info->repos_path,
@@ -301,8 +301,9 @@ vsn_control(dav_resource *resource, cons
   /* All mod_dav_svn resources are versioned objects;  so it doesn't
      make sense to call vsn_control on a resource that exists . */
   if (resource->exists)
-    return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
-                         "vsn_control called on already-versioned resource.");
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "vsn_control called on already-versioned "
+                              "resource.");
 
   /* Only allow a NULL target, which means an create an 'empty' VCR. */
   if (target != NULL)
@@ -413,8 +414,9 @@ dav_svn__checkout(dav_resource *resource
           shared_txn_name = dav_svn__get_txn(resource->info->repos,
                                              shared_activity);
           if (! shared_txn_name)
-            return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                                 "Cannot look up a txn_name by activity");
+            return dav_svn__new_error(resource->pool,
+                                      HTTP_INTERNAL_SERVER_ERROR, 0,
+                                      "Cannot look up a txn_name by activity");
         }
 
       /* Tweak the VCR in-place, making it into a WR.  (Ignore the
@@ -889,21 +891,21 @@ dav_svn__checkin(dav_resource *resource,
       shared_txn_name = dav_svn__get_txn(resource->info->repos,
                                          shared_activity);
       if (! shared_txn_name)
-        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Cannot look up a txn_name by activity");
+        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Cannot look up a txn_name by activity");
 
       /* Sanity checks */
       if (resource->info->root.txn_name
           && (strcmp(shared_txn_name, resource->info->root.txn_name) != 0))
-        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Internal txn_name doesn't match"
-                             " autoversioning transaction.");
+        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Internal txn_name doesn't match "
+                                  "autoversioning transaction.");
 
       if (! resource->info->root.txn)
         /* should already be open by checkout */
-        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
-                             "Autoversioning txn isn't open "
-                             "when it should be.");
+        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Autoversioning txn isn't open "
+                                  "when it should be.");
 
       err = set_auto_revprops(resource);
       if (err)

Modified: subversion/branches/issue-3668-3669/subversion/svn/cat-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/cat-cmd.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/cat-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/cat-cmd.c Thu Nov 11 22:58:49 2010
@@ -27,7 +27,6 @@
 
 /*** Includes. ***/
 
-#include "svn_path.h"
 #include "svn_pools.h"
 #include "svn_client.h"
 #include "svn_error.h"
@@ -69,13 +68,8 @@ svn_cl__cat(apr_getopt_t *os,
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
 
       /* Get peg revisions. */
-      SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
-                                 subpool));
-
-      if (svn_path_is_url(truepath))
-        truepath = svn_uri_canonicalize(truepath, subpool);
-      else
-        truepath = svn_dirent_canonicalize(truepath, subpool);
+      SVN_ERR(svn_cl__opt_parse_path(&peg_revision, &truepath, target,
+                                     subpool));
 
       SVN_ERR(svn_cl__try(svn_client_cat2(out, truepath, &peg_revision,
                                           &(opt_state->start_revision),

Modified: subversion/branches/issue-3668-3669/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/cl.h?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/cl.h (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/cl.h Thu Nov 11 22:58:49 2010
@@ -569,6 +569,21 @@ svn_cl__notifier_mark_checkout(void *bat
 svn_error_t *
 svn_cl__notifier_mark_export(void *baton);
 
+/* Baton for use with svn_cl__check_externals_failed_notify_wrapper(). */
+struct svn_cl__check_externals_failed_notify_baton
+{
+  svn_wc_notify_func2_t wrapped_func; /* The "real" notify_func2. */
+  void *wrapped_baton;                /* The "real" notify_func2 baton. */
+  svn_boolean_t had_externals_error;  /* Did something fail in an external? */
+};
+
+/* Notification function wrapper (implements `svn_wc_notify_func2_t').
+   Use with an svn_cl__check_externals_failed_notify_baton BATON. */
+void
+svn_cl__check_externals_failed_notify_wrapper(void *baton,
+                                              const svn_wc_notify_t *n,
+                                              apr_pool_t *pool);
+
 /* Print conflict stats accumulated in NOTIFY_BATON.
  * Return any error encountered during printing.
  * Do all allocations in POOL.*/
@@ -795,6 +810,13 @@ svn_cl__eat_peg_revisions(apr_array_head
                           const apr_array_header_t *targets,
                           apr_pool_t *pool);
 
+/* Like svn_opt_parse_path(), but canonicalizes dirent/URL */
+svn_error_t *
+svn_cl__opt_parse_path(svn_opt_revision_t *rev,
+                       const char **truepath,
+                       const char *path,
+                       apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/issue-3668-3669/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/conflict-callbacks.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/conflict-callbacks.c Thu Nov 11 22:58:49 2010
@@ -61,7 +61,7 @@ svn_cl__accept_from_word(const char *wor
 {
   /* Shorthand options are consistent with  svn_cl__conflict_handler(). */
   if (strcmp(word, SVN_CL__ACCEPT_POSTPONE) == 0
-      || strcmp(word, "p") == 0)
+      || strcmp(word, "p") == 0 || strcmp(word, ":-P") == 0)
     return svn_cl__accept_postpone;
   if (strcmp(word, SVN_CL__ACCEPT_BASE) == 0)
     /* ### shorthand? */
@@ -70,22 +70,22 @@ svn_cl__accept_from_word(const char *wor
     /* ### shorthand? */
     return svn_cl__accept_working;
   if (strcmp(word, SVN_CL__ACCEPT_MINE_CONFLICT) == 0
-      || strcmp(word, "mc") == 0)
+      || strcmp(word, "mc") == 0 || strcmp(word, "X-)") == 0)
     return svn_cl__accept_mine_conflict;
   if (strcmp(word, SVN_CL__ACCEPT_THEIRS_CONFLICT) == 0
-      || strcmp(word, "tc") == 0)
+      || strcmp(word, "tc") == 0 || strcmp(word, "X-(") == 0)
     return svn_cl__accept_theirs_conflict;
   if (strcmp(word, SVN_CL__ACCEPT_MINE_FULL) == 0
-      || strcmp(word, "mf") == 0)
+      || strcmp(word, "mf") == 0 || strcmp(word, ":-)") == 0)
     return svn_cl__accept_mine_full;
   if (strcmp(word, SVN_CL__ACCEPT_THEIRS_FULL) == 0
-      || strcmp(word, "tf") == 0)
+      || strcmp(word, "tf") == 0 || strcmp(word, ":-(") == 0)
     return svn_cl__accept_theirs_full;
   if (strcmp(word, SVN_CL__ACCEPT_EDIT) == 0
-      || strcmp(word, "e") == 0)
+      || strcmp(word, "e") == 0 || strcmp(word, ":-E") == 0)
     return svn_cl__accept_edit;
   if (strcmp(word, SVN_CL__ACCEPT_LAUNCH) == 0
-      || strcmp(word, "l") == 0)
+      || strcmp(word, "l") == 0 || strcmp(word, ":-l") == 0)
     return svn_cl__accept_launch;
   /* word is an invalid action. */
   return svn_cl__accept_invalid;
@@ -529,13 +529,13 @@ svn_cl__conflict_handler(svn_wc_conflict
                                           "resolve conflict\n"
                 "  (s)  show all         - show this list\n\n")));
             }
-          else if (strcmp(answer, "p") == 0)
+          else if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
             {
               /* Do nothing, let file be marked conflicted. */
               (*result)->choice = svn_wc_conflict_choose_postpone;
               break;
             }
-          else if (strcmp(answer, "mc") == 0)
+          else if (strcmp(answer, "mc") == 0 || strcmp(answer, "X-)") == 0)
             {
               if (desc->is_binary)
                 {
@@ -559,7 +559,7 @@ svn_cl__conflict_handler(svn_wc_conflict
                 (*result)->save_merged = TRUE;
               break;
             }
-          else if (strcmp(answer, "tc") == 0)
+          else if (strcmp(answer, "tc") == 0 || strcmp(answer, "X-(") == 0)
             {
               if (desc->is_binary)
                 {
@@ -582,14 +582,14 @@ svn_cl__conflict_handler(svn_wc_conflict
                 (*result)->save_merged = TRUE;
               break;
             }
-          else if (strcmp(answer, "mf") == 0)
+          else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
             {
               (*result)->choice = svn_wc_conflict_choose_mine_full;
               if (performed_edit)
                 (*result)->save_merged = TRUE;
               break;
             }
-          else if (strcmp(answer, "tf") == 0)
+          else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
             {
               (*result)->choice = svn_wc_conflict_choose_theirs_full;
               if (performed_edit)
@@ -637,13 +637,13 @@ svn_cl__conflict_handler(svn_wc_conflict
               SVN_ERR(show_diff(desc, subpool));
               knows_something = TRUE;
             }
-          else if (strcmp(answer, "e") == 0)
+          else if (strcmp(answer, "e") == 0 || strcmp(answer, ":-E") == 0)
             {
               SVN_ERR(open_editor(&performed_edit, desc, b, subpool));
               if (performed_edit)
                 knows_something = TRUE;
             }
-          else if (strcmp(answer, "l") == 0)
+          else if (strcmp(answer, "l") == 0 || strcmp(answer, ":-l") == 0)
             {
               if (desc->kind == svn_wc_conflict_kind_property)
                 {
@@ -729,17 +729,17 @@ svn_cl__conflict_handler(svn_wc_conflict
                 "(overwrite pre-existing item)\n"
                 "  (h)  help        - show this help\n\n")));
             }
-          if (strcmp(answer, "p") == 0)
+          if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
             {
               (*result)->choice = svn_wc_conflict_choose_postpone;
               break;
             }
-          if (strcmp(answer, "mf") == 0)
+          if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
             {
               (*result)->choice = svn_wc_conflict_choose_mine_full;
               break;
             }
-          if (strcmp(answer, "tf") == 0)
+          if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
             {
               (*result)->choice = svn_wc_conflict_choose_theirs_full;
               break;

Modified: subversion/branches/issue-3668-3669/subversion/svn/export-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/export-cmd.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/export-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/export-cmd.c Thu Nov 11 22:58:49 2010
@@ -52,6 +52,7 @@ svn_cl__export(apr_getopt_t *os,
   svn_error_t *err;
   svn_opt_revision_t peg_revision;
   const char *truefrom;
+  struct svn_cl__check_externals_failed_notify_baton nwb;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -95,6 +96,12 @@ svn_cl__export(apr_getopt_t *os,
   if (opt_state->depth == svn_depth_unknown)
     opt_state->depth = svn_depth_infinity;
 
+  nwb.wrapped_func = ctx->notify_func2;
+  nwb.wrapped_baton = ctx->notify_baton2;
+  nwb.had_externals_error = FALSE;
+  ctx->notify_func2 = svn_cl__check_externals_failed_notify_wrapper;
+  ctx->notify_baton2 = &nwb;
+
   /* Do the export. */
   err = svn_client_export5(NULL, truefrom, to, &peg_revision,
                            &(opt_state->start_revision),
@@ -106,5 +113,10 @@ svn_cl__export(apr_getopt_t *os,
               _("Destination directory exists; please remove "
                 "the directory or use --force to overwrite"));
 
+  if (nwb.had_externals_error)
+    return svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL,
+                            _("Failure occured processing one or more "
+                              "externals definitions"));
+
   return svn_error_return(err);
 }

Modified: subversion/branches/issue-3668-3669/subversion/svn/list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/list-cmd.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/list-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/list-cmd.c Thu Nov 11 22:58:49 2010
@@ -268,13 +268,8 @@ svn_cl__list(apr_getopt_t *os,
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
 
       /* Get peg revisions. */
-      SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
-                                 subpool));
-
-      if (svn_path_is_url(truepath))
-        truepath = svn_uri_canonicalize(truepath, subpool);
-      else
-        truepath = svn_dirent_canonicalize(truepath, subpool);
+      SVN_ERR(svn_cl__opt_parse_path(&peg_revision, &truepath, target,
+                                     subpool));
 
       if (opt_state->xml)
         {

Modified: subversion/branches/issue-3668-3669/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/notify.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/notify.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/notify.c Thu Nov 11 22:58:49 2010
@@ -952,3 +952,18 @@ svn_cl__notifier_mark_export(void *baton
   nb->is_export = TRUE;
   return SVN_NO_ERROR;
 }
+
+void
+svn_cl__check_externals_failed_notify_wrapper(void *baton,
+                                              const svn_wc_notify_t *n,
+                                              apr_pool_t *pool)
+{
+  struct svn_cl__check_externals_failed_notify_baton *nwb = baton;
+
+  if (n->action == svn_wc_notify_failed_external)
+    nwb->had_externals_error = TRUE;
+
+  if (nwb->wrapped_func)
+    nwb->wrapped_func(nwb->wrapped_baton, n, pool);
+}
+

Modified: subversion/branches/issue-3668-3669/subversion/svn/switch-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/switch-cmd.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/switch-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/switch-cmd.c Thu Nov 11 22:58:49 2010
@@ -101,6 +101,7 @@ svn_cl__switch(apr_getopt_t *os,
   svn_opt_revision_t peg_revision;
   svn_depth_t depth;
   svn_boolean_t depth_is_sticky;
+  struct svn_cl__check_externals_failed_notify_baton nwb;
 
   /* This command should discover (or derive) exactly two cmdline
      arguments: a local path to update ("target"), and a new url to
@@ -158,6 +159,12 @@ svn_cl__switch(apr_getopt_t *os,
       depth_is_sticky = FALSE;
     }
 
+  nwb.wrapped_func = ctx->notify_func2;
+  nwb.wrapped_baton = ctx->notify_baton2;
+  nwb.had_externals_error = FALSE;
+  ctx->notify_func2 = svn_cl__check_externals_failed_notify_wrapper;
+  ctx->notify_baton2 = &nwb;
+
   /* Do the 'switch' update. */
   SVN_ERR(svn_client_switch2(NULL, target, switch_url, &peg_revision,
                              &(opt_state->start_revision), depth,
@@ -165,7 +172,12 @@ svn_cl__switch(apr_getopt_t *os,
                              opt_state->force, ctx, scratch_pool));
 
   if (! opt_state->quiet)
-    SVN_ERR(svn_cl__print_conflict_stats(ctx->notify_baton2, scratch_pool));
+    SVN_ERR(svn_cl__print_conflict_stats(nwb.wrapped_baton, scratch_pool));
+
+  if (nwb.had_externals_error)
+    return svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL,
+                            _("Failure occured processing one or more "
+                              "externals definitions"));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/update-cmd.c Thu Nov 11 22:58:49 2010
@@ -50,6 +50,7 @@ svn_cl__update(apr_getopt_t *os,
   apr_array_header_t *targets;
   svn_depth_t depth;
   svn_boolean_t depth_is_sticky;
+  struct svn_cl__check_externals_failed_notify_baton nwb;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -85,6 +86,12 @@ svn_cl__update(apr_getopt_t *os,
       depth_is_sticky = FALSE;
     }
 
+  nwb.wrapped_func = ctx->notify_func2;
+  nwb.wrapped_baton = ctx->notify_baton2;
+  nwb.had_externals_error = FALSE;
+  ctx->notify_func2 = svn_cl__check_externals_failed_notify_wrapper;
+  ctx->notify_baton2 = &nwb;
+  
   SVN_ERR(svn_client_update3(NULL, targets,
                              &(opt_state->start_revision),
                              depth, depth_is_sticky,
@@ -93,7 +100,12 @@ svn_cl__update(apr_getopt_t *os,
                              ctx, scratch_pool));
 
   if (! opt_state->quiet)
-    SVN_ERR(svn_cl__print_conflict_stats(ctx->notify_baton2, scratch_pool));
+    SVN_ERR(svn_cl__print_conflict_stats(nwb.wrapped_baton, scratch_pool));
+
+  if (nwb.had_externals_error)
+    return svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL,
+                            _("Failure occured processing one or more "
+                              "externals definitions"));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/issue-3668-3669/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svn/util.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svn/util.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svn/util.c Thu Nov 11 22:58:49 2010
@@ -71,8 +71,13 @@ svn_cl__print_commit_info(const svn_comm
                           apr_pool_t *pool)
 {
   if (SVN_IS_VALID_REVNUM(commit_info->revision))
-    SVN_ERR(svn_cmdline_printf(pool, _("\nCommitted revision %ld.\n"),
-                               commit_info->revision));
+    SVN_ERR(svn_cmdline_printf(pool, _("\nCommitted revision %ld%s.\n"),
+                               commit_info->revision,
+                               commit_info->revision == 42 &&
+                               getenv("SVN_I_LOVE_PANGALACTIC_GARGLE_BLASTERS")
+                                 ?  _(" (the answer to life, the universe, "
+                                      "and everything)")
+                                 : ""));
 
   /* Writing to stdout, as there maybe systems that consider the
    * presence of stderr as an indication of commit failure.
@@ -1324,3 +1329,19 @@ svn_cl__eat_peg_revisions(apr_array_head
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_cl__opt_parse_path(svn_opt_revision_t *rev,
+                       const char **truepath,
+                       const char *path /* UTF-8! */,
+                       apr_pool_t *pool)
+{
+  SVN_ERR(svn_opt_parse_path(rev, truepath, path, pool));
+  
+  if (svn_path_is_url(*truepath))
+    *truepath = svn_uri_canonicalize(*truepath, pool);
+  else
+    *truepath = svn_dirent_canonicalize(*truepath, pool);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/issue-3668-3669/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svnrdump/load_editor.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svnrdump/load_editor.c Thu Nov 11 22:58:49 2010
@@ -590,7 +590,9 @@ close_revision(void *baton)
           SVN_ERR(commit_editor->close_directory(rb->db->baton, rb->pool));
           rb->db = rb->db->parent;
         }
+      /* root dir's baton */
       LDR_DBG(("Closing edit on %p\n", commit_edit_baton));
+      SVN_ERR(commit_editor->close_directory(rb->db->baton, rb->pool));
       SVN_ERR(commit_editor->close_edit(commit_edit_baton, rb->pool));
     }
   else
@@ -606,6 +608,7 @@ close_revision(void *baton)
 
       LDR_DBG(("Opened root %p\n", child_baton));
       LDR_DBG(("Closing edit on %p\n", commit_edit_baton));
+      SVN_ERR(commit_editor->close_directory(child_baton, rb->pool));
       SVN_ERR(commit_editor->close_edit(commit_edit_baton, rb->pool));
     }
 

Modified: subversion/branches/issue-3668-3669/subversion/svnsync/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/svnsync/main.c?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/svnsync/main.c (original)
+++ subversion/branches/issue-3668-3669/subversion/svnsync/main.c Thu Nov 11 22:58:49 2010
@@ -530,6 +530,8 @@ check_if_session_is_at_repos_root(svn_ra
 /* Remove the properties in TARGET_PROPS but not in SOURCE_PROPS from
  * revision REV of the repository associated with RA session SESSION.
  *
+ * For REV zero, don't remove properties with the "svn:sync-" prefix.
+ * 
  * All allocations will be done in a subpool of POOL.
  */
 static svn_error_t *
@@ -550,6 +552,10 @@ remove_props_not_in_source(svn_ra_sessio
 
       svn_pool_clear(subpool);
 
+      if (rev == 0 && !strncmp(propname, SVNSYNC_PROP_PREFIX,
+                               sizeof(SVNSYNC_PROP_PREFIX) - 1))
+        continue;
+
       /* Delete property if the name can't be found in SOURCE_PROPS. */
       if (! apr_hash_get(source_props, propname, APR_HASH_KEY_STRING))
         SVN_ERR(svn_ra_change_rev_prop2(session, rev, propname, NULL,
@@ -1487,7 +1493,7 @@ do_copy_revprops(svn_ra_session_t *to_se
     {
       int normalized_count;
       SVN_ERR(check_cancel(NULL));
-      SVN_ERR(copy_revprops(from_session, to_session, i, FALSE,
+      SVN_ERR(copy_revprops(from_session, to_session, i, TRUE,
                             baton->quiet, &normalized_count, pool));
       normalized_rev_props_count += normalized_count;
     }

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/authz_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/authz_tests.py Thu Nov 11 22:58:49 2010
@@ -1090,9 +1090,10 @@ test_list = [ None,
               Skip(authz_recursive_ls,
                    svntest.main.is_ra_type_file),
              ]
+serial_only = True
 
 if __name__ == '__main__':
-  svntest.main.run_tests(test_list, serial_only = True)
+  svntest.main.run_tests(test_list, serial_only = serial_only)
   # NOTREACHED
 
 

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/externals_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/externals_tests.py Thu Nov 11 22:58:49 2010
@@ -947,7 +947,7 @@ def old_style_externals_ignore_peg_reg(s
   svntest.actions.run_and_verify_svn2("External '%s' used pegs" % ext.strip(),
                                       None,
                                       expected_error,
-                                      0,
+                                      1,
                                       'up',
                                       wc_dir)
 
@@ -1063,7 +1063,7 @@ def can_place_file_external_into_dir_ext
   svntest.actions.run_and_verify_svn2("Able to put file external in foreign wc",
                                       None,
                                       expected_error,
-                                      0,
+                                      1,
                                       'up',
                                       repo_url, wc_dir)
 

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/merge_authz_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/merge_authz_tests.py Thu Nov 11 22:58:49 2010
@@ -689,9 +689,10 @@ test_list = [ None,
                               svntest.main.is_ra_type_file),
                          svntest.main.server_has_mergeinfo),
              ]
+serial_only = True
 
 if __name__ == '__main__':
-  svntest.main.run_tests(test_list, serial_only = True)
+  svntest.main.run_tests(test_list, serial_only = serial_only)
   # NOTREACHED
 
 

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/patch_tests.py Thu Nov 11 22:58:49 2010
@@ -3356,6 +3356,124 @@ def patch_reverse_revert(sbox):
                                        1, # dry-run
                                        '--reverse-diff')
 
+def patch_one_property(sbox, trailing_eol):
+  """Helper.  Apply a patch that sets the property 'k' to 'v\n' or to 'v',
+   and check the results."""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: .\n",
+    "===================================================================\n",
+    "diff --git a/subversion/branches/1.6.x b/subversion/branches/1.6.x\n",
+    "--- a/subversion/branches/1.6.x\t(revision 1033278)\n",
+    "+++ b/subversion/branches/1.6.x\t(working copy)\n",
+    "\n",
+    "Property changes on: subversion/branches/1.6.x\n",
+    "___________________________________________________________________\n",
+    "Modified: svn:mergeinfo\n",
+    "   Merged /subversion/trunk:r964349\n",
+    "Added: k\n",
+    "## -0,0 +1 ##\n",
+    "+v\n",
+  ]
+
+  if trailing_eol:
+    value = "v\n"
+  else:
+    value = "v"
+    unidiff_patch += ['\ No newline at end of property']
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    ' U        %s\n' % os.path.join(wc_dir),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({'': Item(props={'k' : value})})
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('', status=' M')
+
+  expected_skip = wc.State('.', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1, # dry-run
+                                       '--strip', '3')
+
+  svntest.actions.check_prop('k', wc_dir, [value])
+
+def patch_strip_cwd(sbox):
+  "patch --strip propchanges cwd"
+  return patch_one_property(sbox, True)
+
+def patch_set_prop_no_eol(sbox):
+  "patch doesn't append newline to properties"
+  return patch_one_property(sbox, False)
+
+# Regression test for issue #3697
+def patch_add_symlink(sbox):
+  "patch that adds a symlink"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  patch_file_path = make_patch_path(sbox)
+
+  # Apply patch
+
+  unidiff_patch = [
+    "Index: iota_symlink\n",
+    "===================================================================\n",
+    "--- iota_symlink\t(revision 0)\n",
+    "+++ iota_symlink\t(working copy)\n",
+    "@@ -0,0 +1 @@\n",
+    "+link iota\n",
+    "\n",
+    "Property changes on: iota_symlink\n",
+    "-------------------------------------------------------------------\n",
+    "Added: svn:special\n",
+    "## -0,0 +1 ##\n",
+    "+*\n",
+  ]
+
+  svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+  expected_output = [
+    'A         %s\n' % os.path.join(wc_dir, 'iota_symlink'),
+  ]
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({'iota_symlink': Item(contents="This is the file 'iota'.\n",
+                                          props={'svn:special' : '*'})})
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({'iota_symlink': Item(status='A ', wc_rev='0')})
+
+  expected_skip = wc.State('', { })
+
+  svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path),
+                                       expected_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, # expected err
+                                       1, # check-props
+                                       1) # dry-run
+
+
 ########################################################################
 #Run the tests
 
@@ -3388,6 +3506,9 @@ test_list = [ None,
               patch_git_empty_files,
               patch_old_target_names,
               patch_reverse_revert,
+              patch_strip_cwd,
+              XFail(patch_set_prop_no_eol),
+              patch_add_symlink,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnrdump_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnrdump_tests.py Thu Nov 11 22:58:49 2010
@@ -340,7 +340,7 @@ test_list = [ None,
               tag_trunk_with_file2_dump,
               tag_trunk_with_file2_load,
               dir_prop_change_dump,
-              Wimp("TODO", dir_prop_change_load, svntest.main.is_ra_type_dav),
+              dir_prop_change_load,
               copy_parent_modify_prop_dump,
               copy_parent_modify_prop_load,
               url_encoding_dump,

Modified: subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnsync_tests.py?rev=1034191&r1=1034190&r2=1034191&view=diff
==============================================================================
--- subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/issue-3668-3669/subversion/tests/cmdline/svnsync_tests.py Thu Nov 11 22:58:49 2010
@@ -868,11 +868,12 @@ test_list = [ None,
               delete_svn_props,
               commit_a_copy_of_root,
               descend_into_replace,
-              XFail(delete_revprops),
+              delete_revprops,
              ]
+serial_only = True
 
 if __name__ == '__main__':
-  svntest.main.run_tests(test_list, serial_only = True)
+  svntest.main.run_tests(test_list, serial_only = serial_only)
   # NOTREACHED