/* fs-wrap.c --- filesystem interface wrappers.
 *
 * ====================================================================
 *    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 <stdio.h>
#include <string.h>
#include <ctype.h>

#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
#include "svn_path.h"
#include "svn_props.h"
#include "svn_repos.h"
#include "svn_time.h"
#include "svn_sorts.h"
#include "svn_subst.h"
#include "repos.h"
#include "svn_private_config.h"
#include "private/svn_repos_private.h"
#include "private/svn_sorts_private.h"
#include "private/svn_utf_private.h"
#include "private/svn_fspath.h"


/*** Commit wrappers ***/

svn_error_t *
svn_repos_fs_commit_txn(const char **conflict_p,
                        svn_repos_t *repos,
                        svn_revnum_t *new_rev,
                        svn_fs_txn_t *txn,
                        apr_pool_t *pool)
{
  svn_error_t *err, *err2;
  const char *txn_name;
  apr_hash_t *props;
  apr_pool_t *iterpool;
  apr_hash_index_t *hi;
  apr_hash_t *hooks_env;

  *new_rev = SVN_INVALID_REVNUM;
  if (conflict_p)
    *conflict_p = NULL;

  /* Parse the hooks-env file (if any). */
  SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                     pool, pool));

  /* Run pre-commit hooks. */
  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
  SVN_ERR(svn_repos__hooks_pre_commit(repos, hooks_env, txn_name, pool));

  /* Remove any ephemeral transaction properties.  If the commit fails
     we will attempt to restore the properties but if that fails, or
     the process is killed, the properties will be lost. */
  SVN_ERR(svn_fs_txn_proplist(&props, txn, pool));
  iterpool = svn_pool_create(pool);
  for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
    {
      const char *key = apr_hash_this_key(hi);

      svn_pool_clear(iterpool);

      if (strncmp(key, SVN_PROP_TXN_PREFIX,
                  (sizeof(SVN_PROP_TXN_PREFIX) - 1)) == 0)
        {
          SVN_ERR(svn_fs_change_txn_prop(txn, key, NULL, iterpool));
        }
    }
  svn_pool_destroy(iterpool);

  /* Commit. */
  err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool);
  if (! SVN_IS_VALID_REVNUM(*new_rev))
    {
      /* The commit failed, try to restore the ephemeral properties. */
      iterpool = svn_pool_create(pool);
      for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
        {
          const char *key = apr_hash_this_key(hi);
          svn_string_t *val = apr_hash_this_val(hi);

          svn_pool_clear(iterpool);

          if (strncmp(key, SVN_PROP_TXN_PREFIX,
                      (sizeof(SVN_PROP_TXN_PREFIX) - 1)) == 0)
            svn_error_clear(svn_fs_change_txn_prop(txn, key, val, iterpool));
        }
      svn_pool_destroy(iterpool);

      return err;
    }

  /* Run post-commit hooks. */
  if ((err2 = svn_repos__hooks_post_commit(repos, hooks_env,
                                           *new_rev, txn_name, pool)))
    {
      err2 = svn_error_create
               (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2,
                _("Commit succeeded, but post-commit hook failed"));
    }

  return svn_error_compose_create(err, err2);
}



/*** Transaction creation wrappers. ***/


