On Sat, Oct 07, 2017 at 03:18:11PM -0700, William Orr wrote:
> Thanks for the feedback. I've finally gotten the chance to update the
> patch with the suggestions. Lemme know if this addresses your concerns,
> and I can write up the changelog for it.
> 
> Thanks,
> William Orr
> 

Thanks. Some remarks inline below.

> Index: subversion/include/svn_io.h
> ===================================================================
> --- subversion/include/svn_io.h       (revisi??n: 1811402)
> +++ subversion/include/svn_io.h       (copia de trabajo)
> @@ -2633,6 +2633,14 @@ svn_io_file_readline(apr_file_t *file,
>                       apr_pool_t *result_pool,
>                       apr_pool_t *scratch_pool);
>  
> +/** Reads a string from stdin until a newline or EOF is found
> + *
> + * @since New in 1.9.

This should say "1.10" because our current trunk will become 1.10, not 1.9.

> + */
> +svn_error_t *
> +svn_io_stdin_readline(const char **result,
> +                      apr_pool_t *pool);

Most of our APIs now use a dual-pool idiom: A scratch pool for temporary
data, and a result pool for data which the function will return.
Can we use this idiom here?

> +
>  /** @} */
>  
>  #ifdef __cplusplus
> Index: subversion/libsvn_subr/io.c
> ===================================================================
> --- subversion/libsvn_subr/io.c       (revisi??n: 1811402)
> +++ subversion/libsvn_subr/io.c       (copia de trabajo)
> @@ -5440,3 +5440,19 @@ svn_io_file_readline(apr_file_t *file,
>  
>    return SVN_NO_ERROR;
>  }
> +
> +svn_error_t *
> +svn_io_stdin_readline(const char **result,
> +                       apr_pool_t *pool)
> +{
> +  svn_stringbuf_t *buf = NULL;
> +  svn_stream_t *stdin = NULL;
> +  svn_boolean_t oob = FALSE;
> +
> +  SVN_ERR(svn_stream_for_stdin2(&stdin, TRUE, pool));

The stream would be stored in the scratch_pool.

> +  SVN_ERR(svn_stream_readline(stdin, &buf, APR_EOL_STR, &oob, pool));

The stringbuf would be stored in the result_pool.

> +
> +  *result = buf->data;
> +
> +  return SVN_NO_ERROR;
> +}
> Index: subversion/svn/cl.h
> ===================================================================
> --- subversion/svn/cl.h       (revisi??n: 1811402)
> +++ subversion/svn/cl.h       (copia de trabajo)
> @@ -178,6 +178,7 @@ typedef struct svn_cl__opt_state_t
>    svn_boolean_t help;            /* print usage message */
>    const char *auth_username;     /* auth username */
>    const char *auth_password;     /* auth password */
> +  svn_boolean_t auth_password_from_stdin; /* fd to read password from */

The above comment still talks about a file descriptor. Update it?

