/*
 * serve.c :  Functions for serving the Subversion protocol
 *
 * ====================================================================
 *    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 <limits.h> /* for UINT_MAX */
#include <stdarg.h>

#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_general.h>
#include <apr_lib.h>
#include <apr_strings.h>

#include "svn_compat.h"
#include "svn_private_config.h"  /* For SVN_PATH_LOCAL_SEPARATOR */
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_ra.h"              /* for SVN_RA_CAPABILITY_* */
#include "svn_ra_svn.h"
#include "svn_repos.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_time.h"
#include "svn_config.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_user.h"

#include "private/svn_log.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_ra_svn_private.h"
#include "private/svn_fspath.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>   /* For getpid() */
#endif

#include "server.h"
#include "logger.h"

typedef struct commit_callback_baton_t {
  apr_pool_t *pool;
  svn_revnum_t *new_rev;
  const char **date;
  const char **author;
  const char **post_commit_err;
} commit_callback_baton_t;

typedef struct report_driver_baton_t {
  server_baton_t *sb;
  const char *repos_url;  /* Decoded repository URL. */
  void *report_baton;
  svn_error_t *err;
  /* so update() can distinguish checkout from update in logging */
  int entry_counter;
  svn_boolean_t only_empty_entries;
  /* for diff() logging */
  svn_revnum_t *from_rev;
} report_driver_baton_t;

typedef struct log_baton_t {
  const char *fs_path;
  svn_ra_svn_conn_t *conn;
  int stack_depth;

  /* Set to TRUE when at least one changed path has been sent. */
  svn_boolean_t started;
} log_baton_t;

typedef struct file_revs_baton_t {
  svn_ra_svn_conn_t *conn;
  apr_pool_t *pool;  /* Pool provided in the handler call. */
} file_revs_baton_t;

typedef struct fs_warning_baton_t {
  server_baton_t *server;
  svn_ra_svn_conn_t *conn;
} fs_warning_baton_t;

typedef struct authz_baton_t {
  server_baton_t *server;
  svn_ra_svn_conn_t *conn;
} authz_baton_t;

/* Log an error. */
static void
log_error(const svn_error_t *err, server_baton_t *server)
{
  logger__log_error(server->logger, err, server->repository,
                    server->client_info);
}

/* Log a warning. */
static void
log_warning(const svn_error_t *err, server_baton_t *server)
{
  logger__log_warning(server->logger, err, server->repository,
                      server->client_info);
}

/* svn_error_create() a new error, log_server_error() it, and
   return it. */
static svn_error_t *
error_create_and_log(apr_status_t apr_err, svn_error_t *child,
                     const char *message, server_baton_t *server)
{
  svn_error_t *err = svn_error_create(apr_err, child, message);
  log_error(err, server);
  return err;
}

/* Log a failure ERR, transmit ERR back to the client (as part of a
   "failure" notification), consume ERR, and flush the connection. */
static svn_error_t *
log_fail_and_flush(svn_error_t *err, server_baton_t *server,
                   svn_ra_svn_conn_t *conn, apr_pool_t *pool)
{
  svn_error_t *io_err;

  log_error(err, server);
  io_err = svn_ra_svn__write_cmd_failure(conn, pool, err);
  svn_error_clear(err);
  SVN_ERR(io_err);
  return svn_ra_svn__flush(conn, pool);
}

/* Log a client command. */
static svn_error_t *log_command(server_baton_t *b,
                                svn_ra_svn_conn_t *conn,
                                apr_pool_t *pool,
                                const char *fmt, ...)
{
  const char *remote_host, *timestr, *log, *line;
  va_list ap;
  apr_size_t nbytes;

  if (b->logger == NULL)
    return SVN_NO_ERROR;

  remote_host = svn_ra_svn_conn_remote_host(conn);
  timestr = svn_time_to_cstring(apr_time_now(), pool);

  va_start(ap, fmt);
  log = apr_pvsprintf(pool, fmt, ap);
  va_end(ap);

  line = apr_psprintf(pool, "%" APR_PID_T_FMT
                      " %s %s %s %s %s" APR_EOL_STR,
                      getpid(), timestr,
                      (remote_host ? remote_host : "-"),
                      (b->client_info->user ? b->client_info->user : "-"),
                      b->repository->repos_name, log);
  nbytes = strlen(line);

  return logger__write(b->logger, line, nbytes);
}

/* Log an authz failure */
static svn_error_t *
log_authz_denied(const char *path,
                 svn_repos_authz_access_t required,
                 server_baton_t *b,
                 apr_pool_t *pool)
{
  const char *timestr, *remote_host, *line;

  if (!b->logger)
    return SVN_NO_ERROR;

  if (!b->client_info || !b->client_info->user)
    return SVN_NO_ERROR;

  timestr = svn_time_to_cstring(apr_time_now(), pool);
  remote_host = b->client_info->remote_host;

  line = apr_psprintf(pool, "%" APR_PID_T_FMT
                      " %s %s %s %s Authorization Failed %s%s %s" APR_EOL_STR,
                      getpid(), timestr,
                      (remote_host ? remote_host : "-"),
                      b->client_info->user,
                      b->repository->repos_name,
                      (required & svn_authz_recursive ? "recursive " : ""),
                      (required & svn_authz_write ? "write" : "read"),
                      (path && path[0] ? path : "/"));

  return logger__write(b->logger, line, strlen(line));
}

/* If CFG specifies a path to the password DB, read that DB through
 * CONFIG_POOL and store it in REPOSITORY->PWDB.
 */
static svn_error_t *
load_pwdb_config(repository_t *repository,
                 svn_config_t *cfg,
                 svn_repos__config_pool_t *config_pool,
                 apr_pool_t *pool)
{
  const char *pwdb_path;
  svn_error_t *err;

  svn_config_get(cfg, &pwdb_path,
                 SVN_CONFIG_SECTION_GENERAL,
                 SVN_CONFIG_OPTION_PASSWORD_DB, NULL);

  repository->pwdb = NULL;
  if (pwdb_path)
    {
      pwdb_path = svn_dirent_internal_style(pwdb_path, pool);
      pwdb_path = svn_dirent_join(repository->base, pwdb_path, pool);

      err = svn_repos__config_pool_get(&repository->pwdb, config_pool,
                                       pwdb_path, TRUE,
                                       repository->repos, pool);
      if (err)
        {
          /* Because it may be possible to read the pwdb file with some
             access methods and not others, ignore errors reading the pwdb
             file and just don't present password authentication as an
             option.  Also, some authentications (e.g. --tunnel) can
             proceed without it anyway.

             ### Not entirely sure why SVN_ERR_BAD_FILENAME is checked
             ### for here.  That seems to have been introduced in r856914,
             ### and only in r870942 was the APR_EACCES check introduced. */
          if (err->apr_err != SVN_ERR_BAD_FILENAME
              && ! APR_STATUS_IS_EACCES(err->apr_err))
            {
              return svn_error_create(SVN_ERR_AUTHN_FAILED, err, NULL);
            }
          else
            /* Ignore SVN_ERR_BAD_FILENAME and APR_EACCES and proceed. */
            svn_error_clear(err);
        }
    }

  return SVN_NO_ERROR;
}

/* Canonicalize *ACCESS_FILE based on the type of argument.  Results are
 * placed in *ACCESS_FILE.  REPOSITORY is used to convert relative paths to
 * absolute paths rooted at the server root.  REPOS_ROOT is used to calculate
 * an absolute URL for repos-relative URLs. */
static svn_error_t *
canonicalize_access_file(const char **access_file, repository_t *repository,
                         const char *repos_root, apr_pool_t *pool)
{
  if (svn_path_is_url(*access_file))
    {
      const char *canonical_url;
      SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, *access_file,
                                        pool, pool));
      *access_file = canonical_url;
    }
  else if (svn_path_is_repos_relative_url(*access_file))
    {
      const char *repos_root_url;
      const char *canonical_url;

      SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_root_url, repos_root,
                                               pool));
      SVN_ERR(svn_path_resolve_repos_relative_url(access_file, *access_file,
                                                  repos_root_url, pool));
      SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, *access_file,
                                        pool, pool));
      *access_file = canonical_url;
    }
  else
    {
      *access_file = svn_dirent_internal_style(*access_file, pool);
      *access_file = svn_dirent_join(repository->base, *access_file, pool);
    }

  return SVN_NO_ERROR;
}

/* Load the authz database for the listening server based on the entries
   in the SERVER struct.

   SERVER and CONN must not be NULL. The real errors will be logged with
   SERVER and CONN but return generic errors to the client. */
static svn_error_t *
load_authz_config(repository_t *repository,
                  const char *repos_root,
                  svn_config_t *cfg,
                  svn_repos_authz_warning_func_t warning_func,
                  void *warning_baton,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  const char *authzdb_path;
  const char *groupsdb_path;
  svn_error_t *err;

  /* Read authz configuration. */
  svn_config_get(cfg, &authzdb_path, SVN_CONFIG_SECTION_GENERAL,
                 SVN_CONFIG_OPTION_AUTHZ_DB, NULL);

  svn_config_get(cfg, &groupsdb_path, SVN_CONFIG_SECTION_GENERAL,
                 SVN_CONFIG_OPTION_GROUPS_DB, NULL);

  if (authzdb_path)
    {
      const char *case_force_val;

      /* Canonicalize and add the base onto the authzdb_path (if needed). */
      err = canonicalize_access_file(&authzdb_path, repository,
                                     repos_root, scratch_pool);

      /* Same for the groupsdb_path if it is present. */
      if (groupsdb_path && !err)
        err = canonicalize_access_file(&groupsdb_path, repository,
                                       repos_root, scratch_pool);

      if (!err)
        err = svn_repos_authz_read4(&repository->authzdb, authzdb_path,
                                    groupsdb_path, TRUE, repository->repos,
                                    warning_func, warning_baton,
                                    result_pool, scratch_pool);

      if (err)
        return svn_error_create(SVN_ERR_AUTHZ_INVALID_CONFIG, err, NULL);

      /* Are we going to be case-normalizing usernames when we consult
       * this authz file? */
      svn_config_get(cfg, &case_force_val,
                     SVN_CONFIG_SECTION_GENERAL,
                     SVN_CONFIG_OPTION_FORCE_USERNAME_CASE, NULL);
      if (case_force_val)
        {
          if (strcmp(case_force_val, "upper") == 0)
            repository->username_case = CASE_FORCE_UPPER;
          else if (strcmp(case_force_val, "lower") == 0)
            repository->username_case = CASE_FORCE_LOWER;
          else
            repository->username_case = CASE_ASIS;
        }
    }
  else
    {
      repository->authzdb = NULL;
      repository->username_case = CASE_ASIS;
    }

  return SVN_NO_ERROR;
}

/* If ERROR is a AUTH* error as returned by load_pwdb_config or
 * load_authz_config, write it to SERVER's log file.
 * Return a sanitized version of ERROR.
 */
static svn_error_t *
handle_config_error(svn_error_t *error,
                    server_baton_t *server)
{
  if (   error
      && (   error->apr_err == SVN_ERR_AUTHZ_INVALID_CONFIG
          || error->apr_err == SVN_ERR_AUTHN_FAILED))
    {
      apr_status_t apr_err = error->apr_err;
      log_error(error, server);

      /* Now that we've logged the error, clear it and return a
       * nice, generic error to the user:
       * https://issues.apache.org/jira/browse/SVN-2271 */
      svn_error_clear(error);
      return svn_error_create(apr_err, NULL, NULL);
    }

  return error;
}

/* Set *FS_PATH to the portion of URL that is the path within the
   repository, if URL is inside REPOS_URL (if URL is not inside
   REPOS_URL, then error, with the effect on *FS_PATH undefined).

   If the resultant fs path would be the empty string (i.e., URL and
   REPOS_URL are the same), then set *FS_PATH to "/".

   Assume that REPOS_URL and URL are already URI-decoded. */
static svn_error_t *get_fs_path(const char *repos_url, const char *url,
                                const char **fs_path)
{
  apr_size_t len;

  len = strlen(repos_url);
  if (strncmp(url, repos_url, len) != 0)
    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                             "'%s' is not the same repository as '%s'",
                             url, repos_url);
  *fs_path = url + len;
  if (! **fs_path)
    *fs_path = "/";

  return SVN_NO_ERROR;
}

/* --- AUTHENTICATION AND AUTHORIZATION FUNCTIONS --- */

/* Convert TEXT to upper case if TO_UPPERCASE is TRUE, else
   converts it to lower case. */
static void convert_case(char *text, svn_boolean_t to_uppercase)
{
  char *c = text;
  while (*c)
    {
      *c = (char)(to_uppercase ? apr_toupper(*c) : apr_tolower(*c));
      ++c;
    }
}

/* Set *ALLOWED to TRUE if PATH is accessible in the REQUIRED mode to
   the user described in BATON according to the authz rules in BATON.
   Use POOL for temporary allocations only.  If no authz rules are
   present in BATON, grant access by default. */
static svn_error_t *authz_check_access(svn_boolean_t *allowed,
                                       const char *path,
                                       svn_repos_authz_access_t required,
                                       server_baton_t *b,
                                       apr_pool_t *pool)
{
  repository_t *repository = b->repository;
  client_info_t *client_info = b->client_info;

  /* If authz cannot be performed, grant access.  This is NOT the same
     as the default policy when authz is performed on a path with no
     rules.  In the latter case, the default is to deny access, and is
     set by svn_repos_authz_check_access. */
  if (!repository->authzdb)
    {
      *allowed = TRUE;
      return SVN_NO_ERROR;
    }

  /* If the authz request is for the empty path (ie. ""), replace it
     with the root path.  This happens because of stripping done at
     various levels in svnserve that remove the leading / on an
     absolute path. Passing such a malformed path to the authz
     routines throws them into an infinite loop and makes them miss
     ACLs. */
  if (path && *path != '/')
    path = svn_fspath__canonicalize(path, pool);

  /* If we have a username, and we've not yet used it + any username
     case normalization that might be requested to determine "the
     username we used for authz purposes", do so now. */
  if (client_info->user && (! client_info->authz_user))
    {
      char *authz_user = apr_pstrdup(b->pool, client_info->user);
      if (repository->username_case == CASE_FORCE_UPPER)
        convert_case(authz_user, TRUE);
      else if (repository->username_case == CASE_FORCE_LOWER)
        convert_case(authz_user, FALSE);

      client_info->authz_user = authz_user;
    }

  SVN_ERR(svn_repos_authz_check_access(repository->authzdb,
                                       repository->authz_repos_name,
                                       path, client_info->authz_user,
                                       required, allowed, pool));
  if (!*allowed)
    SVN_ERR(log_authz_denied(path, required, b, pool));

  return SVN_NO_ERROR;
}

/* Set *ALLOWED to TRUE if PATH is readable by the user described in
 * BATON.  Use POOL for temporary allocations only.  ROOT is not used.
 * Implements the svn_repos_authz_func_t interface.
 */
static svn_error_t *authz_check_access_cb(svn_boolean_t *allowed,
                                          svn_fs_root_t *root,
                                          const char *path,
                                          void *baton,
                                          apr_pool_t *pool)
{
  authz_baton_t *sb = baton;

  return authz_check_access(allowed, path, svn_authz_read,
                            sb->server, pool);
}

/* If authz is enabled in the specified BATON, return a read authorization
   function. Otherwise, return NULL. */
static svn_repos_authz_func_t authz_check_access_cb_func(server_baton_t *baton)
{
  if (baton->repository->authzdb)
     return authz_check_access_cb;
  return NULL;
}

/* Set *ALLOWED to TRUE if the REQUIRED access to PATH is granted,
 * according to the state in BATON.  Use POOL for temporary
 * allocations only.  ROOT is not used.  Implements the
 * svn_repos_authz_callback_t interface.
 */
static svn_error_t *authz_commit_cb(svn_repos_authz_access_t required,
                                    svn_boolean_t *allowed,
                                    svn_fs_root_t *root,
                                    const char *path,
                                    void *baton,
                                    apr_pool_t *pool)
{
  authz_baton_t *sb = baton;

  return authz_check_access(allowed, path, required, sb->server, pool);
}

/* Return the access level specified for OPTION in CFG.  If no such
 * setting exists, use DEF.  If READ_ONLY is set, unconditionally disable
 * write access.
 */
static enum access_type
get_access(svn_config_t *cfg,
           const char *option,
           const char *def,
           svn_boolean_t read_only)
{
  enum access_type result;
  const char *val;

  svn_config_get(cfg, &val, SVN_CONFIG_SECTION_GENERAL, option, def);
  result = (strcmp(val, "write") == 0 ? WRITE_ACCESS :
            strcmp(val, "read") == 0 ? READ_ACCESS : NO_ACCESS);

  return result == WRITE_ACCESS && read_only ? READ_ACCESS : result;
}

/* Set the *_ACCESS members in REPOSITORY according to the settings in
 * CFG.  If READ_ONLY is set, unconditionally disable write access.
 */
static void
set_access(repository_t *repository,
           svn_config_t *cfg,
           svn_boolean_t read_only)
{
  repository->auth_access = get_access(cfg, SVN_CONFIG_OPTION_AUTH_ACCESS,
                                       "write", read_only);
  repository->anon_access = get_access(cfg, SVN_CONFIG_OPTION_ANON_ACCESS,
                                       "read", read_only);
}

/* Return the access level for the user in B.
 */
static enum access_type
current_access(server_baton_t *b)
{
  return b->client_info->user ? b->repository->auth_access
                              : b->repository->anon_access;
}

/* Send authentication mechs for ACCESS_TYPE to the client.  If NEEDS_USERNAME
   is true, don't send anonymous mech even if that would give the desired
   access. */