svn_error_t *
svn_repos_fs_begin_txn_for_commit2(svn_fs_txn_t **txn_p,
                                   svn_repos_t *repos,
                                   svn_revnum_t rev,
                                   apr_hash_t *revprop_table,
                                   apr_pool_t *pool)
{
  apr_array_header_t *revprops;
  const char *txn_name;
  svn_string_t *author = svn_hash_gets(revprop_table, SVN_PROP_REVISION_AUTHOR);
  apr_hash_t *hooks_env;
  svn_error_t *err;
  svn_fs_txn_t *txn;

  /* Parse the hooks-env file (if any). */
  SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                     pool, pool));

  /* Begin the transaction, ask for the fs to do on-the-fly lock checks.
     We fetch its name, too, so the start-commit hook can use it.  */
  SVN_ERR(svn_fs_begin_txn2(&txn, repos->fs, rev,
                            SVN_FS_TXN_CHECK_LOCKS, pool));
  err = svn_fs_txn_name(&txn_name, txn, pool);
  if (err)
    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));

  /* We pass the revision properties to the filesystem by adding them
     as properties on the txn.  Later, when we commit the txn, these
     properties will be copied into the newly created revision. */
  revprops = svn_prop_hash_to_array(revprop_table, pool);
  err = svn_repos_fs_change_txn_props(txn, revprops, pool);
  if (err)
    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));

  /* Run start-commit hooks. */
  err = svn_repos__hooks_start_commit(repos, hooks_env,
                                      author ? author->data : NULL,
                                      repos->client_capabilities, txn_name,
                                      pool);
  if (err)
    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));

  /* We have API promise that *TXN_P is unaffected on failure. */
  *txn_p = txn;
  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_fs_begin_txn_for_commit(svn_fs_txn_t **txn_p,
                                  svn_repos_t *repos,
                                  svn_revnum_t rev,
                                  const char *author,
                                  const char *log_msg,
                                  apr_pool_t *pool)
{
  apr_hash_t *revprop_table = apr_hash_make(pool);
  if (author)
    svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
                  svn_string_create(author, pool));
  if (log_msg)
    svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
                  svn_string_create(log_msg, pool));
  return svn_repos_fs_begin_txn_for_commit2(txn_p, repos, rev, revprop_table,
                                            pool);
}


/*** Property wrappers ***/