>    const char *extensions;        /* subprocess extension args */
>    apr_array_header_t *targets;   /* target list from file */
>    svn_boolean_t xml;             /* output in xml, e.g., "svn log --xml" */
> Index: subversion/svn/svn.c
> ===================================================================
> --- subversion/svn/svn.c      (revisi??n: 1811402)
> +++ subversion/svn/svn.c      (copia de trabajo)
> @@ -68,6 +68,7 @@
>     use the short option letter as identifier.  */
>  typedef enum svn_cl__longopt_t {
>    opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
> +  opt_auth_password_from_stdin,
>    opt_auth_username,
>    opt_autoprops,
>    opt_changelist,
> @@ -200,6 +201,9 @@ const apr_getopt_option_t svn_cl__options[] =
>                      N_("specify a password ARG (caution: on many operating\n"
>                         "                             "
>                         "systems, other users will be able to see this)")},
> +  {"password-from-stdin",
> +                    opt_auth_password_from_stdin, 0,
> +                    N_("read password from stdin")},
>    {"extensions",    'x', 1,
>                      N_("Specify differencing options for external diff or\n"
>                         "                             "
> @@ -495,7 +499,8 @@ const apr_getopt_option_t svn_cl__options[] =
>     command to take these arguments allows scripts to just pass them
>     willy-nilly to every invocation of 'svn') . */
>  const int svn_cl__global_options[] =
> -{ opt_auth_username, opt_auth_password, opt_no_auth_cache, 
> opt_non_interactive,
> +{ opt_auth_username, opt_auth_password, opt_auth_password_from_stdin,
> +  opt_no_auth_cache, opt_non_interactive,
>    opt_force_interactive, opt_trust_server_cert,
>    opt_trust_server_cert_failures,
>    opt_config_dir, opt_config_options, 0
> @@ -1959,6 +1964,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    apr_hash_t *changelists;
>    apr_hash_t *cfg_hash;
>    svn_membuf_t buf;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
>  
> @@ -2251,6 +2257,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
>                                          opt_arg, pool));
>          break;
> +      case opt_auth_password_from_stdin:
> +        read_pass_from_stdin = TRUE;
> +        break;
>        case opt_encoding:
>          opt_state.encoding = apr_pstrdup(pool, opt_arg);
>          break;
> @@ -2745,6 +2754,14 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    "--non-interactive"));
>      }
>  
> +  /* --password-from-stdin can only be used with --non-interactive */
> +  if (read_pass_from_stdin && !opt_state.non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
> +
>    /* Disallow simultaneous use of both --diff-cmd and
>       --internal-diff.  */
>    if (opt_state.diff.diff_cmd && opt_state.diff.internal_diff)
> @@ -3034,6 +3051,12 @@ sub_main(int *exit_code, int argc, const char *arg
>                                     conflict_stats, pool));
>      }
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&opt_state.auth_password, pool);

This call needs to be wrapped in SVN_ERR().
In developer builds (./configure --enable-maintainer-mode), ignoring an
'svn_error_t' ("error leak") will make the svn binary dump core upon exit.

> +    }
> +
>    /* Set up our cancellation support. */
>    svn_cl__check_cancel = svn_cmdline__setup_cancellation_handler();
>    ctx->cancel_func = svn_cl__check_cancel;
> Index: subversion/svnbench/svnbench.c
> ===================================================================
> --- subversion/svnbench/svnbench.c    (revisi??n: 1811402)
> +++ subversion/svnbench/svnbench.c    (copia de trabajo)
> @@ -53,6 +53,7 @@
>     use the short option letter as identifier.  */
>  typedef enum svn_cl__longopt_t {
>    opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
> +  opt_auth_password_from_stdin,
>    opt_auth_username,
>    opt_config_dir,
>    opt_config_options,
> @@ -112,6 +113,8 @@ const apr_getopt_option_t svn_cl__options[] =
>    {"verbose",       'v', 0, N_("print extra information")},
>    {"username",      opt_auth_username, 1, N_("specify a username ARG")},
>    {"password",      opt_auth_password, 1, N_("specify a password ARG")},
> +  {"password-from-stdin",
> +                    opt_auth_password_from_stdin, 0, N_("read password from 
> stdin")},
>    {"targets",       opt_targets, 1,
>                      N_("pass contents of file ARG as additional args")},
>    {"depth",         opt_depth, 1,
> @@ -197,7 +200,8 @@ const apr_getopt_option_t svn_cl__options[] =
>     command to take these arguments allows scripts to just pass them
>     willy-nilly to every invocation of 'svn') . */
>  const int svn_cl__global_options[] =
> -{ opt_auth_username, opt_auth_password, opt_no_auth_cache, 
> opt_non_interactive,
> +{ opt_auth_username, opt_auth_password, opt_auth_password_from_stdin,
> +  opt_no_auth_cache, opt_non_interactive,
>    opt_trust_server_cert, opt_trust_server_cert_failures,
>    opt_config_dir, opt_config_options, 0
>  };
> @@ -394,6 +398,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    apr_time_t start_time, time_taken;
>    ra_progress_baton_t ra_progress_baton = {0};
>    svn_membuf_t buf;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
>  
> @@ -625,6 +630,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
>                                              opt_arg, pool));
>          break;
> +      case opt_auth_password_from_stdin:
> +        read_pass_from_stdin = TRUE;
> +        break;
>        case opt_stop_on_copy:
>          opt_state.stop_on_copy = TRUE;
>          break;
> @@ -842,6 +850,14 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    "--non-interactive"));
>      }
>  
> +  /* --password-from-stdin can only be used with --non-interactive */
> +  if (read_pass_from_stdin && !opt_state.non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
> +
>    /* Ensure that 'revision_ranges' has at least one item, and make
>       'start_revision' and 'end_revision' match that item. */
>    if (opt_state.revision_ranges->nelts == 0)
> @@ -919,6 +935,12 @@ sub_main(int *exit_code, int argc, const char *arg
>                                         pool));
>      }
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&opt_state.auth_password, pool);