static svn_error_t *send_mechs(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                               server_baton_t *b, enum access_type required,
                               svn_boolean_t needs_username)
{
  if (!needs_username && b->repository->anon_access >= required)
    SVN_ERR(svn_ra_svn__write_word(conn, pool, "ANONYMOUS"));
  if (b->client_info->tunnel_user && b->repository->auth_access >= required)
    SVN_ERR(svn_ra_svn__write_word(conn, pool, "EXTERNAL"));
  if (b->repository->pwdb && b->repository->auth_access >= required)
    SVN_ERR(svn_ra_svn__write_word(conn, pool, "CRAM-MD5"));
  return SVN_NO_ERROR;
}

/* Context for cleanup handler. */
struct cleanup_fs_access_baton
{
  svn_fs_t *fs;
  apr_pool_t *pool;
};

/* Pool cleanup handler.  Make sure fs's access_t points to NULL when
   the command pool is destroyed. */
static apr_status_t cleanup_fs_access(void *data)
{
  svn_error_t *serr;
  struct cleanup_fs_access_baton *baton = data;

  serr = svn_fs_set_access(baton->fs, NULL);
  if (serr)
    {
      apr_status_t apr_err = serr->apr_err;
      svn_error_clear(serr);
      return apr_err;
    }

  return APR_SUCCESS;
}


/* Create an svn_fs_access_t in POOL for USER and associate it with
   B's filesystem.  Also, register a cleanup handler with POOL which
   de-associates the svn_fs_access_t from B's filesystem. */
static svn_error_t *
create_fs_access(server_baton_t *b, apr_pool_t *pool)
{
  svn_fs_access_t *fs_access;
  struct cleanup_fs_access_baton *cleanup_baton;

  if (!b->client_info->user)
    return SVN_NO_ERROR;

  SVN_ERR(svn_fs_create_access(&fs_access, b->client_info->user, pool));
  SVN_ERR(svn_fs_set_access(b->repository->fs, fs_access));

  cleanup_baton = apr_pcalloc(pool, sizeof(*cleanup_baton));
  cleanup_baton->pool = pool;
  cleanup_baton->fs = b->repository->fs;
  apr_pool_cleanup_register(pool, cleanup_baton, cleanup_fs_access,
                            apr_pool_cleanup_null);

  return SVN_NO_ERROR;
}

/* Authenticate, once the client has chosen a mechanism and possibly
 * sent an initial mechanism token.  On success, set *success to true
 * and b->user to the authenticated username (or NULL for anonymous).
 * On authentication failure, report failure to the client and set
 * *success to FALSE.  On communications failure, return an error.
 * If NEEDS_USERNAME is TRUE, don't allow anonymous authentication. */
static svn_error_t *auth(svn_boolean_t *success,
                         svn_ra_svn_conn_t *conn,
                         const char *mech, const char *mecharg,
                         server_baton_t *b, enum access_type required,
                         svn_boolean_t needs_username,
                         apr_pool_t *scratch_pool)
{
  const char *user;
  *success = FALSE;

  if (b->repository->auth_access >= required
      && b->client_info->tunnel_user && strcmp(mech, "EXTERNAL") == 0)
    {
      if (*mecharg && strcmp(mecharg, b->client_info->tunnel_user) != 0)
        return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
                                       "Requested username does not match");
      b->client_info->user = b->client_info->tunnel_user;
      SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
      *success = TRUE;
      return SVN_NO_ERROR;
    }

  if (b->repository->anon_access >= required
      && strcmp(mech, "ANONYMOUS") == 0 && ! needs_username)
    {
      SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w()", "success"));
      *success = TRUE;
      return SVN_NO_ERROR;
    }

  if (b->repository->auth_access >= required
      && b->repository->pwdb && strcmp(mech, "CRAM-MD5") == 0)
    {
      SVN_ERR(svn_ra_svn_cram_server(conn, scratch_pool, b->repository->pwdb,
                                     &user, success));
      b->client_info->user = apr_pstrdup(b->pool, user);
      return SVN_NO_ERROR;
    }

  return svn_ra_svn__write_tuple(conn, scratch_pool, "w(c)", "failure",
                                "Must authenticate with listed mechanism");
}

/* Perform an authentication request using the built-in SASL implementation. */
static svn_error_t *
internal_auth_request(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                      server_baton_t *b, enum access_type required,
                      svn_boolean_t needs_username)
{
  svn_boolean_t success;
  const char *mech, *mecharg;
  apr_pool_t *iterpool;

  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
  SVN_ERR(send_mechs(conn, pool, b, required, needs_username));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)c)", b->repository->realm));

  iterpool = svn_pool_create(pool);
  do
    {
      svn_pool_clear(iterpool);

      SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "w(?c)", &mech, &mecharg));
      if (!*mech)
        break;
      SVN_ERR(auth(&success, conn, mech, mecharg, b, required,
                   needs_username, iterpool));
    }
  while (!success);
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Perform an authentication request in order to get an access level of
 * REQUIRED or higher.  Since the client may escape the authentication
 * exchange, the caller should check current_access(b) to see if
 * authentication succeeded. */
static svn_error_t *auth_request(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                 server_baton_t *b, enum access_type required,
                                 svn_boolean_t needs_username)
{
#ifdef SVN_HAVE_SASL
  if (b->repository->use_sasl)
    return cyrus_auth_request(conn, pool, b, required, needs_username);
#endif

  return internal_auth_request(conn, pool, b, required, needs_username);
}

/* Send a trivial auth notification on CONN which lists no mechanisms,
 * indicating that authentication is unnecessary.  Usually called in
 * response to invocation of a svnserve command.
 */
static svn_error_t *trivial_auth_request(svn_ra_svn_conn_t *conn,
                                         apr_pool_t *pool, server_baton_t *b)
{
  return svn_ra_svn__write_cmd_response(conn, pool, "()c", "");
}

/* Ensure that the client has the REQUIRED access by checking the
 * access directives (both blanket and per-directory) in BATON.  If
 * PATH is NULL, then only the blanket access configuration will
 * impact the result.
 *
 * If NEEDS_USERNAME is TRUE, then a lookup is only successful if the
 * user described in BATON is authenticated and, well, has a username
 * assigned to him.
 *
 * Use POOL for temporary allocations only.
 */
static svn_boolean_t lookup_access(apr_pool_t *pool,
                                   server_baton_t *baton,
                                   svn_repos_authz_access_t required,
                                   const char *path,
                                   svn_boolean_t needs_username)
{
  enum access_type req = (required & svn_authz_write) ?
    WRITE_ACCESS : READ_ACCESS;
  svn_boolean_t authorized;
  svn_error_t *err;

  /* Get authz's opinion on the access. */
  err = authz_check_access(&authorized, path, required, baton, pool);

  /* If an error made lookup fail, deny access. */
  if (err)
    {
      log_error(err, baton);
      svn_error_clear(err);
      return FALSE;
    }

  /* If the required access is blanket-granted AND granted by authz
     AND we already have a username if one is required, then the
     lookup has succeeded. */
  if (current_access(baton) >= req
      && authorized
      && (! needs_username || baton->client_info->user))
    return TRUE;

  return FALSE;
}

/* Check that the client has the REQUIRED access by consulting the
 * authentication and authorization states stored in BATON.  If the
 * client does not have the required access credentials, attempt to
 * authenticate the client to get that access, using CONN for
 * communication.
 *
 * This function is supposed to be called to handle the authentication
 * half of a standard svn protocol reply.  If an error is returned, it
 * probably means that the server can terminate the client connection
 * with an apologetic error, as it implies an authentication failure.
 *
 * PATH and NEEDS_USERNAME are passed along to lookup_access, their
 * behaviour is documented there.
 */
static svn_error_t *must_have_access(svn_ra_svn_conn_t *conn,
                                     apr_pool_t *pool,
                                     server_baton_t *b,
                                     svn_repos_authz_access_t required,
                                     const char *path,
                                     svn_boolean_t needs_username)
{
  enum access_type req = (required & svn_authz_write) ?
    WRITE_ACCESS : READ_ACCESS;

  /* See whether the user already has the required access.  If so,
     nothing needs to be done.  Create the FS access and send a
     trivial auth request. */
  if (lookup_access(pool, b, required, path, needs_username))
    {
      SVN_ERR(create_fs_access(b, pool));
      return trivial_auth_request(conn, pool, b);
    }

  /* If the required blanket access can be obtained by authenticating,
     try that.  Unfortunately, we can't tell until after
     authentication whether authz will work or not.  We force
     requiring a username because we need one to be able to check
     authz configuration again with a different user credentials than
     the first time round. */
  if (b->client_info->user == NULL
      && b->repository->auth_access >= req
      && (b->client_info->tunnel_user || b->repository->pwdb
          || b->repository->use_sasl))
    SVN_ERR(auth_request(conn, pool, b, req, TRUE));

  /* Now that an authentication has been done get the new take of
     authz on the request. */
  if (! lookup_access(pool, b, required, path, needs_username))
    return svn_error_create(SVN_ERR_RA_SVN_CMD_ERR,
                            error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED,
                                                 NULL, NULL, b),
                            NULL);

  /* Else, access is granted, and there is much rejoicing. */
  SVN_ERR(create_fs_access(b, pool));

  return SVN_NO_ERROR;
}

/* --- REPORTER COMMAND SET --- */

/* To allow for pipelining, reporter commands have no responses.  If we
 * get an error, we ignore all subsequent reporter commands and return
 * the error finish_report, to be handled by the calling command.
 */

static svn_error_t *set_path(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                             svn_ra_svn__list_t *params, void *baton)
{
  report_driver_baton_t *b = baton;
  const char *path, *lock_token, *depth_word, *canonical_relpath;
  svn_revnum_t rev;
  /* Default to infinity, for old clients that don't send depth. */
  svn_depth_t depth = svn_depth_infinity;
  svn_boolean_t start_empty;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "crb?(?c)?w",
                                  &path, &rev, &start_empty, &lock_token,
                                  &depth_word));
  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_relpath, NULL, path,
                                        pool, pool));
  path = canonical_relpath;
  if (b->from_rev && strcmp(path, "") == 0)
    *b->from_rev = rev;
  if (!b->err)
    b->err = svn_repos_set_path3(b->report_baton, path, rev, depth,
                                 start_empty, lock_token, pool);
  b->entry_counter++;
  if (!start_empty)
    b->only_empty_entries = FALSE;
  return SVN_NO_ERROR;
}

static svn_error_t *delete_path(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                svn_ra_svn__list_t *params, void *baton)
{
  report_driver_baton_t *b = baton;
  const char *path, *canonical_relpath;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &path));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_relpath, NULL, path,
                                        pool, pool));
  path = canonical_relpath;
  if (!b->err)
    b->err = svn_repos_delete_path(b->report_baton, path, pool);
  return SVN_NO_ERROR;
}

static svn_error_t *link_path(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                              svn_ra_svn__list_t *params, void *baton)
{
  report_driver_baton_t *b = baton;
  const char *path, *url, *lock_token, *fs_path, *depth_word, *canonical_url;
  const char *canonical_path;
  svn_revnum_t rev;
  svn_boolean_t start_empty;
  /* Default to infinity, for old clients that don't send depth. */
  svn_depth_t depth = svn_depth_infinity;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "ccrb?(?c)?w",
                                 &path, &url, &rev, &start_empty,
                                 &lock_token, &depth_word));

  /* ### WHAT?!  The link path is an absolute URL?!  Didn't see that
     coming...   -- cmpilato  */

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  path = canonical_path;
  SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, url, pool, pool));
  url = canonical_url;
  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  if (!b->err)
    b->err = get_fs_path(svn_path_uri_decode(b->repos_url, pool),
                         svn_path_uri_decode(url, pool),
                         &fs_path);
  if (!b->err)
    b->err = svn_repos_link_path3(b->report_baton, path, fs_path, rev,
                                  depth, start_empty, lock_token, pool);
  b->entry_counter++;
  return SVN_NO_ERROR;
}

static svn_error_t *finish_report(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                  svn_ra_svn__list_t *params, void *baton)
{
  report_driver_baton_t *b = baton;

  /* No arguments to parse. */
  SVN_ERR(trivial_auth_request(conn, pool, b->sb));
  if (!b->err)
    b->err = svn_repos_finish_report(b->report_baton, pool);
  return SVN_NO_ERROR;
}

static svn_error_t *
abort_report(svn_ra_svn_conn_t *conn,
             apr_pool_t *pool,
             svn_ra_svn__list_t *params,
             void *baton)
{
  report_driver_baton_t *b = baton;

  /* No arguments to parse. */
  svn_error_clear(svn_repos_abort_report(b->report_baton, pool));
  return SVN_NO_ERROR;
}

static const svn_ra_svn__cmd_entry_t report_commands[] = {
  { "set-path",      set_path },
  { "delete-path",   delete_path },
  { "link-path",     link_path },
  { "finish-report", finish_report, NULL, TRUE },
  { "abort-report",  abort_report,  NULL, TRUE },
  { NULL }
};

/* Accept a report from the client, drive the network editor with the
 * result, and then write an empty command response.  If there is a
 * non-protocol failure, accept_report will abort the edit and return
 * a command error to be reported by handle_commands().
 *
 * If only_empty_entry is not NULL and the report contains only one
 * item, and that item is empty, set *only_empty_entry to TRUE, else
 * set it to FALSE.
 *
 * If from_rev is not NULL, set *from_rev to the revision number from
 * the set-path on ""; if somehow set-path "" never happens, set
 * *from_rev to SVN_INVALID_REVNUM.
 */
static svn_error_t *accept_report(svn_boolean_t *only_empty_entry,
                                  svn_revnum_t *from_rev,
                                  svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                  server_baton_t *b, svn_revnum_t rev,
                                  const char *target, const char *tgt_path,
                                  svn_boolean_t text_deltas,
                                  svn_depth_t depth,
                                  svn_boolean_t send_copyfrom_args,
                                  svn_boolean_t ignore_ancestry)
{
  const svn_delta_editor_t *editor;
  void *edit_baton, *report_baton;
  report_driver_baton_t rb;
  svn_error_t *err;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  /* Make an svn_repos report baton.  Tell it to drive the network editor
   * when the report is complete. */
  svn_ra_svn_get_editor(&editor, &edit_baton, conn, pool, NULL, NULL);
  SVN_CMD_ERR(svn_repos_begin_report3(&report_baton, rev,
                                      b->repository->repos,
                                      b->repository->fs_path->data, target,
                                      tgt_path, text_deltas, depth,
                                      ignore_ancestry, send_copyfrom_args,
                                      editor, edit_baton,
                                      authz_check_access_cb_func(b),
                                      &ab, svn_ra_svn_zero_copy_limit(conn),
                                      pool));

  rb.sb = b;
  rb.repos_url = svn_path_uri_decode(b->repository->repos_url, pool);
  rb.report_baton = report_baton;
  rb.err = NULL;
  rb.entry_counter = 0;
  rb.only_empty_entries = TRUE;
  rb.from_rev = from_rev;
  if (from_rev)
    *from_rev = SVN_INVALID_REVNUM;
  err = svn_ra_svn__handle_commands2(conn, pool, report_commands, &rb, TRUE);
  if (err)
    {
      /* Network or protocol error while handling commands. */
      svn_error_clear(rb.err);
      return err;
    }
  else if (rb.err)
    {
      /* Some failure during the reporting or editing operations. */
      SVN_CMD_ERR(rb.err);
    }
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  if (only_empty_entry)
    *only_empty_entry = rb.entry_counter == 1 && rb.only_empty_entries;

  return SVN_NO_ERROR;
}

/* --- MAIN COMMAND SET --- */

/* Write out a list of property diffs.  PROPDIFFS is an array of svn_prop_t
 * values. */
static svn_error_t *write_prop_diffs(svn_ra_svn_conn_t *conn,
                                     apr_pool_t *pool,
                                     const apr_array_header_t *propdiffs)
{
  int i;

  for (i = 0; i < propdiffs->nelts; ++i)
    {
      const svn_prop_t *prop = &APR_ARRAY_IDX(propdiffs, i, svn_prop_t);

      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "c(?s)",
                                      prop->name, prop->value));
    }

  return SVN_NO_ERROR;
}

/* Write out a lock to the client. */
static svn_error_t *write_lock(svn_ra_svn_conn_t *conn,
                               apr_pool_t *pool,
                               const svn_lock_t *lock)
{
  const char *cdate, *edate;

  cdate = svn_time_to_cstring(lock->creation_date, pool);
  edate = lock->expiration_date
    ? svn_time_to_cstring(lock->expiration_date, pool) : NULL;
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "ccc(?c)c(?c)", lock->path,
                                  lock->token, lock->owner, lock->comment,
                                  cdate, edate));

  return SVN_NO_ERROR;
}

/* ### This really belongs in libsvn_repos. */
/* Get the explicit properties and/or inherited properties for a PATH in
   ROOT, with hardcoded committed-info values. */
