subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1449262 [8/25] - in /subversion/branches/ev2-export: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ build/win32/ contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ notes/ notes...
Date Sat, 23 Feb 2013 01:25:44 GMT
Modified: subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/rev_hunt.c Sat Feb 23 01:25:38 2013
@@ -532,7 +532,7 @@ check_ancestry_of_peg_path(svn_boolean_t
 {
   svn_fs_root_t *root;
   svn_fs_history_t *history;
-  const char *path;
+  const char *path = NULL;
   svn_revnum_t revision;
   apr_pool_t *lastpool, *currpool;
 
@@ -1252,17 +1252,18 @@ find_merged_revisions(apr_array_header_t
                       apr_hash_t *duplicate_path_revs,
                       svn_repos_authz_func_t authz_read_func,
                       void *authz_read_baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   const apr_array_header_t *old;
   apr_array_header_t *new_merged_path_revs;
   apr_pool_t *iterpool, *last_pool;
   apr_array_header_t *merged_path_revisions =
-    apr_array_make(pool, 0, sizeof(struct path_revision *));
+    apr_array_make(scratch_pool, 0, sizeof(struct path_revision *));
 
   old = mainline_path_revisions;
-  iterpool = svn_pool_create(pool);
-  last_pool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
+  last_pool = svn_pool_create(scratch_pool);
 
   do
     {
@@ -1325,8 +1326,8 @@ find_merged_revisions(apr_array_header_t
                                                      TRUE, TRUE,
                                                      duplicate_path_revs,
                                                      authz_read_func,
-                                                     authz_read_baton, pool,
-                                                     iterpool3));
+                                                     authz_read_baton,
+                                                     result_pool, iterpool3));
                 }
               svn_pool_destroy(iterpool3);
             }
@@ -1350,7 +1351,8 @@ find_merged_revisions(apr_array_header_t
         sizeof(struct path_revision *), compare_path_revisions);
 
   /* Copy to the output array. */
-  *merged_path_revisions_out = apr_array_copy(pool, merged_path_revisions);
+  *merged_path_revisions_out = apr_array_copy(result_pool,
+                                              merged_path_revisions);
 
   svn_pool_destroy(iterpool);
   svn_pool_destroy(last_pool);
@@ -1447,6 +1449,114 @@ send_path_revision(struct path_revision 
   return SVN_NO_ERROR;
 }
 
+/* Similar to svn_repos_get_file_revs2() but returns paths while walking
+   history instead of after collecting all history.
+
+   This allows implementing clients to immediately start processing and
+   stop when they got the information they need. (E.g. all or a specific set
+   of lines were modified) */
+static svn_error_t *
+get_file_revs_backwards(svn_repos_t *repos,
+                        const char *path,
+                        svn_revnum_t start,
+                        svn_revnum_t end,
+                        svn_repos_authz_func_t authz_read_func,
+                        void *authz_read_baton,
+                        svn_file_rev_handler_t handler,
+                        void *handler_baton,
+                        apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool, *last_pool;
+  svn_fs_history_t *history;
+  svn_fs_root_t *root;
+  svn_node_kind_t kind;
+  struct send_baton sb;
+
+  /* We switch between two pools while looping and so does the path-rev
+     handler for actually reported revisions. We do this as we
+     need just information from last iteration to be available. */
+
+  iterpool = svn_pool_create(scratch_pool);
+  last_pool = svn_pool_create(scratch_pool);
+  sb.iterpool = svn_pool_create(scratch_pool);
+  sb.last_pool = svn_pool_create(scratch_pool);
+
+  /* We want the first txdelta to be against the empty file. */
+  sb.last_root = NULL;
+  sb.last_path = NULL;
+
+  /* Create an empty hash table for the first property diff. */
+  sb.last_props = apr_hash_make(sb.last_pool);
+
+  /* The path had better be a file in this revision. */
+  SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, scratch_pool));
+  SVN_ERR(svn_fs_check_path(&kind, root, path, scratch_pool));
+  if (kind != svn_node_file)
+    return svn_error_createf(SVN_ERR_FS_NOT_FILE, 
+                             NULL, _("'%s' is not a file in revision %ld"),
+                             path, end);
+
+  /* Open a history object. */
+  SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+  while (1)
+    {
+      struct path_revision *path_rev;
+      svn_revnum_t tmp_revnum;
+      const char *tmp_path;
+
+      svn_pool_clear(iterpool);
+
+      /* Fetch the history object to walk through. */
+      SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+      if (!history)
+        break;
+      SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
+                                      history, iterpool));
+
+      /* Check authorization. */
+      if (authz_read_func)
+        {
+          svn_boolean_t readable;
+          svn_fs_root_t *tmp_root;
+
+          SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, tmp_revnum,
+                                       iterpool));
+          SVN_ERR(authz_read_func(&readable, tmp_root, tmp_path,
+                                  authz_read_baton, iterpool));
+          if (! readable)
+            break;
+        }
+
+      /* We didn't break, so we must really want this path-rev. */
+      path_rev = apr_palloc(iterpool, sizeof(*path_rev));
+      path_rev->path = tmp_path;
+      path_rev->revnum = tmp_revnum;
+      path_rev->merged = FALSE;
+
+      SVN_ERR(send_path_revision(path_rev, repos, &sb,
+                                 handler, handler_baton));
+
+      if (path_rev->revnum <= start)
+        break;
+
+      /* Swap pools. */
+      {
+        apr_pool_t *tmp_pool = iterpool;
+        iterpool = last_pool;
+        last_pool = tmp_pool;
+      }
+    }
+
+  svn_pool_destroy(iterpool);
+  svn_pool_destroy(last_pool);
+  svn_pool_destroy(sb.last_pool);
+  svn_pool_destroy(sb.iterpool);
+
+  return SVN_NO_ERROR;
+
+}
+
+
 /* We don't yet support sending revisions in reverse order; the caller wait
  * until we've traced back through the entire history, and then accept
  * them from oldest to youngest.  Someday this may change, but in the meantime,
@@ -1463,6 +1573,10 @@ send_path_revision(struct path_revision 
  *     oldest to youngest, interleaving as appropriate.  This is implemented
  *     similar to an insertion sort, but instead of inserting into another
  *     array, we just call the appropriate handler.
+ *
+ * 2013-02: Added a very simple reverse for mainline only changes. Before this,
+ *          this would return an error (path not found) or just the first
+ *          revision before end.
  */
 svn_error_t *
 svn_repos_get_file_revs2(svn_repos_t *repos,
@@ -1474,48 +1588,65 @@ svn_repos_get_file_revs2(svn_repos_t *re
                          void *authz_read_baton,
                          svn_file_rev_handler_t handler,
                          void *handler_baton,
-                         apr_pool_t *pool)
+                         apr_pool_t *scratch_pool)
 {
   apr_array_header_t *mainline_path_revisions, *merged_path_revisions;
   apr_hash_t *duplicate_path_revs;
   struct send_baton sb;
   int mainline_pos, merged_pos;
 
+  if (end < start)
+    {
+      if (include_merged_revisions)
+        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, NULL);
+
+      return svn_error_trace(
+                      get_file_revs_backwards(repos, path,
+                                              end, start,
+                                              authz_read_func,
+                                              authz_read_baton,
+                                              handler,
+                                              handler_baton,
+                                              scratch_pool));
+    }
+
+  /* We switch between two pools while looping, since we need information from
+     the last iteration to be available. */
+  sb.iterpool = svn_pool_create(scratch_pool);
+  sb.last_pool = svn_pool_create(scratch_pool);
+
+  /* We want the first txdelta to be against the empty file. */
+  sb.last_root = NULL;
+  sb.last_path = NULL;
+
+  /* Create an empty hash table for the first property diff. */
+  sb.last_props = apr_hash_make(sb.last_pool);
+
+
   /* Get the revisions we are interested in. */
