/*
 * svnauthz.c : Tool for working with authz files.
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include "svn_cmdline.h"
#include "svn_dirent_uri.h"
#include "svn_opt.h"
#include "svn_pools.h"
#include "svn_repos.h"
#include "svn_utf.h"
#include "svn_path.h"

#include "private/svn_fspath.h"
#include "private/svn_cmdline_private.h"
#include "svn_private_config.h"


/*** Option Processing. ***/

enum svnauthz__cmdline_options_t
{
  svnauthz__version = SVN_OPT_FIRST_LONGOPT_ID,
  svnauthz__username,
  svnauthz__path,
  svnauthz__repos,
  svnauthz__is,
  svnauthz__groups_file
};

/* Option codes and descriptions.
 *
 * The entire list must be terminated with an entry of nulls.
 */
static const apr_getopt_option_t options_table[] =
{
  {"help", 'h', 0, ("show help on a subcommand")},
  {NULL, '?', 0, ("show help on a subcommand")},
  {"version", svnauthz__version, 0, ("show program version information")},
  {"username", svnauthz__username, 1, ("username to check access of")},
  {"path", svnauthz__path, 1, ("path within repository to check access of")},
  {"repository", svnauthz__repos, 1, ("repository authz name")},
  {"transaction", 't', 1, ("transaction id")},
  {"is", svnauthz__is, 1,
    ("instead of outputting, test if the access is\n"
     "                             "
     "exactly ARG\n"
     "                             "
     "ARG can be one of the following values:\n"
     "                             "
     "   rw    write access (which also implies read)\n"
     "                             "
     "    r    read-only access\n"
     "                             "
     "   no    no access")
  },
  {"groups-file", svnauthz__groups_file, 1,
   ("use the groups from file ARG")},
  {"recursive", 'R', 0,
   ("determine recursive access to PATH")},
  {0, 0, 0, 0}
};

struct svnauthz_opt_state
{
  svn_boolean_t help;
  svn_boolean_t version;
  svn_boolean_t recursive;
  const char *authz_file;
  const char *groups_file;
  const char *username;
  const char *fspath;
  const char *repos_name;
  const char *txn;
  const char *repos_path;
  const char *is;
};

/* The name of this binary in 1.7 and earlier. */
#define SVNAUTHZ_COMPAT_NAME "svnauthz-validate"

/* Libtool command prefix */
#define SVNAUTHZ_LT_PREFIX "lt-"

/* The prefix for handling errors and warnings. */
#define SVNAUTHZ_ERR_PREFIX "svnauthz: "


/*** Subcommands. */

static svn_opt_subcommand_t
  subcommand_help,
  subcommand_validate,
  subcommand_accessof;

/* Array of available subcommands.
 * The entire list must be terminated with an entry of nulls.
 */