static svn_error_t *
get_props(apr_hash_t **props,
          apr_array_header_t **iprops,
          authz_baton_t *b,
          svn_fs_root_t *root,
          const char *path,
          apr_pool_t *pool)
{
  /* Get the explicit properties. */
  if (props)
    {
      svn_string_t *str;
      svn_revnum_t crev;
      const char *cdate, *cauthor, *uuid;

      SVN_ERR(svn_fs_node_proplist(props, root, path, pool));

      /* Hardcode the values for the committed revision, date, and author. */
      SVN_ERR(svn_repos_get_committed_info(&crev, &cdate, &cauthor, root,
                                           path, pool));
      str = svn_string_createf(pool, "%ld", crev);
      svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_REV, str);
      str = (cdate) ? svn_string_create(cdate, pool) : NULL;
      svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_DATE, str);
      str = (cauthor) ? svn_string_create(cauthor, pool) : NULL;
      svn_hash_sets(*props, SVN_PROP_ENTRY_LAST_AUTHOR, str);

      /* Hardcode the values for the UUID. */
      SVN_ERR(svn_fs_get_uuid(svn_fs_root_fs(root), &uuid, pool));
      str = (uuid) ? svn_string_create(uuid, pool) : NULL;
      svn_hash_sets(*props, SVN_PROP_ENTRY_UUID, str);
    }

  /* Get any inherited properties the user is authorized to. */
  if (iprops)
    {
      SVN_ERR(svn_repos_fs_get_inherited_props(
                iprops, root, path, NULL,
                authz_check_access_cb_func(b->server),
                b, pool, pool));
    }

  return SVN_NO_ERROR;
}

/* Set BATON->FS_PATH for the repository URL found in PARAMS. */
static svn_error_t *
reparent(svn_ra_svn_conn_t *conn,
         apr_pool_t *pool,
         svn_ra_svn__list_t *params,
         void *baton)
{
  server_baton_t *b = baton;
  const char *url, *canonical_url;
  const char *fs_path;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &url));
  SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, url, pool, pool));
  url = canonical_url;
  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(get_fs_path(svn_path_uri_decode(b->repository->repos_url, pool),
                          svn_path_uri_decode(url, pool),
                          &fs_path));
  SVN_ERR(log_command(b, conn, pool, "%s", svn_log__reparent(fs_path, pool)));
  svn_stringbuf_set(b->repository->fs_path, fs_path);
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));
  return SVN_NO_ERROR;
}

static svn_error_t *
get_latest_rev(svn_ra_svn_conn_t *conn,
               apr_pool_t *pool,
               svn_ra_svn__list_t *params,
               void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;

  SVN_ERR(log_command(b, conn, pool, "get-latest-rev"));

  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "r", rev));
  return SVN_NO_ERROR;
}

static svn_error_t *
get_dated_rev(svn_ra_svn_conn_t *conn,
              apr_pool_t *pool,
              svn_ra_svn__list_t *params,
              void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  apr_time_t tm;
  const char *timestr;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &timestr));
  SVN_ERR(log_command(b, conn, pool, "get-dated-rev %s", timestr));

  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(svn_time_from_cstring(&tm, timestr, pool));
  SVN_CMD_ERR(svn_repos_dated_revision(&rev, b->repository->repos, tm, pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "r", rev));
  return SVN_NO_ERROR;
}

/* Common logic for change_rev_prop() and change_rev_prop2(). */
static svn_error_t *do_change_rev_prop(svn_ra_svn_conn_t *conn,
                                       server_baton_t *b,
                                       svn_revnum_t rev,
                                       const char *name,
                                       const svn_string_t *const *old_value_p,
                                       const svn_string_t *value,
                                       apr_pool_t *pool)
{
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, FALSE));
  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__change_rev_prop(rev, name, pool)));
  SVN_CMD_ERR(svn_repos_fs_change_rev_prop4(b->repository->repos, rev,
                                            b->client_info->user,
                                            name, old_value_p, value,
                                            TRUE, TRUE,
                                            authz_check_access_cb_func(b), &ab,
                                            pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
change_rev_prop2(svn_ra_svn_conn_t *conn,
                 apr_pool_t *pool,
                 svn_ra_svn__list_t *params,
                 void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *name;
  svn_string_t *value;
  const svn_string_t *const *old_value_p;
  svn_string_t *old_value;
  svn_boolean_t dont_care;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "rc(?s)(b?s)",
                                  &rev, &name, &value,
                                  &dont_care, &old_value));

  /* Argument parsing. */
  if (dont_care)
    old_value_p = NULL;
  else
    old_value_p = (const svn_string_t *const *)&old_value;

  /* Input validation. */
  if (dont_care && old_value)
    {
      svn_error_t *err;
      err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                             "'previous-value' and 'dont-care' cannot both be "
                             "set in 'change-rev-prop2' request");
      return log_fail_and_flush(err, b, conn, pool);
    }

  /* Do it. */
  SVN_ERR(do_change_rev_prop(conn, b, rev, name, old_value_p, value, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
change_rev_prop(svn_ra_svn_conn_t *conn,
                apr_pool_t *pool,
                svn_ra_svn__list_t *params,
                void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *name;
  svn_string_t *value;

  /* Because the revprop value was at one time mandatory, the usual
     optional element pattern "(?s)" isn't used. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "rc?s", &rev, &name, &value));

  SVN_ERR(do_change_rev_prop(conn, b, rev, name, NULL, value, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
rev_proplist(svn_ra_svn_conn_t *conn,
             apr_pool_t *pool,
             svn_ra_svn__list_t *params,
             void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  apr_hash_t *props;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "r", &rev));
  SVN_ERR(log_command(b, conn, pool, "%s", svn_log__rev_proplist(rev, pool)));

  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(svn_repos_fs_revision_proplist(&props, b->repository->repos,
                                             rev,
                                             authz_check_access_cb_func(b),
                                             &ab, pool));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
  SVN_ERR(svn_ra_svn__write_proplist(conn, pool, props));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));
  return SVN_NO_ERROR;
}

static svn_error_t *
rev_prop(svn_ra_svn_conn_t *conn,
         apr_pool_t *pool,
         svn_ra_svn__list_t *params,
         void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *name;
  svn_string_t *value;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "rc", &rev, &name));
  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__rev_prop(rev, name, pool)));

  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(svn_repos_fs_revision_prop(&value, b->repository->repos, rev,
                                         name, authz_check_access_cb_func(b),
                                         &ab, pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "(?s)", value));
  return SVN_NO_ERROR;
}

static svn_error_t *commit_done(const svn_commit_info_t *commit_info,
                                void *baton, apr_pool_t *pool)
{
  commit_callback_baton_t *ccb = baton;

  *ccb->new_rev = commit_info->revision;
  *ccb->date = commit_info->date
    ? apr_pstrdup(ccb->pool, commit_info->date): NULL;
  *ccb->author = commit_info->author
    ? apr_pstrdup(ccb->pool, commit_info->author) : NULL;
  *ccb->post_commit_err = commit_info->post_commit_err
    ? apr_pstrdup(ccb->pool, commit_info->post_commit_err) : NULL;
  return SVN_NO_ERROR;
}

/* Add the LOCK_TOKENS (if any) to the filesystem access context,
 * checking path authorizations using the state in SB as we go.
 * LOCK_TOKENS is an array of svn_ra_svn__item_t structs.  Return a
 * client error if LOCK_TOKENS is not a list of lists.  If a lock
 * violates the authz configuration, return SVN_ERR_RA_NOT_AUTHORIZED
 * to the client.  Use POOL for temporary allocations only.
 */
static svn_error_t *
add_lock_tokens(const svn_ra_svn__list_t *lock_tokens,
                server_baton_t *sb,
                apr_pool_t *pool)
{
  const char *canonical_path;
  int i;
  svn_fs_access_t *fs_access;

  SVN_ERR(svn_fs_get_access(&fs_access, sb->repository->fs));

  /* If there is no access context, nowhere to add the tokens. */
  if (! fs_access)
    return SVN_NO_ERROR;

  for (i = 0; i < lock_tokens->nelts; ++i)
    {
      const char *path, *token, *full_path;
      svn_ra_svn__item_t *path_item, *token_item;
      svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(lock_tokens, i);
      if (item->kind != SVN_RA_SVN_LIST)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Lock tokens aren't a list of lists");

      path_item = &SVN_RA_SVN__LIST_ITEM(&item->u.list, 0);
      if (path_item->kind != SVN_RA_SVN_STRING)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Lock path isn't a string");

      token_item = &SVN_RA_SVN__LIST_ITEM(&item->u.list, 1);
      if (token_item->kind != SVN_RA_SVN_STRING)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Lock token isn't a string");

      path = path_item->u.string.data;
      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            pool, pool));
      full_path = svn_fspath__join(sb->repository->fs_path->data,
                                   canonical_path, pool);

      if (! lookup_access(pool, sb, svn_authz_write, full_path, TRUE))
        return error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED, NULL, NULL,
                                    sb);

      token = token_item->u.string.data;
      SVN_ERR(svn_fs_access_add_lock_token2(fs_access, path, token));
    }

  return SVN_NO_ERROR;
}

/* Implements svn_fs_lock_callback_t. */
static svn_error_t *
lock_cb(void *baton,
        const char *path,
        const svn_lock_t *lock,
        svn_error_t *fs_err,
        apr_pool_t *pool)
{
  server_baton_t *sb = baton;

  log_error(fs_err, sb);

  return SVN_NO_ERROR;
}

/* Unlock the paths with lock tokens in LOCK_TOKENS, ignoring any errors.
   LOCK_TOKENS contains svn_ra_svn__item_t elements, assumed to be lists. */
static svn_error_t *
unlock_paths(const svn_ra_svn__list_t *lock_tokens,
             server_baton_t *sb,
             apr_pool_t *pool)
{
  int i;
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_hash_t *targets = apr_hash_make(subpool);
  const char *canonical_path;
  svn_error_t *err;

  for (i = 0; i < lock_tokens->nelts; ++i)
    {
      svn_ra_svn__item_t *item, *path_item, *token_item;
      const char *path, *token, *full_path;

      item = &SVN_RA_SVN__LIST_ITEM(lock_tokens, i);
      path_item = &SVN_RA_SVN__LIST_ITEM(&item->u.list, 0);
      token_item = &SVN_RA_SVN__LIST_ITEM(&item->u.list, 1);

      path = path_item->u.string.data;
      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            subpool, subpool));
      full_path = svn_fspath__join(sb->repository->fs_path->data,
                                   canonical_path, subpool);
      token = token_item->u.string.data;
      svn_hash_sets(targets, full_path, token);
    }


  /* The lock may have become defunct after the commit, so ignore such
     errors. */
  err = svn_repos_fs_unlock_many(sb->repository->repos, targets, FALSE,
                                 lock_cb, sb, subpool, subpool);
  log_error(err, sb);
  svn_error_clear(err);

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}

static svn_error_t *
commit(svn_ra_svn_conn_t *conn,
       apr_pool_t *pool,
       svn_ra_svn__list_t *params,
       void *baton)
{
  server_baton_t *b = baton;
  const char *log_msg,
             *date = NULL,
             *author = NULL,
             *post_commit_err = NULL;
  svn_ra_svn__list_t *lock_tokens;
  svn_boolean_t keep_locks;
  svn_ra_svn__list_t *revprop_list;
  apr_hash_t *revprop_table;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  svn_boolean_t aborted;
  commit_callback_baton_t ccb;
  svn_revnum_t new_rev;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  if (params->nelts == 1)
    {
      /* Clients before 1.2 don't send lock-tokens, keep-locks,
         and rev-props fields. */
      SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &log_msg));
      lock_tokens = NULL;
      keep_locks = TRUE;
      revprop_list = NULL;
    }
  else
    {
      /* Clients before 1.5 don't send the rev-props field. */
      SVN_ERR(svn_ra_svn__parse_tuple(params, "clb?l", &log_msg,
                                      &lock_tokens, &keep_locks,
                                      &revprop_list));
    }

  /* The handling for locks is a little problematic, because the
     protocol won't let us send several auth requests once one has
     succeeded.  So we request write access and a username before
     adding tokens (if we have any), and subsequently fail if a lock
     violates authz. */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write,
                           NULL,
                           (lock_tokens && lock_tokens->nelts)));

  /* Authorize the lock tokens and give them to the FS if we got
     any. */
  if (lock_tokens && lock_tokens->nelts)
    SVN_CMD_ERR(add_lock_tokens(lock_tokens, b, pool));

  /* Ignore LOG_MSG, per the protocol.  See ra_svn_commit(). */
  if (revprop_list)
    SVN_ERR(svn_ra_svn__parse_proplist(revprop_list, pool, &revprop_table));
  else
    {
      revprop_table = apr_hash_make(pool);
      svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
                    svn_string_create(log_msg, pool));
    }

  /* Get author from the baton, making sure clients can't circumvent
     the authentication via the revision props. */
  svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
                b->client_info->user
                   ? svn_string_create(b->client_info->user, pool)
                   : NULL);

  ccb.pool = pool;
  ccb.new_rev = &new_rev;
  ccb.date = &date;
  ccb.author = &author;
  ccb.post_commit_err = &post_commit_err;
  /* ### Note that svn_repos_get_commit_editor5 actually wants a decoded URL. */
  SVN_CMD_ERR(svn_repos_get_commit_editor5
              (&editor, &edit_baton, b->repository->repos, NULL,
               svn_path_uri_decode(b->repository->repos_url, pool),
               b->repository->fs_path->data, revprop_table,
               commit_done, &ccb,
               authz_commit_cb, &ab, pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));
  SVN_ERR(svn_ra_svn_drive_editor2(conn, pool, editor, edit_baton,
                                   &aborted, FALSE));
  if (!aborted)
    {
      SVN_ERR(log_command(b, conn, pool, "%s",
                          svn_log__commit(new_rev, pool)));
      SVN_ERR(trivial_auth_request(conn, pool, b));

      /* In tunnel mode, deltify before answering the client, because
         answering may cause the client to terminate the connection
         and thus kill the server.  But otherwise, deltify after
         answering the client, to avoid user-visible delay. */

      if (b->client_info->tunnel)
        SVN_ERR(svn_fs_deltify_revision(b->repository->fs, new_rev, pool));

      /* Unlock the paths. */
      if (! keep_locks && lock_tokens && lock_tokens->nelts)
        SVN_ERR(unlock_paths(lock_tokens, b, pool));

      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "r(?c)(?c)(?c)",
                                      new_rev, date, author, post_commit_err));

      if (! b->client_info->tunnel)
        SVN_ERR(svn_fs_deltify_revision(b->repository->fs, new_rev, pool));
    }
  return SVN_NO_ERROR;
}

static svn_error_t *
get_file(svn_ra_svn_conn_t *conn,
         apr_pool_t *pool,
         svn_ra_svn__list_t *params,
         void *baton)
{
  server_baton_t *b = baton;
  const char *path, *full_path, *hex_digest, *canonical_path;
  svn_revnum_t rev;
  svn_fs_root_t *root;
  svn_stream_t *contents;
  apr_hash_t *props = NULL;
  apr_array_header_t *inherited_props;
  svn_string_t write_str;
  char buf[4096];
  apr_size_t len;
  svn_boolean_t want_props, want_contents;
  apr_uint64_t wants_inherited_props;
  svn_checksum_t *checksum;
  svn_error_t *err, *write_err;
  int i;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  /* Parse arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?B", &path, &rev,
                                  &want_props, &want_contents,
                                  &wants_inherited_props));

  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
    wants_inherited_props = FALSE;

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path, pool,
                                        pool));
  full_path = svn_fspath__join(b->repository->fs_path->data, canonical_path,
                               pool);

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_file(full_path, rev,
                                        want_contents, want_props, pool)));

  /* Fetch the properties and a stream for the contents. */
  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));
  SVN_CMD_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, root,
                                   full_path, TRUE, pool));
  hex_digest = svn_checksum_to_cstring_display(checksum, pool);

  /* Fetch the file's explicit and/or inherited properties if
     requested.  Although the wants-iprops boolean was added to the
     protocol in 1.8 a standard 1.8 client never requests iprops. */
  if (want_props || wants_inherited_props)
    SVN_CMD_ERR(get_props(want_props ? &props : NULL,
                          wants_inherited_props ? &inherited_props : NULL,
                          &ab, root, full_path,
                          pool));
  if (want_contents)
    SVN_CMD_ERR(svn_fs_file_contents(&contents, root, full_path, pool));

  /* Send successful command response with revision and props. */
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((?c)r(!", "success",
                                  hex_digest, rev));
  SVN_ERR(svn_ra_svn__write_proplist(conn, pool, props));

  if (wants_inherited_props)
    {
      apr_pool_t *iterpool = svn_pool_create(pool);

      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)(?!"));
      for (i = 0; i < inherited_props->nelts; i++)
        {
          svn_prop_inherited_item_t *iprop =
            APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);

          svn_pool_clear(iterpool);
          SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!(c(!",
                                          iprop->path_or_url));
          SVN_ERR(svn_ra_svn__write_proplist(conn, iterpool, iprop->prop_hash));
          SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!))!",
                                          iprop->path_or_url));
        }
      svn_pool_destroy(iterpool);
    }

  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));

  /* Now send the file's contents. */
  if (want_contents)
    {
      err = SVN_NO_ERROR;
      while (1)
        {
          len = sizeof(buf);
          err = svn_stream_read_full(contents, buf, &len);
          if (err)
            break;
          if (len > 0)
            {
              write_str.data = buf;
              write_str.len = len;
              SVN_ERR(svn_ra_svn__write_string(conn, pool, &write_str));
            }
          if (len < sizeof(buf))
            {
              err = svn_stream_close(contents);
              break;
            }
        }
      write_err = svn_ra_svn__write_cstring(conn, pool, "");
      if (write_err)
        {
          svn_error_clear(err);
          return write_err;
        }
      SVN_CMD_ERR(err);
      SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));
    }

  return SVN_NO_ERROR;
}

/* Translate all the words in DIRENT_FIELDS_LIST into the flags in
 * DIRENT_FIELDS_P.  If DIRENT_FIELDS_LIST is NULL, set all flags. */