-  duplicate_path_revs = apr_hash_make(pool);
-  mainline_path_revisions = apr_array_make(pool, 0,
+  duplicate_path_revs = apr_hash_make(scratch_pool);
+  mainline_path_revisions = apr_array_make(scratch_pool, 100,
                                            sizeof(struct path_revision *));
   SVN_ERR(find_interesting_revisions(mainline_path_revisions, repos, path,
                                      start, end, include_merged_revisions,
                                      FALSE, duplicate_path_revs,
-                                     authz_read_func, authz_read_baton, pool,
-                                     pool));
+                                     authz_read_func, authz_read_baton,
+                                     scratch_pool, sb.iterpool));
 
   /* If we are including merged revisions, go get those, too. */
   if (include_merged_revisions)
     SVN_ERR(find_merged_revisions(&merged_path_revisions, start,
                                   mainline_path_revisions, repos,
                                   duplicate_path_revs, authz_read_func,
-                                  authz_read_baton, pool));
+                                  authz_read_baton,
+                                  scratch_pool, sb.iterpool));
   else
-    merged_path_revisions = apr_array_make(pool, 0,
+    merged_path_revisions = apr_array_make(scratch_pool, 0,
                                            sizeof(struct path_revision *));
 
   /* We must have at least one revision to get. */
   SVN_ERR_ASSERT(mainline_path_revisions->nelts > 0);
 
-  /* We switch betwwen two pools while looping, since we need information from
-     the last iteration to be available. */
-  sb.iterpool = svn_pool_create(pool);
-  sb.last_pool = svn_pool_create(pool);
-
-  /* We want the first txdelta to be against the empty file. */
-  sb.last_root = NULL;
-  sb.last_path = NULL;
-
-  /* Create an empty hash table for the first property diff. */
-  sb.last_props = apr_hash_make(sb.last_pool);
-
   /* Walk through both mainline and merged revisions, and send them in
      reverse chronological order, interleaving as appropriate. */
   mainline_pos = mainline_path_revisions->nelts - 1;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/auth.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/auth.c Sat Feb 23 01:25:38 2013
@@ -35,6 +35,8 @@
 #include "svn_dso.h"
 #include "svn_version.h"
 
+#include "auth.h"
+
 /* AN OVERVIEW
    ===========
 
@@ -619,3 +621,20 @@ svn_auth_get_platform_specific_client_pr
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_auth_cleanup_walk(svn_auth_baton_t *baton,
+                      svn_auth_cleanup_callback cleanup,
+                      void *cleanup_baton,
+                      apr_pool_t *scratch_pool)
+{
+
+  if (apr_hash_get(baton->tables, SVN_AUTH_CRED_SIMPLE, APR_HASH_KEY_STRING))
+    {
+      SVN_ERR(svn_auth__simple_cleanup_walk(baton, cleanup, cleanup_baton,
+                                            baton->creds_cache, scratch_pool));
+    }
+  /* ### Maybe add support for other providers? */
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c Sat Feb 23 01:25:38 2013
@@ -1372,7 +1372,7 @@ membuffer_cache_set_internal(svn_membuff
 
   /* if there is an old version of that entry and the new data fits into
    * the old spot, just re-use that space. */
-  if (buffer && entry && entry->size >= size)
+  if (entry && ALIGN_VALUE(entry->size) >= size && buffer)
     {
       cache->data_used += size - entry->size;
       entry->size = size;
@@ -1430,7 +1430,10 @@ membuffer_cache_set_internal(svn_membuff
   else
     {
       /* if there is already an entry for this key, drop it.
+       * Since ensure_data_insertable may have removed entries from
+       * ENTRY's group, re-do the lookup.
        */
+      entry = find_entry(cache, group_index, to_find, FALSE);
       if (entry)
         drop_entry(cache, entry);
     }
@@ -1967,16 +1970,6 @@ svn_membuffer_cache_get(void **value_p,
                               DEBUG_CACHE_MEMBUFFER_TAG
                               result_pool));
 
-  /* We don't need more the key anymore.
-   * But since we allocate only small amounts of data per get() call and
-   * apr_pool_clear is somewhat expensive, we clear it only now and then.
-   */
-  if (++cache->alloc_counter > ALLOCATIONS_PER_POOL_CLEAR)
-    {
-      svn_pool_clear(cache->pool);
-      cache->alloc_counter = 0;
-    }
-
   /* return result */
   *found = *value_p != NULL;
   return SVN_NO_ERROR;
@@ -2060,12 +2053,6 @@ svn_membuffer_cache_get_partial(void **v
       return SVN_NO_ERROR;
     }
 
-  if (++cache->alloc_counter > ALLOCATIONS_PER_POOL_CLEAR)
-    {
-      svn_pool_clear(cache->pool);
-      cache->alloc_counter = 0;
-    }
-
   combine_key(cache, key, cache->key_len);
   SVN_ERR(membuffer_cache_get_partial(cache->membuffer,
                                       cache->combined_key,

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/config_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/config_auth.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/config_auth.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/config_auth.c Sat Feb 23 01:25:38 2013
@@ -29,18 +29,20 @@
 
 #include "config_impl.h"
 
+#include "auth.h"
+
 #include "svn_private_config.h"
 
 /* Helper for svn_config_{read|write}_auth_data.  Return a path to a
    file within ~/.subversion/auth/ that holds CRED_KIND credentials
    within REALMSTRING.  If no path is available *PATH will be set to
    NULL. */
-static svn_error_t *
-auth_file_path(const char **path,
-               const char *cred_kind,
-               const char *realmstring,
-               const char *config_dir,
-               apr_pool_t *pool)
+svn_error_t *
+svn_auth__file_path(const char **path,
+                    const char *cred_kind,
+                    const char *realmstring,
+                    const char *config_dir,
+                    apr_pool_t *pool)
 {
   const char *authdir_path, *hexname;
   svn_checksum_t *checksum;
@@ -81,8 +83,8 @@ svn_config_read_auth_data(apr_hash_t **h
 
   *hash = NULL;
 
-  SVN_ERR(auth_file_path(&auth_path, cred_kind, realmstring, config_dir,
-                         pool));
+  SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir,
+                              pool));
   if (! auth_path)
     return SVN_NO_ERROR;
 
@@ -118,8 +120,8 @@ svn_config_write_auth_data(apr_hash_t *h
   svn_stream_t *stream;
   const char *auth_path;
 
-  SVN_ERR(auth_file_path(&auth_path, cred_kind, realmstring, config_dir,
-                         pool));
+  SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir,
+                              pool));
   if (! auth_path)
     return svn_error_create(SVN_ERR_NO_AUTH_FILE_PATH, NULL,
                             _("Unable to locate auth file"));

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c Sat Feb 23 01:25:38 2013
@@ -1175,8 +1175,18 @@ svn_config_ensure(const char *config_dir
         ""                                                                   NL
         "### Section for configuring working copies."                        NL
         "[working-copy]"                                                     NL
-        "### Set to true to enable exclusive SQLite locking.  Some clients"  NL
-        "### may not support exclusive locking."                             NL
+        "### Set to a list of the names of specific clients that should use" NL
+        "### exclusive SQLite locking of working copies.  This increases the"NL
+        "### performance of the client but prevents concurrent access by"    NL
+        "### other clients."                                                 NL
+        "### Possible values:"                                               NL
+        "###   svn                (the command line client)"                 NL
+        "### Third-party clients may also support this option."              NL
+        "# exclusive-locking-clients ="                                      NL
+        "### Set to true to enable exclusive SQLite locking of working"      NL
+        "### copies by all clients.  Enabling this may cause some clients"   NL
+        "### to fail to work properly. This does not have to be set for"     NL
+        "### exclusive-locking-clients to work."                             NL
         "# exclusive-locking = false"                                        NL;
 
       err = svn_io_file_open(&f, path,

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c Sat Feb 23 01:25:38 2013
@@ -1201,26 +1201,15 @@ range_swap_endpoints(svn_merge_range_t *
 svn_error_t *
 svn_rangelist_reverse(svn_rangelist_t *rangelist, apr_pool_t *pool)
 {
-  int i, swap_index;
-  svn_merge_range_t range;
-  for (i = 0; i < rangelist->nelts / 2; i++)
-    {
-      swap_index = rangelist->nelts - i - 1;
-      range = *APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
-      *APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *) =
-        *APR_ARRAY_IDX(rangelist, swap_index, svn_merge_range_t *);
-      *APR_ARRAY_IDX(rangelist, swap_index, svn_merge_range_t *) = range;
-      range_swap_endpoints(APR_ARRAY_IDX(rangelist, swap_index,
-                                         svn_merge_range_t *));
+  int i;
+
+  svn_sort__array_reverse(rangelist, pool);
+
+  for (i = 0; i < rangelist->nelts; i++)
+    {
       range_swap_endpoints(APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *));
     }
 
-  /* If there's an odd number of elements, we still need to swap the
-     end points of the remaining range. */
-  if (rangelist->nelts % 2 == 1)
-    range_swap_endpoints(APR_ARRAY_IDX(rangelist, rangelist->nelts / 2,
-                                       svn_merge_range_t *));
-
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/prompt.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/prompt.c Sat Feb 23 01:25:38 2013
@@ -29,6 +29,7 @@
 
 #include <apr_lib.h>
 #include <apr_poll.h>
+#include <apr_portable.h>
 
 #include "svn_cmdline.h"
 #include "svn_string.h"
@@ -39,41 +40,385 @@
 #include "private/svn_cmdline_private.h"
 #include "svn_private_config.h"
 
+#ifdef WIN32
+#include <conio.h>
+#elif defined(HAVE_TERMIOS_H)
+#include <termios.h>
+#endif
+
 
 
-/* Wait for input on @a *f.  Doing all allocations
- * in @a pool.  This functions is based on apr_wait_for_io_or_timeout().
- * Note that this will return an EINTR on a signal.
- *
- * ### FIX: When APR gives us a better way of doing this use it. */
-static apr_status_t wait_for_input(apr_file_t *f,
-                                   apr_pool_t *pool)
+/* Descriptor of an open terminal */
+typedef struct terminal_handle_t terminal_handle_t;
+struct terminal_handle_t
+{
+  apr_file_t *infd;              /* input file handle */
+  apr_file_t *outfd;             /* output file handle */
+  svn_boolean_t noecho;          /* terminal echo was turned off */
+  svn_boolean_t close_handles;   /* close handles when closing the terminal */
+  apr_pool_t *pool;              /* pool associated with the file handles */
+
+#ifdef HAVE_TERMIOS_H
+  svn_boolean_t restore_state;   /* terminal state was changed */
+  apr_os_file_t osinfd;          /* OS-specific handle for infd */
+  struct termios attr;           /* saved terminal attributes */
+#endif
+};
+
+/* Initialize safe state of terminal_handle_t. */
+static void
+terminal_handle_init(terminal_handle_t *terminal,
+                     apr_file_t *infd, apr_file_t *outfd,
+                     svn_boolean_t noecho, svn_boolean_t close_handles,
+                     apr_pool_t *pool)
+{
+  memset(terminal, 0, sizeof(*terminal));
+  terminal->infd = infd;
+  terminal->outfd = outfd;
+  terminal->noecho = noecho;
+  terminal->close_handles = close_handles;
+  terminal->pool = pool;
+}
+
+/*
+ * Common pool cleanup handler for terminal_handle_t. Closes TERMINAL.
+ * If CLOSE_HANDLES is TRUE, close the terminal file handles.
+ * If RESTORE_STATE is TRUE, restores the TERMIOS flags of the terminal.
+ */
+static apr_status_t
+terminal_cleanup_handler(terminal_handle_t *terminal,
+                         svn_boolean_t close_handles,
+                         svn_boolean_t restore_state)
+{
+  apr_status_t status = APR_SUCCESS;
+
+#ifdef HAVE_TERMIOS_H
+  /* Restore terminal state flags. */
+  if (restore_state && terminal->restore_state)
+    tcsetattr(terminal->osinfd, TCSANOW, &terminal->attr);
+#endif
+
+  /* Close terminal handles. */
+  if (close_handles && terminal->close_handles)
+    {
+      apr_file_t *const infd = terminal->infd;
+      apr_file_t *const outfd = terminal->outfd;
+
+      if (infd)
+        {
+          terminal->infd = NULL;
+          status = apr_file_close(infd);
+        }
+
+      if (!status && outfd && outfd != infd)
+        {
+          terminal->outfd = NULL;
+          status = apr_file_close(terminal->outfd);
+        }
+    }
+  return status;
+}
+
+/* Normal pool cleanup for a terminal. */
+static apr_status_t terminal_plain_cleanup(void *baton)
 {
-#ifndef WIN32
-  apr_pollfd_t pollset;
-  int srv, n;
+  return terminal_cleanup_handler(baton, FALSE, TRUE);
+}
+
+/* Child pool cleanup for a terminal -- does not restore echo state. */
+static apr_status_t terminal_child_cleanup(void *baton)
+{
+  return terminal_cleanup_handler(baton, FALSE, FALSE);
+}
+
+/* Explicitly close the terminal, removing its cleanup handlers. */
+static svn_error_t *
+terminal_close(terminal_handle_t *terminal)
+{
+  apr_status_t status;
+
+  /* apr_pool_cleanup_kill() removes both normal and child cleanup */
+  apr_pool_cleanup_kill(terminal->pool, terminal, terminal_plain_cleanup);
+
+  status = terminal_cleanup_handler(terminal, TRUE, TRUE);
+  if (status)
+    return svn_error_create(status, NULL, _("Can't close terminal"));
+  return SVN_NO_ERROR;
+}
+
+/* Allocate and open *TERMINAL. If NOECHO is TRUE, try to turn off
+   terminal echo.  Use POOL for all allocations.*/
+static svn_error_t *
+terminal_open(terminal_handle_t **terminal, svn_boolean_t noecho,
+              apr_pool_t *pool)
+{
+  apr_status_t status;
 
-  pollset.desc_type = APR_POLL_FILE;
-  pollset.desc.f = f;
-  pollset.p = pool;
-  pollset.reqevents = APR_POLLIN;
-
-  srv = apr_poll(&pollset, 1, &n, -1);
-
-  if (n == 1 && pollset.rtnevents & APR_POLLIN)
-    return APR_SUCCESS;
-
-  return srv;
-#else
-  /* APR specs say things that are unimplemented are supposed to return
-   * APR_ENOTIMPL.  But when trying to use APR_POLL_FILE with apr_poll
-   * on Windows it returns APR_EBADF instead.  So just return APR_ENOTIMPL
-   * ourselves here.
-   */
-  return APR_ENOTIMPL;
+#ifdef WIN32
+  /* On Windows, we'll use the console API directly if the process has
+     a console attached; otherwise we'll just use stdin and stderr. */
+  const HANDLE conin = CreateFileW(L"CONIN$", GENERIC_READ,
+                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                   NULL, OPEN_EXISTING,
+                                   FILE_ATTRIBUTE_NORMAL, NULL);
+  *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
+  if (conin != INVALID_HANDLE_VALUE)
+    {
+      /* The process has a console. */
+      CloseHandle(conin);
+      terminal_handle_init(*terminal, NULL, NULL, noecho, FALSE, NULL);
+      return SVN_NO_ERROR;
+    }
+#else  /* !WIN32 */
+  /* Without evidence to the contrary, we'll assume this is *nix and
+     try to open /dev/tty. If that fails, we'll use stdin for input
+     and stderr for prompting. */
+  apr_file_t *tmpfd;
+  status = apr_file_open(&tmpfd, "/dev/tty",
+                         APR_FOPEN_READ | APR_FOPEN_WRITE,
+                         APR_OS_DEFAULT, pool);
+  *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
+  if (!status)
+    {
+      /* We have a terminal handle that we can use for input and output. */
+      terminal_handle_init(*terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
+    }
+#endif /* !WIN32 */
+  else
+    {
+      /* There is no terminal. Sigh. */
+      apr_file_t *infd;
+      apr_file_t *outfd;
+
+      status = apr_file_open_stdin(&infd, pool);
+      if (status)
+        return svn_error_wrap_apr(status, _("Can't open stdin"));
+      status = apr_file_open_stderr(&outfd, pool);
+      if (status)
+        return svn_error_wrap_apr(status, _("Can't open stderr"));
+      terminal_handle_init(*terminal, infd, outfd, FALSE, FALSE, pool);
+    }
+
+#ifdef HAVE_TERMIOS_H
+  /* Set terminal state */
+  if (0 == apr_os_file_get(&(*terminal)->osinfd, (*terminal)->infd))
+    {
+      if (0 == tcgetattr((*terminal)->osinfd, &(*terminal)->attr))
+        {
+          struct termios attr = (*terminal)->attr;
+          /* Turn off signal handling and canonical input mode */
+          attr.c_lflag &= ~(ISIG | ICANON);
+          attr.c_cc[VMIN] = 1;          /* Read one byte at a time */
+          attr.c_cc[VTIME] = 0;         /* No timeout, wait indefinitely */
+          if (noecho)
+            attr.c_lflag &= ~(ECHO);    /* Turn off echo */
+          if (0 == tcsetattr((*terminal)->osinfd, TCSAFLUSH, &attr))
+            {
+              (*terminal)->noecho = noecho;
+              (*terminal)->restore_state = TRUE;
+            }
+        }
+    }
+#endif /* HAVE_TERMIOS_H */
+
+  /* Register pool cleanup to close handles and restore echo state. */
+  apr_pool_cleanup_register((*terminal)->pool, *terminal,
+                            terminal_plain_cleanup,
+                            terminal_child_cleanup);
+  return SVN_NO_ERROR;
+}
+
+/* Write a null-terminated STRING to TERMINAL.
+   Use POOL for allocations related to converting STRING from UTF-8. */
+static svn_error_t *
+terminal_puts(const char *string, terminal_handle_t *terminal,
+              apr_pool_t *pool)
+{
+  svn_error_t *err;
+  apr_status_t status;
+  const char *converted;
+
+  err = svn_cmdline_cstring_from_utf8(&converted, string, pool);
+  if (err)
+    {
+      svn_error_clear(err);
+      converted = svn_cmdline_cstring_from_utf8_fuzzy(string, pool);
+    }
+
+#ifdef WIN32
+  if (!terminal->outfd)
+    {
+      /* See terminal_open; we're using Console I/O. */
+      _cputs(converted);
+      return SVN_NO_ERROR;
+    }
 #endif
+
+  status = apr_file_write_full(terminal->outfd, converted,
+                               strlen(converted), NULL);
+  if (!status)
+    status = apr_file_flush(terminal->outfd);
+  if (status)
+    return svn_error_wrap_apr(status, _("Can't write to terminal"));
+  return SVN_NO_ERROR;
 }
 
+/* These codes can be returned from terminal_getc instead of a character. */
+#define TERMINAL_NONE  0x80000               /* no character read, retry */
+#define TERMINAL_DEL   (TERMINAL_NONE + 1)   /* the input was a deleteion */
+#define TERMINAL_EOL   (TERMINAL_NONE + 2)   /* end of input/end of line */
+#define TERMINAL_EOF   (TERMINAL_NONE + 3)   /* end of file during input */
+
+/* Read one character or control code from TERMINAL, returning it in CODE.
+   if CAN_ERASE and the input was a deletion, emit codes to erase the
+   last character displayed on the terminal.
+   Use POOL for all allocations. */
+static svn_error_t *
+terminal_getc(int *code, terminal_handle_t *terminal,
+              svn_boolean_t can_erase, apr_pool_t *pool)
+{
+  apr_status_t status = APR_SUCCESS;
+  char ch;
+
+#ifdef WIN32
+  if (!terminal->infd)
+    {
+      /* See terminal_open; we're using Console I/O. */
+      const svn_boolean_t echo = !terminal->noecho;
+
+      /*  The following was hoisted from APR's getpass for Windows. */
+      int concode = _getch();
+      switch (concode)
+        {
+        case '\r':                      /* end-of-line */
+          *code = TERMINAL_EOL;
+          if (echo)
+            _cputs("\r\n");
+          break;
+
+        case EOF:                       /* end-of-file */
+        case 26:                        /* Ctrl+Z */
+          *code = TERMINAL_EOF;
+          if (echo)
+            _cputs((concode == EOF ? "[EOF]\r\n" : "^Z\r\n"));
+          break;
+
+        case 3:                         /* Ctrl+C, Ctrl+Break */
+          /* _getch() bypasses Ctrl+C but not Ctrl+Break detection! */
+          if (echo)
+            _cputs("^C\r\n");
+          return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+
+        case 0:                         /* Function code prefix */
+        case 0xE0:
+          concode = (concode << 4) | _getch();
+          /* Catch {DELETE}, {<--}, Num{DEL} and Num{<--} */
+          if (concode == 0xE53 || concode == 0xE4B
+              || concode == 0x053 || concode == 0x04B)
+            {
+              *code = TERMINAL_DEL;
+              if (can_erase)
+                _cputs("\b \b");
+            }
+          else
+            {
+              *code = TERMINAL_NONE;
+              _putch('\a');
+            }
+          break;
+
+        case '\b':                      /* BS */
+        case 127:                       /* DEL */
+          *code = TERMINAL_DEL;
+          if (can_erase)
+            _cputs("\b \b");
+          break;
+
+        default:
+          if (!apr_iscntrl(concode))
+            {
+              *code = (int)(unsigned char)concode;
+              _putch(echo ? concode : '*');
+            }
+          else
+            {
+              *code = TERMINAL_NONE;
+              _putch('\a');
+            }
+        }
+      return SVN_NO_ERROR;
+    }
+#elif defined(HAVE_TERMIOS_H)
+  if (terminal->restore_state)
+    {
+      /* We're using a bytewise-immediate termios input */
+      const struct termios *const attr = &terminal->attr;
+
+      status = apr_file_getc(&ch, terminal->infd);
+      if (status)
+        return svn_error_wrap_apr(status, _("Can't read from terminal"));
+
+      if (ch == attr->c_cc[VINTR] || ch == attr->c_cc[VQUIT])
+        return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+      else if (ch == '\r' || ch == '\n' || ch == attr->c_cc[VEOL])
+        *code = TERMINAL_EOL;
+      else if (ch == '\b'
+               || ch == attr->c_cc[VERASE] || ch == attr->c_cc[VKILL])
+        *code = TERMINAL_DEL;
+      else if (ch == attr->c_cc[VEOF])
+        *code = TERMINAL_EOF;
+      else if (!apr_iscntrl(ch))
+        *code = (int)(unsigned char)ch;
+      else
+        {
+          *code = TERMINAL_NONE;
+          apr_file_putc('\a', terminal->outfd);
+        }
+      return SVN_NO_ERROR;
+    }
+#endif /* HAVE_TERMIOS_H */
+
+  /* Fall back to plain stream-based I/O. */
+#ifndef WIN32
+  /* Wait for input on termin. This code is based on
+     apr_wait_for_io_or_timeout().
+     Note that this will return an EINTR on a signal. */
+  {
+    apr_pollfd_t pollset;
+    int n;
+
+    pollset.desc_type = APR_POLL_FILE;
+    pollset.desc.f = terminal->infd;
+    pollset.p = pool;
+    pollset.reqevents = APR_POLLIN;
+
+    status = apr_poll(&pollset, 1, &n, -1);
+
+    if (n == 1 && pollset.rtnevents & APR_POLLIN)
+      status = APR_SUCCESS;
+  }
+#endif /* !WIN32 */
+
+  if (!status)
+    status = apr_file_getc(&ch, terminal->infd);
+  if (APR_STATUS_IS_EINTR(status))
+    {
+      *code = TERMINAL_NONE;
+      return SVN_NO_ERROR;
+    }
+  else if (APR_STATUS_IS_EOF(status))
+    {
+      *code = TERMINAL_EOF;
+      return SVN_NO_ERROR;
+    }
+  else if (status)
+    return svn_error_wrap_apr(status, _("Can't read from terminal"));
+
+  *code = (int)(unsigned char)ch;
+  return SVN_NO_ERROR;
+}
+
+
 /* Set @a *result to the result of prompting the user with @a
  * prompt_msg.  Use @ *pb to get the cancel_func and cancel_baton.
  * Do not call the cancel_func if @a *pb is NULL.
@@ -91,77 +436,91 @@ prompt(const char **result,
   /* XXX: If this functions ever starts using members of *pb
    * which were not included in svn_cmdline_prompt_baton_t,
    * we need to update svn_cmdline_prompt_user2 and its callers. */
-  apr_status_t status;
-  apr_file_t *fp;
-  char c;
 
+  svn_boolean_t saw_first_half_of_eol = FALSE;
   svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
+  terminal_handle_t *terminal;
+  int code;
+  char c;
 
-  status = apr_file_open_stdin(&fp, pool);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't open stdin"));
+  SVN_ERR(terminal_open(&terminal, hide, pool));
+  SVN_ERR(terminal_puts(prompt_msg, terminal, pool));
 
-  if (! hide)
+  while (1)
     {
-      svn_boolean_t saw_first_half_of_eol = FALSE;
-      SVN_ERR(svn_cmdline_fputs(prompt_msg, stderr, pool));
-      fflush(stderr);
-
-      while (1)
-        {
-          /* Hack to allow us to not block for io on the prompt, so
-           * we can cancel. */
-          if (pb)
-            SVN_ERR(pb->cancel_func(pb->cancel_baton));
-          status = wait_for_input(fp, pool);
-          if (APR_STATUS_IS_EINTR(status))
-            continue;
-          else if (status && status != APR_ENOTIMPL)
-            return svn_error_wrap_apr(status, _("Can't read stdin"));
-
-          status = apr_file_getc(&c, fp);
-          if (status)
-            return svn_error_wrap_apr(status, _("Can't read stdin"));
+      SVN_ERR(terminal_getc(&code, terminal, (strbuf->len > 0), pool));
 
-          if (saw_first_half_of_eol)
-            {
-              if (c == APR_EOL_STR[1])
-                break;
-              else
-                saw_first_half_of_eol = FALSE;
-            }
-          else if (c == APR_EOL_STR[0])
+      /* Check for cancellation after a character has been read, some
+         input processing modes may eat ^C and we'll only notice a
+         cancellation signal after characters have been read --
+         sometimes even after a newline. */
+      if (pb)
+        SVN_ERR(pb->cancel_func(pb->cancel_baton));
+
+      switch (code)
+        {
+        case TERMINAL_NONE:
+          /* Nothing useful happened; retry. */
+          continue;
+
+        case TERMINAL_DEL:
+          /* Delete the last input character. terminal_getc takes care
+             of erasing the feedback from the terminal, if applicable. */
+          svn_stringbuf_chop(strbuf, 1);
+          continue;
+
+        case TERMINAL_EOL:
+          /* End-of-line means end of input. Trick the EOL-detection code
+             below to stop reading. */
+          saw_first_half_of_eol = TRUE;
+          c = APR_EOL_STR[1];   /* Could be \0 but still stops reading. */
+          break;
+
+        case TERMINAL_EOF:
+          return svn_error_create(
+              APR_EOF,
+              terminal_close(terminal),
+              _("End of file while reading from terminal"));
+
+        default:
+          /* Convert the returned code back to the character. */
+          c = (char)code;
+        }
+
+      if (saw_first_half_of_eol)
+        {
+          if (c == APR_EOL_STR[1])
+            break;
+          else
+            saw_first_half_of_eol = FALSE;
+        }
+      else if (c == APR_EOL_STR[0])
+        {
+          /* GCC might complain here: "warning: will never be executed"
+           * That's fine. This is a compile-time check for "\r\n\0" */
+          if (sizeof(APR_EOL_STR) == 3)
             {
-              /* GCC might complain here: "warning: will never be executed"
-               * That's fine. This is a compile-time check for "\r\n\0" */
-              if (sizeof(APR_EOL_STR) == 3)
-                {
-                  saw_first_half_of_eol = TRUE;
-                  continue;
-                }
-              else if (sizeof(APR_EOL_STR) == 2)
-                break;
-              else
-                /* ### APR_EOL_STR holds more than two chars?  Who
-                   ever heard of such a thing? */
-                SVN_ERR_MALFUNCTION();
+              saw_first_half_of_eol = TRUE;
+              continue;
             }
-
-          svn_stringbuf_appendbyte(strbuf, c);
+          else if (sizeof(APR_EOL_STR) == 2)
+            break;
+          else
+            /* ### APR_EOL_STR holds more than two chars?  Who
+               ever heard of such a thing? */
+            SVN_ERR_MALFUNCTION();
         }
+
+      svn_stringbuf_appendbyte(strbuf, c);
     }
-  else
-    {
-      const char *prompt_stdout;
-      size_t bufsize = 300;
-      SVN_ERR(svn_cmdline_cstring_from_utf8(&prompt_stdout, prompt_msg,
-                                            pool));
-      svn_stringbuf_ensure(strbuf, bufsize);
 
-      status = apr_password_get(prompt_stdout, strbuf->data, &bufsize);
-      if (status)
-        return svn_error_wrap_apr(status, _("Can't get password"));
+  if (terminal->noecho)
+    {
+      /* If terminal echo was turned off, make sure future output
+         to the terminal starts on a new line, as expected. */
+      terminal_puts(APR_EOL_STR, terminal, pool);
     }
+  SVN_ERR(terminal_close(terminal));
 
   return svn_cmdline_cstring_to_utf8(result, strbuf->data, pool);
 }
@@ -179,9 +538,13 @@ maybe_print_realm(const char *realm, apr
 {
   if (realm)
     {
-      SVN_ERR(svn_cmdline_fprintf(stderr, pool,
-                                  _("Authentication realm: %s\n"), realm));
-      fflush(stderr);
+      terminal_handle_t *terminal;
+      SVN_ERR(terminal_open(&terminal, FALSE, pool));
+      SVN_ERR(terminal_puts(
+                  apr_psprintf(pool,
+                               _("Authentication realm: %s\n"), realm),
+                  terminal, pool));
+      SVN_ERR(terminal_close(terminal));
     }
 
   return SVN_NO_ERROR;
@@ -396,13 +759,17 @@ plaintext_prompt_helper(svn_boolean_t *m
   svn_boolean_t answered = FALSE;
   svn_cmdline_prompt_baton2_t *pb = baton;
   const char *config_path = NULL;
+  terminal_handle_t *terminal;
 
   if (pb)
     SVN_ERR(svn_config_get_user_config_path(&config_path, pb->config_dir,
                                             SVN_CONFIG_CATEGORY_SERVERS, pool));
 
-  SVN_ERR(svn_cmdline_fprintf(stderr, pool, prompt_text, realmstring,
-                              config_path));
+  SVN_ERR(terminal_open(&terminal, FALSE, pool));
+  SVN_ERR(terminal_puts(apr_psprintf(pool, prompt_text,
+                                     realmstring, config_path),
+                        terminal, pool));
+  SVN_ERR(terminal_close(terminal));
 
   do
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/simple_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/simple_providers.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/simple_providers.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/simple_providers.c Sat Feb 23 01:25:38 2013
@@ -29,6 +29,9 @@
 
 #include <apr_pools.h>
 #include "svn_auth.h"
+#include "svn_dirent_uri.h"
+#include "svn_hash.h"
+#include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_utf.h"
 #include "svn_config.h"
@@ -37,6 +40,8 @@
 #include "private/svn_auth_private.h"
 
 #include "svn_private_config.h"
+
+#include "auth.h"
 
 /*-----------------------------------------------------------------------*/
 /* File provider                                                         */
@@ -372,8 +377,9 @@ svn_auth__simple_creds_cache_set(svn_boo
           simple_provider_baton_t *b =
             (simple_provider_baton_t *)provider_baton;
 
-          if (svn_cstring_casecmp(store_plaintext_passwords,
-                                  SVN_CONFIG_ASK) == 0)
+          if (store_plaintext_passwords
+              && svn_cstring_casecmp(store_plaintext_passwords,
+                                     SVN_CONFIG_ASK) == 0)
             {
               if (non_interactive)
                 /* In non-interactive mode, the default behaviour is
@@ -438,13 +444,15 @@ svn_auth__simple_creds_cache_set(svn_boo
                   may_save_password = TRUE;
                 }
             }
-          else if (svn_cstring_casecmp(store_plaintext_passwords,
-                                       SVN_CONFIG_FALSE) == 0)
+          else if (store_plaintext_passwords
+                   && svn_cstring_casecmp(store_plaintext_passwords,
+                                          SVN_CONFIG_FALSE) == 0)
             {
               may_save_password = FALSE;
             }
-          else if (svn_cstring_casecmp(store_plaintext_passwords,
-                                       SVN_CONFIG_TRUE) == 0)
+          else if (!store_plaintext_passwords
+                   || svn_cstring_casecmp(store_plaintext_passwords,
+                                          SVN_CONFIG_TRUE) == 0)
             {
               may_save_password = TRUE;
             }
@@ -517,6 +525,133 @@ simple_save_creds(svn_boolean_t *saved,
                                           pool);
 }
 
+svn_error_t *
+svn_auth__simple_cleanup_walk(svn_auth_baton_t *baton,
+                              svn_auth_cleanup_callback cleanup,
+                              void *cleanup_baton,
+                              apr_hash_t *creds_cache,
+                              apr_pool_t *scratch_pool)
+{
+  const char *config_dir;
+  svn_boolean_t no_auth_cache;
+  int i;
+  apr_pool_t *iterpool;
+
+  const char *cred_kinds[] =
+  {
+      SVN_AUTH_CRED_SIMPLE,
+      SVN_AUTH_CRED_USERNAME,
+      SVN_AUTH_CRED_SSL_CLIENT_CERT,
+      SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
+      SVN_AUTH_CRED_SSL_SERVER_TRUST,
+      NULL
+  };
+
+  config_dir = svn_auth_get_parameter(baton, SVN_AUTH_PARAM_CONFIG_DIR);
+  no_auth_cache = (svn_auth_get_parameter(baton, SVN_AUTH_PARAM_NO_AUTH_CACHE)
+                                != NULL);
+
+  if ((! config_dir) || no_auth_cache)
+    {
+      /* Can't locate the cache to clear */
+      return SVN_NO_ERROR;
+    }
+
+  iterpool = svn_pool_create(scratch_pool);
+  for (i = 0; cred_kinds[i]; i++)
+    {
+      const char *item_path;
+      const char *dir_path;
+      apr_hash_t *nodes;
+      svn_error_t *err;
+      apr_pool_t *itempool;
+      apr_hash_index_t *hi;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_auth__file_path(&item_path, cred_kinds[i], "!", config_dir,
+                                  iterpool));
+
+      dir_path = svn_dirent_dirname(item_path, iterpool);
+
+      err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool);
+
+      if (err)
+        {
+          if (!APR_STATUS_IS_ENOENT(err->apr_err)
+              && !SVN__APR_STATUS_IS_ENOTDIR(err->apr_err))
+            return svn_error_trace(err);
+
+          svn_error_clear(err);
+          continue;
+        }
+
+      itempool = svn_pool_create(iterpool);
+      for (hi = apr_hash_first(iterpool, nodes); hi; hi = apr_hash_next(hi))
+        {
+          svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
+          svn_stream_t *stream;
+          apr_hash_t *file_data;
+
+          if (dirent->kind != svn_node_file)
+            continue;
+
+          svn_pool_clear(itempool);
+
+          item_path = svn_dirent_join(dir_path, svn__apr_hash_index_key(hi),
+                                      itempool);
+
+          err = svn_stream_open_readonly(&stream, item_path, itempool, itempool);
+          if (err)
+            {
+              /* Ignore this file. There are no credentials in it anyway */
+              svn_error_clear(err);
+              continue;
+            }
+
+          file_data = apr_hash_make(itempool);
+          err = svn_hash_read2(file_data, stream, SVN_HASH_TERMINATOR, itempool);
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          if (err)
+            {
+              /* Ignore this file. There are no credentials in it anyway */
+              svn_error_clear(err);
+              continue;
+            }
+
+          {
+            const svn_string_t *realm = svn_hash_gets(file_data, SVN_CONFIG_REALMSTRING_KEY);
+            svn_boolean_t delete_file = FALSE;
+
+            if (! realm)
+              continue; /* Not an auth file */
+
+            SVN_ERR(cleanup(&delete_file, cleanup_baton, cred_kinds[i], realm->data,
+                            SVN_AUTH_CRED_SIMPLE, itempool));
+
+            if (delete_file)
+              {
+                /* Delete from the credential hash */
+                const char *cache_key = apr_pstrcat(itempool,
+                                                    cred_kinds[0],
+                                                    ":",
+                                                    realm->data,
+                                                    (char *)NULL);
+
+                svn_hash_sets(creds_cache, cache_key, NULL);
+
+                /* And the file on disk */
+                SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool));
+              }
+          }
+        }
+    }
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+
 static const svn_auth_provider_t simple_provider = {
   SVN_AUTH_CRED_SIMPLE,
   simple_first_creds,
@@ -718,7 +853,6 @@ simple_prompt_next_creds(void **credenti
                                  ! no_auth_cache, pool);
 }
 
-
 static const svn_auth_provider_t simple_prompt_provider = {
   SVN_AUTH_CRED_SIMPLE,
   simple_prompt_first_creds,

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/sorts.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/sorts.c Sat Feb 23 01:25:38 2013
@@ -270,3 +270,39 @@ svn_sort__array_delete(apr_array_header_
       arr->nelts -= elements_to_delete;
     }
 }
+
+void
+svn_sort__array_reverse(apr_array_header_t *array,
+                        apr_pool_t *scratch_pool)
+{
+  int i;
+
+  if (array->elt_size == sizeof(void *))
+    {
+      for (i = 0; i < array->nelts / 2; i++)
+        {
+          int swap_index = array->nelts - i - 1;
+          void *tmp = APR_ARRAY_IDX(array, i, void *);
+
+          APR_ARRAY_IDX(array, i, void *) =
+            APR_ARRAY_IDX(array, swap_index, void *);
+          APR_ARRAY_IDX(array, swap_index, void *) = tmp;
+        }
+    }
+  else
+    {
+      apr_size_t sz = array->elt_size;
+      char *tmp = apr_palloc(scratch_pool, sz);
+
+      for (i = 0; i < array->nelts / 2; i++)
+        {
+          int swap_index = array->nelts - i - 1;
+          char *x = array->elts + (sz * i);
+          char *y = array->elts + (sz * swap_index);
+
+          memcpy(tmp, x, sz);
+          memcpy(x, y, sz);
+          memcpy(y, tmp, sz);
+        }
+    }
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c Sat Feb 23 01:25:38 2013
@@ -140,8 +140,9 @@ struct svn_sqlite__value_t
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                             NULL, "sqlite: %s",                 \
-                             sqlite3_errmsg((db)->db3));         \
+                             NULL, "sqlite: %s (%d)",             \
+                             sqlite3_errmsg((db)->db3),           \
+                             sqlite_err__temp);                   \
 } while (0)
 
 #define SQLITE_ERR_MSG(x, msg) do                                \
@@ -149,7 +150,8 @@ struct svn_sqlite__value_t
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
     return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                             NULL, "sqlite: %s", (msg));         \
+                             NULL, "sqlite: %s (%d)", (msg),     \
+                             sqlite_err__temp);                  \
 } while (0)
 
 
@@ -171,8 +173,9 @@ exec_sql2(svn_sqlite__db_t *db, const ch
   if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err)
     {
       svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL,
-                                           _("sqlite: %s, executing statement '%s'"),
-                                           err_msg, sql);
+                                           _("sqlite: %s (%d),"
+                                             " executing statement '%s'"),
+                                           err_msg, sqlite_err, sql);
       sqlite3_free(err_msg);
       return err;
     }
@@ -289,7 +292,8 @@ svn_sqlite__step(svn_boolean_t *got_row,
       svn_error_t *err1, *err2;
 
       err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL,
-                               "sqlite: %s", sqlite3_errmsg(stmt->db->db3));
+                               "sqlite: %s (%d)",
+                               sqlite3_errmsg(stmt->db->db3), sqlite_result);
       err2 = svn_sqlite__reset(stmt);
       return svn_error_compose_create(err1, err2);
     }
