You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/11/27 12:52:46 UTC
svn commit: r1546002 [29/39] - in /subversion/branches/verify-keep-going: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/win32/ contrib/client-side/emacs/
contrib/server-side/ contrib/server-side/svnc...
Modified: subversion/branches/verify-keep-going/subversion/svnauth/svnauth.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svnauth/svnauth.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svnauth/svnauth.c (original)
+++ subversion/branches/verify-keep-going/subversion/svnauth/svnauth.c Wed Nov 27 11:52:35 2013
@@ -25,12 +25,21 @@
#include <apr_general.h>
#include <apr_getopt.h>
+#include <apr_fnmatch.h>
#include <apr_tables.h>
+#include "svn_private_config.h"
+
+#ifdef SVN_HAVE_SERF
+#include <serf.h>
+#endif
+
+#include "svn_private_config.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_opt.h"
#include "svn_dirent_uri.h"
+#include "svn_hash.h"
#include "svn_utf.h"
#include "svn_cmdline.h"
#include "svn_config.h"
@@ -38,8 +47,7 @@
#include "svn_sorts.h"
#include "private/svn_cmdline_private.h"
-
-#include "svn_private_config.h"
+#include "private/svn_token.h"
/* Baton for passing option/argument state to a subcommand function. */
struct svnauth_opt_state
@@ -59,7 +67,8 @@ typedef enum svnauth__longopt_t {
/** Subcommands. **/
static svn_opt_subcommand_t
subcommand_help,
- subcommand_list;
+ subcommand_list,
+ subcommand_delete;
/* Array of available subcommands.
* The entire list must be terminated with an entry of nulls.
@@ -72,10 +81,42 @@ static const svn_opt_subcommand_desc2_t
{0} },
{"list", subcommand_list, {0}, N_
- ("usage: svnauth list\n\n"
- "List cached authentication credentials.\n"),
+ ("usage: svnauth list [PATTERN ...]\n"
+ "\n"
+ " List cached authentication credentials.\n"
+ "\n"
+ " If PATTERN is specified, only list credentials with attributes matching\n"
+ " the pattern. All attributes except passwords can be matched. If more than\n"
+ " one pattern is specified credentials are shown if their attributes match\n"
+ " all patterns. Patterns are matched case-sensitively and may contain\n"
+ " glob wildcards:\n"
+ " ? matches any single character\n"
+ " * matches a sequence of arbitrary characters\n"
+ " [abc] matches any of the characters listed inside the brackets\n"
+ " Note that wildcards will usually need to be quoted or escaped on the\n"
+ " command line because many command shells will interfere by trying to\n"
+ " expand them.\n"
+ "\n"
+ " If no pattern is specified, all cached credentials are shown.\n"),
{opt_config_dir, opt_show_passwords} },
+ {"delete", subcommand_delete, {"del", "remove", "rm"}, N_
+ ("usage: svnauth delete PATTERN ...\n"
+ "\n"
+ " Delete cached authentication credentials matching a pattern.\n"
+ "\n"
+ " All credential attributes except passwords can be matched. If more than \n"
+ " one pattern is specified credentials are deleted only if their attributes\n"
+ " match all patterns. Patterns are matched case-sensitively and may contain\n"
+ " glob wildcards:\n"
+ " ? matches any single character\n"
+ " * matches a sequence of arbitrary characters\n"
+ " [abc] matches any of the characters listed inside the brackets\n"
+ " Note that wildcards will usually need to be quoted or escaped on the\n"
+ " command line because many command shells will interfere by trying to\n"
+ " expand them.\n"),
+ {opt_config_dir} },
+
{NULL}
};
@@ -97,6 +138,46 @@ static const apr_getopt_option_t options
{NULL}
};
+/* Parse the remaining command-line arguments from OS, returning them
+ in a new array *ARGS (allocated from POOL) and optionally verifying
+ that we got the expected number thereof. If MIN_EXPECTED is not
+ negative, return an error if the function would return fewer than
+ MIN_EXPECTED arguments. If MAX_EXPECTED is not negative, return an
+ error if the function would return more than MAX_EXPECTED
+ arguments.
+
+ As a special case, when MIN_EXPECTED and MAX_EXPECTED are both 0,
+ allow ARGS to be NULL. */
+static svn_error_t *
+parse_args(apr_array_header_t **args,
+ apr_getopt_t *os,
+ int min_expected,
+ int max_expected,
+ apr_pool_t *pool)
+{
+ int num_args = os ? (os->argc - os->ind) : 0;
+
+ if (min_expected || max_expected)
+ SVN_ERR_ASSERT(args);
+
+ if ((min_expected >= 0) && (num_args < min_expected))
+ return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+ if ((max_expected >= 0) && (num_args > max_expected))
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
+ _("Too many arguments provided"));
+ if (args)
+ {
+ *args = apr_array_make(pool, num_args, sizeof(const char *));
+
+ if (num_args)
+ while (os->ind < os->argc)
+ APR_ARRAY_PUSH(*args, const char *) =
+ apr_pstrdup(pool, os->argv[os->ind++]);
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* This implements `svn_opt_subcommand_t'. */
static svn_error_t *
subcommand_help(apr_getopt_t *os, void *baton, apr_pool_t *pool)
@@ -104,6 +185,7 @@ subcommand_help(apr_getopt_t *os, void *
struct svnauth_opt_state *opt_state = baton;
const char *header =
_("general usage: svnauth SUBCOMMAND [ARGS & OPTIONS ...]\n"
+ "Subversion authentication credentials management tool.\n"
"Type 'svnauth help <subcommand>' for help on a specific subcommand.\n"
"Type 'svnauth --version' to see the program version and available\n"
"authentication credential caches.\n"
@@ -131,16 +213,16 @@ subcommand_help(apr_getopt_t *os, void *
footer, svn_dirent_local_style(config_path, pool));
#endif
#ifdef SVN_HAVE_GNOME_KEYRING
- footer = apr_pstrcat(pool, footer, " Gnome Keyring\n", NULL);
+ footer = apr_pstrcat(pool, footer, " Gnome Keyring\n", SVN_VA_NULL);
#endif
#ifdef SVN_HAVE_GPG_AGENT
- footer = apr_pstrcat(pool, footer, " GPG-Agent\n", NULL);
+ footer = apr_pstrcat(pool, footer, " GPG-Agent\n", SVN_VA_NULL);
#endif
#ifdef SVN_HAVE_KEYCHAIN_SERVICES
- footer = apr_pstrcat(pool, footer, " Mac OS X Keychain\n", NULL);
+ footer = apr_pstrcat(pool, footer, " Mac OS X Keychain\n", SVN_VA_NULL);
#endif
#ifdef SVN_HAVE_KWALLET
- footer = apr_pstrcat(pool, footer, " KWallet (KDE)\n", NULL);
+ footer = apr_pstrcat(pool, footer, " KWallet (KDE)\n", SVN_VA_NULL);
#endif
}
@@ -157,50 +239,553 @@ subcommand_help(apr_getopt_t *os, void *
#define SEP_STRING \
"------------------------------------------------------------------------\n"
-/* This implements `svn_config_auth_walk_func_t` */
+#ifdef SVN_HAVE_SERF
+/* Because APR hash order is unstable we use a token map of keys
+ * to ensure values are always presented in the same order. */
+typedef enum svnauth__cert_info_keys {
+ svnauth__cert_key_cn,
+ svnauth__cert_key_e,
+ svnauth__cert_key_ou,
+ svnauth__cert_key_o,
+ svnauth__cert_key_l,
+ svnauth__cert_key_st,
+ svnauth__cert_key_c,
+ svnauth__cert_key_sha1,
+ svnauth__cert_key_not_before,
+ svnauth__cert_key_not_after,
+} svnauth__cert_info_keys;
+
+static svn_token_map_t cert_info_key_map[] = {
+ { "CN", svnauth__cert_key_cn },
+ { "E", svnauth__cert_key_e },
+ { "OU", svnauth__cert_key_ou },
+ { "O", svnauth__cert_key_o },
+ { "L", svnauth__cert_key_l },
+ { "ST", svnauth__cert_key_st },
+ { "C", svnauth__cert_key_c },
+ { "sha1", svnauth__cert_key_sha1 },
+ { "notBefore", svnauth__cert_key_not_before },
+ { "notAfter", svnauth__cert_key_not_after }
+};
+
+/* Show information stored in CERT_INFO.
+ * Assume all hash table keys occur in the above key map. */
static svn_error_t *
-list_credentials(svn_boolean_t *delete_cred,
- void *baton,
+show_cert_info(apr_hash_t *cert_info,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+
+ for (i = 0; i < sizeof(cert_info_key_map) / sizeof(svn_token_map_t); i++)
+ {
+ const char *key = cert_info_key_map[i].str;
+ const char *value = svn_hash_gets(cert_info, key);
+
+ if (value)
+ {
+ int token;
+
+ token = svn_token__from_word(cert_info_key_map, key);
+ switch (token)
+ {
+ case svnauth__cert_key_cn:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Common Name: %s\n"), value));
+ break;
+ case svnauth__cert_key_e:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Email Address: %s\n"), value));
+ break;
+ case svnauth__cert_key_o:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Organization Name: %s\n"),
+ value));
+ break;
+ case svnauth__cert_key_ou:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Organizational Unit: %s\n"),
+ value));
+ break;
+ case svnauth__cert_key_l:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Locality: %s\n"), value));
+ break;
+ case svnauth__cert_key_st:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" State or Province: %s\n"),
+ value));
+ break;
+ case svnauth__cert_key_c:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Country: %s\n"), value));
+ break;
+ case svnauth__cert_key_sha1:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" SHA1 Fingerprint: %s\n"),
+ value));
+ break;
+ case svnauth__cert_key_not_before:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Valid as of: %s\n"), value));
+ break;
+ case svnauth__cert_key_not_after:
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _(" Valid until: %s\n"), value));
+ break;
+ case SVN_TOKEN_UNKNOWN:
+ default:
+#ifdef SVN_DEBUG
+ SVN_ERR_MALFUNCTION();
+#endif
+ break;
+ }
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+#define MAX_CERT_LINE_LEN 78
+
+/* Break ASCII_CERT into lines of at most MAX_CERT_LINE_LEN characters.
+ * Otherwise, OpenSSL won't parse it due to the way it is invoked by serf. */
+static const char *
+split_ascii_cert(const char *ascii_cert,
+ apr_pool_t *result_pool)
+{
+ apr_array_header_t *lines;
+ int i;
+ apr_size_t cert_len, nlines;
+ const char *p;
+ svn_stringbuf_t *line;
+
+ p = ascii_cert;
+ cert_len = strlen(ascii_cert);
+ nlines = cert_len / MAX_CERT_LINE_LEN;
+ lines = apr_array_make(result_pool, 22, sizeof(const char *));
+ for (i = 0; i < nlines; i++)
+ {
+ line = svn_stringbuf_create_ensure(MAX_CERT_LINE_LEN, result_pool);
+ svn_stringbuf_appendbytes(line, p, MAX_CERT_LINE_LEN);
+ p += MAX_CERT_LINE_LEN;
+ APR_ARRAY_PUSH(lines, const char *) = line->data;
+ }
+ if (*p)
+ {
+ line = svn_stringbuf_create_ensure(MAX_CERT_LINE_LEN, result_pool);
+ while (*p)
+ svn_stringbuf_appendbyte(line, *p++);
+ APR_ARRAY_PUSH(lines, const char *) = line->data;
+ }
+
+ return svn_cstring_join(lines, "\n", result_pool);
+}
+#endif /* SVN_HAVE_SERF */
+
+#ifdef SVN_HAVE_SERF
+static svn_error_t *
+load_cert(serf_ssl_certificate_t **cert,
+ const char *ascii_cert,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_file_t *pem_file;
+ const char *pem_path;
+ const char *pem;
+ apr_size_t pem_len;
+ apr_size_t written;
+ apr_status_t status;
+
+ SVN_ERR(svn_io_open_unique_file3(&pem_file, &pem_path, NULL,
+ svn_io_file_del_on_pool_cleanup,
+ scratch_pool, scratch_pool));
+ pem = apr_psprintf(scratch_pool, "%s%s%s",
+ "-----BEGIN CERTIFICATE-----\n",
+ split_ascii_cert(ascii_cert, scratch_pool),
+ "-----END CERTIFICATE-----\n");
+ pem_len = strlen(pem);
+ SVN_ERR(svn_io_file_write_full(pem_file, pem, pem_len, &written,
+ scratch_pool));
+ if (written != pem_len)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _("Base64-encoded certificate: %s\n"),
+ ascii_cert));
+ return SVN_NO_ERROR;
+ }
+ SVN_ERR(svn_io_file_flush_to_disk(pem_file, scratch_pool));
+
+ status = serf_ssl_load_cert_file(cert, pem_path, result_pool);
+ if (status)
+ {
+ svn_error_t *err;
+
+ err = svn_error_wrap_apr(status, _("serf error: %s"),
+ serf_error_string(status));
+ svn_handle_warning2(stderr, err, "svnauth: ");
+ svn_error_clear(err);
+
+ *cert = NULL;
+ return SVN_NO_ERROR;
+ }
+
+ return SVN_NO_ERROR;
+}
+#endif
+
+/* ### from libsvn_subr/ssl_server_trust_providers.c */
+#define AUTHN_ASCII_CERT_KEY "ascii_cert"
+#define AUTHN_FAILURES_KEY "failures"
+
+/* Display the base64-encoded DER certificate ASCII_CERT. */
+static svn_error_t *
+show_ascii_cert(const char *ascii_cert,
+ apr_pool_t *scratch_pool)
+{
+#ifdef SVN_HAVE_SERF
+ serf_ssl_certificate_t *cert;
+ apr_hash_t *cert_info;
+
+ SVN_ERR(load_cert(&cert, ascii_cert, scratch_pool, scratch_pool));
+
+ if (cert == NULL)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _("Base64-encoded certificate: %s\n"),
+ ascii_cert));
+ return SVN_NO_ERROR;
+ }
+
+ cert_info = serf_ssl_cert_issuer(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, _("Certificate issuer:\n")));
+ SVN_ERR(show_cert_info(cert_info, scratch_pool));
+ }
+
+ cert_info = serf_ssl_cert_subject(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, _("Certificate subject:\n")));
+ SVN_ERR(show_cert_info(cert_info, scratch_pool));
+ }
+
+ cert_info = serf_ssl_cert_certificate(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, _("Certificate validity:\n")));
+ SVN_ERR(show_cert_info(cert_info, scratch_pool));
+ }
+#else
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _("Base64-encoded certificate: %s\n"),
+ ascii_cert));
+#endif /* SVN_HAVE_SERF */
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+show_cert_failures(const char *failure_string,
+ apr_pool_t *scratch_pool)
+{
+ unsigned int failures;
+
+ SVN_ERR(svn_cstring_atoui(&failures, failure_string));
+
+ if (0 == (failures & (SVN_AUTH_SSL_NOTYETVALID | SVN_AUTH_SSL_EXPIRED |
+ SVN_AUTH_SSL_CNMISMATCH | SVN_AUTH_SSL_UNKNOWNCA |
+ SVN_AUTH_SSL_OTHER)))
+ return SVN_NO_ERROR;
+
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _("Automatic certificate validity check failed "
+ "because:\n")));
+
+ if (failures & SVN_AUTH_SSL_NOTYETVALID)
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _(" The certificate is not yet valid.\n")));
+
+ if (failures & SVN_AUTH_SSL_EXPIRED)
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _(" The certificate has expired.\n")));
+
+ if (failures & SVN_AUTH_SSL_CNMISMATCH)
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _(" The certificate's Common Name (hostname) "
+ "does not match the remote hostname.\n")));
+
+ if (failures & SVN_AUTH_SSL_UNKNOWNCA)
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _(" The certificate issuer is unknown.\n")));
+
+ if (failures & SVN_AUTH_SSL_OTHER)
+ SVN_ERR(svn_cmdline_printf(
+ scratch_pool, _(" Unknown verification failure.\n")));
+
+ return SVN_NO_ERROR;
+}
+
+/* ### from libsvn_subr/simple_providers.c */
+#define AUTHN_USERNAME_KEY "username"
+#define AUTHN_PASSWORD_KEY "password"
+#define AUTHN_PASSTYPE_KEY "passtype"
+
+/* ### from libsvn_subr/ssl_client_cert_pw_providers.c */
+#define AUTHN_PASSPHRASE_KEY "passphrase"
+
+struct walk_credentials_baton_t
+{
+ int matches;
+ svn_boolean_t list;
+ svn_boolean_t delete;
+ svn_boolean_t show_passwords;
+ apr_array_header_t *patterns;
+};
+
+static svn_boolean_t
+match_pattern(const char *pattern, const char *value,
+ apr_pool_t *scratch_pool)
+{
+ const char *p = apr_psprintf(scratch_pool, "*%s*", pattern);
+
+ return (apr_fnmatch(p, value, 0) == APR_SUCCESS);
+}
+
+#ifdef SVN_HAVE_SERF
+static svn_error_t *
+match_cert_info(svn_boolean_t *match,
+ const char *pattern,
+ apr_hash_t *cert_info,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ apr_pool_t *iterpool;
+
+ *match = FALSE;
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < sizeof(cert_info_key_map) / sizeof(svn_token_map_t); i++)
+ {
+ const char *key = cert_info_key_map[i].str;
+ const char *value = svn_hash_gets(cert_info, key);
+
+ svn_pool_clear(iterpool);
+ if (value)
+ *match = match_pattern(pattern, value, iterpool);
+ if (*match)
+ break;
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+#endif
+
+
+static svn_error_t *
+match_ascii_cert(svn_boolean_t *match,
+ const char *pattern,
+ const char *ascii_cert,
+ apr_pool_t *scratch_pool)
+{
+#ifdef SVN_HAVE_SERF
+ serf_ssl_certificate_t *cert;
+ apr_hash_t *cert_info;
+
+ *match = FALSE;
+
+ SVN_ERR(load_cert(&cert, ascii_cert, scratch_pool, scratch_pool));
+
+ cert_info = serf_ssl_cert_issuer(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(match_cert_info(match, pattern, cert_info, scratch_pool));
+ if (*match)
+ return SVN_NO_ERROR;
+ }
+
+ cert_info = serf_ssl_cert_subject(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(match_cert_info(match, pattern, cert_info, scratch_pool));
+ if (*match)
+ return SVN_NO_ERROR;
+ }
+
+ cert_info = serf_ssl_cert_certificate(cert, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(match_cert_info(match, pattern, cert_info, scratch_pool));
+ if (*match)
+ return SVN_NO_ERROR;
+ }
+#else
+ *match = FALSE;
+#endif
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+match_credential(svn_boolean_t *match,
const char *cred_kind,
const char *realmstring,
- apr_hash_t *hash,
+ apr_array_header_t *patterns,
+ apr_array_header_t *cred_items,
apr_pool_t *scratch_pool)
{
- struct svnauth_opt_state *opt_state = baton;
- apr_array_header_t *sorted_hash_items;
int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- *delete_cred = FALSE;
+ *match = FALSE;
+
+ for (i = 0; i < patterns->nelts; i++)
+ {
+ const char *pattern = APR_ARRAY_IDX(patterns, i, const char *);
+ int j;
+
+ *match = match_pattern(pattern, cred_kind, iterpool);
+ if (!*match)
+ *match = match_pattern(pattern, realmstring, iterpool);
+ if (!*match)
+ {
+ svn_pool_clear(iterpool);
+ for (j = 0; j < cred_items->nelts; j++)
+ {
+ svn_sort__item_t item;
+ const char *key;
+ svn_string_t *value;
+
+ item = APR_ARRAY_IDX(cred_items, j, svn_sort__item_t);
+ key = item.key;
+ value = item.value;
+ if (strcmp(key, AUTHN_PASSWORD_KEY) == 0 ||
+ strcmp(key, AUTHN_PASSPHRASE_KEY) == 0)
+ continue; /* don't match secrets */
+ else if (strcmp(key, AUTHN_ASCII_CERT_KEY) == 0)
+ SVN_ERR(match_ascii_cert(match, pattern, value->data,
+ iterpool));
+ else
+ *match = match_pattern(pattern, value->data, iterpool);
+
+ if (*match)
+ break;
+ }
+ }
+ if (!*match)
+ break;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+list_credential(const char *cred_kind,
+ const char *realmstring,
+ apr_array_header_t *cred_items,
+ svn_boolean_t show_passwords,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_cmdline_printf(scratch_pool, SEP_STRING));
SVN_ERR(svn_cmdline_printf(scratch_pool,
_("Credential kind: %s\n"), cred_kind));
SVN_ERR(svn_cmdline_printf(scratch_pool,
- _("Authentication realm: %s\n"), realmstring));
+ _("Authentication realm: %s\n"), realmstring));
- sorted_hash_items = svn_sort__hash(hash, svn_sort_compare_items_lexically,
- scratch_pool);
- for (i = 0; i < sorted_hash_items->nelts; i++)
+ for (i = 0; i < cred_items->nelts; i++)
{
svn_sort__item_t item;
const char *key;
svn_string_t *value;
- item = APR_ARRAY_IDX(sorted_hash_items, i, svn_sort__item_t);
+ svn_pool_clear(iterpool);
+ item = APR_ARRAY_IDX(cred_items, i, svn_sort__item_t);
key = item.key;
value = item.value;
- if (!opt_state->show_passwords && strcmp(key, "password") == 0)
- SVN_ERR(svn_cmdline_printf(scratch_pool, _("%s: [not shown]\n"), key));
- else if (strcmp(value->data, realmstring) == 0)
+ if (strcmp(value->data, realmstring) == 0)
continue; /* realm string was already shown above */
+ else if (strcmp(key, AUTHN_PASSWORD_KEY) == 0)
+ {
+ if (show_passwords)
+ SVN_ERR(svn_cmdline_printf(iterpool,
+ _("Password: %s\n"), value->data));
+ else
+ SVN_ERR(svn_cmdline_printf(iterpool, _("Password: [not shown]\n")));
+ }
+ else if (strcmp(key, AUTHN_PASSPHRASE_KEY) == 0)
+ {
+ if (show_passwords)
+ SVN_ERR(svn_cmdline_printf(iterpool,
+ _("Passphrase: %s\n"), value->data));
+ else
+ SVN_ERR(svn_cmdline_printf(iterpool,
+ _("Passphrase: [not shown]\n")));
+ }
+ else if (strcmp(key, AUTHN_PASSTYPE_KEY) == 0)
+ SVN_ERR(svn_cmdline_printf(iterpool, _("Password cache: %s\n"),
+ value->data));
+ else if (strcmp(key, AUTHN_USERNAME_KEY) == 0)
+ SVN_ERR(svn_cmdline_printf(iterpool, _("Username: %s\n"), value->data));
+ else if (strcmp(key, AUTHN_ASCII_CERT_KEY) == 0)
+ SVN_ERR(show_ascii_cert(value->data, iterpool));
+ else if (strcmp(key, AUTHN_FAILURES_KEY) == 0)
+ SVN_ERR(show_cert_failures(value->data, iterpool));
else
- SVN_ERR(svn_cmdline_printf(scratch_pool, "%s: %s\n", key, value->data));
+ SVN_ERR(svn_cmdline_printf(iterpool, "%s: %s\n", key, value->data));
}
+ svn_pool_destroy(iterpool);
SVN_ERR(svn_cmdline_printf(scratch_pool, "\n"));
return SVN_NO_ERROR;
}
+/* This implements `svn_config_auth_walk_func_t` */
+static svn_error_t *
+walk_credentials(svn_boolean_t *delete_cred,
+ void *baton,
+ const char *cred_kind,
+ const char *realmstring,
+ apr_hash_t *cred_hash,
+ apr_pool_t *scratch_pool)
+{
+ struct walk_credentials_baton_t *b = baton;
+ apr_array_header_t *sorted_cred_items;
+
+ *delete_cred = FALSE;
+
+ sorted_cred_items = svn_sort__hash(cred_hash,
+ svn_sort_compare_items_lexically,
+ scratch_pool);
+ if (b->patterns->nelts > 0)
+ {
+ svn_boolean_t match;
+
+ SVN_ERR(match_credential(&match, cred_kind, realmstring,
+ b->patterns, sorted_cred_items,
+ scratch_pool));
+ if (!match)
+ return SVN_NO_ERROR;
+ }
+
+ b->matches++;
+
+ if (b->list)
+ SVN_ERR(list_credential(cred_kind, realmstring, sorted_cred_items,
+ b->show_passwords, scratch_pool));
+ if (b->delete)
+ {
+ *delete_cred = TRUE;
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _("Deleting %s credential for realm '%s'\n"),
+ cred_kind, realmstring));
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* This implements `svn_opt_subcommand_t'. */
static svn_error_t *
@@ -208,35 +793,92 @@ subcommand_list(apr_getopt_t *os, void *
{
struct svnauth_opt_state *opt_state = baton;
const char *config_path;
+ struct walk_credentials_baton_t b;
+
+ b.matches = 0;
+ b.show_passwords = opt_state->show_passwords;
+ b.list = TRUE;
+ b.delete = FALSE;
+ SVN_ERR(parse_args(&b.patterns, os, 0, -1, pool));
SVN_ERR(svn_config_get_user_config_path(&config_path,
opt_state->config_dir, NULL,
pool));
- SVN_ERR(svn_config_walk_auth_data(config_path, list_credentials, opt_state,
+ SVN_ERR(svn_config_walk_auth_data(config_path, walk_credentials, &b,
pool));
+
+ if (b.matches == 0)
+ {
+ if (b.patterns->nelts == 0)
+ SVN_ERR(svn_cmdline_printf(pool,
+ _("Credentials cache in '%s' is empty\n"),
+ svn_dirent_local_style(config_path, pool)));
+ else
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, 0,
+ _("Credentials cache in '%s' contains "
+ "no matching credentials"),
+ svn_dirent_local_style(config_path, pool));
+ }
+ else
+ {
+ if (b.patterns->nelts == 0)
+ SVN_ERR(svn_cmdline_printf(pool,
+ _("Credentials cache in '%s' contains %d "
+ "credentials\n"),
+ svn_dirent_local_style(config_path, pool),
+ b.matches));
+ else
+ SVN_ERR(svn_cmdline_printf(pool,
+ _("Credentials cache in '%s' contains %d "
+ "matching credentials\n"),
+ svn_dirent_local_style(config_path, pool),
+ b.matches));
+ }
return SVN_NO_ERROR;
}
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_delete(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnauth_opt_state *opt_state = baton;
+ const char *config_path;
+ struct walk_credentials_baton_t b;
+
+ b.matches = 0;
+ b.show_passwords = opt_state->show_passwords;
+ b.list = FALSE;
+ b.delete = TRUE;
+ SVN_ERR(parse_args(&b.patterns, os, 1, -1, pool));
+
+ SVN_ERR(svn_config_get_user_config_path(&config_path,
+ opt_state->config_dir, NULL,
+ pool));
-/* Report and clear the error ERR, and return EXIT_FAILURE. */
-#define EXIT_ERROR(err) \
- svn_cmdline_handle_exit_error(err, NULL, "svnauth: ")
-
-/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
- * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR, amd with the
- * program name 'svnauth' instead of 'svn'. */
-#undef SVN_INT_ERR
-#define SVN_INT_ERR(expr) \
- do { \
- svn_error_t *svn_err__temp = (expr); \
- if (svn_err__temp) \
- return EXIT_ERROR(svn_err__temp); \
- } while (0)
+ SVN_ERR(svn_config_walk_auth_data(config_path, walk_credentials, &b, pool));
+ if (b.matches == 0)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, 0,
+ _("Credentials cache in '%s' contains "
+ "no matching credentials"),
+ svn_dirent_local_style(config_path, pool));
+ else
+ SVN_ERR(svn_cmdline_printf(pool, _("Deleted %d matching credentials "
+ "from '%s'\n"), b.matches,
+ svn_dirent_local_style(config_path, pool)));
-static int
-sub_main(int argc, const char *argv[], apr_pool_t *pool)
+ return SVN_NO_ERROR;
+}
+
+
+/*
+ * 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;
const svn_opt_subcommand_desc2_t *subcommand = NULL;
@@ -245,12 +887,13 @@ sub_main(int argc, const char *argv[], a
if (argc <= 1)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Parse options. */
- SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+ SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
os->interleave = 1;
while (1)
@@ -266,8 +909,9 @@ sub_main(int argc, const char *argv[], a
break;
else if (apr_err)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
switch (opt_id) {
@@ -276,7 +920,7 @@ sub_main(int argc, const char *argv[], a
opt_state.help = TRUE;
break;
case opt_config_dir:
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ 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);
break;
case opt_show_passwords:
@@ -287,8 +931,9 @@ sub_main(int argc, const char *argv[], a
break;
default:
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
}
@@ -317,8 +962,9 @@ sub_main(int argc, const char *argv[], a
{
svn_error_clear(svn_cmdline_fprintf(stderr, pool,
_("subcommand argument required\n")));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
else
@@ -328,19 +974,20 @@ sub_main(int argc, const char *argv[], a
if (subcommand == NULL)
{
const char *first_arg_utf8;
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
- first_arg, pool));
+ 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));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
}
- SVN_INT_ERR(svn_config_ensure(opt_state.config_dir, pool));
+ SVN_ERR(svn_config_ensure(opt_state.config_dir, pool));
/* Run the subcommand. */
err = (*subcommand->cmd_func)(os, &opt_state, pool);
@@ -354,28 +1001,18 @@ sub_main(int argc, const char *argv[], a
err = svn_error_quick_wrap(err,
_("Try 'svnauth help' for more info"));
}
- return EXIT_ERROR(err);
- }
- else
- {
- /* Ensure that everything is written to stdout, so the user will
- see any print errors. */
- err = svn_cmdline_fflush(stdout);
- if (err)
- {
- return EXIT_ERROR(err);
- }
- return EXIT_SUCCESS;
+ return err;
}
- return EXIT_SUCCESS;
+ return SVN_NO_ERROR;
}
int
main(int argc, const char *argv[])
{
apr_pool_t *pool;
- int exit_code;
+ int exit_code = EXIT_SUCCESS;
+ svn_error_t *err;
/* Initialize the app. */
if (svn_cmdline_init("svnauth", stderr) != EXIT_SUCCESS)
@@ -386,7 +1023,17 @@ main(int argc, const char *argv[])
*/
pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
- exit_code = sub_main(argc, argv, pool);
+ 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));
+
+ if (err)
+ {
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svnauth: ");
+ }
svn_pool_destroy(pool);
return exit_code;
Modified: subversion/branches/verify-keep-going/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svndumpfilter/svndumpfilter.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/verify-keep-going/subversion/svndumpfilter/svndumpfilter.c Wed Nov 27 11:52:35 2013
@@ -550,9 +550,9 @@ new_node_record(void **node_baton,
/* Ensure that paths start with a leading '/'. */
if (node_path[0] != '/')
- node_path = apr_pstrcat(pool, "/", node_path, (char *)NULL);
+ node_path = apr_pstrcat(pool, "/", node_path, SVN_VA_NULL);
if (copyfrom_path && copyfrom_path[0] != '/')
- copyfrom_path = apr_pstrcat(pool, "/", copyfrom_path, (char *)NULL);
+ copyfrom_path = apr_pstrcat(pool, "/", copyfrom_path, SVN_VA_NULL);
nb->do_skip = skip_path(node_path, pb->prefixes,
pb->do_exclude, pb->glob);
@@ -1146,6 +1146,7 @@ subcommand_help(apr_getopt_t *os, void *
struct svndumpfilter_opt_state *opt_state = baton;
const char *header =
_("general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]\n"
+ "Subversion repository dump filtering tool.\n"
"Type 'svndumpfilter help <subcommand>' for help on a "
"specific subcommand.\n"
"Type 'svndumpfilter --version' to see the program version.\n"
@@ -1176,7 +1177,7 @@ check_lib_versions(void)
};
SVN_VERSION_DEFINE(my_version);
- return svn_ver_check_list(&my_version, checklist);
+ return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
}
@@ -1354,12 +1355,16 @@ subcommand_include(apr_getopt_t *os, voi
/** Main. **/
-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;
apr_status_t apr_err;
- apr_pool_t *pool;
const svn_opt_subcommand_desc2_t *subcommand = NULL;
struct svndumpfilter_opt_state opt_state;
@@ -1368,33 +1373,19 @@ main(int argc, const char *argv[])
apr_array_header_t *received_opts;
int i;
-
- /* Initialize the app. */
- if (svn_cmdline_init("svndumpfilter", 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));
-
/* Check library versions */
- err = check_lib_versions();
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svndumpfilter: ");
+ SVN_ERR(check_lib_versions());
received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
/* Initialize the FS library. */
- err = svn_fs_initialize(pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svndumpfilter: ");
+ SVN_ERR(svn_fs_initialize(pool));
if (argc <= 1)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Initialize opt_state. */
@@ -1403,9 +1394,7 @@ main(int argc, const char *argv[])
opt_state.end_revision.kind = svn_opt_revision_unspecified;
/* Parse options. */
- err = svn_cmdline__getopt_init(&os, argc, argv, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svndumpfilter: ");
+ SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
os->interleave = 1;
while (1)
@@ -1418,9 +1407,9 @@ main(int argc, const char *argv[])
break;
else if (apr_err)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Stash the option code in an array before parsing it. */
@@ -1461,9 +1450,9 @@ main(int argc, const char *argv[])
break;
default:
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
} /* close `switch' */
} /* close `while' */
@@ -1472,10 +1461,10 @@ main(int argc, const char *argv[])
--drop-all-empty-revs. */
if (opt_state.drop_empty_revs && opt_state.drop_all_empty_revs)
{
- err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
- _("--drop-empty-revs cannot be used with "
- "--drop-all-empty-revs"));
- return svn_cmdline_handle_exit_error(err, pool, "svndumpfilter: ");
+ return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS,
+ NULL,
+ _("--drop-empty-revs cannot be used with "
+ "--drop-all-empty-revs"));
}
/* If the user asked for help, then the rest of the arguments are
@@ -1507,9 +1496,9 @@ main(int argc, const char *argv[])
svn_error_clear(svn_cmdline_fprintf
(stderr, pool,
_("Subcommand argument required\n")));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
else
@@ -1519,18 +1508,16 @@ main(int argc, const char *argv[])
if (subcommand == NULL)
{
const char* first_arg_utf8;
- if ((err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg,
- pool)))
- return svn_cmdline_handle_exit_error(err, pool,
- "svndumpfilter: ");
+ 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));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
}
@@ -1550,10 +1537,10 @@ main(int argc, const char *argv[])
/* Ensure that each prefix is UTF8-encoded, in internal
style, and absolute. */
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&prefix, os->argv[i], pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&prefix, os->argv[i], pool));
prefix = svn_relpath__internal_style(prefix, pool);
if (prefix[0] != '/')
- prefix = apr_pstrcat(pool, "/", prefix, (char *)NULL);
+ prefix = apr_pstrcat(pool, "/", prefix, SVN_VA_NULL);
APR_ARRAY_PUSH(opt_state.prefixes, const char *) = prefix;
}
@@ -1568,12 +1555,12 @@ main(int argc, const char *argv[])
the targets into an array, because otherwise we wouldn't
know what delimiter to use for svn_cstring_split(). */
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_targets_file,
- opt_state.targets_file, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&utf8_targets_file,
+ opt_state.targets_file, pool));
- SVN_INT_ERR(svn_stringbuf_from_file2(&buffer, utf8_targets_file,
- pool));
- SVN_INT_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&buffer, utf8_targets_file,
+ pool));
+ SVN_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
targets = apr_array_append(pool,
svn_cstring_split(buffer_utf8->data, "\n\r",
@@ -1584,7 +1571,7 @@ main(int argc, const char *argv[])
{
const char *prefix = APR_ARRAY_IDX(targets, i, const char *);
if (prefix[0] != '/')
- prefix = apr_pstrcat(pool, "/", prefix, (char *)NULL);
+ prefix = apr_pstrcat(pool, "/", prefix, SVN_VA_NULL);
APR_ARRAY_PUSH(opt_state.prefixes, const char *) = prefix;
}
}
@@ -1594,8 +1581,8 @@ main(int argc, const char *argv[])
svn_error_clear(svn_cmdline_fprintf
(stderr, pool,
_("\nError: no prefixes supplied.\n")));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
@@ -1620,15 +1607,15 @@ main(int argc, const char *argv[])
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
else
svn_error_clear(svn_cmdline_fprintf
(stderr, pool,
_("Subcommand '%s' doesn't accept option '%s'\n"
"Type 'svndumpfilter 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;
}
}
@@ -1645,14 +1632,40 @@ main(int argc, const char *argv[])
_("Try 'svndumpfilter help' for more "
"info"));
}
- return svn_cmdline_handle_exit_error(err, pool, "svndumpfilter: ");
+ return err;
}
- else
- {
- svn_pool_destroy(pool);
- /* Flush stdout, making sure the user will see any print errors. */
- SVN_INT_ERR(svn_cmdline_fflush(stdout));
- return EXIT_SUCCESS;
+ return SVN_NO_ERROR;
+}
+
+int
+main(int argc, const char *argv[])
+{
+ apr_pool_t *pool;
+ int exit_code = EXIT_SUCCESS;
+ svn_error_t *err;
+
+ /* Initialize the app. */
+ if (svn_cmdline_init("svndumpfilter", 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));
+
+ if (err)
+ {
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svndumpfilter: ");
}
+
+ svn_pool_destroy(pool);
+ return exit_code;
}
Modified: subversion/branches/verify-keep-going/subversion/svnlook/svnlook.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svnlook/svnlook.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svnlook/svnlook.c (original)
+++ subversion/branches/verify-keep-going/subversion/svnlook/svnlook.c Wed Nov 27 11:52:35 2013
@@ -34,6 +34,7 @@
#define APR_WANT_STRFUNC
#include <apr_want.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_cmdline.h"
#include "svn_types.h"
@@ -59,8 +60,6 @@
#include "private/svn_fspath.h"
#include "private/svn_io_private.h"
-#include "svn_private_config.h"
-
/*** Some convenience macros and types. ***/
@@ -397,7 +396,7 @@ check_lib_versions(void)
};
SVN_VERSION_DEFINE(my_version);
- return svn_ver_check_list(&my_version, checklist);
+ return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
}
@@ -1876,7 +1875,8 @@ do_plist(svnlook_ctxt_t *c,
svn_xml_make_header2(&sb, "UTF-8", pool);
/* "<properties>" */
- svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties", NULL);
+ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties",
+ SVN_VA_NULL);
}
if (inherited_props)
@@ -1895,7 +1895,7 @@ do_plist(svnlook_ctxt_t *c,
svn_xml_make_open_tag(
&sb, pool, svn_xml_normal, "target", "path",
svn_fspath__canonicalize(elt->path_or_url, pool),
- NULL);
+ SVN_VA_NULL);
SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, elt->prop_hash,
!verbose, TRUE,
pool));
@@ -1922,19 +1922,19 @@ do_plist(svnlook_ctxt_t *c,
char *revstr = apr_psprintf(pool, "%ld", c->rev_id);
svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops",
- "rev", revstr, NULL);
+ "rev", revstr, SVN_VA_NULL);
}
else
{
svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops",
- "txn", c->txn_name, NULL);
+ "txn", c->txn_name, SVN_VA_NULL);
}
}
else
{
/* "<target ...>" */
svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
- "path", path, NULL);
+ "path", path, SVN_VA_NULL);
}
}
@@ -1981,7 +1981,7 @@ do_plist(svnlook_ctxt_t *c,
}
else if (xml)
svn_xml_make_open_tag(&sb, pool, svn_xml_self_closing, "property",
- "name", pname, NULL);
+ "name", pname, SVN_VA_NULL);
else
printf(" %s\n", pname);
}
@@ -2213,11 +2213,12 @@ subcommand_help(apr_getopt_t *os, void *
struct svnlook_opt_state *opt_state = baton;
const char *header =
_("general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\n"
+ "Subversion repository inspection tool.\n"
+ "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
+ "Type 'svnlook --version' to see the program version and FS modules.\n"
"Note: any subcommand which takes the '--revision' and '--transaction'\n"
" options will, if invoked without one of those options, act on\n"
" the repository's youngest revision.\n"
- "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
- "Type 'svnlook --version' to see the program version and FS modules.\n"
"\n"
"Available subcommands:\n");
@@ -2432,12 +2433,16 @@ subcommand_uuid(apr_getopt_t *os, void *
/*** Main. ***/
-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;
apr_status_t apr_err;
- apr_pool_t *pool;
const svn_opt_subcommand_desc2_t *subcommand = NULL;
struct svnlook_opt_state opt_state;
@@ -2446,32 +2451,19 @@ main(int argc, const char *argv[])
apr_array_header_t *received_opts;
int i;
- /* Initialize the app. */
- if (svn_cmdline_init("svnlook", 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));
-
received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
/* Check library versions */
- err = check_lib_versions();
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
+ SVN_ERR(check_lib_versions());
/* Initialize the FS library. */
- err = svn_fs_initialize(pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
+ SVN_ERR(svn_fs_initialize(pool));
if (argc <= 1)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Initialize opt_state. */
@@ -2479,9 +2471,7 @@ main(int argc, const char *argv[])
opt_state.rev = SVN_INVALID_REVNUM;
/* Parse options. */
- err = svn_cmdline__getopt_init(&os, argc, argv, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
+ SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
os->interleave = 1;
while (1)
@@ -2494,9 +2484,9 @@ main(int argc, const char *argv[])
break;
else if (apr_err)
{
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Stash the option code in an array before parsing it. */
@@ -2511,9 +2501,8 @@ main(int argc, const char *argv[])
if ((! SVN_IS_VALID_REVNUM(opt_state.rev))
|| (! digits_end)
|| *digits_end)
- SVN_INT_ERR(svn_error_create
- (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Invalid revision number supplied")));
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Invalid revision number supplied"));
}
break;
@@ -2560,15 +2549,13 @@ main(int argc, const char *argv[])
opt_state.limit = strtol(opt_arg, &end, 10);
if (end == opt_arg || *end != '\0')
{
- err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Non-numeric limit argument given"));
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Non-numeric limit argument given"));
}
if (opt_state.limit <= 0)
{
- err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("Argument to --limit must be positive"));
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
}
}
break;
@@ -2614,26 +2601,26 @@ main(int argc, const char *argv[])
break;
default:
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
/* The --transaction and --revision options may not co-exist. */
if ((opt_state.rev != SVN_INVALID_REVNUM) && opt_state.txn)
- SVN_INT_ERR(svn_error_create
+ return svn_error_create
(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("The '--transaction' (-t) and '--revision' (-r) arguments "
- "cannot co-exist")));
+ "cannot co-exist"));
/* The --show-inherited-props and --revprop options may not co-exist. */
if (opt_state.show_inherited_props && opt_state.revprop)
- SVN_INT_ERR(svn_error_create
+ return svn_error_create
(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
_("Cannot use the '--show-inherited-props' option with the "
- "'--revprop' option")));
+ "'--revprop' option"));
/* If the user asked for help, then the rest of the arguments are
the names of subcommands to get help on (if any), or else they're
@@ -2664,9 +2651,9 @@ main(int argc, const char *argv[])
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Subcommand argument required\n")));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
else
@@ -2676,15 +2663,13 @@ 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, "svnlook: ");
+ 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));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
/* Be kind to people who try 'svnlook verify'. */
if (strcmp(first_arg_utf8, "verify") == 0)
@@ -2694,9 +2679,8 @@ main(int argc, const char *argv[])
_("Try 'svnadmin verify' instead.\n")));
}
-
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
}
@@ -2715,9 +2699,9 @@ main(int argc, const char *argv[])
/* Get the repository. */
if (os->ind < os->argc)
{
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&repos_path,
- os->argv[os->ind++],
- pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&repos_path,
+ os->argv[os->ind++],
+ pool));
repos_path = svn_dirent_internal_style(repos_path, pool);
}
@@ -2726,9 +2710,9 @@ main(int argc, const char *argv[])
svn_error_clear
(svn_cmdline_fprintf(stderr, pool,
_("Repository argument required\n")));
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
else if (svn_path_is_url(repos_path))
{
@@ -2736,8 +2720,8 @@ main(int argc, const char *argv[])
(svn_cmdline_fprintf(stderr, pool,
_("'%s' is a URL when it should be a path\n"),
repos_path));
- svn_pool_destroy(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
opt_state.repos_path = repos_path;
@@ -2745,8 +2729,7 @@ main(int argc, const char *argv[])
/* Get next arg (arg1), if any. */
if (os->ind < os->argc)
{
- SVN_INT_ERR(svn_utf_cstring_to_utf8
- (&arg1, os->argv[os->ind++], pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&arg1, os->argv[os->ind++], pool));
arg1 = svn_dirent_internal_style(arg1, pool);
}
opt_state.arg1 = arg1;
@@ -2754,8 +2737,7 @@ main(int argc, const char *argv[])
/* Get next arg (arg2), if any. */
if (os->ind < os->argc)
{
- SVN_INT_ERR(svn_utf_cstring_to_utf8
- (&arg2, os->argv[os->ind++], pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&arg2, os->argv[os->ind++], pool));
arg2 = svn_dirent_internal_style(arg2, pool);
}
opt_state.arg2 = arg2;
@@ -2781,7 +2763,7 @@ main(int argc, const char *argv[])
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
- SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
+ SVN_ERR(subcommand_help(NULL, NULL, pool));
else
svn_error_clear
(svn_cmdline_fprintf
@@ -2789,8 +2771,8 @@ main(int argc, const char *argv[])
_("Subcommand '%s' doesn't accept option '%s'\n"
"Type 'svnlook 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;
}
}
@@ -2831,14 +2813,40 @@ main(int argc, const char *argv[])
err = svn_error_quick_wrap(err,
_("Try 'svnlook help' for more info"));
}
- return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
+ return err;
}
- else
+
+ return SVN_NO_ERROR;
+}
+
+int
+main(int argc, const char *argv[])
+{
+ apr_pool_t *pool;
+ int exit_code = EXIT_SUCCESS;
+ svn_error_t *err;
+
+ /* Initialize the app. */
+ if (svn_cmdline_init("svnlook", 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));
+
+ if (err)
{
- svn_pool_destroy(pool);
- /* Ensure everything is printed on stdout, so the user sees any
- print errors. */
- SVN_INT_ERR(svn_cmdline_fflush(stdout));
- return EXIT_SUCCESS;
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svnlook: ");
}
+
+ svn_pool_destroy(pool);
+ return exit_code;
}
Modified: subversion/branches/verify-keep-going/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svnmucc/svnmucc.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/verify-keep-going/subversion/svnmucc/svnmucc.c Wed Nov 27 11:52:35 2013
@@ -40,6 +40,7 @@
#include <apr_lib.h>
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_client.h"
#include "svn_cmdline.h"
@@ -58,38 +59,20 @@
#include "private/svn_ra_private.h"
#include "private/svn_string_private.h"
-#include "svn_private_config.h"
-
-static void handle_error(svn_error_t *err, apr_pool_t *pool)
-{
- if (err)
- svn_handle_error2(err, stderr, FALSE, "svnmucc: ");
- svn_error_clear(err);
- if (pool)
- svn_pool_destroy(pool);
- exit(EXIT_FAILURE);
-}
-
-static apr_pool_t *
-init(const char *application)
+/* Version compatibility check */
+static svn_error_t *
+check_lib_versions(void)
{
- svn_error_t *err;
- const svn_version_checklist_t checklist[] = {
- {"svn_client", svn_client_version},
- {"svn_subr", svn_subr_version},
- {"svn_ra", svn_ra_version},
- {NULL, NULL}
- };
+ static const svn_version_checklist_t checklist[] =
+ {
+ { "svn_client", svn_client_version },
+ { "svn_subr", svn_subr_version },
+ { "svn_ra", svn_ra_version },
+ { NULL, NULL }
+ };
SVN_VERSION_DEFINE(my_version);
- if (svn_cmdline_init(application, stderr))
- exit(EXIT_FAILURE);
-
- err = svn_ver_check_list(&my_version, checklist);
- if (err)
- handle_error(err, NULL);
-
- return apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+ return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
}
static svn_error_t *
@@ -175,8 +158,8 @@ struct operation {
};
-/* An iterator (for use via apr_table_do) which sets node properties.
- REC is a pointer to a struct driver_state. */
+/* Set node properties.
+ ... */
static svn_error_t *
change_props(const svn_delta_editor_t *editor,
void *baton,
@@ -918,13 +901,14 @@ sanitize_url(const char *url,
return svn_uri_canonicalize(url, pool);
}
+/* Print a usage message on STREAM. */
static void
-usage(apr_pool_t *pool, int exit_val)
+usage(FILE *stream, apr_pool_t *pool)
{
- FILE *stream = exit_val == EXIT_SUCCESS ? stdout : stderr;
svn_error_clear(svn_cmdline_fputs(
- _("Subversion multiple URL command client\n"
- "usage: svnmucc ACTION...\n"
+ _("usage: svnmucc ACTION...\n"
+ "Subversion multiple URL command client.\n"
+ "Type 'svnmucc --version' to see the program version.\n"
"\n"
" Perform one or more Subversion repository URL-based ACTIONs, committing\n"
" the result as a (single) new revision.\n"
@@ -964,16 +948,13 @@ usage(apr_pool_t *pool, int exit_val)
" --no-auth-cache : do not cache authentication tokens\n"
" --version : print version information\n"),
stream, pool));
- svn_pool_destroy(pool);
- exit(exit_val);
}
-static void
-insufficient(apr_pool_t *pool)
+static svn_error_t *
+insufficient(void)
{
- handle_error(svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
- "insufficient arguments"),
- pool);
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "insufficient arguments");
}
static svn_error_t *
@@ -1040,10 +1021,14 @@ sanitize_log_sources(apr_hash_t *revprop
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)
{
- apr_pool_t *pool = init("svnmucc");
apr_array_header_t *actions = apr_array_make(pool, 1,
sizeof(struct action *));
const char *anchor = NULL;
@@ -1094,6 +1079,9 @@ main(int argc, const char **argv)
apr_hash_t *revprops = apr_hash_make(pool);
int i;
+ /* Check library versions */
+ SVN_ERR(check_lib_versions());
+
config_options = apr_array_make(pool, 0,
sizeof(svn_cmdline__config_argument_t*));
@@ -1109,22 +1097,17 @@ main(int argc, const char **argv)
if (APR_STATUS_IS_EOF(status))
break;
if (status != APR_SUCCESS)
- handle_error(svn_error_wrap_apr(status, "getopt failure"), pool);
+ return svn_error_wrap_apr(status, "getopt failure");
switch(opt)
{
case 'm':
- err = svn_utf_cstring_to_utf8(&message, arg, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&message, arg, pool));
break;
case 'F':
{
const char *arg_utf8;
- err = svn_utf_cstring_to_utf8(&arg_utf8, arg, pool);
- if (! err)
- err = svn_stringbuf_from_file2(&filedata, arg, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&arg_utf8, arg, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&filedata, arg, pool));
}
break;
case 'u':
@@ -1134,31 +1117,29 @@ main(int argc, const char **argv)
password = apr_pstrdup(pool, arg);
break;
case 'U':
- err = svn_utf_cstring_to_utf8(&root_url, arg, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&root_url, arg, pool));
if (! svn_path_is_url(root_url))
- handle_error(svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
- "'%s' is not a URL\n", root_url),
- pool);
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "'%s' is not a URL\n", root_url);
root_url = sanitize_url(root_url, pool);
break;
case 'r':
{
+ const char *saved_arg = arg;
char *digits_end = NULL;
+ while (*arg == 'r')
+ arg++;
base_revision = strtol(arg, &digits_end, 10);
if ((! SVN_IS_VALID_REVNUM(base_revision))
|| (! digits_end)
|| *digits_end)
- handle_error(svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR,
- NULL, "Invalid revision number"),
- pool);
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Invalid revision number '%s'"),
+ saved_arg);
}
break;
case with_revprop_opt:
- err = svn_opt_parse_revprop(&revprops, arg, pool);
- if (err != SVN_NO_ERROR)
- handle_error(err, pool);
+ SVN_ERR(svn_opt_parse_revprop(&revprops, arg, pool));
break;
case 'X':
extra_args_file = apr_pstrdup(pool, arg);
@@ -1173,40 +1154,31 @@ main(int argc, const char **argv)
trust_server_cert = TRUE;
break;
case config_dir_opt:
- err = svn_utf_cstring_to_utf8(&config_dir, arg, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&config_dir, arg, pool));
break;
case config_inline_opt:
- err = svn_utf_cstring_to_utf8(&opt_arg, arg, pool);
- if (err)
- handle_error(err, pool);
-
- err = svn_cmdline__parse_config_option(config_options, opt_arg,
- pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, arg, pool));
+ SVN_ERR(svn_cmdline__parse_config_option(config_options, opt_arg,
+ pool));
break;
case no_auth_cache_opt:
no_auth_cache = TRUE;
break;
case version_opt:
- SVN_INT_ERR(display_version(opts, pool));
- exit(EXIT_SUCCESS);
- break;
+ SVN_ERR(display_version(opts, pool));
+ return SVN_NO_ERROR;
case 'h':
case '?':
- usage(pool, EXIT_SUCCESS);
- break;
+ usage(stdout, pool);
+ return SVN_NO_ERROR;
}
}
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, "svnmucc: ");
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--non-interactive and --force-interactive "
+ "are mutually exclusive"));
}
else
non_interactive = !svn_cmdline__be_interactive(non_interactive,
@@ -1214,16 +1186,13 @@ main(int argc, const char **argv)
if (trust_server_cert && !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, "svnmucc: ");
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--trust-server-cert requires "
+ "--non-interactive"));
}
/* Make sure we have a log message to use. */
- err = sanitize_log_sources(revprops, message, filedata);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(sanitize_log_sources(revprops, message, filedata));
/* Copy the rest of our command-line arguments to an array,
UTF-8-ing them along the way. */
@@ -1231,10 +1200,9 @@ main(int argc, const char **argv)
while (opts->ind < opts->argc)
{
const char *arg = opts->argv[opts->ind++];
- if ((err = svn_utf_cstring_to_utf8(&(APR_ARRAY_PUSH(action_args,
- const char *)),
- arg, pool)))
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&APR_ARRAY_PUSH(action_args,
+ const char *),
+ arg, pool));
}
/* If there are extra arguments in a supplementary file, tack those
@@ -1244,14 +1212,10 @@ main(int argc, const char **argv)
const char *extra_args_file_utf8;
svn_stringbuf_t *contents, *contents_utf8;
- err = svn_utf_cstring_to_utf8(&extra_args_file_utf8,
- extra_args_file, pool);
- if (! err)
- err = svn_stringbuf_from_file2(&contents, extra_args_file_utf8, pool);
- if (! err)
- err = svn_utf_stringbuf_to_utf8(&contents_utf8, contents, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(svn_utf_cstring_to_utf8(&extra_args_file_utf8,
+ extra_args_file, pool));
+ SVN_ERR(svn_stringbuf_from_file2(&contents, extra_args_file_utf8, pool));
+ SVN_ERR(svn_utf_stringbuf_to_utf8(&contents_utf8, contents, pool));
svn_cstring_split_append(action_args, contents_utf8->data, "\n\r",
FALSE, pool);
}
@@ -1282,13 +1246,16 @@ main(int argc, const char **argv)
action->action = ACTION_PROPDEL;
else if (! strcmp(action_string, "?") || ! strcmp(action_string, "h")
|| ! strcmp(action_string, "help"))
- usage(pool, EXIT_SUCCESS);
+ {
+ usage(stdout, pool);
+ return SVN_NO_ERROR;
+ }
else
- handle_error(svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
- "'%s' is not an action\n",
- action_string), pool);
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "'%s' is not an action\n",
+ action_string);
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
/* For copies, there should be a revision number next. */
if (action->action == ACTION_CP)
@@ -1307,12 +1274,12 @@ main(int argc, const char **argv)
action->rev = strtol(rev_str, &end, 0);
if (*end)
- handle_error(svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
- "'%s' is not a revision\n",
- rev_str), pool);
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "'%s' is not a revision\n",
+ rev_str);
}
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
}
else
{
@@ -1326,7 +1293,7 @@ main(int argc, const char **argv)
svn_dirent_internal_style(APR_ARRAY_IDX(action_args, i,
const char *), pool);
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
}
/* For propset, propsetf, and propdel, a property name (and
@@ -1337,7 +1304,7 @@ main(int argc, const char **argv)
{
action->prop_name = APR_ARRAY_IDX(action_args, i, const char *);
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
if (action->action == ACTION_PROPDEL)
{
@@ -1349,7 +1316,7 @@ main(int argc, const char **argv)
svn_string_create(APR_ARRAY_IDX(action_args, i,
const char *), pool);
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
}
else
{
@@ -1358,12 +1325,10 @@ main(int argc, const char **argv)
const char *), pool);
if (++i == action_args->nelts)
- insufficient(pool);
+ return insufficient();
- err = read_propvalue_file(&(action->prop_value),
- propval_file, pool);
- if (err)
- handle_error(err, pool);
+ SVN_ERR(read_propvalue_file(&(action->prop_value),
+ propval_file, pool));
action->action = ACTION_PROPSET;
}
@@ -1372,14 +1337,10 @@ main(int argc, const char **argv)
&& svn_prop_needs_translation(action->prop_name))
{
svn_string_t *translated_value;
- err = svn_subst_translate_string2(&translated_value, NULL,
- NULL, action->prop_value, NULL,
- FALSE, pool, pool);
- if (err)
- handle_error(
- svn_error_quick_wrap(err,
- "Error normalizing property value"),
- pool);
+ SVN_ERR_W(svn_subst_translate_string2(&translated_value, NULL,
+ NULL, action->prop_value,
+ NULL, FALSE, pool, pool),
+ "Error normalizing property value");
action->prop_value = translated_value;
}
}
@@ -1407,14 +1368,14 @@ main(int argc, const char **argv)
if (! svn_path_is_url(url))
{
if (! root_url)
- handle_error(svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
- "'%s' is not a URL, and "
- "--root-url (-U) not provided\n",
- url), pool);
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "'%s' is not a URL, and "
+ "--root-url (-U) not provided\n",
+ url);
/* ### These relpaths are already URI-encoded. */
url = apr_pstrcat(pool, root_url, "/",
svn_relpath_canonicalize(url, pool),
- (char *)NULL);
+ SVN_VA_NULL);
}
url = sanitize_url(url, pool);
action->path[j] = url;
@@ -1429,16 +1390,26 @@ main(int argc, const char **argv)
if (! anchor)
anchor = url;
else
- anchor = svn_uri_get_longest_ancestor(anchor, url, pool);
+ {
+ anchor = svn_uri_get_longest_ancestor(anchor, url, pool);
+ if (!anchor || !anchor[0])
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "URLs in the action list do not "
+ "share a common ancestor");
+ }
if ((++i == action_args->nelts) && (j + 1 < num_url_args))
- insufficient(pool);
+ return insufficient();
}
APR_ARRAY_PUSH(actions, struct action *) = action;
}
if (! actions->nelts)
- usage(pool, EXIT_FAILURE);
+ {
+ *exit_code = EXIT_FAILURE;
+ usage(stderr, pool);
+ return SVN_NO_ERROR;
+ }
if ((err = execute(actions, anchor, revprops, username, password,
config_dir, config_options, non_interactive,
@@ -1449,12 +1420,40 @@ main(int argc, const char **argv)
_("Authentication failed and interactive"
" prompting is disabled; see the"
" --force-interactive option"));
- handle_error(err, pool);
+ return err;
}
- /* Ensure that stdout is flushed, so the user will see all results. */
- svn_error_clear(svn_cmdline_fflush(stdout));
+ return SVN_NO_ERROR;
+}
+
+int
+main(int argc, const char *argv[])
+{
+ apr_pool_t *pool;
+ int exit_code = EXIT_SUCCESS;
+ svn_error_t *err;
+
+ /* Initialize the app. */
+ if (svn_cmdline_init("svnmucc", 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));
+
+ if (err)
+ {
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svnmucc: ");
+ }
svn_pool_destroy(pool);
- return EXIT_SUCCESS;
+ return exit_code;
}
Modified: subversion/branches/verify-keep-going/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/svnrdump/dump_editor.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/verify-keep-going/subversion/svnrdump/dump_editor.c Wed Nov 27 11:52:35 2013
@@ -22,6 +22,7 @@
* ====================================================================
*/
+#include "svn_private_config.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_repos.h"