static svn_error_t *
parse_dirent_fields(apr_uint32_t *dirent_fields_p,
                    svn_ra_svn__list_t *dirent_fields_list)
{
  static const svn_string_t str_kind
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_KIND);
  static const svn_string_t str_size
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_SIZE);
  static const svn_string_t str_has_props
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_HAS_PROPS);
  static const svn_string_t str_created_rev
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_CREATED_REV);
  static const svn_string_t str_time
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_TIME);
  static const svn_string_t str_last_author
    = SVN__STATIC_STRING(SVN_RA_SVN_DIRENT_LAST_AUTHOR);

  apr_uint32_t dirent_fields;

  if (! dirent_fields_list)
    {
      dirent_fields = SVN_DIRENT_ALL;
    }
  else
    {
      int i;
      dirent_fields = 0;

      for (i = 0; i < dirent_fields_list->nelts; ++i)
        {
          svn_ra_svn__item_t *elt
            = &SVN_RA_SVN__LIST_ITEM(dirent_fields_list, i);

          if (elt->kind != SVN_RA_SVN_WORD)
            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                    "Dirent field not a word");

          if (svn_string_compare(&str_kind, &elt->u.word))
            dirent_fields |= SVN_DIRENT_KIND;
          else if (svn_string_compare(&str_size, &elt->u.word))
            dirent_fields |= SVN_DIRENT_SIZE;
          else if (svn_string_compare(&str_has_props, &elt->u.word))
            dirent_fields |= SVN_DIRENT_HAS_PROPS;
          else if (svn_string_compare(&str_created_rev, &elt->u.word))
            dirent_fields |= SVN_DIRENT_CREATED_REV;
          else if (svn_string_compare(&str_time, &elt->u.word))
            dirent_fields |= SVN_DIRENT_TIME;
          else if (svn_string_compare(&str_last_author, &elt->u.word))
            dirent_fields |= SVN_DIRENT_LAST_AUTHOR;
        }
    }

  *dirent_fields_p = dirent_fields;
  return SVN_NO_ERROR;
}

static svn_error_t *
get_dir(svn_ra_svn_conn_t *conn,
        apr_pool_t *pool,
        svn_ra_svn__list_t *params,
        void *baton)
{
  server_baton_t *b = baton;
  const char *path, *full_path, *canonical_path;
  svn_revnum_t rev;
  apr_hash_t *entries, *props = NULL;
  apr_array_header_t *inherited_props;
  apr_hash_index_t *hi;
  svn_fs_root_t *root;
  apr_pool_t *subpool;
  svn_boolean_t want_props, want_contents;
  apr_uint64_t wants_inherited_props;
  apr_uint32_t dirent_fields;
  svn_ra_svn__list_t *dirent_fields_list = NULL;
  int i;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)bb?l?B", &path, &rev,
                                  &want_props, &want_contents,
                                  &dirent_fields_list,
                                  &wants_inherited_props));

  if (wants_inherited_props == SVN_RA_SVN_UNSPECIFIED_NUMBER)
    wants_inherited_props = FALSE;

  SVN_ERR(parse_dirent_fields(&dirent_fields, dirent_fields_list));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data, canonical_path,
                               pool);

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_dir(full_path, rev,
                                       want_contents, want_props,
                                       dirent_fields, pool)));

  /* Fetch the root of the appropriate revision. */
  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));

  /* Fetch the directory's explicit and/or inherited properties if
     requested.  Although the wants-iprops boolean was added to the
     protocol in 1.8 a standard 1.8 client never requests iprops. */
  if (want_props || wants_inherited_props)
    SVN_CMD_ERR(get_props(want_props ? &props : NULL,
                          wants_inherited_props ? &inherited_props : NULL,
                          &ab, root, full_path,
                          pool));

  /* Fetch the directories' entries before starting the response, to allow
     proper error handling in cases like when FULL_PATH doesn't exist */
  if (want_contents)
      SVN_CMD_ERR(svn_fs_dir_entries(&entries, root, full_path, pool));

  /* Begin response ... */
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(r(!", "success", rev));
  SVN_ERR(svn_ra_svn__write_proplist(conn, pool, props));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)(!"));

  /* Fetch the directory entries if requested and send them immediately. */
  if (want_contents)
    {
      /* Use epoch for a placeholder for a missing date.  */
      const char *missing_date = svn_time_to_cstring(0, pool);

      /* Transform the hash table's FS entries into dirents.  This probably
       * belongs in libsvn_repos. */
      subpool = svn_pool_create(pool);
      for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
        {
          const char *name = apr_hash_this_key(hi);
          svn_fs_dirent_t *fsent = apr_hash_this_val(hi);
          const char *file_path;

          /* The fields in the entry tuple.  */
          svn_node_kind_t entry_kind = svn_node_none;
          svn_filesize_t entry_size = 0;
          svn_boolean_t has_props = FALSE;
          /* If 'created rev' was not requested, send 0.  We can't use
           * SVN_INVALID_REVNUM as the tuple field is not optional.
           * See the email thread on dev@, 2012-03-28, subject
           * "buildbot failure in ASF Buildbot on svn-slik-w2k3-x64-ra",
           * <http://svn.haxx.se/dev/archive-2012-03/0655.shtml>. */
          svn_revnum_t created_rev = 0;
          const char *cdate = NULL;
          const char *last_author = NULL;

          svn_pool_clear(subpool);

          file_path = svn_fspath__join(full_path, name, subpool);
          if (! lookup_access(subpool, b, svn_authz_read, file_path, FALSE))
            continue;

          if (dirent_fields & SVN_DIRENT_KIND)
              entry_kind = fsent->kind;

          if (dirent_fields & SVN_DIRENT_SIZE)
              if (fsent->kind != svn_node_dir)
                SVN_CMD_ERR(svn_fs_file_length(&entry_size, root, file_path,
                                               subpool));

          if (dirent_fields & SVN_DIRENT_HAS_PROPS)
            {
              /* has_props */
              SVN_CMD_ERR(svn_fs_node_has_props(&has_props, root, file_path,
                                               subpool));
            }

          if ((dirent_fields & SVN_DIRENT_LAST_AUTHOR)
              || (dirent_fields & SVN_DIRENT_TIME)
              || (dirent_fields & SVN_DIRENT_CREATED_REV))
            {
              /* created_rev, last_author, time */
              SVN_CMD_ERR(svn_repos_get_committed_info(&created_rev,
                                                       &cdate,
                                                       &last_author,
                                                       root,
                                                       file_path,
                                                       subpool));
            }

          /* The client does not properly handle a missing CDATE. For
             interoperability purposes, we must fill in some junk.

             See libsvn_ra_svn/client.c:ra_svn_get_dir()  */
          if (cdate == NULL)
            cdate = missing_date;

          /* Send the entry. */
          SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "cwnbr(?c)(?c)", name,
                                          svn_node_kind_to_word(entry_kind),
                                          (apr_uint64_t) entry_size,
                                          has_props, created_rev,
                                          cdate, last_author));
        }
      svn_pool_destroy(subpool);
    }

  if (wants_inherited_props)
    {
      apr_pool_t *iterpool = svn_pool_create(pool);

      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)(?!"));
      for (i = 0; i < inherited_props->nelts; i++)
        {
          svn_prop_inherited_item_t *iprop =
            APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);

          svn_pool_clear(iterpool);
          SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!(c(!",
                                          iprop->path_or_url));
          SVN_ERR(svn_ra_svn__write_proplist(conn, iterpool, iprop->prop_hash));
          SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!))!",
                                          iprop->path_or_url));
        }
      svn_pool_destroy(iterpool);
    }

  /* Finish response. */
  return svn_ra_svn__write_tuple(conn, pool, "!))");
}

static svn_error_t *
update(svn_ra_svn_conn_t *conn,
       apr_pool_t *pool,
       svn_ra_svn__list_t *params,
       void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *target, *full_path, *depth_word, *canonical_target;
  svn_boolean_t recurse;
  svn_tristate_t send_copyfrom_args; /* Optional; default FALSE */
  svn_tristate_t ignore_ancestry; /* Optional; default FALSE */
  /* Default to unknown.  Old clients won't send depth, but we'll
     handle that by converting recurse if necessary. */
  svn_depth_t depth = svn_depth_unknown;
  svn_boolean_t is_checkout;

  /* Parse the arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cb?w3?3", &rev, &target,
                                  &recurse, &depth_word,
                                  &send_copyfrom_args, &ignore_ancestry));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_target, NULL, target,
                                        pool, pool));
  target = canonical_target;

  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  else
    depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  full_path = svn_fspath__join(b->repository->fs_path->data, target, pool);
  /* Check authorization and authenticate the user if necessary. */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read, full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(accept_report(&is_checkout, NULL,
                        conn, pool, b, rev, target, NULL, TRUE,
                        depth,
                        (send_copyfrom_args == svn_tristate_true),
                        (ignore_ancestry == svn_tristate_true)));
  if (is_checkout)
    {
      SVN_ERR(log_command(b, conn, pool, "%s",
                          svn_log__checkout(full_path, rev,
                                            depth, pool)));
    }
  else
    {
      SVN_ERR(log_command(b, conn, pool, "%s",
                          svn_log__update(full_path, rev, depth,
                                          (send_copyfrom_args
                                           == svn_tristate_true),
                                          pool)));
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
switch_cmd(svn_ra_svn_conn_t *conn,
           apr_pool_t *pool,
           svn_ra_svn__list_t *params,
           void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *target, *depth_word;
  const char *switch_url, *switch_path, *canonical_url, *canonical_target;
  svn_boolean_t recurse;
  /* Default to unknown.  Old clients won't send depth, but we'll
     handle that by converting recurse if necessary. */
  svn_depth_t depth = svn_depth_unknown;
  svn_tristate_t send_copyfrom_args; /* Optional; default FALSE */
  svn_tristate_t ignore_ancestry; /* Optional; default TRUE */

  /* Parse the arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbc?w?33", &rev, &target,
                                  &recurse, &switch_url, &depth_word,
                                  &send_copyfrom_args, &ignore_ancestry));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_target, NULL, target,
                                        pool, pool));
  target = canonical_target;
  SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, switch_url, pool,
                                    pool));
  switch_url = canonical_url;
  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  else
    depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  SVN_ERR(trivial_auth_request(conn, pool, b));
  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_CMD_ERR(get_fs_path(svn_path_uri_decode(b->repository->repos_url,
                                              pool),
                          svn_path_uri_decode(switch_url, pool),
                          &switch_path));

  {
    const char *full_path = svn_fspath__join(b->repository->fs_path->data,
                                             target, pool);
    SVN_ERR(log_command(b, conn, pool, "%s",
                        svn_log__switch(full_path, switch_path, rev,
                                        depth, pool)));
  }

  return accept_report(NULL, NULL,
                       conn, pool, b, rev, target, switch_path, TRUE,
                       depth,
                       (send_copyfrom_args == svn_tristate_true),
                       (ignore_ancestry != svn_tristate_false));
}

static svn_error_t *
status(svn_ra_svn_conn_t *conn,
       apr_pool_t *pool,
       svn_ra_svn__list_t *params,
       void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *target, *depth_word, *canonical_target;
  svn_boolean_t recurse;
  /* Default to unknown.  Old clients won't send depth, but we'll
     handle that by converting recurse if necessary. */
  svn_depth_t depth = svn_depth_unknown;

  /* Parse the arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "cb?(?r)?w",
                                  &target, &recurse, &rev, &depth_word));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_target, NULL, target,
                                        pool, pool));
  target = canonical_target;

  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  else
    depth = SVN_DEPTH_INFINITY_OR_EMPTY(recurse);

  SVN_ERR(trivial_auth_request(conn, pool, b));
  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  {
    const char *full_path = svn_fspath__join(b->repository->fs_path->data,
                                             target, pool);
    SVN_ERR(log_command(b, conn, pool, "%s",
                        svn_log__status(full_path, rev, depth, pool)));
  }

  return accept_report(NULL, NULL, conn, pool, b, rev, target, NULL, FALSE,
                       depth, FALSE, FALSE);
}

static svn_error_t *
diff(svn_ra_svn_conn_t *conn,
     apr_pool_t *pool,
     svn_ra_svn__list_t *params,
     void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *target, *versus_url, *versus_path, *depth_word, *canonical_url;
  const char *canonical_target;
  svn_boolean_t recurse, ignore_ancestry;
  svn_boolean_t text_deltas;
  /* Default to unknown.  Old clients won't send depth, but we'll
     handle that by converting recurse if necessary. */
  svn_depth_t depth = svn_depth_unknown;

  /* Parse the arguments. */
  if (params->nelts == 5)
    {
      /* Clients before 1.4 don't send the text_deltas boolean or depth. */
      SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbbc", &rev, &target,
                                      &recurse, &ignore_ancestry, &versus_url));
      text_deltas = TRUE;
      depth_word = NULL;
    }
  else
    {
      SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)cbbcb?w",
                                      &rev, &target, &recurse,
                                      &ignore_ancestry, &versus_url,
                                      &text_deltas, &depth_word));
    }
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_target, NULL, target,
                                        pool, pool));
  target = canonical_target;
  SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, versus_url,
                                    pool, pool));
  versus_url = canonical_url;

  if (depth_word)
    depth = svn_depth_from_word(depth_word);
  else
    depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  SVN_ERR(trivial_auth_request(conn, pool, b));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));
  SVN_CMD_ERR(get_fs_path(svn_path_uri_decode(b->repository->repos_url,
                                              pool),
                          svn_path_uri_decode(versus_url, pool),
                          &versus_path));

  {
    const char *full_path = svn_fspath__join(b->repository->fs_path->data,
                                             target, pool);
    svn_revnum_t from_rev;
    SVN_ERR(accept_report(NULL, &from_rev,
                          conn, pool, b, rev, target, versus_path,
                          text_deltas, depth, FALSE, ignore_ancestry));
    SVN_ERR(log_command(b, conn, pool, "%s",
                        svn_log__diff(full_path, from_rev, versus_path,
                                      rev, depth, ignore_ancestry,
                                      pool)));
  }
  return SVN_NO_ERROR;
}

/* Baton type to be used with mergeinfo_receiver. */
typedef struct mergeinfo_receiver_baton_t
{
  /* Send the response over this connection. */
  svn_ra_svn_conn_t *conn;

  /* Start path of the query; report paths relative to this one. */
  const char *fs_path;

  /* Did we already send the opening sequence? */
  svn_boolean_t starting_tuple_sent;
} mergeinfo_receiver_baton_t;

/* Utility method sending the start of the "get m/i" response once
   over BATON->CONN. */
static svn_error_t *
send_mergeinfo_starting_tuple(mergeinfo_receiver_baton_t *baton,
                              apr_pool_t *scratch_pool)
{
  if (baton->starting_tuple_sent)
    return SVN_NO_ERROR;

  SVN_ERR(svn_ra_svn__write_tuple(baton->conn, scratch_pool,
                                  "w((!", "success"));
  baton->starting_tuple_sent = TRUE;

  return SVN_NO_ERROR;
}

/* Implements svn_repos_mergeinfo_receiver_t, sending the MERGEINFO
 * out over the connection in the mergeinfo_receiver_baton_t * BATON. */
static svn_error_t *
mergeinfo_receiver(const char *path,
                   svn_mergeinfo_t mergeinfo,
                   void *baton,
                   apr_pool_t *scratch_pool)
{
  mergeinfo_receiver_baton_t *b = baton;
  svn_string_t *mergeinfo_string;

  /* Delay starting the response until we checked that the initial
     request went through.  We are at that point now b/c we've got
     the first results in. */
  SVN_ERR(send_mergeinfo_starting_tuple(b, scratch_pool));

  /* Adjust the path info and send the m/i. */
  path = svn_fspath__skip_ancestor(b->fs_path, path);
  SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string, mergeinfo,
                                  scratch_pool));
  SVN_ERR(svn_ra_svn__write_tuple(b->conn, scratch_pool, "cs", path,
                                  mergeinfo_string));

  return SVN_NO_ERROR;
}

/* Regardless of whether a client's capabilities indicate an
   understanding of this command (by way of SVN_RA_SVN_CAP_MERGEINFO),
   we provide a response.

   ASSUMPTION: When performing a 'merge' with two URLs at different
   revisions, the client will call this command more than once. */
static svn_error_t *
get_mergeinfo(svn_ra_svn_conn_t *conn,
              apr_pool_t *pool,
              svn_ra_svn__list_t *params,
              void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  svn_ra_svn__list_t *paths;
  apr_array_header_t *canonical_paths;
  int i;
  const char *inherit_word;
  svn_mergeinfo_inheritance_t inherit;
  svn_boolean_t include_descendants;
  authz_baton_t ab;
  mergeinfo_receiver_baton_t mergeinfo_baton;

  ab.server = b;
  ab.conn = conn;

  mergeinfo_baton.conn = conn;
  mergeinfo_baton.fs_path = b->repository->fs_path->data;
  mergeinfo_baton.starting_tuple_sent = FALSE;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "l(?r)wb", &paths, &rev,
                                  &inherit_word, &include_descendants));
  inherit = svn_inheritance_from_word(inherit_word);

  /* Canonicalize the paths which mergeinfo has been requested for. */
  canonical_paths = apr_array_make(pool, paths->nelts, sizeof(const char *));
  for (i = 0; i < paths->nelts; i++)
     {
        svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(paths, i);
        const char *full_path, *canonical_path;

        if (item->kind != SVN_RA_SVN_STRING)
          return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                  _("Path is not a string"));
        SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL,
            item->u.string.data, pool, pool));
        full_path = svn_fspath__join(b->repository->fs_path->data,
                                     canonical_path, pool);
        APR_ARRAY_PUSH(canonical_paths, const char *) = full_path;
     }

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_mergeinfo(canonical_paths, inherit,
                                             include_descendants,
                                             pool)));

  SVN_ERR(trivial_auth_request(conn, pool, b));

  SVN_CMD_ERR(svn_repos_fs_get_mergeinfo2(b->repository->repos,
                                          canonical_paths, rev,
                                          inherit,
                                          include_descendants,
                                          authz_check_access_cb_func(b), &ab,
                                          mergeinfo_receiver,
                                          &mergeinfo_baton,
                                          pool));

  /* We might not have sent anything
     => ensure to begin the response in any case. */
  SVN_ERR(send_mergeinfo_starting_tuple(&mergeinfo_baton, pool));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));

  return SVN_NO_ERROR;
}