@@ -739,8 +743,8 @@ init_sqlite(void *baton, apr_pool_t *poo
   {
     int err = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
     if (err != SQLITE_OK && err != SQLITE_MISUSE)
-      return svn_error_create(SQLITE_ERROR_CODE(err), NULL,
-                              _("Could not configure SQLite"));
+      return svn_error_createf(SQLITE_ERROR_CODE(err), NULL,
+                               _("Could not configure SQLite (%d)"), err);
   }
   SQLITE_ERR_MSG(sqlite3_initialize(), _("Could not initialize SQLite"));
 
@@ -793,7 +797,8 @@ internal_open(sqlite3 **db3, const char 
           sqlite3_close(*db3);
 
           return svn_error_createf(SQLITE_ERROR_CODE(err_code), NULL,
-                                   "sqlite: %s: '%s'", msg, path);
+                                   "sqlite: %s (%d): '%s'",
+                                   msg, err_code, path);
         }
     }
   }
@@ -863,7 +868,7 @@ close_apr(void *data)
     }
 
   if (result != SQLITE_OK)
-    return SQLITE_ERROR_CODE(result);
+    return SQLITE_ERROR_CODE(result); /* ### lossy */
 
   db->db3 = NULL;
 

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_crawler.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_crawler.c Sat Feb 23 01:25:38 2013
@@ -58,8 +58,8 @@
    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.