This call needs to be wrapped in SVN_ERR().

> +    }
> +
>    /* Set up our cancellation support. */
>    svn_cl__check_cancel = svn_cmdline__setup_cancellation_handler();
>    ctx->cancel_func = svn_cl__check_cancel;
> Index: subversion/svnmucc/svnmucc.c
> ===================================================================
> --- subversion/svnmucc/svnmucc.c      (revisi??n: 1811402)
> +++ subversion/svnmucc/svnmucc.c      (copia de trabajo)
> @@ -297,6 +297,7 @@ help(FILE *stream, apr_pool_t *pool)
>        "  -F [--file] ARG        : read log message from file ARG\n"
>        "  -u [--username] ARG    : commit the changes as username ARG\n"
>        "  -p [--password] ARG    : use ARG as the password\n"
> +      "  --password-from-stdin  : read password from stdin\n"
>        "  -U [--root-url] ARG    : interpret all action URLs relative to 
> ARG\n"
>        "  -r [--revision] ARG    : use revision ARG as baseline for changes\n"
>        "  --with-revprop ARG     : set revision property in the following 
> format:\n"
> @@ -480,7 +481,8 @@ sub_main(int *exit_code, int argc, const char *arg
>      non_interactive_opt,
>      force_interactive_opt,
>      trust_server_cert_opt,
> -    trust_server_cert_failures_opt
> +    trust_server_cert_failures_opt,
> +    password_from_stdin_opt
>    };
>    static const apr_getopt_option_t options[] = {
>      {"message", 'm', 1, ""},
> @@ -487,6 +489,7 @@ sub_main(int *exit_code, int argc, const char *arg
>      {"file", 'F', 1, ""},
>      {"username", 'u', 1, ""},
>      {"password", 'p', 1, ""},
> +    {"password-from-stdin", password_from_stdin_opt, 0, ""},
>      {"root-url", 'U', 1, ""},
>      {"revision", 'r', 1, ""},
>      {"with-revprop",  with_revprop_opt, 1, ""},
> @@ -527,6 +530,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    svn_client_ctx_t *ctx;
>    struct log_message_baton lmb;
>    int i;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    /* Check library versions */
>    SVN_ERR(check_lib_versions());
> @@ -572,6 +576,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          case 'p':
>            password = apr_pstrdup(pool, arg);
>            break;
> +        case password_from_stdin_opt:
> +          read_pass_from_stdin = TRUE;
> +          break;
>          case 'U':
>            SVN_ERR(svn_utf_cstring_to_utf8(&root_url, arg, pool));
>            if (! svn_path_is_url(root_url))
> @@ -672,6 +679,15 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    "--non-interactive"));
>      }
>  
> +  /* --password-from-stdin can only be used with --non-interactive */
> +  if (read_pass_from_stdin && !non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
> +
> +
>    /* Copy the rest of our command-line arguments to an array,
>       UTF-8-ing them along the way. */
>    action_args = apr_array_make(pool, opts->argc, sizeof(const char *));
> @@ -721,6 +737,12 @@ sub_main(int *exit_code, int argc, const char *arg
>                                              "svnmucc: ", "--config-option"));
>      }
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&password, pool);

This call needs to be wrapped in SVN_ERR().