/* Send a changed paths list entry to the client.
   This implements svn_repos_path_change_receiver_t. */
static svn_error_t *
path_change_receiver(void *baton,
                     svn_repos_path_change_t *change,
                     apr_pool_t *scratch_pool)
{
  const char symbol[] = "MADR";

  log_baton_t *b = baton;
  svn_ra_svn_conn_t *conn = b->conn;

  /* Sanitize and convert change kind to ra-svn level action.

     Pushing that conversion down into libsvn_ra_svn would add yet another
     API dependency there. */
  char action = (   change->change_kind < svn_fs_path_change_modify
                 || change->change_kind > svn_fs_path_change_replace)
              ? 0
              : symbol[change->change_kind];

  /* Open lists once: LOG_ENTRY and LOG_ENTRY->CHANGED_PATHS. */
  if (!b->started)
    {
      SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
      SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
      b->started = TRUE;
    }

  /* Serialize CHANGE. */
  SVN_ERR(svn_ra_svn__write_data_log_changed_path(
              conn, scratch_pool,
              &change->path,
              action,
              change->copyfrom_path,
              change->copyfrom_rev,
              change->node_kind,
              change->text_mod,
              change->prop_mod));

  return SVN_NO_ERROR;
}

/* Send a the meta data and the revpros for LOG_ENTRY to the client.
   This implements svn_log_entry_receiver_t. */
static svn_error_t *
revision_receiver(void *baton,
                  svn_repos_log_entry_t *log_entry,
                  apr_pool_t *scratch_pool)
{
  log_baton_t *b = baton;
  svn_ra_svn_conn_t *conn = b->conn;
  svn_boolean_t invalid_revnum = FALSE;
  const svn_string_t *author, *date, *message;
  unsigned revprop_count;

  if (log_entry->revision == SVN_INVALID_REVNUM)
    {
      /* If the stack depth is zero, we've seen the last revision, so don't
         send it, just return. */
      if (b->stack_depth == 0)
        return SVN_NO_ERROR;

      /* Because the svn protocol won't let us send an invalid revnum, we have
         to fudge here and send an additional flag. */
      log_entry->revision = 0;
      invalid_revnum = TRUE;
      b->stack_depth--;
    }

  svn_compat_log_revprops_out_string(&author, &date, &message,
                                     log_entry->revprops);

  /* Revprops list filtering is somewhat expensive.
     Avoid doing that for the 90% case where only the standard revprops
     have been requested and delivered. */
  if (author && date && message && apr_hash_count(log_entry->revprops) == 3)
    {
      revprop_count = 0;
    }
  else
    {
      svn_compat_log_revprops_clear(log_entry->revprops);
      if (log_entry->revprops)
        revprop_count = apr_hash_count(log_entry->revprops);
      else
        revprop_count = 0;
    }

  /* Open lists once: LOG_ENTRY and LOG_ENTRY->CHANGED_PATHS. */
  if (!b->started)
    {
      SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
      SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
    }

  /* Close LOG_ENTRY->CHANGED_PATHS. */
  SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));
  b->started = FALSE;

  /* send LOG_ENTRY main members */
  SVN_ERR(svn_ra_svn__write_data_log_entry(conn, scratch_pool,
                                           log_entry->revision,
                                           author, date, message,
                                           log_entry->has_children,
                                           invalid_revnum, revprop_count));

  /* send LOG_ENTRY->REVPROPS */
  SVN_ERR(svn_ra_svn__start_list(conn, scratch_pool));
  if (revprop_count)
    SVN_ERR(svn_ra_svn__write_proplist(conn, scratch_pool,
                                       log_entry->revprops));
  SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));

  /* send LOG_ENTRY members that were added in later SVN releases */
  SVN_ERR(svn_ra_svn__write_boolean(conn, scratch_pool,
                                    log_entry->subtractive_merge));
  SVN_ERR(svn_ra_svn__end_list(conn, scratch_pool));

  if (log_entry->has_children)
    b->stack_depth++;

  return SVN_NO_ERROR;
}

static svn_error_t *
log_cmd(svn_ra_svn_conn_t *conn,
        apr_pool_t *pool,
        svn_ra_svn__list_t *params,
        void *baton)
{
  svn_error_t *err, *write_err;
  server_baton_t *b = baton;
  svn_revnum_t start_rev, end_rev;
  const char *full_path, *canonical_path;
  svn_boolean_t send_changed_paths, strict_node, include_merged_revisions;
  apr_array_header_t *full_paths, *revprops;
  svn_ra_svn__list_t *paths, *revprop_items;
  char *revprop_word;
  svn_ra_svn__item_t *elt;
  int i;
  apr_uint64_t limit, include_merged_revs_param;
  log_baton_t lb;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "l(?r)(?r)bb?n?Bwl", &paths,
                                  &start_rev, &end_rev, &send_changed_paths,
                                  &strict_node, &limit,
                                  &include_merged_revs_param,
                                  &revprop_word, &revprop_items));

  if (include_merged_revs_param == SVN_RA_SVN_UNSPECIFIED_NUMBER)
    include_merged_revisions = FALSE;
  else
    include_merged_revisions = (svn_boolean_t) include_merged_revs_param;

  if (revprop_word == NULL)
    /* pre-1.5 client */
    revprops = svn_compat_log_revprops_in(pool);
  else if (strcmp(revprop_word, "all-revprops") == 0)
    revprops = NULL;
  else if (strcmp(revprop_word, "revprops") == 0)
    {
      SVN_ERR_ASSERT(revprop_items);

      revprops = apr_array_make(pool, revprop_items->nelts,
                                sizeof(char *));
      for (i = 0; i < revprop_items->nelts; i++)
        {
          elt = &SVN_RA_SVN__LIST_ITEM(revprop_items, i);
          if (elt->kind != SVN_RA_SVN_STRING)
            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                    _("Log revprop entry not a string"));
          APR_ARRAY_PUSH(revprops, const char *) = elt->u.string.data;
        }
    }
  else
    return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("Unknown revprop word '%s' in log command"),
                             revprop_word);

  /* If we got an unspecified number then the user didn't send us anything,
     so we assume no limit.  If it's larger than INT_MAX then someone is
     messing with us, since we know the svn client libraries will never send
     us anything that big, so play it safe and default to no limit. */
  if (limit == SVN_RA_SVN_UNSPECIFIED_NUMBER || limit > INT_MAX)
    limit = 0;

  full_paths = apr_array_make(pool, paths->nelts, sizeof(const char *));
  for (i = 0; i < paths->nelts; i++)
    {
      elt = &SVN_RA_SVN__LIST_ITEM(paths, i);
      if (elt->kind != SVN_RA_SVN_STRING)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                _("Log path entry not a string"));
      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL,
                                            elt->u.string.data, pool, pool));
      full_path = svn_fspath__join(b->repository->fs_path->data,
                                   canonical_path, pool);
      APR_ARRAY_PUSH(full_paths, const char *) = full_path;
    }
  SVN_ERR(trivial_auth_request(conn, pool, b));

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__log(full_paths, start_rev, end_rev,
                                   (int) limit, send_changed_paths,
                                   strict_node, include_merged_revisions,
                                   revprops, pool)));

  /* Get logs.  (Can't report errors back to the client at this point.) */
  lb.fs_path = b->repository->fs_path->data;
  lb.conn = conn;
  lb.stack_depth = 0;
  lb.started = FALSE;
  err = svn_repos_get_logs5(b->repository->repos, full_paths, start_rev,
                            end_rev, (int) limit,
                            strict_node, include_merged_revisions,
                            revprops, authz_check_access_cb_func(b), &ab,
                            send_changed_paths ? path_change_receiver : NULL,
                            send_changed_paths ? &lb : NULL,
                            revision_receiver, &lb, pool);

  write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (write_err)
    {
      svn_error_clear(err);
      return write_err;
    }
  SVN_CMD_ERR(err);
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));
  return SVN_NO_ERROR;
}

static svn_error_t *
check_path(svn_ra_svn_conn_t *conn,
           apr_pool_t *pool,
           svn_ra_svn__list_t *params,
           void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *path, *full_path, *canonical_path;
  svn_fs_root_t *root;
  svn_node_kind_t kind;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));;
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(log_command(b, conn, pool, "check-path %s@%d",
                      svn_path_uri_encode(full_path, pool), rev));

  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));
  SVN_CMD_ERR(svn_fs_check_path(&kind, root, full_path, pool));
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "w",
                                         svn_node_kind_to_word(kind)));
  return SVN_NO_ERROR;
}

static svn_error_t *
stat_cmd(svn_ra_svn_conn_t *conn,
         apr_pool_t *pool,
         svn_ra_svn__list_t *params,
         void *baton)
{
  server_baton_t *b = baton;
  svn_revnum_t rev;
  const char *path, *full_path, *cdate, *canonical_path;
  svn_fs_root_t *root;
  svn_dirent_t *dirent;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path, pool,
                                        pool));
  full_path = svn_fspath__join(b->repository->fs_path->data, canonical_path,
                               pool);

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(log_command(b, conn, pool, "stat %s@%d",
                      svn_path_uri_encode(full_path, pool), rev));

  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));
  SVN_CMD_ERR(svn_repos_stat(&dirent, root, full_path, pool));

  /* Need to return the equivalent of "(?l)", since that's what the
     client is reading.  */

  if (dirent == NULL)
    {
      SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "()"));
      return SVN_NO_ERROR;
    }

  cdate = (dirent->time == (time_t) -1) ? NULL
    : svn_time_to_cstring(dirent->time, pool);

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "((wnbr(?c)(?c)))",
                                         svn_node_kind_to_word(dirent->kind),
                                         (apr_uint64_t) dirent->size,
                                         dirent->has_props, dirent->created_rev,
                                         cdate, dirent->last_author));

  return SVN_NO_ERROR;
}

static svn_error_t *
get_locations(svn_ra_svn_conn_t *conn,
              apr_pool_t *pool,
              svn_ra_svn__list_t *params,
              void *baton)
{
  svn_error_t *err, *write_err;
  server_baton_t *b = baton;
  svn_revnum_t revision;
  apr_array_header_t *location_revisions;
  svn_ra_svn__list_t *loc_revs_proto;
  svn_ra_svn__item_t *elt;
  int i;
  const char *relative_path, *canonical_path;
  svn_revnum_t peg_revision;
  apr_hash_t *fs_locations;
  const char *abs_path;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  /* Parse the arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "crl", &relative_path,
                                  &peg_revision,
                                  &loc_revs_proto));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, relative_path,
                                        pool, pool));
  relative_path = canonical_path;

  abs_path = svn_fspath__join(b->repository->fs_path->data, relative_path,
                              pool);

  location_revisions = apr_array_make(pool, loc_revs_proto->nelts,
                                      sizeof(svn_revnum_t));
  for (i = 0; i < loc_revs_proto->nelts; i++)
    {
      elt = &SVN_RA_SVN__LIST_ITEM(loc_revs_proto, i);
      if (elt->kind != SVN_RA_SVN_NUMBER)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Get-locations location revisions entry "
                                "not a revision number");
      revision = (svn_revnum_t)(elt->u.number);
      APR_ARRAY_PUSH(location_revisions, svn_revnum_t) = revision;
    }
  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_locations(abs_path, peg_revision,
                                             location_revisions, pool)));

  /* All the parameters are fine - let's perform the query against the
   * repository. */

  /* We store both err and write_err here, so the client will get
   * the "done" even if there was an error in fetching the results. */

  err = svn_repos_trace_node_locations(b->repository->fs, &fs_locations,
                                       abs_path, peg_revision,
                                       location_revisions,
                                       authz_check_access_cb_func(b), &ab,
                                       pool);

  /* Now, write the results to the connection. */
  if (!err)
    {
      if (fs_locations)
        {
          apr_hash_index_t *iter;

          for (iter = apr_hash_first(pool, fs_locations); iter;
              iter = apr_hash_next(iter))
            {
              const svn_revnum_t *iter_key = apr_hash_this_key(iter);
              const char *iter_value = apr_hash_this_val(iter);

              SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "rc",
                                              *iter_key, iter_value));
            }
        }
    }

  write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (write_err)
    {
      svn_error_clear(err);
      return write_err;
    }
  SVN_CMD_ERR(err);

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *gls_receiver(svn_location_segment_t *segment,
                                 void *baton,
                                 apr_pool_t *pool)
{
  svn_ra_svn_conn_t *conn = baton;
  return svn_ra_svn__write_tuple(conn, pool, "rr(?c)",
                                 segment->range_start,
                                 segment->range_end,
                                 segment->path);
}

static svn_error_t *
get_location_segments(svn_ra_svn_conn_t *conn,
                      apr_pool_t *pool,
                      svn_ra_svn__list_t *params,
                      void *baton)
{
  svn_error_t *err, *write_err;
  server_baton_t *b = baton;
  svn_revnum_t peg_revision, start_rev, end_rev;
  const char *relative_path, *canonical_path;
  const char *abs_path;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  /* Parse the arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)(?r)(?r)",
                                  &relative_path, &peg_revision,
                                  &start_rev, &end_rev));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, relative_path,
                                        pool, pool));
  relative_path = canonical_path;

  abs_path = svn_fspath__join(b->repository->fs_path->data, relative_path,
                              pool);

  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_ERR(log_command(baton, conn, pool, "%s",
                      svn_log__get_location_segments(abs_path, peg_revision,
                                                     start_rev, end_rev,
                                                     pool)));

  /* No START_REV or PEG_REVISION?  We'll use HEAD. */
  if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision))
    {
      svn_revnum_t youngest;

      err = svn_fs_youngest_rev(&youngest, b->repository->fs, pool);

      if (err)
        {
          err = svn_error_compose_create(
                    svn_ra_svn__write_word(conn, pool, "done"),
                    err);

          return log_fail_and_flush(err, b, conn, pool);
        }

      if (!SVN_IS_VALID_REVNUM(start_rev))
        start_rev = youngest;
      if (!SVN_IS_VALID_REVNUM(peg_revision))
        peg_revision = youngest;
    }

  /* No END_REV?  We'll use 0. */
  if (!SVN_IS_VALID_REVNUM(end_rev))
    end_rev = 0;

  if (end_rev > start_rev)
    {
      err = svn_ra_svn__write_word(conn, pool, "done");
      err = svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, err,
                              "Get-location-segments end revision must not be "
                              "younger than start revision");
      return log_fail_and_flush(err, b, conn, pool);
    }

  if (start_rev > peg_revision)
    {
      err = svn_ra_svn__write_word(conn, pool, "done");
      err = svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, err,
                              "Get-location-segments start revision must not "
                              "be younger than peg revision");
      return log_fail_and_flush(err, b, conn, pool);
    }

  /* All the parameters are fine - let's perform the query against the
   * repository. */

  /* We store both err and write_err here, so the client will get
   * the "done" even if there was an error in fetching the results. */

  err = svn_repos_node_location_segments(b->repository->repos, abs_path,
                                         peg_revision, start_rev, end_rev,
                                         gls_receiver, (void *)conn,
                                         authz_check_access_cb_func(b), &ab,
                                         pool);
  write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (write_err)
    {
      return svn_error_compose_create(write_err, err);
    }
  SVN_CMD_ERR(err);

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

/* This implements svn_write_fn_t.  Write LEN bytes starting at DATA to the
   client as a string. */
static svn_error_t *svndiff_handler(void *baton, const char *data,
                                    apr_size_t *len)
{
  file_revs_baton_t *b = baton;
  svn_string_t str;

  str.data = data;
  str.len = *len;
  return svn_ra_svn__write_string(b->conn, b->pool, &str);
}

/* This implements svn_close_fn_t.  Mark the end of the data by writing an
   empty string to the client. */
static svn_error_t *svndiff_close_handler(void *baton)
{
  file_revs_baton_t *b = baton;

  SVN_ERR(svn_ra_svn__write_cstring(b->conn, b->pool, ""));
  return SVN_NO_ERROR;
}