svn_error_t *
svn_repos__validate_prop(const char *name,
                         const svn_string_t *value,
                         apr_pool_t *pool)
{
  svn_prop_kind_t kind = svn_property_kind2(name);

  /* Allow deleting any property, even a property we don't allow to set. */
  if (value == NULL)
    return SVN_NO_ERROR;

  /* Disallow setting non-regular properties. */
  if (kind != svn_prop_regular_kind)
    return svn_error_createf
      (SVN_ERR_REPOS_BAD_ARGS, NULL,
       _("Storage of non-regular property '%s' is disallowed through the "
         "repository interface, and could indicate a bug in your client"),
       name);

  /* Validate "svn:" properties. */
  if (svn_prop_is_svn_prop(name) && value != NULL)
    {
      /* Validate that translated props (e.g., svn:log) are UTF-8 with
       * LF line endings. */
      if (svn_prop_needs_translation(name))
        {
          if (!svn_utf__is_valid(value->data, value->len))
            {
              return svn_error_createf
                (SVN_ERR_BAD_PROPERTY_VALUE, NULL,
                 _("Cannot accept '%s' property because it is not encoded in "
                   "UTF-8"), name);
            }

          /* Disallow inconsistent line ending style, by simply looking for
           * carriage return characters ('\r'). */
          if (strchr(value->data, '\r') != NULL)
            {
              svn_error_t *err = svn_error_createf
                (SVN_ERR_BAD_PROPERTY_VALUE_EOL, NULL,
                 _("Cannot accept non-LF line endings in '%s' property"),
                   name);

              return svn_error_create(SVN_ERR_BAD_PROPERTY_VALUE, err,
                                      _("Invalid property value"));
            }
        }

      /* "svn:date" should be a valid date. */
      if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
        {
          apr_time_t temp;
          svn_error_t *err;

          err = svn_time_from_cstring(&temp, value->data, pool);
          if (err)
            return svn_error_create(SVN_ERR_BAD_PROPERTY_VALUE,
                                    err, NULL);
        }
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos__normalize_prop(const svn_string_t **result_p,
                          svn_boolean_t *normalized_p,
                          const char *name,
                          const svn_string_t *value,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  if (svn_prop_needs_translation(name) && value)
    {
      svn_string_t *new_value;

      SVN_ERR(svn_subst_translate_string2(&new_value, NULL, normalized_p,
                                          value, "UTF-8", TRUE,
                                          result_pool, scratch_pool));
      *result_p = new_value;
    }
  else
    {
      *result_p = value;
      if (normalized_p)
        *normalized_p = FALSE;
    }

  return SVN_NO_ERROR;
}


/* Verify the mergeinfo property value VALUE and return an error if it
 * is invalid. The PATH on which that property is set is used for error
 * messages only.  Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
verify_mergeinfo(const svn_string_t *value,
                 const char *path,
                 apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  svn_mergeinfo_t mergeinfo;

  /* It's okay to delete svn:mergeinfo. */
  if (value == NULL)
    return SVN_NO_ERROR;

  /* Mergeinfo is UTF-8 encoded so the number of bytes returned by strlen()
   * should match VALUE->LEN. Prevents trailing garbage in the property. */
  if (strlen(value->data) != value->len)
    return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                             _("Commit rejected because mergeinfo on '%s' "
                               "contains unexpected string terminator"),
                             path);

  err = svn_mergeinfo_parse(&mergeinfo, value->data, scratch_pool);
  if (err)
    return svn_error_createf(err->apr_err, err,
                             _("Commit rejected because mergeinfo on '%s' "
                               "is syntactically invalid"),
                             path);
  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_fs_change_node_prop(svn_fs_root_t *root,
                              const char *path,
                              const char *name,
                              const svn_string_t *value,
                              apr_pool_t *pool)
{
  if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
    SVN_ERR(verify_mergeinfo(value, path, pool));

  /* Validate the property, then call the wrapped function. */
  SVN_ERR(svn_repos__validate_prop(name, value, pool));
  return svn_fs_change_node_prop(root, path, name, value, pool);
}


svn_error_t *
svn_repos_fs_change_txn_props(svn_fs_txn_t *txn,
                              const apr_array_header_t *txnprops,
                              apr_pool_t *pool)
{
  int i;

  for (i = 0; i < txnprops->nelts; i++)
    {
      svn_prop_t *prop = &APR_ARRAY_IDX(txnprops, i, svn_prop_t);
      SVN_ERR(svn_repos__validate_prop(prop->name, prop->value, pool));
    }

  return svn_fs_change_txn_props(txn, txnprops, pool);
}


svn_error_t *
svn_repos_fs_change_txn_prop(svn_fs_txn_t *txn,
                             const char *name,
                             const svn_string_t *value,
                             apr_pool_t *pool)
{
  apr_array_header_t *props = apr_array_make(pool, 1, sizeof(svn_prop_t));
  svn_prop_t prop;

  prop.name = name;
  prop.value = value;
  APR_ARRAY_PUSH(props, svn_prop_t) = prop;

  return svn_repos_fs_change_txn_props(txn, props, pool);
}


svn_error_t *
svn_repos_fs_change_rev_prop4(svn_repos_t *repos,
                              svn_revnum_t rev,
                              const char *author,
                              const char *name,
                              const svn_string_t *const *old_value_p,
                              const svn_string_t *new_value,
                              svn_boolean_t use_pre_revprop_change_hook,
                              svn_boolean_t use_post_revprop_change_hook,
                              svn_repos_authz_func_t authz_read_func,
                              void *authz_read_baton,
                              apr_pool_t *pool)
{
  svn_repos_revision_access_level_t readability;

  SVN_ERR(svn_repos_check_revision_access(&readability, repos, rev,
                                          authz_read_func, authz_read_baton,
                                          pool));

  if (readability == svn_repos_revision_access_full)
    {
      const svn_string_t *old_value;
      char action;
      apr_hash_t *hooks_env;

      SVN_ERR(svn_repos__validate_prop(name, new_value, pool));

      /* Fetch OLD_VALUE for svn_fs_change_rev_prop2(). */
      if (old_value_p)
        {
          old_value = *old_value_p;
        }
      else
        {
          /* Get OLD_VALUE anyway, in order for ACTION and OLD_VALUE arguments
           * to the hooks to be accurate. */
          svn_string_t *old_value2;

          SVN_ERR(svn_fs_revision_prop2(&old_value2, repos->fs, rev, name,
                                        TRUE, pool, pool));
          old_value = old_value2;
        }

      /* Prepare ACTION. */
      if (! new_value)
        action = 'D';
      else if (! old_value)
        action = 'A';
      else
        action = 'M';

      /* Parse the hooks-env file (if any, and if to be used). */
      if (use_pre_revprop_change_hook || use_post_revprop_change_hook)
        SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                           pool, pool));

      /* ### currently not passing the old_value to hooks */
      if (use_pre_revprop_change_hook)
        SVN_ERR(svn_repos__hooks_pre_revprop_change(repos, hooks_env, rev,
                                                    author, name, new_value,
                                                    action, pool));

      SVN_ERR(svn_fs_change_rev_prop2(repos->fs, rev, name,
                                      &old_value, new_value, pool));

      if (use_post_revprop_change_hook)
        SVN_ERR(svn_repos__hooks_post_revprop_change(repos, hooks_env, rev,
                                                     author, name, old_value,
                                                     action, pool));
    }
  else  /* rev is either unreadable or only partially readable */
    {
      return svn_error_createf
        (SVN_ERR_AUTHZ_UNREADABLE, NULL,
         _("Write denied:  not authorized to read all of revision %ld"), rev);
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_fs_revision_prop(svn_string_t **value_p,
                           svn_repos_t *repos,
                           svn_revnum_t rev,
                           const char *propname,
                           svn_repos_authz_func_t authz_read_func,
                           void *authz_read_baton,
                           apr_pool_t *pool)
{
  svn_repos_revision_access_level_t readability;

  SVN_ERR(svn_repos_check_revision_access(&readability, repos, rev,
                                          authz_read_func, authz_read_baton,
                                          pool));

  if (readability == svn_repos_revision_access_none)
    {
      /* Property?  What property? */
      *value_p = NULL;
    }
  else if (readability == svn_repos_revision_access_partial)
    {
      /* Only svn:author and svn:date are fetchable. */
      if ((strcmp(propname, SVN_PROP_REVISION_AUTHOR) != 0)
          && (strcmp(propname, SVN_PROP_REVISION_DATE) != 0))
        *value_p = NULL;

      else
        SVN_ERR(svn_fs_revision_prop2(value_p, repos->fs,
                                      rev, propname, TRUE, pool, pool));
    }
  else /* wholly readable revision */
    {
      SVN_ERR(svn_fs_revision_prop2(value_p, repos->fs, rev, propname, TRUE,
                                    pool, pool));
    }

  return SVN_NO_ERROR;
}



svn_error_t *
svn_repos_fs_revision_proplist(apr_hash_t **table_p,
                               svn_repos_t *repos,
                               svn_revnum_t rev,
                               svn_repos_authz_func_t authz_read_func,
                               void *authz_read_baton,
                               apr_pool_t *pool)
{
  svn_repos_revision_access_level_t readability;

  SVN_ERR(svn_repos_check_revision_access(&readability, repos, rev,
                                          authz_read_func, authz_read_baton,
                                          pool));

  if (readability == svn_repos_revision_access_none)
    {
      /* Return an empty hash. */
      *table_p = apr_hash_make(pool);
    }
  else if (readability == svn_repos_revision_access_partial)
    {
      apr_hash_t *tmphash;
      svn_string_t *value;

      /* Produce two property hashtables, both in POOL. */
      SVN_ERR(svn_fs_revision_proplist2(&tmphash, repos->fs, rev, TRUE,
                                        pool, pool));
      *table_p = apr_hash_make(pool);

      /* If they exist, we only copy svn:author and svn:date into the
         'real' hashtable being returned. */
      value = svn_hash_gets(tmphash, SVN_PROP_REVISION_AUTHOR);
      if (value)
        svn_hash_sets(*table_p, SVN_PROP_REVISION_AUTHOR, value);

      value = svn_hash_gets(tmphash, SVN_PROP_REVISION_DATE);
      if (value)
        svn_hash_sets(*table_p, SVN_PROP_REVISION_DATE, value);
    }
  else /* wholly readable revision */
    {
      SVN_ERR(svn_fs_revision_proplist2(table_p, repos->fs, rev, TRUE,
                                        pool, pool));
    }

  return SVN_NO_ERROR;
}

struct lock_many_baton_t {
  svn_boolean_t need_lock;
  apr_array_header_t *paths;
  svn_fs_lock_callback_t lock_callback;
  void *lock_baton;
  svn_error_t *cb_err;
  apr_pool_t *pool;
};

/* Implements svn_fs_lock_callback_t.  Used by svn_repos_fs_lock_many
   and svn_repos_fs_unlock_many to record the paths for use by post-
   hooks, forward to the supplied callback and record any callback
   error. */
static svn_error_t *
lock_many_cb(void *lock_baton,
             const char *path,
             const svn_lock_t *lock,
             svn_error_t *fs_err,
             apr_pool_t *pool)
{
  struct lock_many_baton_t *b = lock_baton;

  if (!b->cb_err && b->lock_callback)
    b->cb_err = b->lock_callback(b->lock_baton, path, lock, fs_err, pool);

  if ((b->need_lock && lock) || (!b->need_lock && !fs_err))
    APR_ARRAY_PUSH(b->paths, const char *) = apr_pstrdup(b->pool, path);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos_fs_lock_many(svn_repos_t *repos,
                       apr_hash_t *targets,
                       const char *comment,
                       svn_boolean_t is_dav_comment,
                       apr_time_t expiration_date,
                       svn_boolean_t steal_lock,
                       svn_fs_lock_callback_t lock_callback,
                       void *lock_baton,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  svn_error_t *err, *cb_err = SVN_NO_ERROR;
  svn_fs_access_t *access_ctx = NULL;
  const char *username = NULL;
  apr_hash_t *hooks_env;
  apr_hash_t *pre_targets = apr_hash_make(scratch_pool);
  apr_hash_index_t *hi;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  struct lock_many_baton_t baton;

  if (!apr_hash_count(targets))
    return SVN_NO_ERROR;

  /* Parse the hooks-env file (if any). */
  SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                     scratch_pool, scratch_pool));

  SVN_ERR(svn_fs_get_access(&access_ctx, repos->fs));
  if (access_ctx)
    SVN_ERR(svn_fs_access_get_username(&username, access_ctx));

  if (! username)
    return svn_error_create
      (SVN_ERR_FS_NO_USER, NULL,
       "Cannot lock path, no authenticated username available.");

  /* Run pre-lock hook.  This could throw error, preventing
     svn_fs_lock2() from happening for that path. */
  for (hi = apr_hash_first(scratch_pool, targets); hi; hi = apr_hash_next(hi))
    {
      const char *new_token;
      svn_fs_lock_target_t *target;
      const char *path = apr_hash_this_key(hi);

      svn_pool_clear(iterpool);

      err = svn_repos__hooks_pre_lock(repos, hooks_env, &new_token, path,
                                      username, comment, steal_lock, iterpool);
      if (err)
        {
          if (!cb_err && lock_callback)
            cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
          svn_error_clear(err);

          continue;
        }

      target = apr_hash_this_val(hi);
      if (*new_token)
        svn_fs_lock_target_set_token(target, new_token);
      svn_hash_sets(pre_targets, path, target);
    }

  if (!apr_hash_count(pre_targets))
    return svn_error_trace(cb_err);

  baton.need_lock = TRUE;
  baton.paths = apr_array_make(scratch_pool, apr_hash_count(pre_targets),
                               sizeof(const char *));
  baton.lock_callback = lock_callback;
  baton.lock_baton = lock_baton;
  baton.cb_err = cb_err;
  baton.pool = scratch_pool;

  err = svn_fs_lock_many(repos->fs, pre_targets, comment,
                         is_dav_comment, expiration_date, steal_lock,
                         lock_many_cb, &baton, result_pool, iterpool);

  /* If there are locks run the post-lock even if there is an error. */
  if (baton.paths->nelts)
    {
      svn_error_t *perr = svn_repos__hooks_post_lock(repos, hooks_env,
                                                     baton.paths, username,
                                                     iterpool);
      if (perr)
        {
          perr = svn_error_create(SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED, perr,
                            _("Locking succeeded, but post-lock hook failed"));
          err = svn_error_compose_create(err, perr);
        }
    }

  svn_pool_destroy(iterpool);

  if (err && cb_err)
    svn_error_compose(err, cb_err);
  else if (!err)
    err = cb_err;

  return svn_error_trace(err);
}