+   If MARK_RESOLVED_TEXT_CONFLICT is TRUE, mark as resolved any existing
+   text conflict on LOCAL_ABSPATH.
 
    Not that a valid access baton with a write lock to the directory of
    LOCAL_ABSPATH must be available in DB.*/
@@ -67,7 +67,7 @@ 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,
+             svn_boolean_t mark_resolved_text_conflict,
              apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_item;
@@ -89,8 +89,8 @@ restore_file(svn_wc__db_t *db,
                          scratch_pool));
 
   /* Remove any text conflict */
-  if (remove_text_conflicts)
-    SVN_ERR(svn_wc__resolve_text_conflict(db, local_abspath, scratch_pool));
+  if (mark_resolved_text_conflict)
+    SVN_ERR(svn_wc__mark_resolved_text_conflict(db, local_abspath, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -135,7 +135,8 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
     }
 
   if (kind == svn_kind_file || kind == svn_kind_symlink)
-    SVN_ERR(restore_file(wc_ctx->db, local_abspath, use_commit_times, FALSE,
+    SVN_ERR(restore_file(wc_ctx->db, local_abspath, use_commit_times,
+                         FALSE /*mark_resolved_text_conflict*/,
                          scratch_pool));
   else
     SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
@@ -161,8 +162,9 @@ restore_node(svn_wc__db_t *db,
 {
   if (kind == svn_kind_file || kind == svn_kind_symlink)
     {
-      /* Recreate file from text-base */
-      SVN_ERR(restore_file(db, local_abspath, use_commit_times, TRUE,
+      /* Recreate file from text-base; mark any text conflict as resolved */
+      SVN_ERR(restore_file(db, local_abspath, use_commit_times,
+                           TRUE /*mark_resolved_text_conflict*/,
                            scratch_pool));
     }
   else if (kind == svn_kind_dir)

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c Sat Feb 23 01:25:38 2013
@@ -570,40 +570,6 @@ svn_wc__adm_cleanup_tmp_area(svn_wc__db_
 }
 
 
-
-svn_error_t *
-svn_wc_create_tmp_file2(apr_file_t **fp,
-                        const char **new_name,
-                        const char *path,
-                        svn_io_file_del_t delete_when,
-                        apr_pool_t *pool)
-{
-  svn_wc__db_t *db;
-  const char *local_abspath;
-  const char *temp_dir;
-  svn_error_t *err;
-
-  SVN_ERR_ASSERT(fp || new_name);
-
-  SVN_ERR(svn_wc__db_open(&db,
-                          NULL /* config */,
-                          FALSE /* auto_upgrade */,
-                          TRUE /* enforce_empty_wq */,
-                          pool, pool));
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  err = svn_wc__db_temp_wcroot_tempdir(&temp_dir, db, local_abspath,
-                                       pool, pool);
-  err = svn_error_compose_create(err, svn_wc__db_close(db));
-  if (err)
-    return svn_error_trace(err);
-
-  SVN_ERR(svn_io_open_unique_file3(fp, new_name, temp_dir,
-                                   delete_when, pool, pool));
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_wc__get_tmpdir(const char **tmpdir_abspath,
                    svn_wc_context_t *wc_ctx,

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1449262&r1=1449261&r2=1449262&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Sat Feb 23 01:25:38 2013
@@ -1249,9 +1249,19 @@ svn_wc_remove_lock2(svn_wc_context_t *wc
     }
 
   /* if svn:needs-lock is present, then make the file read-only. */
-  SVN_ERR(svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath,
-                                   SVN_PROP_NEEDS_LOCK, scratch_pool,
-                                   scratch_pool));
+  err = svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath,
+                                 SVN_PROP_NEEDS_LOCK, scratch_pool,
+                                 scratch_pool);
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+        return svn_error_trace(err);
+
+      svn_error_clear(err);
+      return SVN_NO_ERROR; /* Node is shadowed and/or deleted,
+                              so we shouldn't apply its lock */
+    }
+
   if (needs_lock)
     SVN_ERR(svn_io_set_file_read_only(local_abspath, FALSE, scratch_pool));
 



Mime
View raw message