Author: rinrab
Date: Wed May 28 19:56:36 2025
New Revision: 1925917

URL: http://svn.apache.org/viewvc?rev=1925917&view=rev
Log:
Move svn-editor stuff into a separate file, cmdline_editor.c.

* subversion/libsvn_subr/cmdline.c
  (find_editor_binary,
   escape_path,
   svn_cmdline__edit_file_externally,
   svn_cmdline__edit_string_externally): Removed.
* subversion/libsvn_subr/cmdline_editor.c: svn-copied from cmdline.c, keeping
  only required things.
  (includes): cleanup.
  (find_editor_binary,
   escape_path,
   svn_cmdline__edit_file_externally,
   svn_cmdline__edit_string_externally): Copied from cmdline.c.

No functional changes. Let GHA workflows verify it.

Added:
    subversion/trunk/subversion/libsvn_subr/cmdline_editor.c
      - copied, changed from r1925915, 
subversion/trunk/subversion/libsvn_subr/cmdline.c
Modified:
    subversion/trunk/subversion/libsvn_subr/cmdline.c

Modified: subversion/trunk/subversion/libsvn_subr/cmdline.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cmdline.c?rev=1925917&r1=1925916&r2=1925917&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cmdline.c Wed May 28 19:56:36 2025
@@ -1240,522 +1240,6 @@ svn_cmdline__be_interactive(svn_boolean_
 }
 
 