struct lock_baton_t {
  const svn_lock_t *lock;
  svn_error_t *fs_err;
};

/* Implements svn_fs_lock_callback_t.  Used by svn_repos_fs_lock and
   svn_repos_fs_unlock to record the lock and error from
   svn_repos_fs_lock_many and svn_repos_fs_unlock_many. */
static svn_error_t *
lock_cb(void *lock_baton,
        const char *path,
        const svn_lock_t *lock,
        svn_error_t *fs_err,
        apr_pool_t *pool)
{
  struct lock_baton_t *b = lock_baton;

  b->lock = lock;
  b->fs_err = svn_error_dup(fs_err);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos_fs_lock(svn_lock_t **lock,
                  svn_repos_t *repos,
                  const char *path,
                  const char *token,
                  const char *comment,
                  svn_boolean_t is_dav_comment,
                  apr_time_t expiration_date,
                  svn_revnum_t current_rev,
                  svn_boolean_t steal_lock,
                  apr_pool_t *pool)
{
  apr_hash_t *targets = apr_hash_make(pool);
  svn_fs_lock_target_t *target = svn_fs_lock_target_create(token, current_rev,
                                                           pool);
  svn_error_t *err;
  struct lock_baton_t baton = {0};

  svn_hash_sets(targets, path, target);

  err = svn_repos_fs_lock_many(repos, targets, comment, is_dav_comment,
                               expiration_date, steal_lock, lock_cb, &baton,
                               pool, pool);

  if (baton.lock)
    *lock = (svn_lock_t*)baton.lock;

  if (err && baton.fs_err)
    svn_error_compose(err, baton.fs_err);
  else if (!err)
    err = baton.fs_err;

  return svn_error_trace(err);
}


svn_error_t *
svn_repos_fs_unlock_many(svn_repos_t *repos,
                         apr_hash_t *targets,
                         svn_boolean_t break_lock,
                         svn_fs_lock_callback_t lock_callback,
                         void *lock_baton,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  svn_error_t *err, *cb_err = SVN_NO_ERROR;
  svn_fs_access_t *access_ctx = NULL;
  const char *username = NULL;
  apr_hash_t *hooks_env;
  apr_hash_t *pre_targets = apr_hash_make(scratch_pool);
  apr_hash_index_t *hi;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  struct lock_many_baton_t baton;

  if (!apr_hash_count(targets))
    return SVN_NO_ERROR;

  /* Parse the hooks-env file (if any). */
  SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                     scratch_pool, scratch_pool));

  SVN_ERR(svn_fs_get_access(&access_ctx, repos->fs));
  if (access_ctx)
    SVN_ERR(svn_fs_access_get_username(&username, access_ctx));

  if (! break_lock && ! username)
    return svn_error_create
      (SVN_ERR_FS_NO_USER, NULL,
       _("Cannot unlock, no authenticated username available"));

  /* Run pre-unlock hook.  This could throw error, preventing
     svn_fs_unlock_many() from happening for that path. */
  for (hi = apr_hash_first(scratch_pool, targets); hi; hi = apr_hash_next(hi))
    {
      const char *path = apr_hash_this_key(hi);
      const char *token = apr_hash_this_val(hi);

      svn_pool_clear(iterpool);

      err = svn_repos__hooks_pre_unlock(repos, hooks_env, path, username, token,
                                        break_lock, iterpool);
      if (err)
        {
          if (!cb_err && lock_callback)
            cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
          svn_error_clear(err);

          continue;
        }

      svn_hash_sets(pre_targets, path, token);
    }

  if (!apr_hash_count(pre_targets))
    return svn_error_trace(cb_err);

  baton.need_lock = FALSE;
  baton.paths = apr_array_make(scratch_pool, apr_hash_count(pre_targets),
                               sizeof(const char *));
  baton.lock_callback = lock_callback;
  baton.lock_baton = lock_baton;
  baton.cb_err = cb_err;
  baton.pool = scratch_pool;

  err = svn_fs_unlock_many(repos->fs, pre_targets, break_lock,
                           lock_many_cb, &baton, result_pool, iterpool);

  /* If there are 'unlocks' run the post-unlock even if there is an error. */
  if (baton.paths->nelts)
    {
      svn_error_t *perr = svn_repos__hooks_post_unlock(repos, hooks_env,
                                                       baton.paths,
                                                       username, iterpool);
      if (perr)
        {
          perr = svn_error_create(SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED, perr,
                           _("Unlock succeeded, but post-unlock hook failed"));
          err = svn_error_compose_create(err, perr);
        }
    }

  svn_pool_destroy(iterpool);

  if (err && cb_err)
    svn_error_compose(err, cb_err);
  else if (!err)
    err = cb_err;

  return svn_error_trace(err);
}

