diff options
Diffstat (limited to 'subversion/svnrdump/svnrdump.c')
-rw-r--r-- | subversion/svnrdump/svnrdump.c | 403 |
1 files changed, 192 insertions, 211 deletions
diff --git a/subversion/svnrdump/svnrdump.c b/subversion/svnrdump/svnrdump.c index 6bf409c..df0286b 100644 --- a/subversion/svnrdump/svnrdump.c +++ b/subversion/svnrdump/svnrdump.c @@ -39,6 +39,7 @@ #include "svnrdump.h" +#include "private/svn_repos_private.h" #include "private/svn_cmdline_private.h" #include "private/svn_ra_private.h" @@ -80,9 +81,11 @@ enum svn_svnrdump__longopt_t opt_auth_password, opt_auth_nocache, opt_non_interactive, + opt_skip_revprop, opt_force_interactive, opt_incremental, opt_trust_server_cert, + opt_trust_server_cert_failures, opt_version }; @@ -92,6 +95,7 @@ enum svn_svnrdump__longopt_t opt_auth_password, \ opt_auth_nocache, \ opt_trust_server_cert, \ + opt_trust_server_cert_failures, \ opt_non_interactive, \ opt_force_interactive @@ -106,7 +110,7 @@ static const svn_opt_subcommand_desc2_t svnrdump__cmd_table[] = { "load", load_cmd, { 0 }, N_("usage: svnrdump load URL\n\n" "Load a 'dumpfile' given on stdin to a repository at remote URL.\n"), - { 'q', SVN_SVNRDUMP__BASE_OPTIONS } }, + { 'q', opt_skip_revprop, SVN_SVNRDUMP__BASE_OPTIONS } }, { "help", 0, { "?", "h" }, N_("usage: svnrdump help [SUBCOMMAND...]\n\n" "Describe the usage of this program or its subcommands.\n"), @@ -122,6 +126,8 @@ static const apr_getopt_option_t svnrdump__options[] = N_("no progress (only errors) to stderr")}, {"incremental", opt_incremental, 0, N_("dump incrementally")}, + {"skip-revprop", opt_skip_revprop, 1, + N_("skip revision property ARG (e.g., \"svn:author\")")}, {"config-dir", opt_config_dir, 1, N_("read user configuration files from directory ARG")}, {"username", opt_auth_username, 1, @@ -150,12 +156,24 @@ static const apr_getopt_option_t svnrdump__options[] = "For example:\n" " " " servers:global:http-library=serf")}, - {"trust-server-cert", opt_trust_server_cert, 0, - N_("accept SSL server certificates from unknown\n" - " " - "certificate authorities without prompting (but only\n" - " " - "with '--non-interactive')") }, + {"trust-server-cert", opt_trust_server_cert, 0, + N_("deprecated; same as\n" + " " + "--trust-server-cert-failures=unknown-ca")}, + {"trust-server-cert-failures", opt_trust_server_cert_failures, 1, + N_("with --non-interactive, accept SSL server\n" + " " + "certificates with failures; ARG is comma-separated\n" + " " + "list of 'unknown-ca' (Unknown Authority),\n" + " " + "'cn-mismatch' (Hostname mismatch), 'expired'\n" + " " + "(Expired certificate), 'not-yet-valid' (Not yet\n" + " " + "valid certificate) and 'other' (all other not\n" + " " + "separately classified certificate errors).")}, {0, 0, 0, 0} }; @@ -182,6 +200,7 @@ typedef struct opt_baton_t { svn_opt_revision_t end_revision; svn_boolean_t quiet; svn_boolean_t incremental; + apr_hash_t *skip_revprops; } opt_baton_t; /* Print dumpstream-formatted information about REVISION. @@ -197,38 +216,13 @@ replay_revstart(svn_revnum_t revision, { struct replay_baton *rb = replay_baton; apr_hash_t *normal_props; - svn_stringbuf_t *propstring; - svn_stream_t *stdout_stream; - svn_stream_t *revprop_stream; - - SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool)); - /* Revision-number: 19 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_REVISION_NUMBER - ": %ld\n", revision)); + /* Normalize and dump the revprops */ SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool)); - propstring = svn_stringbuf_create_ensure(0, pool); - revprop_stream = svn_stream_from_stringbuf(propstring, pool); - SVN_ERR(svn_hash_write2(normal_props, revprop_stream, "PROPS-END", pool)); - SVN_ERR(svn_stream_close(revprop_stream)); - - /* Prop-content-length: 13 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n", propstring->len)); - - /* Content-length: 29 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n\n", propstring->len)); - - /* Property data. */ - SVN_ERR(svn_stream_write(stdout_stream, propstring->data, - &(propstring->len))); - - SVN_ERR(svn_stream_puts(stdout_stream, "\n")); - SVN_ERR(svn_stream_close(stdout_stream)); + SVN_ERR(svn_repos__dump_revision_record(rb->stdout_stream, revision, NULL, + normal_props, + TRUE /*props_section_always*/, + pool)); SVN_ERR(svn_rdump__get_dump_editor(editor, edit_baton, revision, rb->stdout_stream, rb->extra_ra_session, @@ -271,38 +265,13 @@ replay_revstart_v2(svn_revnum_t revision, { struct replay_baton *rb = replay_baton; apr_hash_t *normal_props; - svn_stringbuf_t *propstring; - svn_stream_t *stdout_stream; - svn_stream_t *revprop_stream; - - SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool)); - /* Revision-number: 19 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_REVISION_NUMBER - ": %ld\n", revision)); + /* Normalize and dump the revprops */ SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool)); - propstring = svn_stringbuf_create_ensure(0, pool); - revprop_stream = svn_stream_from_stringbuf(propstring, pool); - SVN_ERR(svn_hash_write2(normal_props, revprop_stream, "PROPS-END", pool)); - SVN_ERR(svn_stream_close(revprop_stream)); - - /* Prop-content-length: 13 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n", propstring->len)); - - /* Content-length: 29 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n\n", propstring->len)); - - /* Property data. */ - SVN_ERR(svn_stream_write(stdout_stream, propstring->data, - &(propstring->len))); - - SVN_ERR(svn_stream_puts(stdout_stream, "\n")); - SVN_ERR(svn_stream_close(stdout_stream)); + SVN_ERR(svn_repos__dump_revision_record(rb->stdout_stream, revision, + normal_props, + TRUE /*props_section_always*/, + pool)); SVN_ERR(svn_rdump__get_dump_editor_v2(editor, revision, rb->stdout_stream, @@ -348,7 +317,11 @@ init_client_context(svn_client_ctx_t **ctx_p, const char *config_dir, const char *repos_url, svn_boolean_t no_auth_cache, - svn_boolean_t trust_server_cert, + svn_boolean_t trust_unknown_ca, + svn_boolean_t trust_cn_mismatch, + svn_boolean_t trust_expired, + svn_boolean_t trust_not_yet_valid, + svn_boolean_t trust_other_failure, apr_array_header_t *config_options, apr_pool_t *pool) { @@ -412,11 +385,14 @@ init_client_context(svn_client_ctx_t **ctx_p, ctx->cancel_func = check_cancel; /* Default authentication providers for non-interactive use */ - SVN_ERR(svn_cmdline_create_auth_baton(&(ctx->auth_baton), non_interactive, - username, password, config_dir, - no_auth_cache, trust_server_cert, - cfg_config, ctx->cancel_func, - ctx->cancel_baton, pool)); + SVN_ERR(svn_cmdline_create_auth_baton2(&(ctx->auth_baton), non_interactive, + username, password, config_dir, + no_auth_cache, trust_unknown_ca, + trust_cn_mismatch, trust_expired, + trust_not_yet_valid, + trust_other_failure, + cfg_config, ctx->cancel_func, + ctx->cancel_baton, pool)); *ctx_p = ctx; return SVN_NO_ERROR; } @@ -432,35 +408,12 @@ dump_revision_header(svn_ra_session_t *session, apr_pool_t *pool) { apr_hash_t *prophash; - svn_stringbuf_t *propstring; - svn_stream_t *propstream; - - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_REVISION_NUMBER - ": %ld\n", revision)); - prophash = apr_hash_make(pool); - propstring = svn_stringbuf_create_empty(pool); SVN_ERR(svn_ra_rev_proplist(session, revision, &prophash, pool)); - - propstream = svn_stream_from_stringbuf(propstring, pool); - SVN_ERR(svn_hash_write2(prophash, propstream, "PROPS-END", pool)); - SVN_ERR(svn_stream_close(propstream)); - - /* Property-content-length: 14; Content-length: 14 */ - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n", - propstring->len)); - SVN_ERR(svn_stream_printf(stdout_stream, pool, - SVN_REPOS_DUMPFILE_CONTENT_LENGTH - ": %" APR_SIZE_T_FMT "\n\n", - propstring->len)); - /* The properties */ - SVN_ERR(svn_stream_write(stdout_stream, propstring->data, - &(propstring->len))); - SVN_ERR(svn_stream_puts(stdout_stream, "\n")); - + SVN_ERR(svn_repos__dump_revision_record(stdout_stream, revision, NULL, + prophash, + TRUE /*props_section_always*/, + pool)); return SVN_NO_ERROR; } @@ -608,6 +561,7 @@ load_revisions(svn_ra_session_t *session, svn_ra_session_t *aux_session, const char *url, svn_boolean_t quiet, + apr_hash_t *skip_revprops, apr_pool_t *pool) { apr_file_t *stdin_file; @@ -617,7 +571,8 @@ load_revisions(svn_ra_session_t *session, stdin_stream = svn_stream_from_aprfile2(stdin_file, FALSE, pool); SVN_ERR(svn_rdump__load_dumpstream(stdin_stream, session, aux_session, - quiet, check_cancel, NULL, pool)); + quiet, skip_revprops, + check_cancel, NULL, pool)); SVN_ERR(svn_stream_close(stdin_stream)); @@ -667,23 +622,6 @@ version(const char *progname, } -/* A statement macro, similar to @c SVN_ERR, but returns an integer. - * Evaluate @a expr. If it yields an error, handle that error and - * return @c EXIT_FAILURE. - */ -#define SVNRDUMP_ERR(expr) \ - do \ - { \ - svn_error_t *svn_err__temp = (expr); \ - if (svn_err__temp) \ - { \ - svn_handle_error2(svn_err__temp, stderr, FALSE, "svnrdump: "); \ - svn_error_clear(svn_err__temp); \ - return EXIT_FAILURE; \ - } \ - } \ - while (0) - /* Handle the "dump" subcommand. Implements `svn_opt_subcommand_t'. */ static svn_error_t * dump_cmd(apr_getopt_t *os, @@ -718,7 +656,7 @@ 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, pool); + opt_baton->quiet, opt_baton->skip_revprops, pool); } /* Handle the "help" subcommand. Implements `svn_opt_subcommand_t'. */ @@ -729,6 +667,7 @@ help_cmd(apr_getopt_t *os, { const char *header = _("general usage: svnrdump SUBCOMMAND URL [-r LOWER[:UPPER]]\n" + "Subversion remote repository dump and load tool.\n" "Type 'svnrdump help <subcommand>' for help on a specific subcommand.\n" "Type 'svnrdump --version' to see the program version and RA modules.\n" "\n" @@ -831,19 +770,27 @@ validate_and_resolve_revisions(opt_baton_t *opt_baton, return SVN_NO_ERROR; } -int -main(int argc, const char **argv) +/* + * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error, + * either return an error to be displayed, or set *EXIT_CODE to non-zero and + * return SVN_NO_ERROR. + */ +static svn_error_t * +sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool) { svn_error_t *err = SVN_NO_ERROR; const svn_opt_subcommand_desc2_t *subcommand = NULL; opt_baton_t *opt_baton; svn_revnum_t latest_revision = SVN_INVALID_REVNUM; - apr_pool_t *pool = NULL; const char *config_dir = NULL; const char *username = NULL; const char *password = NULL; svn_boolean_t no_auth_cache = FALSE; - svn_boolean_t trust_server_cert = FALSE; + svn_boolean_t trust_unknown_ca = FALSE; + svn_boolean_t trust_cn_mismatch = FALSE; + svn_boolean_t trust_expired = FALSE; + svn_boolean_t trust_not_yet_valid = FALSE; + svn_boolean_t trust_other_failure = FALSE; svn_boolean_t non_interactive = FALSE; svn_boolean_t force_interactive = FALSE; apr_array_header_t *config_options = NULL; @@ -852,20 +799,13 @@ main(int argc, const char **argv) apr_array_header_t *received_opts; int i; - if (svn_cmdline_init ("svnrdump", stderr) != EXIT_SUCCESS) - return EXIT_FAILURE; - - /* Create our top-level pool. Use a separate mutexless allocator, - * given this application is single threaded. - */ - pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE)); - opt_baton = apr_pcalloc(pool, sizeof(*opt_baton)); opt_baton->start_revision.kind = svn_opt_revision_unspecified; opt_baton->end_revision.kind = svn_opt_revision_unspecified; opt_baton->url = NULL; + opt_baton->skip_revprops = apr_hash_make(pool); - SVNRDUMP_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool)); + SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool)); os->interleave = TRUE; /* Options and arguments can be interleaved */ @@ -905,8 +845,9 @@ main(int argc, const char **argv) break; if (status != APR_SUCCESS) { - SVNRDUMP_ERR(usage(argv[0], pool)); - exit(EXIT_FAILURE); + SVN_ERR(usage(argv[0], pool)); + *exit_code = EXIT_FAILURE; + return SVN_NO_ERROR; } /* Stash the option code in an array before parsing it. */ @@ -919,11 +860,10 @@ main(int argc, const char **argv) /* Make sure we've not seen -r already. */ if (opt_baton->start_revision.kind != svn_opt_revision_unspecified) { - err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("Multiple revision arguments " - "encountered; try '-r N:M' instead " - "of '-r N -r M'")); - return svn_cmdline_handle_exit_error(err, pool, "svnrdump: "); + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("Multiple revision arguments " + "encountered; try '-r N:M' instead " + "of '-r N -r M'")); } /* Parse the -r argument. */ if (svn_opt_parse_revision(&(opt_baton->start_revision), @@ -931,12 +871,10 @@ main(int argc, const char **argv) opt_arg, pool) != 0) { const char *utf8_opt_arg; - err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool); - if (! err) - err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("Syntax error in revision " - "argument '%s'"), utf8_opt_arg); - return svn_cmdline_handle_exit_error(err, pool, "svnrdump: "); + SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool)); + return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("Syntax error in revision " + "argument '%s'"), utf8_opt_arg); } } break; @@ -953,10 +891,10 @@ main(int argc, const char **argv) opt_baton->help = TRUE; break; case opt_auth_username: - SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&username, opt_arg, pool)); + SVN_ERR(svn_utf_cstring_to_utf8(&username, opt_arg, pool)); break; case opt_auth_password: - SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool)); + SVN_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool)); break; case opt_auth_nocache: no_auth_cache = TRUE; @@ -970,8 +908,22 @@ main(int argc, const char **argv) case opt_incremental: opt_baton->incremental = TRUE; break; - case opt_trust_server_cert: - trust_server_cert = TRUE; + case opt_skip_revprop: + SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool)); + svn_hash_sets(opt_baton->skip_revprops, opt_arg, opt_arg); + break; + case opt_trust_server_cert: /* backward compat */ + trust_unknown_ca = TRUE; + break; + case opt_trust_server_cert_failures: + SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool)); + SVN_ERR(svn_cmdline__parse_trust_options( + &trust_unknown_ca, + &trust_cn_mismatch, + &trust_expired, + &trust_not_yet_valid, + &trust_other_failure, + opt_arg, pool)); break; case opt_config_option: if (!config_options) @@ -979,9 +931,11 @@ main(int argc, const char **argv) apr_array_make(pool, 1, sizeof(svn_cmdline__config_argument_t*)); - SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool)); - SVNRDUMP_ERR(svn_cmdline__parse_config_option(config_options, - opt_arg, pool)); + SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool)); + SVN_ERR(svn_cmdline__parse_config_option(config_options, + opt_arg, + "svnrdump: ", + pool)); } } @@ -989,10 +943,9 @@ main(int argc, const char **argv) * exclusive. */ if (non_interactive && force_interactive) { - err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("--non-interactive and --force-interactive " - "are mutually exclusive")); - return svn_cmdline_handle_exit_error(err, pool, "svnrdump: "); + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--non-interactive and --force-interactive " + "are mutually exclusive")); } if (opt_baton->help) @@ -1017,9 +970,9 @@ main(int argc, const char **argv) else { - SVNRDUMP_ERR(help_cmd(NULL, NULL, pool)); - svn_pool_destroy(pool); - exit(EXIT_FAILURE); + SVN_ERR(help_cmd(NULL, NULL, pool)); + *exit_code = EXIT_FAILURE; + return SVN_NO_ERROR; } } else @@ -1031,16 +984,15 @@ main(int argc, const char **argv) if (subcommand == NULL) { const char *first_arg_utf8; - err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool); - if (err) - return svn_cmdline_handle_exit_error(err, pool, "svnrdump: "); + SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, + pool)); svn_error_clear( svn_cmdline_fprintf(stderr, pool, _("Unknown subcommand: '%s'\n"), first_arg_utf8)); - SVNRDUMP_ERR(help_cmd(NULL, NULL, pool)); - svn_pool_destroy(pool); - exit(EXIT_FAILURE); + SVN_ERR(help_cmd(NULL, NULL, pool)); + *exit_code = EXIT_FAILURE; + return SVN_NO_ERROR; } } } @@ -1065,69 +1017,64 @@ main(int argc, const char **argv) subcommand, pool); svn_opt_format_option(&optstr, badopt, FALSE, pool); if (subcommand->name[0] == '-') - SVN_INT_ERR(help_cmd(NULL, NULL, pool)); + SVN_ERR(help_cmd(NULL, NULL, pool)); else svn_error_clear(svn_cmdline_fprintf( stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n" "Type 'svnrdump help %s' for usage.\n"), subcommand->name, optstr, subcommand->name)); - svn_pool_destroy(pool); - return EXIT_FAILURE; + *exit_code = EXIT_FAILURE; + return SVN_NO_ERROR; } } - if (subcommand && strcmp(subcommand->name, "--version") == 0) + if (strcmp(subcommand->name, "--version") == 0) { - SVNRDUMP_ERR(version(argv[0], opt_baton->quiet, pool)); - svn_pool_destroy(pool); - exit(EXIT_SUCCESS); + SVN_ERR(version(argv[0], opt_baton->quiet, pool)); + return SVN_NO_ERROR; } - if (subcommand && strcmp(subcommand->name, "help") == 0) + if (strcmp(subcommand->name, "help") == 0) { - SVNRDUMP_ERR(help_cmd(os, opt_baton, pool)); - svn_pool_destroy(pool); - exit(EXIT_SUCCESS); + SVN_ERR(help_cmd(os, opt_baton, pool)); + return SVN_NO_ERROR; } - /* --trust-server-cert can only be used with --non-interactive */ - if (trust_server_cert && !non_interactive) + /* --trust-* can only be used with --non-interactive */ + if (!non_interactive) { - err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, - _("--trust-server-cert requires " - "--non-interactive")); - return svn_cmdline_handle_exit_error(err, pool, "svnrdump: "); + if (trust_unknown_ca || trust_cn_mismatch || trust_expired + || trust_not_yet_valid || trust_other_failure) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--trust-server-cert-failures requires " + "--non-interactive")); } /* Expect one more non-option argument: the repository URL. */ if (os->ind != os->argc - 1) { - SVNRDUMP_ERR(usage(argv[0], pool)); - svn_pool_destroy(pool); - exit(EXIT_FAILURE); + SVN_ERR(usage(argv[0], pool)); + *exit_code = EXIT_FAILURE; + return SVN_NO_ERROR; } else { const char *repos_url; - SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&repos_url, - os->argv[os->ind], pool)); + SVN_ERR(svn_utf_cstring_to_utf8(&repos_url, os->argv[os->ind], pool)); if (! svn_path_is_url(repos_url)) { - err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, 0, - "Target '%s' is not a URL", - repos_url); - SVNRDUMP_ERR(err); - svn_pool_destroy(pool); - exit(EXIT_FAILURE); + return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, 0, + "Target '%s' is not a URL", + repos_url); } opt_baton->url = svn_uri_canonicalize(repos_url, pool); } if (strcmp(subcommand->name, "load") == 0) { - /* + /* * By default (no --*-interactive options given), the 'load' subcommand * is interactive unless username and password were provided on the * command line. This allows prompting for auth creds to work without @@ -1141,16 +1088,20 @@ main(int argc, const char **argv) non_interactive = !svn_cmdline__be_interactive(non_interactive, force_interactive); - SVNRDUMP_ERR(init_client_context(&(opt_baton->ctx), - non_interactive, - username, - password, - config_dir, - opt_baton->url, - no_auth_cache, - trust_server_cert, - config_options, - pool)); + SVN_ERR(init_client_context(&(opt_baton->ctx), + non_interactive, + username, + password, + config_dir, + opt_baton->url, + no_auth_cache, + trust_unknown_ca, + trust_cn_mismatch, + trust_expired, + trust_not_yet_valid, + trust_other_failure, + config_options, + pool)); err = svn_client_open_ra_session2(&(opt_baton->session), opt_baton->url, NULL, @@ -1171,15 +1122,45 @@ main(int argc, const char **argv) if (err && err->apr_err == SVN_ERR_AUTHN_FAILED && non_interactive) { - err = svn_error_quick_wrap(err, - _("Authentication failed and interactive" - " prompting is disabled; see the" - " --force-interactive option")); + return svn_error_quick_wrap(err, + _("Authentication failed and interactive" + " prompting is disabled; see the" + " --force-interactive option")); } + else if (err) + return err; + else + return SVN_NO_ERROR; +} - SVNRDUMP_ERR(err); +int +main(int argc, const char *argv[]) +{ + apr_pool_t *pool; + int exit_code = EXIT_SUCCESS; + svn_error_t *err; - svn_pool_destroy(pool); + /* Initialize the app. */ + if (svn_cmdline_init("svnrdump", stderr) != EXIT_SUCCESS) + return EXIT_FAILURE; + + /* Create our top-level pool. Use a separate mutexless allocator, + * given this application is single threaded. + */ + pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE)); + + err = sub_main(&exit_code, argc, argv, pool); + + /* Flush stdout and report if it fails. It would be flushed on exit anyway + but this makes sure that output is not silently lost if it fails. */ + err = svn_error_compose_create(err, svn_cmdline_fflush(stdout)); - return EXIT_SUCCESS; + if (err) + { + exit_code = EXIT_FAILURE; + svn_cmdline_handle_exit_error(err, NULL, "svnrdump: "); + } + + svn_pool_destroy(pool); + return exit_code; } |