static const svn_opt_subcommand_desc3_t cmd_table[] =
{
  {"help", subcommand_help, {"?", "h"}, {(
    "usage: svnauthz help [SUBCOMMAND...]\n"
    "\n"
    "Describe the usage of this program or its subcommands.\n"
    )},
   {0} },
  {"validate", subcommand_validate, {0} /* no aliases */, {(
    "Checks the syntax of an authz file.\n"
    "usage: 1. svnauthz validate TARGET\n"
    "       2. svnauthz validate --transaction TXN REPOS_PATH FILE_PATH\n"
    "\n"
    "  1. Loads and validates the syntax of the authz file at TARGET.\n"
    "     TARGET can be a path to a file or an absolute file:// URL to an authz\n"
    "     file in a repository, but cannot be a repository relative URL (^/).\n"
    "\n"
    "  2. Loads and validates the syntax of the authz file at FILE_PATH in the\n"
    "     transaction TXN in the repository at REPOS_PATH.\n"
    "\n"
    "Returns:\n"
    "    0   when syntax is OK.\n"
    "    1   when syntax is invalid.\n"
    "    2   operational error\n"
    )},
   {'t'} },
  {"accessof", subcommand_accessof, {0} /* no aliases */, {(
    "Print or test the permissions set by an authz file.\n"
    "usage: 1. svnauthz accessof TARGET\n"
    "       2. svnauthz accessof -t TXN REPOS_PATH FILE_PATH\n"
    "\n"
    "  1. Prints the access of USER to PATH based on authorization file at TARGET.\n"
    "     TARGET can be a path to a file or an absolute file:// URL to an authz\n"
    "     file in a repository, but cannot be a repository relative URL (^/).\n"
    "\n"
    "  2. Prints the access of USER to PATH based on authz file at FILE_PATH in the\n"
    "     transaction TXN in the repository at REPOS_PATH.\n"
    "\n"
    "  USER is the argument to the --username option; if that option is not\n"
    "  provided, then access of an anonymous user will be printed or tested.\n"
    "\n"
    "  PATH is the argument to the --path option; if that option is not provided,\n"
    "  the maximal access to any path in the repository will be considered.\n"
    "\n"
    "Outputs one of the following:\n"
    "     rw    write access (which also implies read)\n"
    "      r    read access\n"
    "     no    no access\n"
    "\n"
    "Returns:\n"
    "    0   when syntax is OK and '--is' argument (if any) matches.\n"
    "    1   when syntax is invalid.\n"
    "    2   operational error\n"
    "    3   when '--is' argument doesn't match\n"
    )},
   {'t', svnauthz__username, svnauthz__path, svnauthz__repos, svnauthz__is,
    svnauthz__groups_file, 'R'} },
  { NULL, NULL, {0}, {NULL}, {0} }
};

static svn_error_t *
subcommand_help(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  struct svnauthz_opt_state *opt_state = baton;
  const char *header =
    ("general usage: svnauthz SUBCOMMAND TARGET [ARGS & OPTIONS ...]\n"
     "               " SVNAUTHZ_COMPAT_NAME " TARGET\n"
    "\n"
     "If the command name starts with '" SVNAUTHZ_COMPAT_NAME "', runs in\n"
     "pre-1.8 compatibility mode: run the 'validate' subcommand on TARGET.\n"
    "\n"
     "Type 'svnauthz help <subcommand>' for help on a specific subcommand.\n"
     "Type 'svnauthz --version' to see the program version.\n"
    "\n"
     "Available subcommands:\n");

  const char *fs_desc_start
    = ("The following repository back-end (FS) modules are available:\n\n");

  svn_stringbuf_t *version_footer;

  version_footer = svn_stringbuf_create(fs_desc_start, pool);
  SVN_ERR(svn_fs_print_modules(version_footer, pool));

  SVN_ERR(svn_opt_print_help5(os, "svnauthz",
                              opt_state ? opt_state->version : FALSE,
                              FALSE, /* quiet */
                              FALSE, /* verbose */
                              version_footer->data,
                              header, cmd_table, options_table, NULL, NULL,
                              pool));

  return SVN_NO_ERROR;
}

/* Loads the fs FILENAME contents into *CONTENTS ensuring that the
   corresponding node is a file. Using POOL for allocations. */
static svn_error_t *
read_file_contents(svn_stream_t **contents, const char *filename,
                   svn_fs_root_t *root, apr_pool_t *pool)
{
  svn_node_kind_t node_kind;

  /* Make sure the path is a file */
  SVN_ERR(svn_fs_check_path(&node_kind, root, filename, pool));
  if (node_kind != svn_node_file)
    return svn_error_createf(SVN_ERR_FS_NOT_FILE, NULL,
                             "Path '%s' is not a file", filename);

  SVN_ERR(svn_fs_file_contents(contents, root, filename, pool));

  return SVN_NO_ERROR;
}

/* Handles warning emitted by the authz parser. */
static void
handle_parser_warning(void *baton,
                      const svn_error_t *err,
                      apr_pool_t *scratch_pool)
{
  svn_handle_warning2(stderr, err, SVNAUTHZ_ERR_PREFIX);
  SVN_UNUSED(baton);
  SVN_UNUSED(scratch_pool);
}


