summaryrefslogtreecommitdiff
path: root/tools/server-side/svnauthz.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/server-side/svnauthz.c')
-rw-r--r--tools/server-side/svnauthz.c147
1 files changed, 61 insertions, 86 deletions
diff --git a/tools/server-side/svnauthz.c b/tools/server-side/svnauthz.c
index ab8c62d..3fadd23 100644
--- a/tools/server-side/svnauthz.c
+++ b/tools/server-side/svnauthz.c
@@ -234,7 +234,7 @@ get_authz_from_txn(svn_authz_t **authz, const char *repos_path,
svn_error_t *err;
/* Open up the repository and find the transaction root */
- SVN_ERR(svn_repos_open2(&repos, repos_path, NULL, pool));
+ SVN_ERR(svn_repos_open3(&repos, repos_path, NULL, pool, pool));
fs = svn_repos_fs(repos);
SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, pool));
SVN_ERR(svn_fs_txn_root(&root, txn, pool));
@@ -382,42 +382,6 @@ subcommand_accessof(apr_getopt_t *os, void *baton, apr_pool_t *pool)
#undef EXIT_FAILURE
#define EXIT_FAILURE 2
-/* Similar to svn_cmdline_handle_exit_error but with an exit_code argument
- so we can comply with our contract and exit with 2 for internal failures.
- Also is missing the pool argument since we don't need it given
- main/sub_main. */
-static int
-handle_exit_error(svn_error_t *err, const char *prefix, int exit_code)
-{
- /* Issue #3014:
- * Don't print anything on broken pipes. The pipe was likely
- * closed by the process at the other end. We expect that
- * process to perform error reporting as necessary.
- *
- * ### This assumes that there is only one error in a chain for
- * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */
- if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
- svn_handle_error2(err, stderr, FALSE, prefix);
- svn_error_clear(err);
- return exit_code;
-}
-
-/* Report and clear the error ERR, and return EXIT_FAILURE. */
-#define EXIT_ERROR(err, exit_code) \
- handle_exit_error(err, "svnauthz: ", exit_code)
-
-/* 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 'svnauthz' 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, EXIT_FAILURE); \
- } while (0)
-
-
/* Return TRUE if the UI of 'svnauthz-validate' (svn 1.7 and earlier)
should be emulated, given argv[0]. */
static svn_boolean_t
@@ -485,8 +449,13 @@ canonicalize_access_file(const char **canonicalized_access_file,
return SVN_NO_ERROR;
}
-static int
-sub_main(int argc, const char *argv[], apr_pool_t *pool)
+/*
+ * 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;
@@ -497,7 +466,7 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
int i;
/* Initialize the FS library. */
- SVN_INT_ERR(svn_fs_initialize(pool));
+ SVN_ERR(svn_fs_initialize(pool));
received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
@@ -506,7 +475,7 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
opt_state.txn = opt_state.repos_path = opt_state.groups_file = NULL;
/* 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;
if (!use_compat_mode(argv[0], pool))
@@ -521,8 +490,9 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
break;
if (status != APR_SUCCESS)
{
- 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;
}
/* Stash the option code in an array before parsing it. */
@@ -535,7 +505,7 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
opt_state.help = TRUE;
break;
case 't':
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.txn, arg, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.txn, arg, pool));
break;
case 'R':
opt_state.recursive = TRUE;
@@ -544,28 +514,29 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
opt_state.version = TRUE;
break;
case svnauthz__username:
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.username, arg, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.username, arg, pool));
break;
case svnauthz__path:
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.fspath, arg, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.fspath, arg, pool));
opt_state.fspath = svn_fspath__canonicalize(opt_state.fspath,
pool);
break;
case svnauthz__repos:
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_name, arg, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_name, arg, pool));
break;
case svnauthz__is:
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.is, arg, pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.is, arg, pool));
break;
case svnauthz__groups_file:
- SVN_INT_ERR(
+ SVN_ERR(
svn_utf_cstring_to_utf8(&opt_state.groups_file,
arg, pool));
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;
}
}
}
@@ -603,8 +574,9 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
{
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
@@ -616,14 +588,15 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
const char *first_arg_utf8;
os->ind++;
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+ 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;
}
}
}
@@ -637,13 +610,12 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
{
if (os->ind +2 != argc)
{
- err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- ("Repository and authz file arguments "
- "required"));
- return EXIT_ERROR(err, EXIT_FAILURE);
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ ("Repository and authz file arguments "
+ "required"));
}
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_path, os->argv[os->ind],
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_path, os->argv[os->ind],
pool));
os->ind++;
@@ -653,24 +625,23 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
/* Exactly 1 non-option argument */
if (os->ind + 1 != argc)
{
- err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- ("Authz file argument required"));
- return EXIT_ERROR(err, EXIT_FAILURE);
+ return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ ("Authz file argument required"));
}
/* Grab AUTHZ_FILE from argv. */
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.authz_file, os->argv[os->ind],
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.authz_file, os->argv[os->ind],
pool));
/* Canonicalize opt_state.authz_file appropriately. */
- SVN_INT_ERR(canonicalize_access_file(&opt_state.authz_file,
+ SVN_ERR(canonicalize_access_file(&opt_state.authz_file,
opt_state.authz_file,
opt_state.txn != NULL, pool));
/* Same for opt_state.groups_file if it is present. */
if (opt_state.groups_file)
{
- SVN_INT_ERR(canonicalize_access_file(&opt_state.groups_file,
+ SVN_ERR(canonicalize_access_file(&opt_state.groups_file,
opt_state.groups_file,
opt_state.txn != NULL, pool));
}
@@ -696,13 +667,14 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
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 'svnauthz help %s' for usage.\n"),
subcommand->name, optstr, subcommand->name));
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
@@ -724,7 +696,8 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
{
/* Follow our contract that says we exit with 1 if the file does not
validate. */
- return EXIT_ERROR(err, 1);
+ *exit_code = 1;
+ return err;
}
else if (err->apr_err == SVN_ERR_AUTHZ_UNREADABLE
|| err->apr_err == SVN_ERR_AUTHZ_UNWRITABLE
@@ -732,31 +705,22 @@ sub_main(int argc, const char *argv[], apr_pool_t *pool)
{
/* Follow our contract that says we exit with 3 if --is does not
* match. */
- return EXIT_ERROR(err, 3);
+ *exit_code = 3;
+ return err;
}
-
- return EXIT_ERROR(err, EXIT_FAILURE);
- }
- 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, EXIT_FAILURE);
- }
- return EXIT_SUCCESS;
+ return err;
}
+ 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. Send all error messages to 'stderr'. */
if (svn_cmdline_init(argv[0], stderr) != EXIT_SUCCESS)
@@ -764,7 +728,18 @@ main(int argc, const char *argv[])
pool = svn_pool_create(NULL);
- 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)
+ {
+ if (exit_code == 0)
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svnauthz: ");
+ }
svn_pool_destroy(pool);
return exit_code;