/* This implements the svn_repos_file_rev_handler_t interface. */
static svn_error_t *file_rev_handler(void *baton, const char *path,
                                     svn_revnum_t rev, apr_hash_t *rev_props,
                                     svn_boolean_t merged_revision,
                                     svn_txdelta_window_handler_t *d_handler,
                                     void **d_baton,
                                     apr_array_header_t *prop_diffs,
                                     apr_pool_t *pool)
{
  file_revs_baton_t *frb = baton;
  svn_stream_t *stream;

  SVN_ERR(svn_ra_svn__write_tuple(frb->conn, pool, "cr(!",
                                  path, rev));
  SVN_ERR(svn_ra_svn__write_proplist(frb->conn, pool, rev_props));
  SVN_ERR(svn_ra_svn__write_tuple(frb->conn, pool, "!)(!"));
  SVN_ERR(write_prop_diffs(frb->conn, pool, prop_diffs));
  SVN_ERR(svn_ra_svn__write_tuple(frb->conn, pool, "!)b", merged_revision));

  /* Store the pool for the delta stream. */
  frb->pool = pool;

  /* Prepare for the delta or just write an empty string. */
  if (d_handler)
    {
      stream = svn_stream_create(baton, pool);
      svn_stream_set_write(stream, svndiff_handler);
      svn_stream_set_close(stream, svndiff_close_handler);

      svn_txdelta_to_svndiff3(d_handler, d_baton, stream,
                              svn_ra_svn__svndiff_version(frb->conn),
                              svn_ra_svn_compression_level(frb->conn), pool);
    }
  else
    SVN_ERR(svn_ra_svn__write_cstring(frb->conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
get_file_revs(svn_ra_svn_conn_t *conn,
              apr_pool_t *pool,
              svn_ra_svn__list_t *params,
              void *baton)
{
  server_baton_t *b = baton;
  svn_error_t *err, *write_err;
  file_revs_baton_t frb;
  svn_revnum_t start_rev, end_rev;
  const char *path;
  const char *full_path;
  const char *canonical_path;
  apr_uint64_t include_merged_revs_param;
  svn_boolean_t include_merged_revisions;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  /* Parse arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)(?r)?B",
                                  &path, &start_rev, &end_rev,
                                  &include_merged_revs_param));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  path = canonical_path;
  SVN_ERR(trivial_auth_request(conn, pool, b));
  full_path = svn_fspath__join(b->repository->fs_path->data, path, pool);

  if (include_merged_revs_param == SVN_RA_SVN_UNSPECIFIED_NUMBER)
    include_merged_revisions = FALSE;
  else
    include_merged_revisions = (svn_boolean_t) include_merged_revs_param;

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_file_revs(full_path, start_rev, end_rev,
                                             include_merged_revisions,
                                             pool)));

  frb.conn = conn;
  frb.pool = NULL;

  err = svn_repos_get_file_revs2(b->repository->repos, full_path, start_rev,
                                 end_rev, include_merged_revisions,
                                 authz_check_access_cb_func(b), &ab,
                                 file_rev_handler, &frb, pool);
  write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (write_err)
    {
      svn_error_clear(err);
      return write_err;
    }
  SVN_CMD_ERR(err);
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
lock(svn_ra_svn_conn_t *conn,
     apr_pool_t *pool,
     svn_ra_svn__list_t *params,
     void *baton)
{
  server_baton_t *b = baton;
  const char *path;
  const char *comment;
  const char *full_path;
  const char *canonical_path;
  svn_boolean_t steal_lock;
  svn_revnum_t current_rev;
  svn_lock_t *l;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?c)b(?r)", &path, &comment,
                                  &steal_lock, &current_rev));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));;
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write,
                           full_path, TRUE));
  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__lock_one_path(full_path, steal_lock, pool)));

  SVN_CMD_ERR(svn_repos_fs_lock(&l, b->repository->repos, full_path, NULL,
                                comment, 0, 0, /* No expiration time. */
                                current_rev, steal_lock, pool));

  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(!", "success"));
  SVN_ERR(write_lock(conn, pool, l));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)"));

  return SVN_NO_ERROR;
}

struct lock_result_t {
  const svn_lock_t *lock;
  svn_error_t *err;
};

struct lock_many_baton_t {
  apr_hash_t *results;
  apr_pool_t *pool;
};

/* Implements svn_fs_lock_callback_t. */
static svn_error_t *
lock_many_cb(void *baton,
             const char *path,
             const svn_lock_t *fs_lock,
             svn_error_t *fs_err,
             apr_pool_t *pool)
{
  struct lock_many_baton_t *b = baton;
  struct lock_result_t *result = apr_palloc(b->pool,
                                            sizeof(struct lock_result_t));

  result->lock = fs_lock;
  result->err = svn_error_dup(fs_err);
  svn_hash_sets(b->results, apr_pstrdup(b->pool, path), result);

  return SVN_NO_ERROR;
}

static void
clear_lock_result_hash(apr_hash_t *results,
                       apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, results); hi; hi = apr_hash_next(hi))
    {
      struct lock_result_t *result = apr_hash_this_val(hi);
      svn_error_clear(result->err);
    }
}

static svn_error_t *
lock_many(svn_ra_svn_conn_t *conn,
          apr_pool_t *pool,
          svn_ra_svn__list_t *params,
          void *baton)
{
  server_baton_t *b = baton;
  svn_ra_svn__list_t *path_revs;
  const char *comment;
  svn_boolean_t steal_lock;
  int i;
  apr_pool_t *subpool;
  svn_error_t *err, *write_err = SVN_NO_ERROR;
  apr_hash_t *targets = apr_hash_make(pool);
  apr_hash_t *authz_results = apr_hash_make(pool);
  apr_hash_index_t *hi;
  struct lock_many_baton_t lmb;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "(?c)bl", &comment, &steal_lock,
                                  &path_revs));

  subpool = svn_pool_create(pool);

  /* Because we can only send a single auth reply per request, we send
     a reply before parsing the lock commands.  This means an authz
     access denial will abort the processing of the locks and return
     an error. */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, TRUE));

  /* Parse the lock requests from PATH_REVS into TARGETS. */
  for (i = 0; i < path_revs->nelts; ++i)
    {
      const char *path, *full_path, *canonical_path;
      svn_revnum_t current_rev;
      svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(path_revs, i);
      svn_fs_lock_target_t *target;

      svn_pool_clear(subpool);

      if (item->kind != SVN_RA_SVN_LIST)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Lock requests should be list of lists");

      SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, "c(?r)", &path,
                                      &current_rev));

      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            subpool, subpool));
      full_path = svn_fspath__join(b->repository->fs_path->data,
                                   canonical_path, pool);
      target = svn_fs_lock_target_create(NULL, current_rev, pool);

      /* Any duplicate paths, once canonicalized, get collapsed into a
         single path that is processed once.  The result is then
         returned multiple times. */
      svn_hash_sets(targets, full_path, target);
    }

  SVN_ERR(log_command(b, conn, subpool, "%s",
                      svn_log__lock(targets, steal_lock, subpool)));

  /* Check authz.

     Note: From here on we need to make sure any errors in authz_results, or
     results, are cleared before returning from this function. */
  for (hi = apr_hash_first(pool, targets); hi; hi = apr_hash_next(hi))
    {
      const char *full_path = apr_hash_this_key(hi);

      svn_pool_clear(subpool);

      if (! lookup_access(subpool, b, svn_authz_write, full_path, TRUE))
        {
          struct lock_result_t *result
            = apr_palloc(pool, sizeof(struct lock_result_t));

          result->lock = NULL;
          result->err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED,
                                             NULL, NULL, b);
          svn_hash_sets(authz_results, full_path, result);
          svn_hash_sets(targets, full_path, NULL);
        }
    }

  lmb.results = apr_hash_make(pool);
  lmb.pool = pool;

  err = svn_repos_fs_lock_many(b->repository->repos, targets,
                               comment, FALSE,
                               0, /* No expiration time. */
                               steal_lock, lock_many_cb, &lmb,
                               pool, subpool);

  /* Return results in the same order as the paths were supplied. */
  for (i = 0; i < path_revs->nelts; ++i)
    {
      const char *path, *full_path, *canonical_path;
      svn_revnum_t current_rev;
      svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(path_revs, i);
      struct lock_result_t *result;

      svn_pool_clear(subpool);

      write_err = svn_ra_svn__parse_tuple(&item->u.list, "c(?r)",
                                          &path, &current_rev);
      if (write_err)
        break;

      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            subpool, subpool));
      full_path = svn_fspath__join(b->repository->fs_path->data,
                                   canonical_path, subpool);

      result = svn_hash_gets(lmb.results, full_path);
      if (!result)
        result = svn_hash_gets(authz_results, full_path);
      if (!result)
        {
          /* No result?  Something really odd happened, create a
             placeholder error so that any other results can be
             reported in the correct order. */
          result = apr_palloc(pool, sizeof(struct lock_result_t));
          result->err = svn_error_createf(SVN_ERR_FS_LOCK_OPERATION_FAILED, 0,
                                          _("No result for '%s'."), path);
          svn_hash_sets(lmb.results, full_path, result);
        }

      if (result->err)
        write_err = svn_ra_svn__write_cmd_failure(conn, subpool,
                                                  result->err);
      else
        {
          write_err = svn_ra_svn__write_tuple(conn, subpool,
                                              "w!", "success");
          if (!write_err)
            write_err = write_lock(conn, subpool, result->lock);
          if (!write_err)
            write_err = svn_ra_svn__write_tuple(conn, subpool, "!");
        }
      if (write_err)
        break;
    }

  clear_lock_result_hash(authz_results, subpool);
  clear_lock_result_hash(lmb.results, subpool);

  svn_pool_destroy(subpool);

  if (!write_err)
    write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (!write_err)
    SVN_CMD_ERR(err);
  svn_error_clear(err);
  SVN_ERR(write_err);
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
unlock(svn_ra_svn_conn_t *conn,
       apr_pool_t *pool,
       svn_ra_svn__list_t *params,
       void *baton)
{
  server_baton_t *b = baton;
  const char *path, *token, *full_path, *canonical_path;
  svn_boolean_t break_lock;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?c)b", &path, &token,
                                 &break_lock));

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  /* Username required unless break_lock was specified. */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write,
                           full_path, ! break_lock));
  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__unlock_one_path(full_path, break_lock, pool)));

  SVN_CMD_ERR(svn_repos_fs_unlock(b->repository->repos, full_path, token,
                                  break_lock, pool));

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
unlock_many(svn_ra_svn_conn_t *conn,
            apr_pool_t *pool,
            svn_ra_svn__list_t *params,
            void *baton)
{
  server_baton_t *b = baton;
  svn_boolean_t break_lock;
  svn_ra_svn__list_t *unlock_tokens;
  int i;
  apr_pool_t *subpool;
  svn_error_t *err = SVN_NO_ERROR, *write_err = SVN_NO_ERROR;
  apr_hash_t *targets = apr_hash_make(pool);
  apr_hash_t *authz_results = apr_hash_make(pool);
  apr_hash_index_t *hi;
  struct lock_many_baton_t lmb;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "bl", &break_lock, &unlock_tokens));

  /* Username required unless break_lock was specified. */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, ! break_lock));

  subpool = svn_pool_create(pool);

  /* Parse the unlock requests from PATH_REVS into TARGETS. */
  for (i = 0; i < unlock_tokens->nelts; i++)
    {
      svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(unlock_tokens, i);
      const char *path, *full_path, *token, *canonical_path;

      svn_pool_clear(subpool);

      if (item->kind != SVN_RA_SVN_LIST)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                "Unlock request should be a list of lists");

      SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, "c(?c)", &path,
                                      &token));
      if (!token)
        token = "";

      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            subpool, subpool));
      full_path = svn_fspath__join(b->repository->fs_path->data,
                                   canonical_path, pool);

      /* Any duplicate paths, once canonicalized, get collapsed into a
         single path that is processed once.  The result is then
         returned multiple times. */
      svn_hash_sets(targets, full_path, token);
    }

  SVN_ERR(log_command(b, conn, subpool, "%s",
                      svn_log__unlock(targets, break_lock, subpool)));

  /* Check authz.

     Note: From here on we need to make sure any errors in authz_results, or
     results, are cleared before returning from this function. */
  for (hi = apr_hash_first(pool, targets); hi; hi = apr_hash_next(hi))
    {
      const char *full_path = apr_hash_this_key(hi);

      svn_pool_clear(subpool);

      if (! lookup_access(subpool, b, svn_authz_write, full_path,
                          ! break_lock))
        {
          struct lock_result_t *result
            = apr_palloc(pool, sizeof(struct lock_result_t));

          result->lock = NULL;
          result->err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED,
                                             NULL, NULL, b);
          svn_hash_sets(authz_results, full_path, result);
          svn_hash_sets(targets, full_path, NULL);
        }
    }

  lmb.results = apr_hash_make(pool);
  lmb.pool = pool;

  err = svn_repos_fs_unlock_many(b->repository->repos, targets,
                                 break_lock, lock_many_cb, &lmb,
                                 pool, subpool);

  /* Return results in the same order as the paths were supplied. */
  for (i = 0; i < unlock_tokens->nelts; ++i)
    {
      const char *path, *token, *full_path, *canonical_path;
      svn_ra_svn__item_t *item = &SVN_RA_SVN__LIST_ITEM(unlock_tokens, i);
      struct lock_result_t *result;

      svn_pool_clear(subpool);

      write_err = svn_ra_svn__parse_tuple(&item->u.list, "c(?c)",
                                          &path, &token);
      if (write_err)
        break;

      SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                            subpool, subpool));
      full_path = svn_fspath__join(b->repository->fs_path->data,
                                   canonical_path, pool);

      result = svn_hash_gets(lmb.results, full_path);
      if (!result)
        result = svn_hash_gets(authz_results, full_path);
      if (!result)
        {
          /* No result?  Something really odd happened, create a
             placeholder error so that any other results can be
             reported in the correct order. */
          result = apr_palloc(pool, sizeof(struct lock_result_t));
          result->err = svn_error_createf(SVN_ERR_FS_LOCK_OPERATION_FAILED, 0,
                                          _("No result for '%s'."), path);
          svn_hash_sets(lmb.results, full_path, result);
        }

      if (result->err)
        write_err = svn_ra_svn__write_cmd_failure(conn, pool, result->err);
      else
        write_err = svn_ra_svn__write_tuple(conn, subpool, "w(c)", "success",
                                            path);
      if (write_err)
        break;
    }

  clear_lock_result_hash(authz_results, subpool);
  clear_lock_result_hash(lmb.results, subpool);

  svn_pool_destroy(subpool);

  if (!write_err)
    write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (! write_err)
    SVN_CMD_ERR(err);
  svn_error_clear(err);
  SVN_ERR(write_err);
  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
get_lock(svn_ra_svn_conn_t *conn,
         apr_pool_t *pool,
         svn_ra_svn__list_t *params,
         void *baton)
{
  server_baton_t *b = baton;
  const char *path;
  const char *full_path;
  const char *canonical_path;
  svn_lock_t *l;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c", &path));

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));
  SVN_ERR(log_command(b, conn, pool, "get-lock %s",
                      svn_path_uri_encode(full_path, pool)));

  SVN_CMD_ERR(svn_fs_get_lock(&l, b->repository->fs, full_path, pool));

  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
  if (l)
    SVN_ERR(write_lock(conn, pool, l));
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));

  return SVN_NO_ERROR;
}

static svn_error_t *
get_locks(svn_ra_svn_conn_t *conn,
          apr_pool_t *pool,
          svn_ra_svn__list_t *params,
          void *baton)
{
  server_baton_t *b = baton;
  const char *path;
  const char *full_path;
  const char *canonical_path;
  const char *depth_word;
  svn_depth_t depth;
  apr_hash_t *locks;
  apr_hash_index_t *hi;
  svn_error_t *err;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "c?(?w)", &path, &depth_word));

  depth = depth_word ? svn_depth_from_word(depth_word) : svn_depth_infinity;
  if ((depth != svn_depth_empty) &&
      (depth != svn_depth_files) &&
      (depth != svn_depth_immediates) &&
      (depth != svn_depth_infinity))
    {
      err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                             "Invalid 'depth' specified in get-locks request");
      return log_fail_and_flush(err, b, conn, pool);
    }

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  SVN_ERR(trivial_auth_request(conn, pool, b));

  SVN_ERR(log_command(b, conn, pool, "get-locks %s",
                      svn_path_uri_encode(full_path, pool)));
  SVN_CMD_ERR(svn_repos_fs_get_locks2(&locks, b->repository->repos,
                                      full_path, depth,
                                      authz_check_access_cb_func(b), &ab,
                                      pool));

  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "success"));
  for (hi = apr_hash_first(pool, locks); hi; hi = apr_hash_next(hi))
    {
      svn_lock_t *l = apr_hash_this_val(hi);

      SVN_ERR(write_lock(conn, pool, l));
    }
  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));

  return SVN_NO_ERROR;
}

static svn_error_t *replay_one_revision(svn_ra_svn_conn_t *conn,
                                        server_baton_t *b,
                                        svn_revnum_t rev,
                                        svn_revnum_t low_water_mark,
                                        svn_boolean_t send_deltas,
                                        apr_pool_t *pool)
{
  const svn_delta_editor_t *editor;
  void *edit_baton;
  svn_fs_root_t *root;
  svn_error_t *err;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(log_command(b, conn, pool,
                      svn_log__replay(b->repository->fs_path->data, rev,
                                      pool)));

  svn_ra_svn_get_editor(&editor, &edit_baton, conn, pool, NULL, NULL);

  err = svn_fs_revision_root(&root, b->repository->fs, rev, pool);

  if (! err)
    err = svn_repos_replay2(root, b->repository->fs_path->data,
                            low_water_mark, send_deltas, editor, edit_baton,
                            authz_check_access_cb_func(b), &ab, pool);

  if (err)
    svn_error_clear(editor->abort_edit(edit_baton, pool));
  SVN_CMD_ERR(err);

  return svn_ra_svn__write_cmd_finish_replay(conn, pool);
}