/* Loads the authz config into *AUTHZ from the file at AUTHZ_FILE
   in repository at REPOS_PATH from the transaction TXN_NAME.  If GROUPS_FILE
   is set, the resulting *AUTHZ will be constructed from AUTHZ_FILE with
   global groups taken from GROUPS_FILE.  Using POOL for allocations. */
static svn_error_t *
get_authz_from_txn(svn_authz_t **authz, const char *repos_path,
                   const char *authz_file, const char *groups_file,
                   const char *txn_name, apr_pool_t *pool)
{
  svn_repos_t *repos;
  svn_fs_t *fs;
  svn_fs_txn_t *txn;
  svn_fs_root_t *root;
  svn_stream_t *authz_contents;
  svn_stream_t *groups_contents;
  svn_error_t *err;

  /* Open up the repository and find the transaction root */
  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));

  /* Get the authz file contents. */
  SVN_ERR(read_file_contents(&authz_contents, authz_file, root, pool));

  /* Get the groups file contents if needed. */
  if (groups_file)
    SVN_ERR(read_file_contents(&groups_contents, groups_file, root, pool));
  else
    groups_contents = NULL;

  err = svn_repos_authz_parse2(authz, authz_contents, groups_contents,
                               handle_parser_warning, NULL, pool, pool);

  /* Add the filename to the error stack since the parser doesn't have it. */
  if (err != SVN_NO_ERROR)
    return svn_error_createf(err->apr_err, err,
                             "Error parsing authz file: '%s':", authz_file);

  return SVN_NO_ERROR;
}

/* Loads the authz config into *AUTHZ from OPT_STATE->AUTHZ_FILE.  If
   OPT_STATE->GROUPS_FILE is set, loads the global groups from it.
   If OPT_STATE->TXN is set then OPT_STATE->AUTHZ_FILE and
   OPT_STATE->GROUPS_FILE are treated as fspaths in repository at
   OPT_STATE->REPOS_PATH. */
static svn_error_t *
get_authz(svn_authz_t **authz, struct svnauthz_opt_state *opt_state,
          apr_pool_t *pool)
{
  /* Read the access file and validate it. */
  if (opt_state->txn)
    return get_authz_from_txn(authz, opt_state->repos_path,
                              opt_state->authz_file,
                              opt_state->groups_file,
                              opt_state->txn, pool);

  /* Else */
  return svn_repos_authz_read4(authz, opt_state->authz_file,
                               opt_state->groups_file,
                               TRUE, NULL,
                               handle_parser_warning, NULL,
                               pool, pool);
}

static svn_error_t *
subcommand_validate(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  struct svnauthz_opt_state *opt_state = baton;
  svn_authz_t *authz;

  /* Not much to do here since just loading the authz file also validates. */
  return get_authz(&authz, opt_state, pool);
}