> +    }
> +
>    SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
>  
>    cfg_config = svn_hash_gets(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG);
> Index: subversion/svnrdump/svnrdump.c
> ===================================================================
> --- subversion/svnrdump/svnrdump.c    (revisi??n: 1811402)
> +++ subversion/svnrdump/svnrdump.c    (copia de trabajo)
> @@ -59,6 +59,7 @@ enum svn_svnrdump__longopt_t
>      opt_config_option,
>      opt_auth_username,
>      opt_auth_password,
> +    opt_auth_password_from_stdin,
>      opt_auth_nocache,
>      opt_non_interactive,
>      opt_skip_revprop,
> @@ -66,7 +67,7 @@ enum svn_svnrdump__longopt_t
>      opt_incremental,
>      opt_trust_server_cert,
>      opt_trust_server_cert_failures,
> -    opt_version
> +    opt_version,

Is the comma here added on purpose? It's not strictly needed.
Since we're tyring to be C89 compatible (yes, that's old), I suspect
adding this comma could cause problems with some compilers.

>    };
>  
>  #define SVN_SVNRDUMP__BASE_OPTIONS opt_config_dir, \
> @@ -73,6 +74,7 @@ enum svn_svnrdump__longopt_t
>                                     opt_config_option, \
>                                     opt_auth_username, \
>                                     opt_auth_password, \
> +                                   opt_auth_password_from_stdin, \
>                                     opt_auth_nocache, \
>                                     opt_trust_server_cert, \
>                                     opt_trust_server_cert_failures, \
> @@ -114,6 +116,8 @@ static const apr_getopt_option_t svnrdump__options
>                        N_("specify a username ARG")},
>      {"password",      opt_auth_password, 1,
>                        N_("specify a password ARG")},
> +    {"password-from-stdin",   opt_auth_password_from_stdin, 0,
> +                      N_("read password from stdin")},
>      {"non-interactive", opt_non_interactive, 0,
>                        N_("do no interactive prompting (default is to 
> prompt\n"
>                           "                             "
> @@ -154,6 +158,7 @@ static const apr_getopt_option_t svnrdump__options
>                         "valid certificate) and 'other' (all other not\n"
>                         "                             "
>                         "separately classified certificate errors).")},
> +    {"dumpfile", 'F', 1, N_("Read or write to a dumpfile instead of 
> stdin/stdout")},
>      {0, 0, 0, 0}
>    };
>  
> @@ -174,6 +179,7 @@ typedef struct opt_baton_t {
>    svn_client_ctx_t *ctx;
>    svn_ra_session_t *session;
>    const char *url;
> +  const char *dumpfile;
>    svn_boolean_t help;
>    svn_boolean_t version;
>    svn_opt_revision_t start_revision;
> @@ -366,7 +372,8 @@ init_client_context(svn_client_ctx_t **ctx_p,
>  
>    /* Default authentication providers for non-interactive use */
>    SVN_ERR(svn_cmdline_create_auth_baton2(&(ctx->auth_baton), non_interactive,
> -                                         username, password, config_dir,
> +                                         username, password,
> +                                         config_dir,

Adding line wrapping here is unnecessary.

>                                           no_auth_cache, trust_unknown_ca,
>                                           trust_cn_mismatch, trust_expired,
>                                           trust_not_yet_valid,
> @@ -463,31 +470,39 @@ replay_revisions(svn_ra_session_t *session,
>                   svn_revnum_t end_revision,
>                   svn_boolean_t quiet,
>                   svn_boolean_t incremental,
> +                 const char *dumpfile,
>                   apr_pool_t *pool)
>  {
>    struct replay_baton *replay_baton;
>    const char *uuid;
> -  svn_stream_t *stdout_stream;
> +  svn_stream_t *dump_stream;

This is very nitpicky of me, but maybe call it 'output_stream'?
In any case, I agree that stdout_stream should be renamed.

>  
> -  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
> +  if (dumpfile)
> +    {
> +      SVN_ERR(svn_stream_open_writable(&dump_stream, dumpfile, pool, pool));
> +    }
> +  else
> +    {
> +      SVN_ERR(svn_stream_for_stdout(&dump_stream, pool));
> +    }
>  
>    replay_baton = apr_pcalloc(pool, sizeof(*replay_baton));
> -  replay_baton->stdout_stream = stdout_stream;
> +  replay_baton->stdout_stream = dump_stream;
>    replay_baton->extra_ra_session = extra_ra_session;
>    replay_baton->quiet = quiet;
>  
>    /* Write the magic header and UUID */
> -  SVN_ERR(svn_stream_printf(stdout_stream, pool,
> +  SVN_ERR(svn_stream_printf(dump_stream, pool,
>                              SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
>                              SVN_REPOS_DUMPFILE_FORMAT_VERSION));
>    SVN_ERR(svn_ra_get_uuid2(session, &uuid, pool));
> -  SVN_ERR(svn_stream_printf(stdout_stream, pool,
> +  SVN_ERR(svn_stream_printf(dump_stream, pool,
>                              SVN_REPOS_DUMPFILE_UUID ": %s\n\n", uuid));
>  
>    /* Fake revision 0 if necessary */
>    if (start_revision == 0)
>      {
> -      SVN_ERR(dump_revision_header(session, stdout_stream,
> +      SVN_ERR(dump_revision_header(session, dump_stream,
>                                     start_revision, pool));
>  
>        /* Revision 0 has no tree changes, so we're done. */
> @@ -506,7 +521,7 @@ replay_revisions(svn_ra_session_t *session,
>    if (!incremental)
>      {
>        SVN_ERR(dump_initial_full_revision(session, extra_ra_session,
> -                                         stdout_stream, start_revision,
> +                                         dump_stream, start_revision,
>                                           quiet, pool));
>        start_revision++;
>      }
> @@ -538,16 +553,23 @@ replay_revisions(svn_ra_session_t *session,
>  static svn_error_t *
>  load_revisions(svn_ra_session_t *session,
>                 svn_ra_session_t *aux_session,
> -               const char *url,
> +               const char *dumpfile,
>                 svn_boolean_t quiet,
>                 apr_hash_t *skip_revprops,
>                 apr_pool_t *pool)
>  {
> -  svn_stream_t *stdin_stream;
> +  svn_stream_t *dump_stream;
>  
> -  SVN_ERR(svn_stream_for_stdin2(&stdin_stream, TRUE, pool));
> +  if (dumpfile)
> +    {
> +      SVN_ERR(svn_stream_open_readonly(&dump_stream, dumpfile, pool, pool));
> +    }
> +  else
> +    {
> +      SVN_ERR(svn_stream_for_stdin2(&dump_stream, TRUE, pool));
> +    }
>  
> -  SVN_ERR(svn_rdump__load_dumpstream(stdin_stream, session, aux_session,
> +  SVN_ERR(svn_rdump__load_dumpstream(dump_stream, session, aux_session,
>                                       quiet, skip_revprops,
>                                       check_cancel, NULL, pool));
>  
> @@ -616,7 +638,8 @@ dump_cmd(apr_getopt_t *os,
>    return replay_revisions(opt_baton->session, extra_ra_session,
>                            opt_baton->start_revision.value.number,
>                            opt_baton->end_revision.value.number,
> -                          opt_baton->quiet, opt_baton->incremental, pool);
> +                          opt_baton->quiet, opt_baton->incremental,
> +                          opt_baton->dumpfile, pool);
>  }
>  
>  /* Handle the "load" subcommand.  Implements `svn_opt_subcommand_t'.  */
> @@ -630,8 +653,9 @@ load_cmd(apr_getopt_t *os,
>  
>    SVN_ERR(svn_client_open_ra_session2(&aux_session, opt_baton->url, NULL,
>                                        opt_baton->ctx, pool, pool));
> -  return load_revisions(opt_baton->session, aux_session, opt_baton->url,
> -                        opt_baton->quiet, opt_baton->skip_revprops, pool);
> +  return load_revisions(opt_baton->session, aux_session,
> +                        opt_baton->dumpfile, opt_baton->quiet,
> +                        opt_baton->skip_revprops, pool);
>  }
>  
>  /* Handle the "help" subcommand.  Implements `svn_opt_subcommand_t'.  */
> @@ -772,6 +796,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    apr_getopt_t *os;
>    apr_array_header_t *received_opts;
>    int i;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    opt_baton = apr_pcalloc(pool, sizeof(*opt_baton));
>    opt_baton->start_revision.kind = svn_opt_revision_unspecified;
> @@ -778,6 +803,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    opt_baton->end_revision.kind = svn_opt_revision_unspecified;
>    opt_baton->url = NULL;
>    opt_baton->skip_revprops = apr_hash_make(pool);
> +  opt_baton->dumpfile = NULL;
>  
>    SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
>  
> @@ -850,6 +876,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          case opt_auth_password:
>            SVN_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool));
>            break;
> +        case opt_auth_password_from_stdin:
> +          read_pass_from_stdin = TRUE;
> +          break;
>          case opt_auth_nocache:
>            no_auth_cache = TRUE;
>            break;
> @@ -890,6 +919,11 @@ sub_main(int *exit_code, int argc, const char *arg
>                                                       opt_arg, 
>                                                       "svnrdump: ",
>                                                       pool));
> +          break;
> +        case 'F':
> +          SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
> +          opt_baton->dumpfile = opt_arg;
> +          break;
>          }
>      }
>  
> @@ -1005,6 +1039,20 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    "--non-interactive"));
>      }
>  
> +  if (read_pass_from_stdin && !non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
> +
> +  if (strcmp(subcommand->name, "load") == 0)
> +    {
> +      if (read_pass_from_stdin)
> +        {
> +        }

There seems to be some code missing above.

> +    }
> +
>    /* Expect one more non-option argument:  the repository URL. */
>    if (os->ind != os->argc - 1)
>      {
> @@ -1039,9 +1087,16 @@ sub_main(int *exit_code, int argc, const char *arg
>          force_interactive = (username == NULL || password == NULL);
>      }
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&password, pool);

The above call needs to be wrapped in SVN_ERR().

> +    }
> +
>    non_interactive = !svn_cmdline__be_interactive(non_interactive,
>                                                   force_interactive);
>  
> +

Adding an empty line here is not necessary.

>    SVN_ERR(init_client_context(&(opt_baton->ctx),
>                                non_interactive,
>                                username,
> Index: subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
> ===================================================================
> --- subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout     
> (revisi??n: 1811402)
> +++ subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout     
> (copia de trabajo)
> @@ -134,6 +134,7 @@ Global options:
>    --username ARG           : specify a username ARG
>    --password ARG           : specify a password ARG (caution: on many 
> operating
>                               systems, other users will be able to see this)
> +  --password-from-stdin    : read password from stdin
>    --no-auth-cache          : do not cache authentication tokens
>    --non-interactive        : do no interactive prompting (default is to 
> prompt
>                               only if standard input is a terminal device)
> @@ -224,6 +225,7 @@ Global options:
>    --username ARG           : specify a username ARG
>    --password ARG           : specify a password ARG (caution: on many 
> operating
>                               systems, other users will be able to see this)
> +  --password-from-stdin    : read password from stdin
>    --no-auth-cache          : do not cache authentication tokens
>    --non-interactive        : do no interactive prompting (default is to 
> prompt
>                               only if standard input is a terminal device)
> Index: tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c
> ===================================================================
> --- tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c     
> (revisi??n: 1811402)
> +++ tools/client-side/svn-mergeinfo-normalizer/svn-mergeinfo-normalizer.c     
> (copia de trabajo)
> @@ -68,6 +68,7 @@
>     use the short option letter as identifier.  */
>  typedef enum svn_min__longopt_t {
>    opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
> +  opt_auth_password_from_stdin,
>    opt_auth_username,
>    opt_config_dir,
>    opt_config_options,
> @@ -113,6 +114,9 @@ const apr_getopt_option_t svn_min__options[] =
>                      N_("specify a password ARG (caution: on many operating\n"
>                         "                             "
>                         "systems, other users will be able to see this)")},
> +  {"password-from-stdin",
> +                    opt_auth_password_from_stdin, 0,
> +                    N_("read password from stdin")},
>    {"targets",       opt_targets, 1,
>                      N_("pass contents of file ARG as additional args")},
>    {"depth",         opt_depth, 1,
> @@ -209,11 +213,11 @@ const apr_getopt_option_t svn_min__options[] =
>     command to take these arguments allows scripts to just pass them
>     willy-nilly to every invocation of 'svn') . */
>  const int svn_min__global_options[] =
> -{ opt_auth_username, opt_auth_password, opt_no_auth_cache, 
> opt_non_interactive,
> -  opt_force_interactive, opt_trust_server_cert,
> -  opt_trust_server_cert_unknown_ca, opt_trust_server_cert_cn_mismatch,
> -  opt_trust_server_cert_expired, opt_trust_server_cert_not_yet_valid,
> -  opt_trust_server_cert_other_failure,
> +{ opt_auth_username, opt_auth_password, opt_auth_password_from_stdin,
> +  opt_no_auth_cache, opt_non_interactive, opt_force_interactive,
> +  opt_trust_server_cert, opt_trust_server_cert_unknown_ca,
> +  opt_trust_server_cert_cn_mismatch, opt_trust_server_cert_expired,
> +  opt_trust_server_cert_not_yet_valid, opt_trust_server_cert_other_failure,
>    opt_config_dir, opt_config_options, 0
>  };
>  
> @@ -417,6 +421,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    svn_boolean_t interactive_conflicts = FALSE;
>    svn_boolean_t force_interactive = FALSE;
>    apr_hash_t *cfg_hash;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
>  
> @@ -528,6 +533,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
>                                          opt_arg, pool));
>          break;
> +      case opt_auth_password_from_stdin:
> +        read_pass_from_stdin = TRUE;
> +        break;
>        case opt_no_auth_cache:
>          opt_state.no_auth_cache = TRUE;
>          break;
> @@ -606,6 +614,14 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    opt_state.non_interactive,
>                                    force_interactive);
>  
> +  /* --password-from-stdin can only be used with --non-interactive */
> +  if (read_pass_from_stdin && !opt_state.non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
> +
>    /* ### This really belongs in libsvn_client.  The trouble is,
>       there's no one place there to run it from, no
>       svn_client_init().  We'd have to add it to all the public
> @@ -788,6 +804,12 @@ sub_main(int *exit_code, int argc, const char *arg
>    }
>  #endif
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&opt_state.auth_password, pool);

The above call needs to be wrapped in SVN_ERR().

> +    }
> +
>    /* Create a client context object. */
>    command_baton.opt_state = &opt_state;
>    SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
> Index: tools/client-side/svnconflict/svnconflict.c
> ===================================================================
> --- tools/client-side/svnconflict/svnconflict.c       (revisi??n: 1811402)
> +++ tools/client-side/svnconflict/svnconflict.c       (copia de trabajo)
> @@ -78,6 +78,7 @@ typedef struct svnconflict_cmd_baton_t
>     use the short option letter as identifier.  */
>  typedef enum svnconflict_longopt_t {
>    opt_auth_password = SVN_OPT_FIRST_LONGOPT_ID,
> +  opt_auth_password_from_stdin,
>    opt_auth_username,
>    opt_config_dir,
>    opt_config_options,
> @@ -96,6 +97,9 @@ static const apr_getopt_option_t svnconflict_optio
>                      N_("specify a password ARG (caution: on many operating\n"
>                         "                             "
>                         "systems, other users will be able to see this)")},
> +  {"password-from-stdin",
> +                    opt_auth_password_from_stdin, 0,
> +                    N_("read password from stdin")},
>    {"config-dir",    opt_config_dir, 1,
>                      N_("read user configuration files from directory ARG")},
>    {"config-option", opt_config_options, 1,
> @@ -141,7 +145,8 @@ static svn_error_t * svnconflict_resolve_tree(apr_
>  
>  /* Options that apply to all commands. */
>  static const int svnconflict_global_options[] =
> -{ opt_auth_username, opt_auth_password, opt_config_dir, opt_config_options, 
> 0 };
> +{ opt_auth_username, opt_auth_password, opt_auth_password_from_stdin,
> +  opt_config_dir, opt_config_options, 0 };
>  
>  static const svn_opt_subcommand_desc2_t svnconflict_cmd_table[] =
>  {
> @@ -639,6 +644,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    svn_auth_baton_t *ab;
>    svn_config_t *cfg_config;
>    apr_hash_t *cfg_hash;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
>  
> @@ -704,6 +710,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
>                                          opt_arg, pool));
>          break;
> +      case opt_auth_password_from_stdin:
> +        read_pass_from_stdin = TRUE;
> +        break;
>        case opt_config_dir:
>          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
>          opt_state.config_dir = svn_dirent_internal_style(utf8_opt_arg, pool);
> @@ -845,6 +854,13 @@ sub_main(int *exit_code, int argc, const char *arg
>  
>    cfg_config = svn_hash_gets(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG);
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&opt_state.auth_password, pool);

The above call needs to be wrapped in SVN_ERR().

> +    }
> +
> +
>    /* Create a client context object. */
>    command_baton.opt_state = &opt_state;
>    SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
> Index: tools/dev/svnmover/svnmover.c
> ===================================================================
> --- tools/dev/svnmover/svnmover.c     (revisi??n: 1811402)
> +++ tools/dev/svnmover/svnmover.c     (copia de trabajo)
> @@ -4332,7 +4332,8 @@ sub_main(int *exit_code, int argc, const char *arg
>      trust_server_cert_opt,
>      trust_server_cert_failures_opt,
>      ui_opt,
> -    colour_opt
> +    colour_opt,
> +    auth_password_from_stdin_opt
>    };
>    static const apr_getopt_option_t options[] = {
>      {"verbose", 'v', 0, ""},
> @@ -4341,6 +4342,7 @@ sub_main(int *exit_code, int argc, const char *arg
>      {"file", 'F', 1, ""},
>      {"username", 'u', 1, ""},
>      {"password", 'p', 1, ""},
> +    {"password-from-stdin", auth_password_from_stdin_opt, 1, ""},
>      {"root-url", 'U', 1, ""},
>      {"revision", 'r', 1, ""},
>      {"branch-id", 'B', 1, ""},
> @@ -4387,6 +4389,7 @@ sub_main(int *exit_code, int argc, const char *arg
>    const char *log_msg;
>    svn_tristate_t coloured_output = svn_tristate_false;
>    svnmover_wc_t *wc;
> +  svn_boolean_t read_pass_from_stdin = FALSE;
>  
>    /* Check library versions */
>    SVN_ERR(check_lib_versions());
> @@ -4431,6 +4434,9 @@ sub_main(int *exit_code, int argc, const char *arg
>          case 'p':
>            password = apr_pstrdup(pool, arg);
>            break;
> +        case auth_password_from_stdin_opt:
> +          read_pass_from_stdin = TRUE;
> +          break;
>          case 'U':
>            SVN_ERR(svn_utf_cstring_to_utf8(&anchor_url, arg, pool));
>            if (! svn_path_is_url(anchor_url))
> @@ -4553,6 +4559,13 @@ sub_main(int *exit_code, int argc, const char *arg
>                                    "--non-interactive"));
>      }
>  
> +  /* --password-from-stdin can only be used with --non-interactive */
> +  if (read_pass_from_stdin && !non_interactive)
> +    {
> +      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
> +                              _("--password-from-stdin requires "
> +                                "--non-interactive"));
> +    }
>  
>    /* Now initialize the client context */
>  
> @@ -4580,6 +4593,12 @@ sub_main(int *exit_code, int argc, const char *arg
>                                              "svnmover: ", 
> "--config-option"));
>      }
>  
> +  /* Get password from stdin if necessary */
> +  if (read_pass_from_stdin)
> +    {
> +      svn_io_stdin_readline(&password, pool);

The above call needs to be wrapped in SVN_ERR().

> +    }
> +
>    SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
>  
>    cfg_config = svn_hash_gets(cfg_hash, SVN_CONFIG_CATEGORY_CONFIG);

Reply via email to