static svn_error_t *
replay(svn_ra_svn_conn_t *conn,
       apr_pool_t *pool,
       svn_ra_svn__list_t *params,
       void *baton)
{
  svn_revnum_t rev, low_water_mark;
  svn_boolean_t send_deltas;
  server_baton_t *b = baton;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "rrb", &rev, &low_water_mark,
                                 &send_deltas));

  SVN_ERR(trivial_auth_request(conn, pool, b));

  SVN_ERR(replay_one_revision(conn, b, rev, low_water_mark,
                              send_deltas, pool));

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
replay_range(svn_ra_svn_conn_t *conn,
             apr_pool_t *pool,
             svn_ra_svn__list_t *params,
             void *baton)
{
  svn_revnum_t start_rev, end_rev, rev, low_water_mark;
  svn_boolean_t send_deltas;
  server_baton_t *b = baton;
  apr_pool_t *iterpool;
  authz_baton_t ab;

  ab.server = b;
  ab.conn = conn;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "rrrb", &start_rev,
                                 &end_rev, &low_water_mark,
                                 &send_deltas));

  SVN_ERR(trivial_auth_request(conn, pool, b));

  iterpool = svn_pool_create(pool);
  for (rev = start_rev; rev <= end_rev; rev++)
    {
      apr_hash_t *props;

      svn_pool_clear(iterpool);

      SVN_CMD_ERR(svn_repos_fs_revision_proplist(&props,
                                                 b->repository->repos, rev,
                                                 authz_check_access_cb_func(b),
                                                 &ab,
                                                 iterpool));
      SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "w(!", "revprops"));
      SVN_ERR(svn_ra_svn__write_proplist(conn, iterpool, props));
      SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!)"));

      SVN_ERR(replay_one_revision(conn, b, rev, low_water_mark,
                                  send_deltas, iterpool));

    }
  svn_pool_destroy(iterpool);

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, ""));

  return SVN_NO_ERROR;
}

static svn_error_t *
get_deleted_rev(svn_ra_svn_conn_t *conn,
                apr_pool_t *pool,
                svn_ra_svn__list_t *params,
                void *baton)
{
  server_baton_t *b = baton;
  const char *path, *full_path, *canonical_path;
  svn_revnum_t peg_revision;
  svn_revnum_t end_revision;
  svn_revnum_t revision_deleted;

  SVN_ERR(svn_ra_svn__parse_tuple(params, "crr",
                                 &path, &peg_revision, &end_revision));
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);
  SVN_ERR(log_command(b, conn, pool, "get-deleted-rev"));
  SVN_ERR(trivial_auth_request(conn, pool, b));
  SVN_CMD_ERR(svn_repos_deleted_rev(b->repository->fs, full_path, peg_revision,
                                    end_revision, &revision_deleted, pool));

  /* The protocol does not allow for a reply of SVN_INVALID_REVNUM directly.
     Instead, return SVN_ERR_ENTRY_MISSING_REVISION. A new enough client
     knows that this means the answer to the query is SVN_INVALID_REVNUM.
     (An older client reports this as an error.) */
  if (revision_deleted == SVN_INVALID_REVNUM)
    SVN_CMD_ERR(svn_error_createf(SVN_ERR_ENTRY_MISSING_REVISION, NULL,
                                  "svn protocol command 'get-deleted-rev': "
                                  "path '%s' was not deleted in r%ld-%ld; "
                                  "NOTE: newer clients handle this case "
                                  "and do not report it as an error",
                                  full_path, peg_revision, end_revision));

  SVN_ERR(svn_ra_svn__write_cmd_response(conn, pool, "r", revision_deleted));
  return SVN_NO_ERROR;
}

static svn_error_t *
get_inherited_props(svn_ra_svn_conn_t *conn,
                    apr_pool_t *pool,
                    svn_ra_svn__list_t *params,
                    void *baton)
{
  server_baton_t *b = baton;
  const char *path, *full_path, *canonical_path;
  svn_revnum_t rev;
  svn_fs_root_t *root;
  apr_array_header_t *inherited_props;
  int i;
  apr_pool_t *iterpool = svn_pool_create(pool);
  authz_baton_t ab;
  svn_node_kind_t node_kind;

  ab.server = b;
  ab.conn = conn;

  /* Parse arguments. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)", &path, &rev));

  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        iterpool, iterpool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, iterpool, b, svn_authz_read,
                           full_path, FALSE));

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__get_inherited_props(full_path, rev,
                                                   iterpool)));

  /* Fetch the properties and a stream for the contents. */
  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, iterpool));
  SVN_CMD_ERR(svn_fs_check_path(&node_kind, root, full_path, pool));
  if (node_kind == svn_node_none)
    {
      SVN_CMD_ERR(svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                                    _("'%s' path not found"), full_path));
    }
  SVN_CMD_ERR(get_props(NULL, &inherited_props, &ab, root, full_path, pool));

  /* Send successful command response with revision and props. */
  SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "w(!", "success"));

  SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!(?!"));

  for (i = 0; i < inherited_props->nelts; i++)
    {
      svn_prop_inherited_item_t *iprop =
        APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);

      svn_pool_clear(iterpool);
      SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!(c(!",
                                      iprop->path_or_url));
      SVN_ERR(svn_ra_svn__write_proplist(conn, iterpool, iprop->prop_hash));
      SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!))!",
                                      iprop->path_or_url));
    }

  SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "!))"));
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Baton type to be used with list_receiver. */
typedef struct list_receiver_baton_t
{
  /* Send the data through this connection. */
  svn_ra_svn_conn_t *conn;

  /* Send the field selected by these flags. */
  apr_uint32_t dirent_fields;
} list_receiver_baton_t;

/* Implements svn_repos_dirent_receiver_t, sending DIRENT and PATH to the
 * client.  BATON must be a list_receiver_baton_t. */
static svn_error_t *
list_receiver(const char *path,
              svn_dirent_t *dirent,
              void *baton,
              apr_pool_t *pool)
{
  list_receiver_baton_t *b = baton;
  return svn_error_trace(svn_ra_svn__write_dirent(b->conn, pool, path, dirent,
                                                  b->dirent_fields));
}

static svn_error_t *
list(svn_ra_svn_conn_t *conn,
     apr_pool_t *pool,
     svn_ra_svn__list_t *params,
     void *baton)
{
  server_baton_t *b = baton;
  const char *path, *full_path, *canonical_path;
  svn_revnum_t rev;
  svn_depth_t depth;
  apr_array_header_t *patterns = NULL;
  svn_fs_root_t *root;
  const char *depth_word;
  svn_boolean_t path_info_only;
  svn_ra_svn__list_t *dirent_fields_list = NULL;
  svn_ra_svn__list_t *patterns_list = NULL;
  int i;
  list_receiver_baton_t rb;
  svn_error_t *err, *write_err;

  authz_baton_t ab;
  ab.server = b;
  ab.conn = conn;

  /* Read the command parameters. */
  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)w?l?l", &path, &rev,
                                  &depth_word, &dirent_fields_list,
                                  &patterns_list));

  rb.conn = conn;
  SVN_ERR(parse_dirent_fields(&rb.dirent_fields, dirent_fields_list));

  depth = svn_depth_from_word(depth_word);
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        pool, pool));
  full_path = svn_fspath__join(b->repository->fs_path->data,
                               canonical_path, pool);

  /* Read the patterns list.  */
  if (patterns_list)
    {
      patterns = apr_array_make(pool, 0, sizeof(const char *));
      for (i = 0; i < patterns_list->nelts; ++i)
        {
          svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(patterns_list, i);

          if (elt->kind != SVN_RA_SVN_STRING)
            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                    "Pattern field not a string");

          APR_ARRAY_PUSH(patterns, const char *) = elt->u.string.data;
        }
    }

  /* Check authorizations */
  SVN_ERR(must_have_access(conn, pool, b, svn_authz_read,
                           full_path, FALSE));

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_CMD_ERR(svn_fs_youngest_rev(&rev, b->repository->fs, pool));

  SVN_ERR(log_command(b, conn, pool, "%s",
                      svn_log__list(full_path, rev, patterns, depth,
                                    rb.dirent_fields, pool)));

  /* Fetch the root of the appropriate revision. */
  SVN_CMD_ERR(svn_fs_revision_root(&root, b->repository->fs, rev, pool));

  /* Fetch the directory entries if requested and send them immediately. */
  path_info_only = (rb.dirent_fields & ~SVN_DIRENT_KIND) == 0;
  err = svn_repos_list(root, full_path, patterns, depth, path_info_only,
                       authz_check_access_cb_func(b), &ab, list_receiver,
                       &rb, NULL, NULL, pool);


  /* Finish response. */
  write_err = svn_ra_svn__write_word(conn, pool, "done");
  if (write_err)
    {
      svn_error_clear(err);
      return write_err;
    }
  SVN_CMD_ERR(err);

  return svn_error_trace(svn_ra_svn__write_cmd_response(conn, pool, ""));
}

static const svn_ra_svn__cmd_entry_t main_commands[] = {
  { "reparent",        reparent },
  { "get-latest-rev",  get_latest_rev },
  { "get-dated-rev",   get_dated_rev },
  { "change-rev-prop", change_rev_prop },
  { "change-rev-prop2",change_rev_prop2 },
  { "rev-proplist",    rev_proplist },
  { "rev-prop",        rev_prop },
  { "commit",          commit },
  { "get-file",        get_file },
  { "get-dir",         get_dir },
  { "update",          update },
  { "switch",          switch_cmd },
  { "status",          status },
  { "diff",            diff },
  { "get-mergeinfo",   get_mergeinfo },
  { "log",             log_cmd },
  { "check-path",      check_path },
  { "stat",            stat_cmd },
  { "get-locations",   get_locations },
  { "get-location-segments",   get_location_segments },
  { "get-file-revs",   get_file_revs },
  { "lock",            lock },
  { "lock-many",       lock_many },
  { "unlock",          unlock },
  { "unlock-many",     unlock_many },
  { "get-lock",        get_lock },
  { "get-locks",       get_locks },
  { "replay",          replay },
  { "replay-range",    replay_range },
  { "get-deleted-rev", get_deleted_rev },
  { "get-iprops",      get_inherited_props },
  { "list",            list },
  { NULL }
};

/* Skip past the scheme part of a URL, including the tunnel specification
 * if present.  Return NULL if the scheme part is invalid for ra_svn. */
static const char *skip_scheme_part(const char *url)
{
  if (strncmp(url, "svn", 3) != 0)
    return NULL;
  url += 3;
  if (*url == '+')
    url += strcspn(url, ":");
  if (strncmp(url, "://", 3) != 0)
    return NULL;
  return url + 3;
}

/* Check that PATH is a valid repository path, meaning it doesn't contain any
   '..' path segments.
   NOTE: This is similar to svn_path_is_backpath_present, but that function
   assumes the path separator is '/'.  This function also checks for
   segments delimited by the local path separator. */
static svn_boolean_t
repos_path_valid(const char *path)
{
  const char *s = path;

  while (*s)
    {
      /* Scan for the end of the segment. */
      while (*path && *path != '/' && *path != SVN_PATH_LOCAL_SEPARATOR)
        ++path;

      /* Check for '..'. */
#ifdef WIN32
      /* On Windows, don't allow sequences of more than one character
         consisting of just dots and spaces.  Win32 functions treat
         paths such as ".. " and "......." inconsistently.  Make sure
         no one can escape out of the root. */
      if (path - s >= 2 && strspn(s, ". ") == (size_t)(path - s))
        return FALSE;
#else  /* ! WIN32 */
      if (path - s == 2 && s[0] == '.' && s[1] == '.')
        return FALSE;
#endif

      /* Skip all separators. */
      while (*path && (*path == '/' || *path == SVN_PATH_LOCAL_SEPARATOR))
        ++path;
      s = path;
    }

  return TRUE;
}

/* Look for the repository given by URL, using ROOT as the virtual
 * repository root.  If we find one, fill in the repos, fs, repos_url,
 * and fs_path fields of REPOSITORY.  VHOST and READ_ONLY flags are the
 * same as in the server baton.
 *
 * CONFIG_POOL shall be used to load config objects.
 *
 * Use SCRATCH_POOL for temporary allocations.
 *
 */
static svn_error_t *
find_repos(const char *url,
           const char *root,
           svn_boolean_t vhost,
           svn_boolean_t read_only,
           svn_config_t *cfg,
           repository_t *repository,
           svn_repos__config_pool_t *config_pool,
           apr_hash_t *fs_config,
           svn_repos_authz_warning_func_t authz_warning_func,
           void *authz_warning_baton,
           apr_pool_t *result_pool,
           apr_pool_t *scratch_pool)
{
  const char *path, *full_path, *fs_path, *hooks_env, *canonical_path;
  const char *canonical_root;
  svn_stringbuf_t *url_buf;
  svn_boolean_t sasl_requested;

  /* Skip past the scheme and authority part. */
  path = skip_scheme_part(url);
  if (path == NULL)
    return svn_error_createf(SVN_ERR_BAD_URL, NULL,
                             "Non-svn URL passed to svn server: '%s'", url);

  if (! vhost)
    {
      path = strchr(path, '/');
      if (path == NULL)
        path = "";
    }
  SVN_ERR(svn_relpath_canonicalize_safe(&canonical_path, NULL, path,
                                        scratch_pool, scratch_pool));
  path = svn_path_uri_decode(canonical_path, scratch_pool);

  /* Ensure that it isn't possible to escape the root by disallowing
     '..' segments. */
  if (!repos_path_valid(path))
    return svn_error_create(SVN_ERR_BAD_FILENAME, NULL,
                            "Couldn't determine repository path");

  /* Join the server-configured root with the client path. */
  SVN_ERR(svn_dirent_canonicalize_safe(&canonical_root, NULL, root,
                                       scratch_pool, scratch_pool));
  full_path = svn_dirent_join(canonical_root, path, scratch_pool);

  /* Search for a repository in the full path. */
  repository->repos_root = svn_repos_find_root_path(full_path, result_pool);
  if (!repository->repos_root)
    return svn_error_createf(SVN_ERR_RA_SVN_REPOS_NOT_FOUND, NULL,
                             "No repository found in '%s'", url);

  /* Open the repository and fill in b with the resulting information. */
  SVN_ERR(svn_repos_open3(&repository->repos, repository->repos_root,
                          fs_config, result_pool, scratch_pool));
  SVN_ERR(svn_repos_remember_client_capabilities(repository->repos,
                                                 repository->capabilities));
  repository->fs = svn_repos_fs(repository->repos);
  fs_path = full_path + strlen(repository->repos_root);
  repository->fs_path = svn_stringbuf_create(*fs_path ? fs_path : "/",
                                             result_pool);
  url_buf = svn_stringbuf_create(url, result_pool);
  svn_path_remove_components(url_buf,
                        svn_path_component_count(repository->fs_path->data));
  repository->repos_url = url_buf->data;
  repository->authz_repos_name = svn_dirent_is_child(canonical_root,
                                                     repository->repos_root,
                                                     result_pool);
  if (repository->authz_repos_name == NULL)
    repository->repos_name = svn_dirent_basename(repository->repos_root,
                                                 result_pool);
  else
    repository->repos_name = repository->authz_repos_name;
  repository->repos_name = svn_path_uri_encode(repository->repos_name,
                                               result_pool);

  /* If the svnserve configuration has not been loaded then load it from the
   * repository. */
  if (NULL == cfg)
    {
      repository->base = svn_repos_conf_dir(repository->repos, result_pool);

      SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
                                         svn_repos_svnserve_conf
                                            (repository->repos, result_pool),
                                         FALSE, repository->repos,
                                         result_pool));
    }

  SVN_ERR(load_pwdb_config(repository, cfg, config_pool, result_pool));
  SVN_ERR(load_authz_config(repository, repository->repos_root, cfg,
                            authz_warning_func, authz_warning_baton,
                            result_pool, scratch_pool));

  /* Should we use Cyrus SASL? */
  SVN_ERR(svn_config_get_bool(cfg, &sasl_requested,
                              SVN_CONFIG_SECTION_SASL,
                              SVN_CONFIG_OPTION_USE_SASL, FALSE));
  if (sasl_requested)
    {
#ifdef SVN_HAVE_SASL
      const char *val;

      repository->use_sasl = sasl_requested;

      svn_config_get(cfg, &val, SVN_CONFIG_SECTION_SASL,
                    SVN_CONFIG_OPTION_MIN_SSF, "0");
      SVN_ERR(svn_cstring_atoui(&repository->min_ssf, val));

      svn_config_get(cfg, &val, SVN_CONFIG_SECTION_SASL,
                    SVN_CONFIG_OPTION_MAX_SSF, "256");
      SVN_ERR(svn_cstring_atoui(&repository->max_ssf, val));
#else /* !SVN_HAVE_SASL */
      return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
                               _("SASL requested but not compiled in; "
                                 "set '%s' to 'false' or recompile "
                                 "svnserve with SASL support"),
                               SVN_CONFIG_OPTION_USE_SASL);
#endif /* SVN_HAVE_SASL */
    }
  else
    {
      repository->use_sasl = FALSE;
    }

  /* Use the repository UUID as the default realm. */
  SVN_ERR(svn_fs_get_uuid(repository->fs, &repository->realm, scratch_pool));
  svn_config_get(cfg, &repository->realm, SVN_CONFIG_SECTION_GENERAL,
                 SVN_CONFIG_OPTION_REALM, repository->realm);
  repository->realm = apr_pstrdup(result_pool, repository->realm);

  /* Make sure it's possible for the client to authenticate.  Note
     that this doesn't take into account any authz configuration read
     above, because we can't know about access it grants until paths
     are given by the client. */
  set_access(repository, cfg, read_only);

  /* Configure hook script environment variables. */
  svn_config_get(cfg, &hooks_env, SVN_CONFIG_SECTION_GENERAL,
                 SVN_CONFIG_OPTION_HOOKS_ENV, NULL);
  if (hooks_env)
    hooks_env = svn_dirent_internal_style(hooks_env, scratch_pool);

  SVN_ERR(svn_repos_hooks_setenv(repository->repos, hooks_env, scratch_pool));
  repository->hooks_env = apr_pstrdup(result_pool, hooks_env);

  return SVN_NO_ERROR;
}