static svn_error_t *
subcommand_accessof(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  svn_authz_t *authz;
  svn_boolean_t read_access = FALSE, write_access = FALSE;
  svn_boolean_t check_r = FALSE, check_rw = FALSE, check_no = FALSE;
  svn_error_t *err;
  struct svnauthz_opt_state *opt_state = baton;
  const char *user = opt_state->username;
  const char *path = opt_state->fspath;
  const char *repos = opt_state->repos_name;
  const char *is = opt_state->is;
  svn_repos_authz_access_t request;

  if (opt_state->recursive && !path)
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                            ("--recursive not valid without --path"));

  /* Handle is argument parsing/allowed values */
  if (is) {
      if (0 == strcmp(is, "rw"))
        check_rw = TRUE;
      else if (0 == strcmp(is, "r"))
        check_r = TRUE;
      else if (0 == strcmp(is, "no"))
        check_no = TRUE;
      else
        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 ("'%s' is not a valid argument for --is"), is);
  }

  SVN_ERR(get_authz(&authz, opt_state, pool));


  request = svn_authz_write;
  if (opt_state->recursive)
    request |= svn_authz_recursive;
  err = svn_repos_authz_check_access(authz, repos, path, user,
                                     request, &write_access,
                                     pool);

  if (!write_access && !err)
    {
      request = svn_authz_read;
      if (opt_state->recursive)
        request |= svn_authz_recursive;
      err = svn_repos_authz_check_access(authz, repos, path, user,
                                         request, &read_access,
                                         pool);
    }

  if (!err)
    {
      const char *access_str = write_access ? "rw" : read_access ? "r" : "no";

      if (is)
        {
          /* Check that --is argument matches.
           * The errors returned here are not strictly correct, but
           * none of the other code paths will generate them and they
           * roughly mean what we're saying here. */
          if (check_rw && !write_access)
            err = svn_error_createf(SVN_ERR_AUTHZ_UNWRITABLE, NULL,
                                    ("%s is '%s', not writable"),
                                    path ? path : ("Repository"), access_str);
          else if (check_r && !read_access)
            err = svn_error_createf(SVN_ERR_AUTHZ_UNREADABLE, NULL,
                                    ("%s is '%s', not read only"),
                                    path ? path : ("Repository"), access_str);
          else if (check_no && (read_access || write_access))
            err = svn_error_createf(SVN_ERR_AUTHZ_PARTIALLY_READABLE,
                                    NULL, ("%s is '%s', not no access"),
                                    path ? path : ("Repository"), access_str);
        }
      else
        {
          err = svn_cmdline_printf(pool, "%s\n", access_str);
        }
    }

  return err;
}



/*** Main. ***/

/* A redefinition of EXIT_FAILURE since our contract demands that we
   exit with 2 for internal failures. */
#undef EXIT_FAILURE
#define EXIT_FAILURE 2

/* Return TRUE if the UI of 'svnauthz-validate' (svn 1.7 and earlier)
   should be emulated, given argv[0]. */
static svn_boolean_t
use_compat_mode(const char *cmd, apr_pool_t *pool)
{
  svn_error_t *err = svn_dirent_internal_style_safe(&cmd, NULL, cmd, pool, pool);
  if (err)
    {
      svn_error_clear(err);
      return FALSE;
    }
  cmd = svn_dirent_basename(cmd, NULL);

  /* Skip over the Libtool command prefix if it exists on the command. */
  if (0 == strncmp(SVNAUTHZ_LT_PREFIX, cmd, sizeof(SVNAUTHZ_LT_PREFIX)-1))
    cmd += sizeof(SVNAUTHZ_LT_PREFIX) - 1;

  /* Deliberately look only for the start of the name to deal with
     the executable extension on some platforms. */
  return 0 == strncmp(SVNAUTHZ_COMPAT_NAME, cmd,
                      sizeof(SVNAUTHZ_COMPAT_NAME)-1);
}

/* Canonicalize ACCESS_FILE into *CANONICALIZED_ACCESS_FILE based on the type
   of argument.  Error out on unsupported path types.  If WITHIN_TXN is set,
   ACCESS_FILE has to be a fspath in the repo.  Use POOL for allocations. */