svn_error_t *
svn_repos_fs_unlock(svn_repos_t *repos,
                    const char *path,
                    const char *token,
                    svn_boolean_t break_lock,
                    apr_pool_t *pool)
{
  apr_hash_t *targets = apr_hash_make(pool);
  svn_error_t *err;
  struct lock_baton_t baton = {0};

  if (!token)
    token = "";

  svn_hash_sets(targets, path, token);

  err = svn_repos_fs_unlock_many(repos, targets, break_lock, lock_cb, &baton,
                                 pool, pool);

  if (err && baton.fs_err)
    svn_error_compose(err, baton.fs_err);
  else if (!err)
    err = baton.fs_err;

  return svn_error_trace(err);
}


struct get_locks_baton_t
{
  svn_fs_t *fs;
  svn_fs_root_t *head_root;
  svn_repos_authz_func_t authz_read_func;
  void *authz_read_baton;
  apr_hash_t *locks;
};


/* This implements the svn_fs_get_locks_callback_t interface. */
static svn_error_t *
get_locks_callback(void *baton,
                   svn_lock_t *lock,
                   apr_pool_t *pool)
{
  struct get_locks_baton_t *b = baton;
  svn_boolean_t readable = TRUE;
  apr_pool_t *hash_pool = apr_hash_pool_get(b->locks);

  /* If there's auth to deal with, deal with it. */
  if (b->authz_read_func)
    SVN_ERR(b->authz_read_func(&readable, b->head_root, lock->path,
                               b->authz_read_baton, pool));

  /* If we can read this lock path, add the lock to the return hash. */
  if (readable)
    svn_hash_sets(b->locks, apr_pstrdup(hash_pool, lock->path),
                  svn_lock_dup(lock, hash_pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_fs_get_locks2(apr_hash_t **locks,
                        svn_repos_t *repos,
                        const char *path,
                        svn_depth_t depth,
                        svn_repos_authz_func_t authz_read_func,
                        void *authz_read_baton,
                        apr_pool_t *pool)
{
  apr_hash_t *all_locks = apr_hash_make(pool);
  svn_revnum_t head_rev;
  struct get_locks_baton_t baton;

  SVN_ERR_ASSERT((depth == svn_depth_empty) ||
                 (depth == svn_depth_files) ||
                 (depth == svn_depth_immediates) ||
                 (depth == svn_depth_infinity));

  SVN_ERR(svn_fs_youngest_rev(&head_rev, repos->fs, pool));

  /* Populate our callback baton. */
  baton.fs = repos->fs;
  baton.locks = all_locks;
  baton.authz_read_func = authz_read_func;
  baton.authz_read_baton = authz_read_baton;
  SVN_ERR(svn_fs_revision_root(&(baton.head_root), repos->fs,
                               head_rev, pool));

  /* Get all the locks. */
  SVN_ERR(svn_fs_get_locks2(repos->fs, path, depth,
                            get_locks_callback, &baton, pool));

  *locks = baton.locks;
  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_fs_get_mergeinfo2(svn_repos_t *repos,
                            const apr_array_header_t *paths,
                            svn_revnum_t rev,
                            svn_mergeinfo_inheritance_t inherit,
                            svn_boolean_t include_descendants,
                            svn_repos_authz_func_t authz_read_func,
                            void *authz_read_baton,
                            svn_repos_mergeinfo_receiver_t receiver,
                            void *receiver_baton,
                            apr_pool_t *scratch_pool)
{
  /* Here we cast away 'const', but won't try to write through this pointer
   * without first allocating a new array. */
  apr_array_header_t *readable_paths = (apr_array_header_t *) paths;
  svn_fs_root_t *root;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  if (!SVN_IS_VALID_REVNUM(rev))
    SVN_ERR(svn_fs_youngest_rev(&rev, repos->fs, scratch_pool));
  SVN_ERR(svn_fs_revision_root(&root, repos->fs, rev, scratch_pool));

  /* Filter out unreadable paths before divining merge tracking info. */
  if (authz_read_func)
    {
      int i;

      for (i = 0; i < paths->nelts; i++)
        {
          svn_boolean_t readable;
          const char *path = APR_ARRAY_IDX(paths, i, char *);
          svn_pool_clear(iterpool);
          SVN_ERR(authz_read_func(&readable, root, path, authz_read_baton,
                                  iterpool));
          if (readable && readable_paths != paths)
            APR_ARRAY_PUSH(readable_paths, const char *) = path;
          else if (!readable && readable_paths == paths)
            {
              /* Requested paths differ from readable paths.  Fork
                 list of readable paths from requested paths. */
              int j;
              readable_paths = apr_array_make(scratch_pool, paths->nelts - 1,
                                              sizeof(char *));
              for (j = 0; j < i; j++)
                {
                  path = APR_ARRAY_IDX(paths, j, char *);
                  APR_ARRAY_PUSH(readable_paths, const char *) = path;
                }
            }
        }
    }

  /* We consciously do not perform authz checks on the paths returned
     in *MERGEINFO, avoiding massive authz overhead which would allow
     us to protect the name of where a change was merged from, but not
     the change itself. */
  /* ### TODO(reint): ... but how about descendant merged-to paths? */
  if (readable_paths->nelts > 0)
    SVN_ERR(svn_fs_get_mergeinfo3(root, readable_paths, inherit,
                                  include_descendants, TRUE,
                                  receiver, receiver_baton,
                                  scratch_pool));

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

struct pack_notify_baton
{
  svn_repos_notify_func_t notify_func;
  void *notify_baton;
};

/* Implements svn_fs_pack_notify_t. */
static svn_error_t *
pack_notify_func(void *baton,
                 apr_int64_t shard,
                 svn_fs_pack_notify_action_t pack_action,
                 apr_pool_t *pool)
{
  struct pack_notify_baton *pnb = baton;
  svn_repos_notify_t *notify;
  svn_repos_notify_action_t repos_action;

  /* Simple conversion works for these values. */
  SVN_ERR_ASSERT(pack_action >= svn_fs_pack_notify_start
                 && pack_action <= svn_fs_pack_notify_noop);

  repos_action = pack_action == svn_fs_pack_notify_noop
               ? svn_repos_notify_pack_noop
               : pack_action + svn_repos_notify_pack_shard_start
                             - svn_fs_pack_notify_start;

  notify = svn_repos_notify_create(repos_action, pool);
  notify->shard = shard;
  pnb->notify_func(pnb->notify_baton, notify, pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos_fs_pack2(svn_repos_t *repos,
                   svn_repos_notify_func_t notify_func,
                   void *notify_baton,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
                   apr_pool_t *pool)
{
  struct pack_notify_baton pnb;

  pnb.notify_func = notify_func;
  pnb.notify_baton = notify_baton;

  return svn_fs_pack(repos->db_path,
                     notify_func ? pack_notify_func : NULL,
                     notify_func ? &pnb : NULL,
                     cancel_func, cancel_baton, pool);
}

svn_error_t *
svn_repos_fs_get_inherited_props(apr_array_header_t **inherited_props_p,
                                 svn_fs_root_t *root,
                                 const char *path,
                                 const char *propname,
                                 svn_repos_authz_func_t authz_read_func,
                                 void *authz_read_baton,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_array_header_t *inherited_props;
  const char *parent_path = path;

  inherited_props = apr_array_make(result_pool, 1,
                                   sizeof(svn_prop_inherited_item_t *));
  while (!(parent_path[0] == '/' && parent_path[1] == '\0'))
    {
      svn_boolean_t allowed = TRUE;
      apr_hash_t *parent_properties = NULL;

      svn_pool_clear(iterpool);
      parent_path = svn_fspath__dirname(parent_path, scratch_pool);

      if (authz_read_func)
        SVN_ERR(authz_read_func(&allowed, root, parent_path,
                                authz_read_baton, iterpool));
      if (allowed)
        {
          if (propname)
            {
              svn_string_t *propval;

              SVN_ERR(svn_fs_node_prop(&propval, root, parent_path, propname,
                                       result_pool));
              if (propval)
                {
                  parent_properties = apr_hash_make(result_pool);
                  svn_hash_sets(parent_properties, propname, propval);
                }
            }
          else
            {
              SVN_ERR(svn_fs_node_proplist(&parent_properties, root,
                                           parent_path, result_pool));
            }

          if (parent_properties && apr_hash_count(parent_properties))
            {
              svn_prop_inherited_item_t *i_props =
                apr_pcalloc(result_pool, sizeof(*i_props));
              i_props->path_or_url =
                apr_pstrdup(result_pool, parent_path + 1);
              i_props->prop_hash = parent_properties;
              /* Build the output array in depth-first order. */
              SVN_ERR(svn_sort__array_insert2(inherited_props, &i_props, 0));
            }
        }
    }

  svn_pool_destroy(iterpool);

  *inherited_props_p = inherited_props;
  return SVN_NO_ERROR;
}

/*
 * vim:ts=4:sw=2:expandtab:tw=80:fo=tcroq
 * vim:isk=a-z,A-Z,48-57,_,.,-,>
 * vim:cino=>1s,e0,n0,f0,{.5s,}0,^-.5s,=.5s,t0,+1s,c3,(0,u0,\:0
 */