/* Compute the authentication name EXTERNAL should be able to get, if any. */
static const char *get_tunnel_user(serve_params_t *params, apr_pool_t *pool)
{
  /* Only offer EXTERNAL for connections tunneled over a login agent. */
  if (!params->tunnel)
    return NULL;

  /* If a tunnel user was provided on the command line, use that. */
  if (params->tunnel_user)
    return params->tunnel_user;

  return svn_user_get_name(pool);
}

static void
fs_warning_func(void *baton, svn_error_t *err)
{
  fs_warning_baton_t *b = baton;
  log_error(err, b->server);
}

/* Return the normalized repository-relative path for the given PATH
 * (may be a URL, full path or relative path) and fs contained in the
 * server baton BATON. Allocate the result in POOL.
 */
static const char *
get_normalized_repo_rel_path(void *baton,
                             const char *path,
                             apr_pool_t *pool)
{
  server_baton_t *sb = baton;

  if (svn_path_is_url(path))
    {
      /* This is a copyfrom URL. */
      path = svn_uri_skip_ancestor(sb->repository->repos_url, path, pool);
      path = svn_fspath__canonicalize(path, pool);
    }
  else
    {
      /* This is a base-relative path. */
      if ((path)[0] != '/')
        /* Get an absolute path for use in the FS. */
        path = svn_fspath__join(sb->repository->fs_path->data, path, pool);
    }

  return path;
}

/* Get the revision root for REVISION in fs given by server baton BATON
 * and return it in *FS_ROOT. Use HEAD if REVISION is SVN_INVALID_REVNUM.
 * Use POOL for allocations.
 */
static svn_error_t *
get_revision_root(svn_fs_root_t **fs_root,
                  void *baton,
                  svn_revnum_t revision,
                  apr_pool_t *pool)
{
  server_baton_t *sb = baton;

  if (!SVN_IS_VALID_REVNUM(revision))
    SVN_ERR(svn_fs_youngest_rev(&revision, sb->repository->fs, pool));

  SVN_ERR(svn_fs_revision_root(fs_root, sb->repository->fs, revision, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_props_func(apr_hash_t **props,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  svn_fs_root_t *fs_root;
  svn_error_t *err;

  path = get_normalized_repo_rel_path(baton, path, scratch_pool);
  SVN_ERR(get_revision_root(&fs_root, baton, base_revision, scratch_pool));

  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
    {
      svn_error_clear(err);
      *props = apr_hash_make(result_pool);
      return SVN_NO_ERROR;
    }
  else if (err)
    return svn_error_trace(err);

  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_kind_func(svn_node_kind_t *kind,
                void *baton,
                const char *path,
                svn_revnum_t base_revision,
                apr_pool_t *scratch_pool)
{
  svn_fs_root_t *fs_root;

  path = get_normalized_repo_rel_path(baton, path, scratch_pool);
  SVN_ERR(get_revision_root(&fs_root, baton, base_revision, scratch_pool));

  SVN_ERR(svn_fs_check_path(kind, fs_root, path, scratch_pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_base_func(const char **filename,
                void *baton,
                const char *path,
                svn_revnum_t base_revision,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  svn_stream_t *contents;
  svn_stream_t *file_stream;
  const char *tmp_filename;
  svn_fs_root_t *fs_root;
  svn_error_t *err;

  path = get_normalized_repo_rel_path(baton, path, scratch_pool);
  SVN_ERR(get_revision_root(&fs_root, baton, base_revision, scratch_pool));

  err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
    {
      svn_error_clear(err);
      *filename = NULL;
      return SVN_NO_ERROR;
    }
  else if (err)
    return svn_error_trace(err);
  SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
                                 svn_io_file_del_on_pool_cleanup,
                                 scratch_pool, scratch_pool));
  SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));

  *filename = apr_pstrdup(result_pool, tmp_filename);

  return SVN_NO_ERROR;
}

client_info_t *
get_client_info(svn_ra_svn_conn_t *conn,
                serve_params_t *params,
                apr_pool_t *pool)
{
  client_info_t *client_info = apr_pcalloc(pool, sizeof(*client_info));

  client_info->tunnel = params->tunnel;
  client_info->tunnel_user = get_tunnel_user(params, pool);
  client_info->user = NULL;
  client_info->authz_user = NULL;
  client_info->remote_host = svn_ra_svn_conn_remote_host(conn);

  return client_info;
}

static void
handle_authz_warning(void *baton,
                     const svn_error_t *err,
                     apr_pool_t *scratch_pool)
{
  server_baton_t *const server_baton = baton;
  log_warning(err, server_baton);
  SVN_UNUSED(scratch_pool);
}

/* Construct the server baton for CONN using PARAMS and return it in *BATON.
 * It's lifetime is the same as that of CONN.  SCRATCH_POOL
 */
static svn_error_t *
construct_server_baton(server_baton_t **baton,
                       svn_ra_svn_conn_t *conn,
                       serve_params_t *params,
                       apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  apr_uint64_t ver;
  const char *client_url, *ra_client_string, *client_string, *canonical_url;
  svn_ra_svn__list_t *caplist;
  apr_pool_t *conn_pool = svn_ra_svn__get_pool(conn);
  server_baton_t *b = apr_pcalloc(conn_pool, sizeof(*b));
  fs_warning_baton_t *warn_baton;
  svn_stringbuf_t *cap_log = svn_stringbuf_create_empty(scratch_pool);

  b->repository = apr_pcalloc(conn_pool, sizeof(*b->repository));
  b->repository->username_case = params->username_case;
  b->repository->base = params->base;
  b->repository->pwdb = NULL;
  b->repository->authzdb = NULL;
  b->repository->realm = NULL;
  b->repository->use_sasl = FALSE;

  b->read_only = params->read_only;
  b->pool = conn_pool;
  b->vhost = params->vhost;

  b->logger = params->logger;
  b->client_info = get_client_info(conn, params, conn_pool);

  /* Send greeting.  We don't support version 1 any more, so we can
   * send an empty mechlist. */
  if (params->compression_level > 0)
    SVN_ERR(svn_ra_svn__write_cmd_response(conn, scratch_pool,
                                           "nn()(wwwwwwwwwwwww)",
                                           (apr_uint64_t) 2, (apr_uint64_t) 2,
                                           SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                           SVN_RA_SVN_CAP_SVNDIFF1,
                                           SVN_RA_SVN_CAP_SVNDIFF2_ACCEPTED,
                                           SVN_RA_SVN_CAP_ABSENT_ENTRIES,
                                           SVN_RA_SVN_CAP_COMMIT_REVPROPS,
                                           SVN_RA_SVN_CAP_DEPTH,
                                           SVN_RA_SVN_CAP_LOG_REVPROPS,
                                           SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
                                           SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                           SVN_RA_SVN_CAP_INHERITED_PROPS,
                                           SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE,
                                           SVN_RA_SVN_CAP_LIST
                                           ));
  else
    SVN_ERR(svn_ra_svn__write_cmd_response(conn, scratch_pool,
                                           "nn()(wwwwwwwwwww)",
                                           (apr_uint64_t) 2, (apr_uint64_t) 2,
                                           SVN_RA_SVN_CAP_EDIT_PIPELINE,
                                           SVN_RA_SVN_CAP_ABSENT_ENTRIES,
                                           SVN_RA_SVN_CAP_COMMIT_REVPROPS,
                                           SVN_RA_SVN_CAP_DEPTH,
                                           SVN_RA_SVN_CAP_LOG_REVPROPS,
                                           SVN_RA_SVN_CAP_ATOMIC_REVPROPS,
                                           SVN_RA_SVN_CAP_PARTIAL_REPLAY,
                                           SVN_RA_SVN_CAP_INHERITED_PROPS,
                                           SVN_RA_SVN_CAP_EPHEMERAL_TXNPROPS,
                                           SVN_RA_SVN_CAP_GET_FILE_REVS_REVERSE,
                                           SVN_RA_SVN_CAP_LIST
                                           ));

  /* Read client response, which we assume to be in version 2 format:
   * version, capability list, and client URL; then we do an auth
   * request. */
  SVN_ERR(svn_ra_svn__read_tuple(conn, scratch_pool, "nlc?c(?c)",
                                 &ver, &caplist, &client_url,
                                 &ra_client_string,
                                 &client_string));
  if (ver != 2)
    return svn_error_createf(SVN_ERR_RA_SVN_BAD_VERSION, NULL,
                             "Unsupported ra_svn protocol version"
                             " %"APR_UINT64_T_FMT
                             " (supported versions: [2])", ver);

  SVN_ERR(svn_uri_canonicalize_safe(&canonical_url, NULL, client_url,
                                    conn_pool, scratch_pool));
  client_url = canonical_url;
  SVN_ERR(svn_ra_svn__set_capabilities(conn, caplist));

  /* All released versions of Subversion support edit-pipeline,
   * so we do not accept connections from clients that do not. */
  if (! svn_ra_svn_has_capability(conn, SVN_RA_SVN_CAP_EDIT_PIPELINE))
    return svn_error_create(SVN_ERR_RA_SVN_BAD_VERSION, NULL,
                            "Missing edit-pipeline capability");

  /* find_repos needs the capabilities as a list of words (eventually
     they get handed to the start-commit hook).  While we could add a
     new interface to re-retrieve them from conn and convert the
     result to a list, it's simpler to just convert caplist by hand
     here, since we already have it and turning 'svn_ra_svn__item_t's
     into 'const char *'s is pretty easy.

     We only record capabilities we care about.  The client may report
     more (because it doesn't know what the server cares about). */
  {
    int i;
    svn_ra_svn__item_t *item;

    b->repository->capabilities = apr_array_make(conn_pool, 1,
                                                 sizeof(const char *));
    for (i = 0; i < caplist->nelts; i++)
      {
        static const svn_string_t str_cap_mergeinfo
          = SVN__STATIC_STRING(SVN_RA_SVN_CAP_MERGEINFO);

        item = &SVN_RA_SVN__LIST_ITEM(caplist, i);
        /* ra_svn_set_capabilities() already type-checked for us */
        if (svn_string_compare(&item->u.word, &str_cap_mergeinfo))
          {
            APR_ARRAY_PUSH(b->repository->capabilities, const char *)
              = SVN_RA_CAPABILITY_MERGEINFO;
          }
        /* Save for operational log. */
        if (cap_log->len > 0)
          svn_stringbuf_appendcstr(cap_log, " ");
        svn_stringbuf_appendcstr(cap_log, item->u.word.data);
      }
  }

  /* (*b) has the logger, repository and client_info set, so it can
     be used as the authz_warning_baton that eventyally gets passed
     to log_warning(). */
  err = handle_config_error(find_repos(client_url, params->root, b->vhost,
                                       b->read_only, params->cfg,
                                       b->repository, params->config_pool,
                                       params->fs_config,
                                       handle_authz_warning, b,
                                       conn_pool, scratch_pool),
                            b);
  if (!err)
    {
      if (b->repository->anon_access == NO_ACCESS
          && (b->repository->auth_access == NO_ACCESS
              || (!b->client_info->tunnel_user && !b->repository->pwdb
                  && !b->repository->use_sasl)))
        err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                   "No access allowed to this repository",
                                   b);
    }
  if (!err)
    {
      SVN_ERR(auth_request(conn, scratch_pool, b, READ_ACCESS, FALSE));
      if (current_access(b) == NO_ACCESS)
        err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
                                   "Not authorized for access", b);
    }
  if (err)
    {
      /* Report these errors to the client before closing the connection. */
      err = svn_error_compose_create(err,
              svn_ra_svn__write_cmd_failure(conn, scratch_pool, err));
      err = svn_error_compose_create(err,
              svn_ra_svn__flush(conn, scratch_pool));
      return err;
    }

  SVN_ERR(svn_fs_get_uuid(b->repository->fs, &b->repository->uuid,
                          conn_pool));

  /* We can't claim mergeinfo capability until we know whether the
     repository supports mergeinfo (i.e., is not a 1.4 repository),
     but we don't get the repository url from the client until after
     we've already sent the initial list of server capabilities.  So
     we list repository capabilities here, in our first response after
     the client has sent the url. */
  {
    svn_boolean_t supports_mergeinfo;
    SVN_ERR(svn_repos_has_capability(b->repository->repos,
                                     &supports_mergeinfo,
                                     SVN_REPOS_CAPABILITY_MERGEINFO,
                                     scratch_pool));

    SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "w(cc(!",
                                    "success", b->repository->uuid,
                                    b->repository->repos_url));
    if (supports_mergeinfo)
      SVN_ERR(svn_ra_svn__write_word(conn, scratch_pool,
                                     SVN_RA_SVN_CAP_MERGEINFO));
    SVN_ERR(svn_ra_svn__write_tuple(conn, scratch_pool, "!))"));
    SVN_ERR(svn_ra_svn__flush(conn, scratch_pool));
  }

  /* Log the open. */
  if (ra_client_string == NULL || ra_client_string[0] == '\0')
    ra_client_string = "-";
  else
    ra_client_string = svn_path_uri_encode(ra_client_string, scratch_pool);
  if (client_string == NULL || client_string[0] == '\0')
    client_string = "-";
  else
    client_string = svn_path_uri_encode(client_string, scratch_pool);
  SVN_ERR(log_command(b, conn, scratch_pool,
                      "open %" APR_UINT64_T_FMT " cap=(%s) %s %s %s",
                      ver, cap_log->data,
                      svn_path_uri_encode(b->repository->fs_path->data,
                                          scratch_pool),
                      ra_client_string, client_string));

  warn_baton = apr_pcalloc(conn_pool, sizeof(*warn_baton));
  warn_baton->server = b;
  warn_baton->conn = conn;
  svn_fs_set_warning_func(b->repository->fs, fs_warning_func, warn_baton);

  /* Set up editor shims. */
  {
    svn_delta_shim_callbacks_t *callbacks =
                                svn_delta_shim_callbacks_default(conn_pool);

    callbacks->fetch_base_func = fetch_base_func;
    callbacks->fetch_props_func = fetch_props_func;
    callbacks->fetch_kind_func = fetch_kind_func;
    callbacks->fetch_baton = b;

    SVN_ERR(svn_ra_svn__set_shim_callbacks(conn, callbacks));
  }

  *baton = b;

  return SVN_NO_ERROR;
}

svn_error_t *
serve_interruptable(svn_boolean_t *terminate_p,
                    connection_t *connection,
                    svn_boolean_t (* is_busy)(connection_t *),
                    apr_pool_t *pool)
{
  svn_boolean_t terminate = FALSE;
  svn_error_t *err = NULL;
  const svn_ra_svn__cmd_entry_t *command;
  apr_pool_t *iterpool = svn_pool_create(pool);

  /* Prepare command parser. */
  apr_hash_t *cmd_hash = apr_hash_make(pool);
  for (command = main_commands; command->cmdname; command++)
    svn_hash_sets(cmd_hash, command->cmdname, command);

  /* Auto-initialize connection */
  if (! connection->conn)
    {
      apr_status_t ar;

      /* Enable TCP keep-alives on the socket so we time out when
       * the connection breaks due to network-layer problems.
       * If the peer has dropped the connection due to a network partition
       * or a crash, or if the peer no longer considers the connection
       * valid because we are behind a NAT and our public IP has changed,
       * it will respond to the keep-alive probe with a RST instead of an
       * acknowledgment segment, which will cause svn to abort the session
       * even while it is currently blocked waiting for data from the peer. */
      ar = apr_socket_opt_set(connection->usock, APR_SO_KEEPALIVE, 1);
      if (ar)
        {
          /* It's not a fatal error if we cannot enable keep-alives. */
        }

      /* create the connection, configure ports etc. */
      connection->conn
        = svn_ra_svn_create_conn5(connection->usock, NULL, NULL,
                                  connection->params->compression_level,
                                  connection->params->zero_copy_limit,
                                  connection->params->error_check_interval,
                                  connection->params->max_request_size,
                                  connection->params->max_response_size,
                                  connection->pool);

      /* Construct server baton and open the repository for the first time. */
      err = construct_server_baton(&connection->baton, connection->conn,
                                   connection->params, pool);
    }

  /* If we can't access the repo for some reason, end this connection. */
  if (err)
    terminate = TRUE;

  /* Process incoming commands. */
  while (!terminate && !err)
    {
      svn_pool_clear(iterpool);
      if (is_busy && is_busy(connection))
        {
          svn_boolean_t has_command;

          /* If the server is busy, execute just one command and only if
           * there is one currently waiting in our receive buffers.
           */
          err = svn_ra_svn__has_command(&has_command, &terminate,
                                        connection->conn, iterpool);
          if (!err && has_command)
            err = svn_ra_svn__handle_command(&terminate, cmd_hash,
                                             connection->baton,
                                             connection->conn,
                                             FALSE, iterpool);

          break;
        }
      else
        {
          /* The server is not busy, thus let's serve whichever command
           * comes in next and whenever it comes in.  This requires the
           * busy() callback test to return TRUE while there are still some
           * resources left.
           */
          err = svn_ra_svn__handle_command(&terminate, cmd_hash,
                                           connection->baton,
                                           connection->conn,
                                           FALSE, iterpool);
        }
    }

  /* error or normal end of session. Close the connection */
  svn_pool_destroy(iterpool);
  if (terminate_p)
    *terminate_p = terminate;

  return svn_error_trace(err);
}

svn_error_t *serve(svn_ra_svn_conn_t *conn,
                   serve_params_t *params,
                   apr_pool_t *pool)
{
  server_baton_t *baton = NULL;

  SVN_ERR(construct_server_baton(&baton, conn, params, pool));
  return svn_ra_svn__handle_commands2(conn, pool, main_commands, baton, FALSE);
}