-/* Helper for the edit_externally functions.  Set *EDITOR to some path to an
-   editor binary, in native C string on Unix/Linux platforms and in UTF-8
-   string on Windows platform.  Sources to search include: the EDITOR_CMD
-   argument (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG
-   is not NULL), $VISUAL, $EDITOR.  Return
-   SVN_ERR_CL_NO_EXTERNAL_EDITOR if no binary can be found. */
-static svn_error_t *
-find_editor_binary(const char **editor,
-                   const char *editor_cmd,
-                   apr_hash_t *config,
-                   apr_pool_t *pool)
-{
-  const char *e;
-  const char *e_cfg;
-  struct svn_config_t *cfg;
-  apr_status_t status;
-
-  /* Use the editor specified on the command line via --editor-cmd, if any. */
-#ifdef WIN32
-  /* On Windows, editor_cmd is transcoded to the system active code page
-     because we use main() as a entry point without APR's (or our own) wrapper
-     in command line tools. */
-  if (editor_cmd)
-    {
-      SVN_ERR(svn_utf_cstring_to_utf8(&e, editor_cmd, pool));
-    }
-  else
-    {
-      e = NULL;
-    }
-#else
-  e = editor_cmd;
-#endif
-
-  /* Otherwise look for the Subversion-specific environment variable. */
-  if (! e)
-    {
-      status = apr_env_get((char **)&e, "SVN_EDITOR", pool);
-      if (status || ! *e)
-        {
-           e = NULL;
-        }
-    }
-
-  /* If not found then fall back on the config file. */
-  if (! e)
-    {
-      cfg = config ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG) : NULL;
-      svn_config_get(cfg, &e_cfg, SVN_CONFIG_SECTION_HELPERS,
-                     SVN_CONFIG_OPTION_EDITOR_CMD, NULL);
-#ifdef WIN32
-      if (e_cfg)
-        {
-          /* On Windows, we assume that config values are set in system active
-             code page, so we need transcode it here. */
-          SVN_ERR(svn_utf_cstring_to_utf8(&e, e_cfg, pool));
-        }
-#else
-      e = e_cfg;
-#endif
-    }
-
-  /* If not found yet then try general purpose environment variables. */
-  if (! e)
-    {
-      status = apr_env_get((char**)&e, "VISUAL", pool);
-      if (status || ! *e)
-        {
-           e = NULL;
-        }
-    }
-  if (! e)
-    {
-      status = apr_env_get((char**)&e, "EDITOR", pool);
-      if (status || ! *e)
-        {
-           e = NULL;
-        }
-    }
-
-#ifdef SVN_CLIENT_EDITOR
-  /* If still not found then fall back on the hard-coded default. */
-  if (! e)
-    e = SVN_CLIENT_EDITOR;
-#endif
-
-  /* Error if there is no editor specified */
-  if (e)
-    {
-      const char *c;
-
-      for (c = e; *c; c++)
-        if (!svn_ctype_isspace(*c))
-          break;
-
-      if (! *c)
-        return svn_error_create
-          (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
-           _("The EDITOR, SVN_EDITOR or VISUAL environment variable or "
-             "'editor-cmd' run-time configuration option is empty or "
-             "consists solely of whitespace. Expected a shell command."));
-    }
-  else
-    return svn_error_create
-      (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
-       _("None of the environment variables SVN_EDITOR, VISUAL or EDITOR are "
-         "set, and no 'editor-cmd' run-time configuration option was found"));
-
-  *editor = e;
-  return SVN_NO_ERROR;
-}
-
-/* Wrapper around apr_pescape_shell() which also escapes whitespace. */
-static const char *
-escape_path(apr_pool_t *pool, const char *orig_path)
-{
-  apr_size_t len, esc_len;
-  apr_status_t status;
-
-  len = strlen(orig_path);
-  esc_len = 0;
-
-  status = apr_escape_shell(NULL, orig_path, len, &esc_len);
-
-  if (status == APR_NOTFOUND)
-    {
-      /* No special characters found by APR, so just surround it in double
-         quotes in case there is whitespace, which APR (as of 1.6.5) doesn't
-         consider special. */
-      return apr_psprintf(pool, "\"%s\"", orig_path);
-    }
-  else
-    {
-#ifdef WIN32
-      const char *p;
-      /* Following the advice from
-         
https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
-         1. Surround argument with double-quotes
-         2. Escape backslashes, if they're followed by a double-quote, and 
double-quotes
-         3. Escape any metacharacter, including double-quotes, with ^ */
-
-      /* Use APR's buffer size as an approximation for how large the escaped
-         string should be, plus 4 bytes for the leading/trailing ^" */
-      svn_stringbuf_t *buf = svn_stringbuf_create_ensure(esc_len + 4, pool);
-      svn_stringbuf_appendcstr(buf, "^\"");
-      for (p = orig_path; *p; p++)
-        {
-          int nr_backslash = 0;
-          while (*p && *p == '\\')
-            {
-              nr_backslash++;
-              p++;
-            }
-
-          if (!*p)
-            /* We've reached the end of the argument, so we need 2n backslash
-               characters.  That will be interpreted as n backslashes and the
-               final double-quote character will be interpreted as the final
-               string delimiter. */
-            svn_stringbuf_appendfill(buf, '\\', nr_backslash * 2);
-          else if (*p == '"')
-            {
-              /* Double-quote as part of the argument means we need to double
-                 any preceding backslashes and then add one to escape the
-                 double-quote. */
-              svn_stringbuf_appendfill(buf, '\\', nr_backslash * 2 + 1);
-              svn_stringbuf_appendbyte(buf, '^');
-              svn_stringbuf_appendbyte(buf, *p);
-            }
-          else
-            {
-              /* Since there's no double-quote, we just insert any backslashes
-                 literally.  No escaping needed. */
-              svn_stringbuf_appendfill(buf, '\\', nr_backslash);
-              if (strchr("()%!^<>&|", *p))
-                svn_stringbuf_appendbyte(buf, '^');
-              svn_stringbuf_appendbyte(buf, *p);
-            }
-        }
-      svn_stringbuf_appendcstr(buf, "^\"");
-      return buf->data;
-#else
-      char *path, *p, *esc_path;
-
-      /* Account for whitespace, since APR doesn't */
-      for (p = (char *)orig_path; *p; p++)
-        if (strchr(" \t\n\r", *p))
-          esc_len++;
-
-      path = apr_pcalloc(pool, esc_len);
-      apr_escape_shell(path, orig_path, len, NULL);
-
-      p = esc_path = apr_pcalloc(pool, len + esc_len + 1);
-      while (*path)
-        {
-          if (strchr(" \t\n\r", *path))
-            *p++ = '\\';
-          *p++ = *path++;
-        }
-
-      return esc_path;
-#endif
-    }
-}
-
-svn_error_t *
-svn_cmdline__edit_file_externally(const char *path,
-                                  const char *editor_cmd,
-                                  apr_hash_t *config,
-                                  apr_pool_t *pool)
-{
-  const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr;
-  const char *file_name_local;
-#ifdef WIN32
-  const WCHAR *wcmd;
-#endif
-  char *old_cwd;
-  int sys_err;
-  apr_status_t apr_err;
-
-  svn_dirent_split(&base_dir, &file_name, path, pool);
-
-  SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool));
-
-  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
-  /* APR doesn't like "" directories */
-  if (base_dir[0] == '\0')
-    base_dir_apr = ".";
-  else
-    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
-
-  apr_err = apr_filepath_set(base_dir_apr, pool);
-  if (apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Can't change working directory to '%s'"), base_dir);
-
-  SVN_ERR(svn_path_cstring_from_utf8(&file_name_local,
-                                     escape_path(pool, file_name), pool));
-  /* editor is explicitly documented as being interpreted by the user's shell,
-     and as such should already be quoted/escaped as needed. */
-#ifndef WIN32
-  cmd = apr_psprintf(pool, "%s %s", editor, file_name_local);
-  sys_err = system(cmd);
-#else
-  cmd = apr_psprintf(pool, "\"%s %s\"", editor, file_name_local);
-  SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool));
-  sys_err = _wsystem(wcmd);
-#endif
-
-  apr_err = apr_filepath_set(old_cwd, pool);
-  if (apr_err)
-    svn_handle_error2(svn_error_wrap_apr
-                      (apr_err, _("Can't restore working directory")),
-                      stderr, TRUE /* fatal */, "svn: ");
-
-  if (sys_err)
-    {
-      const char *cmd_utf8;
-
-      /* Extracting any meaning from sys_err is platform specific, so just
-         use the raw value. */
-      SVN_ERR(svn_path_cstring_to_utf8(&cmd_utf8, cmd, pool));
-      return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
-                               _("system('%s') returned %d"),
-                               cmd_utf8, sys_err);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_cmdline__edit_string_externally(svn_string_t **edited_contents /* UTF-8! 
*/,
-                                    const char **tmpfile_left /* UTF-8! */,
-                                    const char *editor_cmd,
-                                    const char *base_dir /* UTF-8! */,
-                                    const svn_string_t *contents /* UTF-8! */,
-                                    const char *filename,
-                                    apr_hash_t *config,
-                                    svn_boolean_t as_text,
-                                    const char *encoding,
-                                    apr_pool_t *pool)
-{
-  const char *editor;
-  const char *cmd;
-#ifdef WIN32
-  const WCHAR *wcmd;
-#endif
-  apr_file_t *tmp_file;
-  const char *tmpfile_name;
-  const char *tmpfile_native;
-  const char *base_dir_apr;
-  svn_string_t *translated_contents;
-  apr_status_t apr_err;
-  apr_size_t written;
-  apr_finfo_t finfo_before, finfo_after;
-  svn_error_t *err = SVN_NO_ERROR;
-  char *old_cwd;
-  int sys_err;
-  svn_boolean_t remove_file = TRUE;
-
-  SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool));
-
-  /* Convert file contents from UTF-8/LF if desired. */
-  if (as_text)
-    {
-      const char *translated;
-      SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
-                                           APR_EOL_STR, FALSE,
-                                           NULL, FALSE, pool));
-      translated_contents = svn_string_create_empty(pool);
-      if (encoding)
-        SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
-                                              translated, encoding, pool));
-      else
-        SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
-                                          translated, pool));
-      translated_contents->len = strlen(translated_contents->data);
-    }
-  else
-    translated_contents = svn_string_dup(contents, pool);
-
-  /* Move to BASE_DIR to avoid getting characters that need quoting
-     into tmpfile_name */
-  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));
-
-  /* APR doesn't like "" directories */
-  if (base_dir[0] == '\0')
-    base_dir_apr = ".";
-  else
-    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
-  apr_err = apr_filepath_set(base_dir_apr, pool);
-  if (apr_err)
-    {
-      return svn_error_wrap_apr
-        (apr_err, _("Can't change working directory to '%s'"), base_dir);
-    }
-
-  /*** From here on, any problems that occur require us to cd back!! ***/
-
-  /* Ask the working copy for a temporary file named FILENAME-something. */
-  err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
-                                   "" /* dirpath */,
-                                   filename,
-                                   ".tmp",
-                                   svn_io_file_del_none, pool, pool);
-
-  if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
-    {
-      const char *temp_dir_apr;
-
-      svn_error_clear(err);
-
-      SVN_ERR(svn_io_temp_dir(&base_dir, pool));
-
-      SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
-      apr_err = apr_filepath_set(temp_dir_apr, pool);
-      if (apr_err)
-        {
-          return svn_error_wrap_apr
-            (apr_err, _("Can't change working directory to '%s'"), base_dir);
-        }
-
-      err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
-                                       "" /* dirpath */,
-                                       filename,
-                                       ".tmp",
-                                       svn_io_file_del_none, pool, pool);
-    }
-
-  if (err)
-    goto cleanup2;
-
-  /*** From here on, any problems that occur require us to cleanup
-       the file we just created!! ***/
-
-  /* Dump initial CONTENTS to TMP_FILE. */
-  err = svn_io_file_write_full(tmp_file, translated_contents->data,
-                               translated_contents->len, &written,
-                               pool);
-
-  err = svn_error_compose_create(err, svn_io_file_close(tmp_file, pool));
-
-  /* Make sure the whole CONTENTS were written, else return an error. */
-  if (err)
-    goto cleanup;
-
-  /* Get information about the temporary file before the user has
-     been allowed to edit its contents. */
-  err = svn_io_stat(&finfo_before, tmpfile_name, APR_FINFO_MTIME, pool);
-  if (err)
-    goto cleanup;
-
-  /* Backdate the file a little bit in case the editor is very fast
-     and doesn't change the size.  (Use two seconds, since some
-     filesystems have coarse granularity.)  It's OK if this call
-     fails, so we don't check its return value.*/
-  err = svn_io_set_file_affected_time(finfo_before.mtime
-                                              - apr_time_from_sec(2),
-                                      tmpfile_name, pool);
-  svn_error_clear(err);
-
-  /* Stat it again to get the mtime we actually set. */
-  err = svn_io_stat(&finfo_before, tmpfile_name,
-                    APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
-  if (err)
-    goto cleanup;
-
-  /* Prepare the editor command line.  */
-  err = svn_path_cstring_from_utf8(&tmpfile_native,
-                                   escape_path(pool, tmpfile_name), pool);
-  if (err)
-    goto cleanup;
-
-  /* editor is explicitly documented as being interpreted by the user's shell,
-     and as such should already be quoted/escaped as needed. */
-#ifndef WIN32
-  cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);
-#else
-  cmd = apr_psprintf(pool, "\"%s %s\"", editor, tmpfile_native);
-#endif
-
-  /* If the caller wants us to leave the file around, return the path
-     of the file we'll use, and make a note not to destroy it.  */
-  if (tmpfile_left)
-    {
-      *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
-      remove_file = FALSE;
-    }
-
-  /* Now, run the editor command line.  */
-#ifndef WIN32
-  sys_err = system(cmd);
-#else
-  SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool));
-  sys_err = _wsystem(wcmd);
-#endif
-  if (sys_err != 0)
-    {
-      const char *cmd_utf8;
-
-      /* Extracting any meaning from sys_err is platform specific, so just
-         use the raw value. */
-      SVN_ERR(svn_path_cstring_to_utf8(&cmd_utf8, cmd, pool));
-      err =  svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
-                               _("system('%s') returned %d"),
-                               cmd_utf8, sys_err);
-      goto cleanup;
-    }
-
-  /* Get information about the temporary file after the assumed editing. */
-  err = svn_io_stat(&finfo_after, tmpfile_name,
-                    APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
-  if (err)
-    goto cleanup;
-
-  /* If the file looks changed... */
-  if ((finfo_before.mtime != finfo_after.mtime) ||
-      (finfo_before.size != finfo_after.size))
-    {
-      svn_stringbuf_t *edited_contents_s;
-      err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
-      if (err)
-        goto cleanup;
-
-      *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);
-
-      /* Translate back to UTF8/LF if desired. */
-      if (as_text)
-        {
-          err = svn_subst_translate_string2(edited_contents, NULL, NULL,
-                                            *edited_contents, encoding, FALSE,
-                                            pool, pool);
-          if (err)
-            {
-              err = svn_error_quick_wrap
-                (err,
-                 _("Error normalizing edited contents to internal format"));
-              goto cleanup;
-            }
-        }
-    }
-  else
-    {
-      /* No edits seem to have been made */
-      *edited_contents = NULL;
-    }
-
- cleanup:
-  if (remove_file)
-    {
-      /* Remove the file from disk.  */
-      err = svn_error_compose_create(
-              err,
-              svn_io_remove_file2(tmpfile_name, FALSE, pool));
-    }
-
- cleanup2:
-  /* If we against all probability can't cd back, all further relative
-     file references would be screwed up, so we have to abort. */
-  apr_err = apr_filepath_set(old_cwd, pool);
-  if (apr_err)
-    {
-      svn_handle_error2(svn_error_wrap_apr
-                        (apr_err, _("Can't restore working directory")),
-                        stderr, TRUE /* fatal */, "svn: ");
-    }
-
-  return svn_error_trace(err);
-}
-
 svn_error_t *
 svn_cmdline__parse_trust_options(
                         svn_boolean_t *trust_server_cert_unknown_ca,

Copied: subversion/trunk/subversion/libsvn_subr/cmdline_editor.c (from 
r1925915, subversion/trunk/subversion/libsvn_subr/cmdline.c)
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cmdline_editor.c?p2=subversion/trunk/subversion/libsvn_subr/cmdline_editor.c&p1=subversion/trunk/subversion/libsvn_subr/cmdline.c&r1=1925915&r2=1925917&rev=1925917&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cmdline_editor.c Wed May 28 
19:56:36 2025
@@ -1,5 +1,5 @@
 /*
- * cmdline.c :  Helpers for command-line programs.
+ * cmdline_editor.c :  svn editor implementation.
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -21,1225 +21,31 @@
  * ====================================================================
  */
 
-
-#include <stdlib.h>             /* for atexit() */
-#include <stdio.h>              /* for setvbuf() */
-#include <locale.h>             /* for setlocale() */
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#else
-#include <crtdbg.h>
-#include <io.h>
-#include <conio.h>
-#endif
-
-#include <apr.h>                /* for STDIN_FILENO */
-#include <apr_errno.h>          /* for apr_strerror */
 #include <apr_version.h>
 #if APR_VERSION_AT_LEAST(1,5,0)
 #include <apr_escape.h>
 #else
 #include "private/svn_dep_compat.h"
 #endif
-#include <apr_general.h>        /* for apr_initialize/apr_terminate */
-#include <apr_strings.h>        /* for apr_snprintf */
 #include <apr_env.h>            /* for apr_env_get */
 #include <apr_pools.h>
-#include <apr_signal.h>
 
 #include "svn_cmdline.h"
 #include "svn_ctype.h"
-#include "svn_dso.h"
 #include "svn_dirent_uri.h"
 #include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_pools.h"
 #include "svn_error.h"
-#include "svn_nls.h"
 #include "svn_utf.h"
-#include "svn_auth.h"
-#include "svn_xml.h"
-#include "svn_base64.h"
 #include "svn_config.h"
-#include "svn_sorts.h"
-#include "svn_props.h"
 #include "svn_subst.h"
 
 #include "private/svn_cmdline_private.h"
 #include "private/svn_utf_private.h"
-#include "private/svn_sorts_private.h"
-#include "private/svn_string_private.h"
 
 #include "svn_private_config.h"
 
-#include "win32_crashrpt.h"
-
-#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1400)
-/* Before Visual Studio 2005, the C runtime didn't handle encodings for the
-   stdio output handling. */
-#define CMDLINE_USE_CUSTOM_ENCODING
-
-/* The stdin encoding. If null, it's the same as the native encoding. */
-static const char *input_encoding = NULL;
-
-/* The stdout encoding. If null, it's the same as the native encoding. */
-static const char *output_encoding = NULL;
-#elif defined(WIN32) && defined(_MSC_VER)
-/* For now limit this code to Visual C++, as the result is highly dependent
-   on the CRT implementation */
-#define USE_WIN32_CONSOLE_SHORTCUT
-
-/* When TRUE, stdout/stderr is directly connected to a console */
-static svn_boolean_t shortcut_stdout_to_console = FALSE;
-static svn_boolean_t shortcut_stderr_to_console = FALSE;
-#endif
-
-
-int
-svn_cmdline_init(const char *progname, FILE *error_stream)
-{
-  apr_status_t status;
-  apr_pool_t *pool;
-  svn_error_t *err;
-  char prefix_buf[64];  /* 64 is probably bigger than most program names */
-
-#ifndef WIN32
-  {
-    struct stat st;
-
-    /* The following makes sure that file descriptors 0 (stdin), 1
-       (stdout) and 2 (stderr) will not be "reused", because if
-       e.g. file descriptor 2 would be reused when opening a file, a
-       write to stderr would write to that file and most likely
-       corrupt it. */
-    if ((fstat(0, &st) == -1 && open("/dev/null", O_RDONLY) == -1) ||
-        (fstat(1, &st) == -1 && open("/dev/null", O_WRONLY) == -1) ||
-        (fstat(2, &st) == -1 && open("/dev/null", O_WRONLY) == -1))
-      {
-        if (error_stream)
-          fprintf(error_stream, "%s: error: cannot open '/dev/null'\n",
-                  progname);
-        return EXIT_FAILURE;
-      }
-  }
-#endif
-
-  /* Ignore any errors encountered while attempting to change stream
-     buffering, as the streams should retain their default buffering
-     modes. */
-  if (error_stream)
-    setvbuf(error_stream, NULL, _IONBF, 0);
-#ifndef WIN32
-  setvbuf(stdout, NULL, _IOLBF, 0);
-#endif
-
-#ifdef WIN32
-#ifdef CMDLINE_USE_CUSTOM_ENCODING
-  /* Initialize the input and output encodings. */
-  {
-    static char input_encoding_buffer[16];
-    static char output_encoding_buffer[16];
-
-    apr_snprintf(input_encoding_buffer, sizeof input_encoding_buffer,
-                 "CP%u", (unsigned) GetConsoleCP());
-    input_encoding = input_encoding_buffer;
-
-    apr_snprintf(output_encoding_buffer, sizeof output_encoding_buffer,
-                 "CP%u", (unsigned) GetConsoleOutputCP());
-    output_encoding = output_encoding_buffer;
-  }
-#endif /* CMDLINE_USE_CUSTOM_ENCODING */
-
-#ifdef SVN_USE_WIN32_CRASHHANDLER
-  if (!getenv("SVN_CMDLINE_DISABLE_CRASH_HANDLER"))
-    {
-      /* Attach (but don't load) the crash handler */
-      SetUnhandledExceptionFilter(svn__unhandled_exception_filter);
-
-#if _MSC_VER >= 1400
-      /* ### This should work for VC++ 2002 (=1300) and later */
-      /* Show the abort message on STDERR instead of a dialog to allow
-         scripts (e.g. our testsuite) to continue after an abort without
-         user intervention. Allow overriding for easier debugging. */
-      if (!getenv("SVN_CMDLINE_USE_DIALOG_FOR_ABORT"))
-        {
-          /* In release mode: Redirect abort() errors to stderr */
-          _set_error_mode(_OUT_TO_STDERR);
-
-          /* In _DEBUG mode: Redirect all debug output (E.g. assert() to 
stderr.
-             (Ignored in release builds) */
-          _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR);
-          _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR);
-          _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR);
-          _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
-          _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | 
_CRTDBG_MODE_DEBUG);
-          _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | 
_CRTDBG_MODE_DEBUG);
-        }
-#endif /* _MSC_VER >= 1400 */
-    }
-#endif /* SVN_USE_WIN32_CRASHHANDLER */
-
-#endif /* WIN32 */
-
-  /* C programs default to the "C" locale. But because svn is supposed
-     to be i18n-aware, it should inherit the default locale of its
-     environment.  */
-  if (!setlocale(LC_ALL, "")
-      && !setlocale(LC_CTYPE, ""))
-    {
-      if (error_stream)
-        {
-          const char *env_vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
-          const char **env_var = &env_vars[0], *env_val = NULL;
-          while (*env_var)
-            {
-              env_val = getenv(*env_var);
-              if (env_val && env_val[0])
-                break;
-              ++env_var;
-            }
-
-          if (!*env_var)
-            {
-              /* Unlikely. Can setlocale fail if no env vars are set? */
-              --env_var;
-              env_val = "not set";
-            }
-
-          fprintf(error_stream,
-                  "%s: warning: cannot set LC_CTYPE locale\n"
-                  "%s: warning: environment variable %s is %s\n"
-                  "%s: warning: please check that your locale name is 
correct\n",
-                  progname, progname, *env_var, env_val, progname);
-        }
-    }
-
-  /* Initialize the APR subsystem, and register an atexit() function
-     to Uninitialize that subsystem at program exit. */
-  status = apr_initialize();
-  if (status)
-    {
-      if (error_stream)
-        {
-          char buf[1024];
-          apr_strerror(status, buf, sizeof(buf) - 1);
-          fprintf(error_stream,
-                  "%s: error: cannot initialize APR: %s\n",
-                  progname, buf);
-        }
-      return EXIT_FAILURE;
-    }
-
-  strncpy(prefix_buf, progname, sizeof(prefix_buf) - 3);
-  prefix_buf[sizeof(prefix_buf) - 3] = '\0';
-  strcat(prefix_buf, ": ");
-
-  /* DSO pool must be created before any other pools used by the
-     application so that pool cleanup doesn't unload DSOs too
-     early. See docstring of svn_dso_initialize2(). */
-  if ((err = svn_dso_initialize2()))
-    {
-      if (error_stream)
-        svn_handle_error2(err, error_stream, TRUE, prefix_buf);
-
-      svn_error_clear(err);
-      return EXIT_FAILURE;
-    }
-
-  if (0 > atexit(apr_terminate))
-    {
-      if (error_stream)
-        fprintf(error_stream,
-                "%s: error: atexit registration failed\n",
-                progname);
-      return EXIT_FAILURE;
-    }
-
-  /* Create a pool for use by the UTF-8 routines.  It will be cleaned
-     up by APR at exit time. */
-  pool = svn_pool_create(NULL);
-  svn_utf_initialize2(FALSE, pool);
-
-  if ((err = svn_nls_init()))
-    {
-      if (error_stream)
-        svn_handle_error2(err, error_stream, TRUE, prefix_buf);
-
-      svn_error_clear(err);
-      return EXIT_FAILURE;
-    }
-
-#ifdef USE_WIN32_CONSOLE_SHORTCUT
-  if (_isatty(STDOUT_FILENO))
-    {
-      DWORD ignored;
-      HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
-
-       /* stdout is a char device handle, but is it the console? */
-       if (GetConsoleMode(stdout_handle, &ignored))
-        shortcut_stdout_to_console = TRUE;
-
-       /* Don't close stdout_handle */
-    }
-  if (_isatty(STDERR_FILENO))
-    {
-      DWORD ignored;
-      HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
-
-       /* stderr is a char device handle, but is it the console? */
-      if (GetConsoleMode(stderr_handle, &ignored))
-          shortcut_stderr_to_console = TRUE;
-
-      /* Don't close stderr_handle */
-    }
-#endif
-
-  return EXIT_SUCCESS;
-}
-
-
-svn_error_t *
-svn_cmdline_cstring_from_utf8(const char **dest,
-                              const char *src,
-                              apr_pool_t *pool)
-{
-#ifdef CMDLINE_USE_CUSTOM_ENCODING
-  if (output_encoding != NULL)
-    return svn_utf_cstring_from_utf8_ex2(dest, src, output_encoding, pool);
-#endif
-
-  return svn_utf_cstring_from_utf8(dest, src, pool);
-}
-
-
-const char *
-svn_cmdline_cstring_from_utf8_fuzzy(const char *src,
-                                    apr_pool_t *pool)
-{
-  return svn_utf__cstring_from_utf8_fuzzy(src, pool,
-                                          svn_cmdline_cstring_from_utf8);
-}
-
-
-svn_error_t *
-svn_cmdline_cstring_to_utf8(const char **dest,
-                            const char *src,
-                            apr_pool_t *pool)
-{
-#ifdef CMDLINE_USE_CUSTOM_ENCODING
-  if (input_encoding != NULL)
-    return svn_utf_cstring_to_utf8_ex2(dest, src, input_encoding, pool);
-#endif
-
-  return svn_utf_cstring_to_utf8(dest, src, pool);
-}
-
-
-svn_error_t *
-svn_cmdline_path_local_style_from_utf8(const char **dest,
-                                       const char *src,
-                                       apr_pool_t *pool)
-{
-  return svn_cmdline_cstring_from_utf8(dest,
-                                       svn_dirent_local_style(src, pool),
-                                       pool);
-}
-
-svn_error_t *
-svn_cmdline__stdin_readline(const char **result,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
-{
-  svn_stringbuf_t *buf = NULL;
-  svn_stream_t *stdin_stream = NULL;
-  svn_boolean_t oob = FALSE;
-
-  SVN_ERR(svn_stream_for_stdin2(&stdin_stream, TRUE, scratch_pool));
-  SVN_ERR(svn_stream_readline(stdin_stream, &buf, APR_EOL_STR, &oob, 
result_pool));
-
-  *result = buf->data;
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline_printf(apr_pool_t *pool, const char *fmt, ...)
-{
-  const char *message;
-  va_list ap;
-
-  /* A note about encoding issues:
-   * APR uses the execution character set, but here we give it UTF-8 strings,
-   * both the fmt argument and any other string arguments.  Since apr_pvsprintf
-   * only cares about and produces ASCII characters, this works under the
-   * assumption that all supported platforms use an execution character set
-   * with ASCII as a subset.
-   */
-
-  va_start(ap, fmt);
-  message = apr_pvsprintf(pool, fmt, ap);
-  va_end(ap);
-
-  return svn_cmdline_fputs(message, stdout, pool);
-}
-
-svn_error_t *
-svn_cmdline_fprintf(FILE *stream, apr_pool_t *pool, const char *fmt, ...)
-{
-  const char *message;
-  va_list ap;
-
-  /* See svn_cmdline_printf () for a note about character encoding issues. */
-
-  va_start(ap, fmt);
-  message = apr_pvsprintf(pool, fmt, ap);
-  va_end(ap);
-
-  return svn_cmdline_fputs(message, stream, pool);
-}
-
-svn_error_t *
-svn_cmdline_fputs(const char *string, FILE* stream, apr_pool_t *pool)
-{
-  svn_error_t *err;
-  const char *out;
-
-#ifdef USE_WIN32_CONSOLE_SHORTCUT
-  /* For legacy reasons the Visual C++ runtime converts output to the console
-     from the native 'ansi' encoding, to unicode, then back to 'ansi' and then
-     onwards to the console which is implemented as unicode.
-
-     For operations like 'svn status -v' this may cause about 70% of the total
-     processing time, with absolutely no gain.
-
-     For this specific scenario this shortcut exists. It has the nice side
-     effect of allowing full unicode output to the console.
-
-     Note that this shortcut is not used when the output is redirected, as in
-     that case the data is put on the pipe/file after the first conversion to
-     ansi. In this case the most expensive conversion is already avoided.
-   */
-  if ((stream == stdout && shortcut_stdout_to_console)
-      || (stream == stderr && shortcut_stderr_to_console))
-    {
-      WCHAR *result;
-
-      if (string[0] == '\0')
-        return SVN_NO_ERROR;
-
-      SVN_ERR(svn_cmdline_fflush(stream)); /* Flush existing output */
-
-      SVN_ERR(svn_utf__win32_utf8_to_utf16(&result, string, NULL, pool));
-
-      if (_cputws(result))
-        {
-          if (apr_get_os_error())
-          {
-            return svn_error_wrap_apr(apr_get_os_error(), _("Write error"));
-          }
-        }
-
-      return SVN_NO_ERROR;
-    }
-#endif
-
-  err = svn_cmdline_cstring_from_utf8(&out, string, pool);
-
-  if (err)
-    {
-      svn_error_clear(err);
-      out = svn_cmdline_cstring_from_utf8_fuzzy(string, pool);
-    }
-
-  /* On POSIX systems, errno will be set on an error in fputs, but this might
-     not be the case on other platforms.  We reset errno and only
-     use it if it was set by the below fputs call.  Else, we just return
-     a generic error. */
-  errno = 0;
-
-  if (fputs(out, stream) == EOF)
-    {
-      if (apr_get_os_error()) /* is errno on POSIX */
-        {
-          /* ### Issue #3014: Return a specific error for broken pipes,
-           * ### with a single element in the error chain. */
-          if (SVN__APR_STATUS_IS_EPIPE(apr_get_os_error()))
-            return svn_error_create(SVN_ERR_IO_PIPE_WRITE_ERROR, NULL, NULL);
-          else
-            return svn_error_wrap_apr(apr_get_os_error(), _("Write error"));
-        }
-      else
-        return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline_fflush(FILE *stream)
-{
-  /* See comment in svn_cmdline_fputs about use of errno and stdio. */
-  errno = 0;
-  if (fflush(stream) == EOF)
-    {
-      if (apr_get_os_error()) /* is errno on POSIX */
-        {
-          /* ### Issue #3014: Return a specific error for broken pipes,
-           * ### with a single element in the error chain. */
-          if (SVN__APR_STATUS_IS_EPIPE(apr_get_os_error()))
-            return svn_error_create(SVN_ERR_IO_PIPE_WRITE_ERROR, NULL, NULL);
-          else
-            return svn_error_wrap_apr(apr_get_os_error(), _("Write error"));
-        }
-      else
-        return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-const char *svn_cmdline_output_encoding(apr_pool_t *pool)
-{
-#ifdef CMDLINE_USE_CUSTOM_ENCODING
-  if (output_encoding)
-    return apr_pstrdup(pool, output_encoding);
-#endif
-
-  return SVN_APR_LOCALE_CHARSET;
-}
-
-int
-svn_cmdline_handle_exit_error(svn_error_t *err,
-                              apr_pool_t *pool,
-                              const char *prefix)
-{
-  /* Issue #3014:
-   * Don't print anything on broken pipes. The pipe was likely
-   * closed by the process at the other end. We expect that
-   * process to perform error reporting as necessary.
-   *
-   * ### This assumes that there is only one error in a chain for
-   * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */
-  if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
-    svn_handle_error2(err, stderr, FALSE, prefix);
-  svn_error_clear(err);
-  if (pool)
-    svn_pool_destroy(pool);
-  return EXIT_FAILURE;
-}
-
-struct trust_server_cert_non_interactive_baton {
-  svn_boolean_t trust_server_cert_unknown_ca;
-  svn_boolean_t trust_server_cert_cn_mismatch;
-  svn_boolean_t trust_server_cert_expired;
-  svn_boolean_t trust_server_cert_not_yet_valid;
-  svn_boolean_t trust_server_cert_other_failure;
-};
-
-/* This implements 'svn_auth_ssl_server_trust_prompt_func_t'.
-
-   Don't actually prompt.  Instead, set *CRED_P to valid credentials
-   iff FAILURES is empty or may be accepted according to the flags
-   in BATON. If there are any other failure bits, then set *CRED_P
-   to null (that is, reject the cert).
-
-   Ignore MAY_SAVE; we don't save certs we never prompted for.
-
-   Ignore REALM and CERT_INFO,
-
-   Ignore any further films by George Lucas. */
-static svn_error_t *
-trust_server_cert_non_interactive(svn_auth_cred_ssl_server_trust_t **cred_p,
-                                  void *baton,
-                                  const char *realm,
-                                  apr_uint32_t failures,
-                                  const svn_auth_ssl_server_cert_info_t
-                                    *cert_info,
-                                  svn_boolean_t may_save,
-                                  apr_pool_t *pool)
-{
-  struct trust_server_cert_non_interactive_baton *b = baton;
-  apr_uint32_t non_ignored_failures;
-  *cred_p = NULL;
-
-  /* Mask away bits we are instructed to ignore. */
-  non_ignored_failures = failures & ~(
-        (b->trust_server_cert_unknown_ca ? SVN_AUTH_SSL_UNKNOWNCA : 0)
-      | (b->trust_server_cert_cn_mismatch ? SVN_AUTH_SSL_CNMISMATCH : 0)
-      | (b->trust_server_cert_expired ? SVN_AUTH_SSL_EXPIRED : 0)
-      | (b->trust_server_cert_not_yet_valid ? SVN_AUTH_SSL_NOTYETVALID : 0)
-      | (b->trust_server_cert_other_failure ? SVN_AUTH_SSL_OTHER : 0)
-  );
-
-  /* If no failures remain, accept the certificate. */
-  if (non_ignored_failures == 0)
-    {
-      *cred_p = apr_pcalloc(pool, sizeof(**cred_p));
-      (*cred_p)->may_save = FALSE;
-      (*cred_p)->accepted_failures = failures;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline_create_auth_baton2(svn_auth_baton_t **ab,
-                               svn_boolean_t non_interactive,
-                               const char *auth_username,
-                               const char *auth_password,
-                               const char *config_dir,
-                               svn_boolean_t no_auth_cache,
-                               svn_boolean_t trust_server_cert_unknown_ca,
-                               svn_boolean_t trust_server_cert_cn_mismatch,
-                               svn_boolean_t trust_server_cert_expired,
-                               svn_boolean_t trust_server_cert_not_yet_valid,
-                               svn_boolean_t trust_server_cert_other_failure,
-                               svn_config_t *cfg,
-                               svn_cancel_func_t cancel_func,
-                               void *cancel_baton,
-                               apr_pool_t *pool)
-
-{
-  svn_boolean_t store_password_val = TRUE;
-  svn_boolean_t store_auth_creds_val = TRUE;
-  svn_auth_provider_object_t *provider;
-  svn_cmdline_prompt_baton2_t *pb = NULL;
-
-  /* The whole list of registered providers */
-  apr_array_header_t *providers;
-
-  /* Populate the registered providers with the platform-specific providers */
-  SVN_ERR(svn_auth_get_platform_specific_client_providers(&providers,
-                                                          cfg, pool));
-
-  /* If we have a cancellation function, cram it and the stuff it
-     needs into the prompt baton. */
-  if (cancel_func)
-    {
-      pb = apr_palloc(pool, sizeof(*pb));
-      pb->cancel_func = cancel_func;
-      pb->cancel_baton = cancel_baton;
-      pb->config_dir = config_dir;
-    }
-
-  if (!non_interactive)
-    {
-      /* This provider doesn't prompt the user in order to get creds;
-         it prompts the user regarding the caching of creds. */
-      svn_auth_get_simple_provider2(&provider,
-                                    svn_cmdline_auth_plaintext_prompt,
-                                    pb, pool);
-    }
-  else
-    {
-      svn_auth_get_simple_provider2(&provider, NULL, NULL, pool);
-    }
-
-  APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-  svn_auth_get_username_provider(&provider, pool);
-  APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-  svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
-  APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-  svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
-  APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-  if (!non_interactive)
-    {
-      /* This provider doesn't prompt the user in order to get creds;
-         it prompts the user regarding the caching of creds. */
-      svn_auth_get_ssl_client_cert_pw_file_provider2
-        (&provider, svn_cmdline_auth_plaintext_passphrase_prompt,
-         pb, pool);
-    }
-  else
-    {
-      svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, NULL, NULL,
-                                                     pool);
-    }
-  APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-  if (!non_interactive)
-    {
-      svn_boolean_t ssl_client_cert_file_prompt;
-
-      SVN_ERR(svn_config_get_bool(cfg, &ssl_client_cert_file_prompt,
-                                  SVN_CONFIG_SECTION_AUTH,
-                                  
SVN_CONFIG_OPTION_SSL_CLIENT_CERT_FILE_PROMPT,
-                                  FALSE));
-
-      /* Two basic prompt providers: username/password, and just username. */
-      svn_auth_get_simple_prompt_provider(&provider,
-                                          svn_cmdline_auth_simple_prompt,
-                                          pb,
-                                          2, /* retry limit */
-                                          pool);
-      APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-      svn_auth_get_username_prompt_provider
-        (&provider, svn_cmdline_auth_username_prompt, pb,
-         2, /* retry limit */ pool);
-      APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-      /* SSL prompt providers: server-certs and client-cert-passphrases.  */
-      svn_auth_get_ssl_server_trust_prompt_provider
-        (&provider, svn_cmdline_auth_ssl_server_trust_prompt, pb, pool);
-      APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-      svn_auth_get_ssl_client_cert_pw_prompt_provider
-        (&provider, svn_cmdline_auth_ssl_client_cert_pw_prompt, pb, 2, pool);
-      APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-      /* If configuration allows, add a provider for client-cert path
-         prompting, too. */
-      if (ssl_client_cert_file_prompt)
-        {
-          svn_auth_get_ssl_client_cert_prompt_provider
-            (&provider, svn_cmdline_auth_ssl_client_cert_prompt, pb, 2, pool);
-          APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-        }
-    }
-  else if (trust_server_cert_unknown_ca || trust_server_cert_cn_mismatch ||
-           trust_server_cert_expired || trust_server_cert_not_yet_valid ||
-           trust_server_cert_other_failure)
-    {
-      struct trust_server_cert_non_interactive_baton *b;
-
-      b = apr_palloc(pool, sizeof(*b));
-      b->trust_server_cert_unknown_ca = trust_server_cert_unknown_ca;
-      b->trust_server_cert_cn_mismatch = trust_server_cert_cn_mismatch;
-      b->trust_server_cert_expired = trust_server_cert_expired;
-      b->trust_server_cert_not_yet_valid = trust_server_cert_not_yet_valid;
-      b->trust_server_cert_other_failure = trust_server_cert_other_failure;
-
-      /* Remember, only register this provider if non_interactive. */
-      svn_auth_get_ssl_server_trust_prompt_provider
-        (&provider, trust_server_cert_non_interactive, b, pool);
-      APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-    }
-
-  /* Build an authentication baton to give to libsvn_client. */
-  svn_auth_open(ab, providers, pool);
-
-  /* Place any default --username or --password credentials into the
-     auth_baton's run-time parameter hash. */
-  if (auth_username)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DEFAULT_USERNAME,
-                           auth_username);
-  if (auth_password)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD,
-                           auth_password);
-
-  /* Same with the --non-interactive option. */
-  if (non_interactive)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NON_INTERACTIVE, "");
-
-  if (config_dir)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_CONFIG_DIR,
-                           config_dir);
-
-  /* Determine whether storing passwords in any form is allowed.
-   * This is the deprecated location for this option, the new
-   * location is SVN_CONFIG_CATEGORY_SERVERS. The RA layer may
-   * override the value we set here. */
-  SVN_ERR(svn_config_get_bool(cfg, &store_password_val,
-                              SVN_CONFIG_SECTION_AUTH,
-                              SVN_CONFIG_OPTION_STORE_PASSWORDS,
-                              SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS));
-
-  if (! store_password_val)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
-
-  /* Determine whether we are allowed to write to the auth/ area.
-   * This is the deprecated location for this option, the new
-   * location is SVN_CONFIG_CATEGORY_SERVERS. The RA layer may
-   * override the value we set here. */
-  SVN_ERR(svn_config_get_bool(cfg, &store_auth_creds_val,
-                              SVN_CONFIG_SECTION_AUTH,
-                              SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
-                              SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS));
-
-  if (no_auth_cache || ! store_auth_creds_val)
-    svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
-
-#ifdef SVN_HAVE_GNOME_KEYRING
-  svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
-                         &svn_cmdline__auth_gnome_keyring_unlock_prompt);
-#endif /* SVN_HAVE_GNOME_KEYRING */
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline__getopt_init(apr_getopt_t **os,
-                         int argc,
-                         const char *argv[],
-                         apr_pool_t *pool)
-{
-  apr_status_t apr_err = apr_getopt_init(os, pool, argc, argv);
-  if (apr_err)
-    return svn_error_wrap_apr(apr_err,
-                              _("Error initializing command line arguments"));
-  return SVN_NO_ERROR;
-}
-
-
-void
-svn_cmdline__print_xml_prop(svn_stringbuf_t **outstr,
-                            const char* propname,
-                            svn_string_t *propval,
-                            svn_boolean_t inherited_prop,
-                            apr_pool_t *pool)
-{
-  const char *xml_safe;
-  const char *encoding = NULL;
-
-  if (*outstr == NULL)
-    *outstr = svn_stringbuf_create_empty(pool);
-
-  if (svn_xml_is_xml_safe(propval->data, propval->len))
-    {
-      svn_stringbuf_t *xml_esc = NULL;
-      svn_xml_escape_cdata_string(&xml_esc, propval, pool);
-      xml_safe = xml_esc->data;
-    }
-  else
-    {
-      const svn_string_t *base64ed = svn_base64_encode_string2(propval, TRUE,
-                                                               pool);
-      encoding = "base64";
-      xml_safe = base64ed->data;
-    }
-
-  if (encoding)
-    svn_xml_make_open_tag(
-      outstr, pool, svn_xml_protect_pcdata,
-      inherited_prop ? "inherited_property" : "property",
-      "name", propname,
-      "encoding", encoding, SVN_VA_NULL);
-  else
-    svn_xml_make_open_tag(
-      outstr, pool, svn_xml_protect_pcdata,
-      inherited_prop ? "inherited_property" : "property",
-      "name", propname, SVN_VA_NULL);
-
-  svn_stringbuf_appendcstr(*outstr, xml_safe);
-
-  svn_xml_make_close_tag(
-    outstr, pool,
-    inherited_prop ? "inherited_property" : "property");
-
-  return;
-}
-
-/* Return the most similar string to NEEDLE in HAYSTACK, which contains
- * HAYSTACK_LEN elements.  Return NULL if no string is sufficiently similar.
- */
-/* See svn_cl__similarity_check() for a more general solution. */
-static const char *
-most_similar(const char *needle_cstr,
-             const char **haystack,
-             apr_size_t haystack_len,
-             apr_pool_t *scratch_pool)
-{
-  const char *max_similar = NULL;
-  apr_size_t max_score = 0;
-  apr_size_t i;
-  svn_membuf_t membuf;
-  svn_string_t *needle_str = svn_string_create(needle_cstr, scratch_pool);
-
-  svn_membuf__create(&membuf, 64, scratch_pool);
-
-  for (i = 0; i < haystack_len; i++)
-    {
-      apr_size_t score;
-      svn_string_t *hay = svn_string_create(haystack[i], scratch_pool);
-
-      score = svn_string__similarity(needle_str, hay, &membuf, NULL);
-
-      /* If you update this factor, consider updating
-       * svn_cl__similarity_check(). */
-      if (score >= (2 * SVN_STRING__SIM_RANGE_MAX + 1) / 3
-          && score > max_score)
-        {
-          max_score = score;
-          max_similar = haystack[i];
-        }
-    }
-
-  return max_similar;
-}
-
-/* Verify that NEEDLE is in HAYSTACK, which contains HAYSTACK_LEN elements. */
-static svn_error_t *
-string_in_array(const char *needle,
-                const char **haystack,
-                apr_size_t haystack_len,
-                apr_pool_t *scratch_pool)
-{
-  const char *next_of_kin;
-  apr_size_t i;
-  for (i = 0; i < haystack_len; i++)
-    {
-      if (!strcmp(needle, haystack[i]))
-        return SVN_NO_ERROR;
-    }
-
-  /* Error. */
-  next_of_kin = most_similar(needle, haystack, haystack_len, scratch_pool);
-  if (next_of_kin)
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("Ignoring unknown value '%s'; "
-                               "did you mean '%s'?"),
-                             needle, next_of_kin);
-  else
-    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("Ignoring unknown value '%s'"),
-                             needle);
-}
-
-#include "config_keys.inc"
-
-/* Validate the FILE, SECTION, and OPTION components of CONFIG_OPTION are
- * known.  Return an error if not.  (An unknown value may be either a typo
- * or added in a newer minor version of Subversion.) */
-static svn_error_t *
-validate_config_option(svn_cmdline__config_argument_t *config_option,
-                       apr_pool_t *scratch_pool)
-{
-  svn_boolean_t arbitrary_keys = FALSE;
-
-  /* TODO: some day, we could also verify that OPTION is valid for SECTION;
-     i.e., forbid invalid combinations such as config:auth:diff-extensions. */
-
-#define ARRAYLEN(x) ( sizeof((x)) / sizeof((x)[0]) )
-
-  SVN_ERR(string_in_array(config_option->file, svn__valid_config_files,
-                          ARRAYLEN(svn__valid_config_files),
-                          scratch_pool));
-  SVN_ERR(string_in_array(config_option->section, svn__valid_config_sections,
-                          ARRAYLEN(svn__valid_config_sections),
-                          scratch_pool));
-
-  /* Don't validate option names for sections such as servers[group],
-   * config[tunnels], and config[auto-props] that permit arbitrary options. */
-    {
-      int i;
-
-      for (i = 0; i < ARRAYLEN(svn__empty_config_sections); i++)
-        {
-        if (!strcmp(config_option->section, svn__empty_config_sections[i]))
-          arbitrary_keys = TRUE;
-        }
-    }
-
-  if (! arbitrary_keys)
-    SVN_ERR(string_in_array(config_option->option, svn__valid_config_options,
-                            ARRAYLEN(svn__valid_config_options),
-                            scratch_pool));
-
-#undef ARRAYLEN
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline__parse_config_option(apr_array_header_t *config_options,
-                                 const char *opt_arg,
-                                 const char *prefix,
-                                 apr_pool_t *pool)
-{
-  svn_cmdline__config_argument_t *config_option;
-  const char *first_colon, *second_colon, *equals_sign;
-  apr_size_t len = strlen(opt_arg);
-  if ((first_colon = strchr(opt_arg, ':')) && (first_colon != opt_arg))
-    {
-      if ((second_colon = strchr(first_colon + 1, ':')) &&
-          (second_colon != first_colon + 1))
-        {
-          if ((equals_sign = strchr(second_colon + 1, '=')) &&
-              (equals_sign != second_colon + 1))
-            {
-              svn_error_t *warning;
-
-              config_option = apr_pcalloc(pool, sizeof(*config_option));
-              config_option->file = apr_pstrndup(pool, opt_arg,
-                                                 first_colon - opt_arg);
-              config_option->section = apr_pstrndup(pool, first_colon + 1,
-                                                    second_colon - first_colon 
- 1);
-              config_option->option = apr_pstrndup(pool, second_colon + 1,
-                                                   equals_sign - second_colon 
- 1);
-
-              warning = validate_config_option(config_option, pool);
-              if (warning)
-                {
-                  svn_handle_warning2(stderr, warning, prefix);
-                  svn_error_clear(warning);
-                }
-
-              if (! (strchr(config_option->option, ':')))
-                {
-                  config_option->value = apr_pstrndup(pool, equals_sign + 1,
-                                                      opt_arg + len - 
equals_sign - 1);
-                  APR_ARRAY_PUSH(config_options, 
svn_cmdline__config_argument_t *)
-                                       = config_option;
-                  return SVN_NO_ERROR;
-                }
-            }
-        }
-    }
-  return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                          _("Invalid syntax of argument of --config-option"));
-}
-
-svn_error_t *
-svn_cmdline__apply_config_options(apr_hash_t *config,
-                                  const apr_array_header_t *config_options,
-                                  const char *prefix,
-                                  const char *argument_name)
-{
-  int i;
-
-  for (i = 0; i < config_options->nelts; i++)
-   {
-     svn_config_t *cfg;
-     svn_cmdline__config_argument_t *arg =
-                          APR_ARRAY_IDX(config_options, i,
-                                        svn_cmdline__config_argument_t *);
-
-     cfg = svn_hash_gets(config, arg->file);
-
-     if (cfg)
-       {
-         svn_config_set(cfg, arg->section, arg->option, arg->value);
-       }
-     else
-       {
-         svn_error_t *err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, 
NULL,
-             _("Unrecognized file in argument of %s"), argument_name);
-
-         svn_handle_warning2(stderr, err, prefix);
-         svn_error_clear(err);
-       }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Return a copy, allocated in POOL, of the next line of text from *STR
- * up to and including a CR and/or an LF. Change *STR to point to the
- * remainder of the string after the returned part. If there are no
- * characters to be returned, return NULL; never return an empty string.
- */
-static const char *
-next_line(const char **str, apr_pool_t *pool)
-{
-  const char *start = *str;
-  const char *p = *str;
-
-  /* n.b. Throughout this fn, we never read any character after a '\0'. */
-  /* Skip over all non-EOL characters, if any. */
-  while (*p != '\r' && *p != '\n' && *p != '\0')
-    p++;
-  /* Skip over \r\n or \n\r or \r or \n, if any. */
-  if (*p == '\r' || *p == '\n')
-    {
-      char c = *p++;
-
-      if ((c == '\r' && *p == '\n') || (c == '\n' && *p == '\r'))
-        p++;
-    }
-
-  /* Now p points after at most one '\n' and/or '\r'. */
-  *str = p;
-
-  if (p == start)
-    return NULL;
-
-  return svn_string_ncreate(start, p - start, pool)->data;
-}
-
-const char *
-svn_cmdline__indent_string(const char *str,
-                           const char *indent,
-                           apr_pool_t *pool)
-{
-  svn_stringbuf_t *out = svn_stringbuf_create_empty(pool);
-  const char *line;
-
-  while ((line = next_line(&str, pool)))
-    {
-      svn_stringbuf_appendcstr(out, indent);
-      svn_stringbuf_appendcstr(out, line);
-    }
-  return out->data;
-}
-
-svn_error_t *
-svn_cmdline__print_prop_hash(svn_stream_t *out,
-                             apr_hash_t *prop_hash,
-                             svn_boolean_t names_only,
-                             apr_pool_t *pool)
-{
-  apr_array_header_t *sorted_props;
-  int i;
-
-  sorted_props = svn_sort__hash(prop_hash, svn_sort_compare_items_lexically,
-                                pool);
-  for (i = 0; i < sorted_props->nelts; i++)
-    {
-      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
-      const char *pname = item.key;
-      svn_string_t *propval = item.value;
-      const char *pname_stdout;
-
-      if (svn_prop_needs_translation(pname))
-        SVN_ERR(svn_subst_detranslate_string(&propval, propval,
-                                             TRUE, pool));
-
-      SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_stdout, pname, pool));
-
-      if (out)
-        {
-          pname_stdout = apr_psprintf(pool, "  %s\n", pname_stdout);
-          SVN_ERR(svn_subst_translate_cstring2(pname_stdout, &pname_stdout,
-                                              APR_EOL_STR,  /* 'native' eol */
-                                              FALSE, /* no repair */
-                                              NULL,  /* no keywords */
-                                              FALSE, /* no expansion */
-                                              pool));
-
-          SVN_ERR(svn_stream_puts(out, pname_stdout));
-        }
-      else
-        {
-          /* ### We leave these printfs for now, since if propval wasn't
-             translated above, we don't know anything about its encoding.
-             In fact, it might be binary data... */
-          printf("  %s\n", pname_stdout);
-        }
-
-      if (!names_only)
-        {
-          /* Add an extra newline to the value before indenting, so that
-           * every line of output has the indentation whether the value
-           * already ended in a newline or not. */
-          const char *newval = apr_psprintf(pool, "%s\n", propval->data);
-          const char *indented_newval = svn_cmdline__indent_string(newval,
-                                                                   "    ",
-                                                                   pool);
-          if (out)
-            {
-              SVN_ERR(svn_stream_puts(out, indented_newval));
-            }
-          else
-            {
-              printf("%s", indented_newval);
-            }
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_cmdline__print_xml_prop_hash(svn_stringbuf_t **outstr,
-                                 apr_hash_t *prop_hash,
-                                 svn_boolean_t names_only,
-                                 svn_boolean_t inherited_props,
-                                 apr_pool_t *pool)
-{
-  apr_array_header_t *sorted_props;
-  int i;
-
-  if (*outstr == NULL)
-    *outstr = svn_stringbuf_create_empty(pool);
-
-  sorted_props = svn_sort__hash(prop_hash, svn_sort_compare_items_lexically,
-                                pool);
-  for (i = 0; i < sorted_props->nelts; i++)
-    {
-      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
-      const char *pname = item.key;
-      svn_string_t *propval = item.value;
-
-      if (names_only)
-        {
-          svn_xml_make_open_tag(
-            outstr, pool, svn_xml_self_closing,
-            inherited_props ? "inherited_property" : "property",
-            "name", pname, SVN_VA_NULL);
-        }
-      else
-        {
-          const char *pname_out;
-
-          if (svn_prop_needs_translation(pname))
-            SVN_ERR(svn_subst_detranslate_string(&propval, propval,
-                                                 TRUE, pool));
-
-          SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_out, pname, pool));
-
-          svn_cmdline__print_xml_prop(outstr, pname_out, propval,
-                                      inherited_props, pool);
-        }
-    }
-
-    return SVN_NO_ERROR;
-}
-
-svn_boolean_t
-svn_cmdline__stdin_is_a_terminal(void)
-{
-#ifdef WIN32
-  return (_isatty(STDIN_FILENO) != 0);
-#else
-  return (isatty(STDIN_FILENO) != 0);
-#endif
-}
-
-svn_boolean_t
-svn_cmdline__stdout_is_a_terminal(void)
-{
-#ifdef WIN32
-  return (_isatty(STDOUT_FILENO) != 0);
-#else
-  return (isatty(STDOUT_FILENO) != 0);
-#endif
-}
-
-svn_boolean_t
-svn_cmdline__stderr_is_a_terminal(void)
-{
-#ifdef WIN32
-  return (_isatty(STDERR_FILENO) != 0);
-#else
-  return (isatty(STDERR_FILENO) != 0);
-#endif
-}
-
-svn_boolean_t
-svn_cmdline__be_interactive(svn_boolean_t non_interactive,
-                            svn_boolean_t force_interactive)
-{
-  /* If neither --non-interactive nor --force-interactive was passed,
-   * be interactive if stdin is a terminal.
-   * If --force-interactive was passed, always be interactive. */
-  if (!force_interactive && !non_interactive)
-    {
-      return svn_cmdline__stdin_is_a_terminal();
-    }
-  else if (force_interactive)
-    return TRUE;
-
-  return !non_interactive;
-}
-
-
 /* Helper for the edit_externally functions.  Set *EDITOR to some path to an
    editor binary, in native C string on Unix/Linux platforms and in UTF-8
    string on Windows platform.  Sources to search include: the EDITOR_CMD
@@ -1755,203 +561,3 @@ svn_cmdline__edit_string_externally(svn_
 
   return svn_error_trace(err);
 }
-
-svn_error_t *
-svn_cmdline__parse_trust_options(
-                        svn_boolean_t *trust_server_cert_unknown_ca,
-                        svn_boolean_t *trust_server_cert_cn_mismatch,
-                        svn_boolean_t *trust_server_cert_expired,
-                        svn_boolean_t *trust_server_cert_not_yet_valid,
-                        svn_boolean_t *trust_server_cert_other_failure,
-                        const char *opt_arg,
-                        apr_pool_t *scratch_pool)
-{
-  apr_array_header_t *failures;
-  int i;
-
-  *trust_server_cert_unknown_ca = FALSE;
-  *trust_server_cert_cn_mismatch = FALSE;
-  *trust_server_cert_expired = FALSE;
-  *trust_server_cert_not_yet_valid = FALSE;
-  *trust_server_cert_other_failure = FALSE;
-
-  failures = svn_cstring_split(opt_arg, ", \n\r\t\v", TRUE, scratch_pool);
-
-  for (i = 0; i < failures->nelts; i++)
-    {
-      const char *value = APR_ARRAY_IDX(failures, i, const char *);
-      if (!strcmp(value, "unknown-ca"))
-        *trust_server_cert_unknown_ca = TRUE;
-      else if (!strcmp(value, "cn-mismatch"))
-        *trust_server_cert_cn_mismatch = TRUE;
-      else if (!strcmp(value, "expired"))
-        *trust_server_cert_expired = TRUE;
-      else if (!strcmp(value, "not-yet-valid"))
-        *trust_server_cert_not_yet_valid = TRUE;
-      else if (!strcmp(value, "other"))
-        *trust_server_cert_other_failure = TRUE;
-      else
-        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                  _("Unknown value '%s' for %s.\n"
-                                    "Supported values: %s"),
-                                  value,
-                                  "--trust-server-cert-failures",
-                                  "unknown-ca, cn-mismatch, expired, "
-                                  "not-yet-valid, other");
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Flags to see if we've been cancelled by the client or not. */
-static volatile sig_atomic_t cancelled = FALSE;
-static volatile sig_atomic_t signum_cancelled = 0;
-
-/* The signals we handle. */
-static int signal_map [] = {
-  SIGINT
-#ifdef SIGBREAK
-  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
-  , SIGBREAK
-#endif
-#ifdef SIGHUP
-  , SIGHUP
-#endif
-#ifdef SIGTERM
-  , SIGTERM
-#endif
-};
-
-/* A signal handler to support cancellation. */
-static void
-signal_handler(int signum)
-{
-  int i;
-
-  apr_signal(signum, SIG_IGN);
-  cancelled = TRUE;
-  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
-    if (signal_map[i] == signum)
-      {
-        signum_cancelled = i + 1;
-        break;
-      }
-}
-
-/* An svn_cancel_func_t callback. */
-static svn_error_t *
-check_cancel(void *baton)
-{
-  /* Cancel baton should be always NULL in command line client. */
-  SVN_ERR_ASSERT(baton == NULL);
-  if (cancelled)
-    return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));
-  else
-    return SVN_NO_ERROR;
-}
-
-svn_cancel_func_t
-svn_cmdline__setup_cancellation_handler(void)
-{
-  int i;
-
-  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
-    apr_signal(signal_map[i], signal_handler);
-
-#ifdef SIGPIPE
-  /* Disable SIGPIPE generation for the platforms that have it. */
-  apr_signal(SIGPIPE, SIG_IGN);
-#endif
-
-#ifdef SIGXFSZ
-  /* Disable SIGXFSZ generation for the platforms that have it, otherwise
-   * working with large files when compiled against an APR that doesn't have
-   * large file support will crash the program, which is uncool. */
-  apr_signal(SIGXFSZ, SIG_IGN);
-#endif
-
-  return check_cancel;
-}
-
-void
-svn_cmdline__disable_cancellation_handler(void)
-{
-  int i;
-
-  for (i = 0; i < sizeof(signal_map)/sizeof(signal_map[0]); ++i)
-    apr_signal(signal_map[i], SIG_DFL);
-}
-
-void
-svn_cmdline__cancellation_exit(void)
-{
-  int signum = 0;
-
-  if (cancelled && signum_cancelled)
-    signum = signal_map[signum_cancelled - 1];
-  if (signum)
-    {
-#ifndef WIN32
-      apr_signal(signum, SIG_DFL);
-      /* No APR support for getpid() so cannot use apr_proc_kill(). */
-      kill(getpid(), signum);
-#endif
-    }
-}
-
-#if defined(WIN32)
-
-svn_error_t *
-svn_cmdline__win32_get_cstring_argv(const char **cstring_argv_p[],
-                                    int argc,
-                                    const wchar_t *argv[],
-                                    apr_pool_t *result_pool)
-{
-  apr_array_header_t *cstring_argv;
-  int i;
-
-  cstring_argv = apr_array_make(result_pool, argc + 1, sizeof(const char *));
-
-  for (i = 0; i < argc; i++)
-    {
-      const wchar_t *arg = argv[i];
-      char *cstring_arg;
-      int rv;
-
-      /* Passing -1 for the string length guarantees that the returned length
-         will account for a terminating null character. */
-      rv = WideCharToMultiByte(CP_ACP, 0, arg, -1, NULL, 0, NULL, NULL);
-      if (rv <= 0)
-        {
-          return svn_error_wrap_apr(apr_get_os_error(),
-                                    _("Conversion from UTF-16 failed"));
-        }
-
-      cstring_arg = apr_palloc(result_pool, rv);
-      rv = WideCharToMultiByte(CP_ACP, 0, arg, -1, cstring_arg, rv, NULL, 
NULL);
-      if (rv <= 0)
-        {
-          return svn_error_wrap_apr(apr_get_os_error(),
-                                    _("Conversion from UTF-16 failed"));
-        }
-
-      APR_ARRAY_PUSH(cstring_argv, const char *) = cstring_arg;
-    }
-
-  APR_ARRAY_PUSH(cstring_argv, const char *) = NULL;
-
-  *cstring_argv_p = (const char **)cstring_argv->elts;
-  return SVN_NO_ERROR;
-}
-
-#endif
-
-svn_error_t *
-svn_cmdline__default_get_cstring_argv(const char **cstring_argv_p[],
-                                      int argc,
-                                      const char *argv[],
-                                      apr_pool_t *result_pool)
-{
-  *cstring_argv_p = argv;
-  return SVN_NO_ERROR;
-}


Reply via email to