static svn_error_t *
canonicalize_access_file(const char **canonicalized_access_file,
                         const char *access_file,
                         svn_boolean_t within_txn,
                         apr_pool_t *pool)
{
  if (svn_path_is_repos_relative_url(access_file))
    {
      /* Can't accept repos relative urls since we don't have the path to
       * the repository. */
      return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               ("'%s' is a repository relative URL when it "
                               "should be a local path or file:// URL"),
                               access_file);
    }
  else if (svn_path_is_url(access_file))
    {
      if (within_txn)
        {
          /* Don't allow urls with transaction argument. */
          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                   ("'%s' is a URL when it should be a "
                                   "repository-relative path"),
                                   access_file);
        }

      SVN_ERR(svn_uri_canonicalize_safe(
                  canonicalized_access_file, NULL,
                  access_file, pool, pool));
    }
  else if (within_txn)
    {
      /* Transaction flag means this has to be a fspath to the access file
       * in the repo. */
      *canonicalized_access_file =
          svn_fspath__canonicalize(access_file, pool);
    }
  else
    {
      /* If it isn't a URL and there's no transaction flag then it's a
       * dirent to the access file on local disk. */
      SVN_ERR(svn_dirent_internal_style_safe(
                  canonicalized_access_file, NULL,
                  access_file, pool, 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 svn_cmdline__argv_char_t *cmdline_argv[],
         apr_pool_t *pool)
{
  svn_error_t *err;

  const svn_opt_subcommand_desc3_t *subcommand = NULL;
  struct svnauthz_opt_state opt_state = { 0 };
  apr_getopt_t *os;
  apr_array_header_t *received_opts;
  int i;
  const char **argv;

  SVN_ERR(svn_cmdline__get_cstring_argv(&argv, argc, cmdline_argv, pool));

  /* Initialize the FS library. */
  SVN_ERR(svn_fs_initialize(pool));

  received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));

  /* Initialize opt_state */
  opt_state.username = opt_state.fspath = opt_state.repos_name = NULL;
  opt_state.txn = opt_state.repos_path = opt_state.groups_file = NULL;

  /* Parse options. */
  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
  os->interleave = 1;

  if (!use_compat_mode(argv[0], pool))
    {
      while (1)
        {
          int opt;
          const char *arg;
          apr_status_t status = apr_getopt_long(os, options_table, &opt, &arg);

          if (APR_STATUS_IS_EOF(status))
            break;
          if (status != APR_SUCCESS)
            {
              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. */
          APR_ARRAY_PUSH(received_opts, int) = opt;

          switch (opt)
            {
            case 'h':
            case '?':
              opt_state.help = TRUE;
              break;
            case 't':
              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.txn, arg, pool));
              break;
            case 'R':
              opt_state.recursive = TRUE;
              break;
            case svnauthz__version:
              opt_state.version = TRUE;
              break;
            case svnauthz__username:
              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.username, arg, pool));
              break;
            case svnauthz__path:
              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_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_name, arg, pool));
              break;
            case svnauthz__is:
              SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.is, arg, pool));
              break;
            case svnauthz__groups_file:
              SVN_ERR(
                  svn_utf_cstring_to_utf8(&opt_state.groups_file,
                                          arg, pool));
              break;
            default:
                {
                  SVN_ERR(subcommand_help(NULL, NULL, pool));
                  *exit_code = EXIT_FAILURE;
                  return SVN_NO_ERROR;
                }
            }
        }
    }
  else
    {
      /* Pre 1.8 compatibility mode. */
      if (argc == 1) /* No path argument */
        subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "help");
      else
        subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "validate");
    }

  /* 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
     just typos/mistakes.  Whatever the case, the subcommand to
     actually run is subcommand_help(). */
  if (opt_state.help)
    subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "help");

  if (subcommand == NULL)
    {
      if (os->ind >= os->argc)
        {
          if (opt_state.version)
            {
              /* Use the "help" subcommand to handle the "--version" option. */
              static const svn_opt_subcommand_desc3_t pseudo_cmd =
                { "--version", subcommand_help, {0}, {""},
                  {svnauthz__version /* must accept its own option */ } };

              subcommand = &pseudo_cmd;
            }
          else
            {
              svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                        ("subcommand argument required\n")));
              SVN_ERR(subcommand_help(NULL, NULL, pool));
              *exit_code = EXIT_FAILURE;
              return SVN_NO_ERROR;
            }
        }
      else
        {
          const char *first_arg;

          SVN_ERR(svn_utf_cstring_to_utf8(&first_arg, os->argv[os->ind++],
                                          pool));
          subcommand = svn_opt_get_canonical_subcommand3(cmd_table, first_arg);
          if (subcommand == NULL)
            {
              os->ind++;
              svn_error_clear(
                svn_cmdline_fprintf(stderr, pool,
                                    ("Unknown subcommand: '%s'\n"),
                                    first_arg));
              SVN_ERR(subcommand_help(NULL, NULL, pool));
              *exit_code = EXIT_FAILURE;
              return SVN_NO_ERROR;
            }
        }
    }

  /* Every subcommand except `help' requires one or two non-option arguments.
     Parse them and store them in opt_state.*/
  if (subcommand->cmd_func != subcommand_help)
    {
      /* Consume a non-option argument (repos_path) if --transaction */
      if (opt_state.txn)
        {
          if (os->ind +2 != argc)
            {
              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                      ("Repository and authz file arguments "
                                       "required"));
            }

          SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.repos_path, os->argv[os->ind],
                                              pool));
          os->ind++;

          SVN_ERR(svn_dirent_internal_style_safe(&opt_state.repos_path, NULL,
                                                 opt_state.repos_path,
                                                 pool, pool));
        }

      /* Exactly 1 non-option argument */
      if (os->ind + 1 != argc)
        {
          return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                  ("Authz file argument required"));
        }

      /* Grab AUTHZ_FILE from argv. */
      SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.authz_file, os->argv[os->ind],
                                          pool));

      /* Canonicalize opt_state.authz_file appropriately. */
      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_ERR(canonicalize_access_file(&opt_state.groups_file,
                                               opt_state.groups_file,
                                               opt_state.txn != NULL, pool));
        }
    }

  /* Check that the subcommand wasn't passed any inappropriate options. */
  for (i = 0; i < received_opts->nelts; i++)
    {
      int opt_id = APR_ARRAY_IDX(received_opts, i, int);

      /* All commands implicitly accept --help, so just skip over this
         when we see it. Note that we don't want to include this option
         in their "accepted options" list because it would be awfully
         redundant to display it in every commands' help text. */
      if (opt_id == 'h' || opt_id == '?')
        continue;

      if (! svn_opt_subcommand_takes_option4(subcommand, opt_id, NULL))
        {
          const char *optstr;
          const apr_getopt_option_t *badopt =
            svn_opt_get_option_from_code3(opt_id, options_table, subcommand,
                                          pool);
          svn_opt_format_option(&optstr, badopt, FALSE, pool);
          if (subcommand->name[0] == '-')
            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));
          *exit_code = EXIT_FAILURE;
          return SVN_NO_ERROR;
        }
    }

  /* Run the subcommand. */
  err = (*subcommand->cmd_func)(os, &opt_state, pool);

  if (err)
    {
      if (err->apr_err == SVN_ERR_CL_INSUFFICIENT_ARGS
          || err->apr_err == SVN_ERR_CL_ARG_PARSING_ERROR)
        {
          /* For argument-related problems, suggest using the 'help'
             subcommand. */
          err = svn_error_quick_wrap(err,
                                     ("Try 'svnauthz help' for more info"));
        }
      else if (err->apr_err == SVN_ERR_AUTHZ_INVALID_CONFIG
               || err->apr_err == SVN_ERR_MALFORMED_FILE)
        {
          /* Follow our contract that says we exit with 1 if the file does not
             validate. */
          *exit_code = 1;
          return err;
        }
      else if (err->apr_err == SVN_ERR_AUTHZ_UNREADABLE
               || err->apr_err == SVN_ERR_AUTHZ_UNWRITABLE
               || err->apr_err == SVN_ERR_AUTHZ_PARTIALLY_READABLE)
        {
          /* Follow our contract that says we exit with 3 if --is does not
           * match. */
          *exit_code = 3;
          return err;
        }

      return err;
    }

  return SVN_NO_ERROR;
}

int
SVN_CMDLINE__MAIN(int argc, const svn_cmdline__argv_char_t *argv[])
{
  apr_pool_t *pool;
  int exit_code = EXIT_SUCCESS;
  svn_error_t *err;

  /* Initialize the app.  Send all error messages to 'stderr'.  */
  if (svn_cmdline_init("svnauthz", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  pool = svn_pool_create(NULL);

  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_ERR_PREFIX);
    }

  svn_pool_destroy(pool);
  return exit_code;
}
