/*
 * lock.c:  routines for locking working copy subdirectories.
 *
 * ====================================================================
 * Copyright (c) 2000-2008 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

#include <apr_pools.h>
#include <apr_time.h>

#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_sorts.h"
#include "svn_types.h"

#include "wc.h"
#include "adm_files.h"
#include "lock.h"
#include "questions.h"
#include "props.h"
#include "log.h"
#include "entries.h"
#include "wc_db.h"

#include "svn_private_config.h"
#include "private/svn_wc_private.h"



typedef struct
{
  /* Handle to the administrative database. */
  svn_wc__db_t *db;

  /* SET is a hash of svn_wc_adm_access_t* keyed on char* representing the
     path to directories that are open. */
  apr_hash_t *set;

} svn_wc__adm_shared_t;


struct svn_wc_adm_access_t
{
  /* The working copy format version number for the directory */
  int wc_format;

  /* PATH to directory which contains the administrative area */
  const char *path;

  enum svn_wc__adm_access_type {

    /* SVN_WC__ADM_ACCESS_UNLOCKED indicates no lock is held allowing
       read-only access */
    svn_wc__adm_access_unlocked,

    /* SVN_WC__ADM_ACCESS_WRITE_LOCK indicates that a write lock is held
       allowing read-write access */
    svn_wc__adm_access_write_lock,

    /* SVN_WC__ADM_ACCESS_CLOSED indicates that the baton has been
       closed. */
    svn_wc__adm_access_closed

  } type;

  /* LOCK_EXISTS is set TRUE when the write lock exists */
  svn_boolean_t lock_exists;

  /* SHARED contains state that is shared among all associated
     access batons. */
  svn_wc__adm_shared_t *shared;

  /* SET_OWNER is TRUE if SET is allocated from this access baton */
  svn_boolean_t set_owner;

  /* ENTRIES_HIDDEN is all cached entries including those in
     state deleted or state absent. It may be NULL. */
  apr_hash_t *entries_all;

  /* A hash mapping const char * entry names to hashes of wcprops.
     These hashes map const char * names to svn_string_t * values.
     NULL of the wcprops hasn't been read into memory.
     ### Since there are typically just one or two wcprops per entry,
     ### we could use a more compact way of storing them. */
  apr_hash_t *wcprops;

  /* POOL is used to allocate cached items, they need to persist for the
     lifetime of this access baton */
  apr_pool_t *pool;

};

/* This is a placeholder used in the set hash to represent missing
   directories.  Only its address is important, it contains no useful
   data. */
static const svn_wc_adm_access_t missing;


static svn_error_t *
do_close(svn_wc_adm_access_t *adm_access, svn_boolean_t preserve_lock,
         svn_boolean_t recurse, apr_pool_t *scratch_pool);
static void join_batons(svn_wc__adm_shared_t *dst_shared,
                        svn_wc_adm_access_t *t_access,
                        apr_pool_t *pool);


/* Defining this conditional will result in a client that will refuse to
   upgrade working copies.  This can be useful if you want to avoid
   problems caused by accidentally running a development version of SVN
   on a working copy that you typically use with an older version. */
#ifndef SVN_DISABLE_WC_UPGRADE

/* Write, to LOG_ACCUM, log entries to convert an old WC that did not have
   propcaching into a WC that uses propcaching.  Do this conversion for
   the directory of ADM_ACCESS and its file children.  Use POOL for
   temporary allocations.  */
static svn_error_t *
introduce_propcaching(svn_stringbuf_t *log_accum,
                      svn_wc_adm_access_t *adm_access,
                      apr_pool_t *pool)
{
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create(pool);

  SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool));

  /* Reinstall the properties for each file and this dir; subdirs are handled
     when they're opened. */
  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      void *val;
      const svn_wc_entry_t *entry;
      const char *entrypath;
      apr_hash_t *base_props, *props;

      apr_hash_this(hi, NULL, NULL, &val);
      entry = val;

      if (entry->kind != svn_node_file
          && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) != 0)
        continue;

      svn_pool_clear(subpool);

      entrypath = svn_dirent_join(adm_access->path, entry->name, subpool);
      SVN_ERR(svn_wc__load_props(&base_props, &props, NULL, adm_access,
                                 entrypath, subpool));
      SVN_ERR(svn_wc__install_props(&log_accum, adm_access, entrypath,
                                    base_props, props, TRUE, subpool));
    }

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}

/* Write, to LOG_ACCUM, commands to convert a WC that has wcprops in individual
   files to use one wcprops file per directory.
   Do this for ADM_ACCESS and its file children, using POOL for temporary
   allocations. */
static svn_error_t *
convert_wcprops(svn_stringbuf_t *log_accum,
                svn_wc_adm_access_t *adm_access,
                apr_pool_t *pool)
{
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create(pool);

  SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool));

  /* Walk over the entries, adding a modify-wcprop command for each wcprop.
     Note that the modifications happen in memory and are just written once
     at the end of the log execution, so this isn't as inefficient as it
     might sound. */
  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      void *val;
      const svn_wc_entry_t *entry;
      apr_hash_t *wcprops;
      apr_hash_index_t *hj;
      const char *full_path;

      apr_hash_this(hi, NULL, NULL, &val);
      entry = val;

      full_path = svn_dirent_join(adm_access->path, entry->name, pool);

      if (entry->kind != svn_node_file
          && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) != 0)
        continue;

      svn_pool_clear(subpool);

      SVN_ERR(svn_wc__wcprop_list(&wcprops, entry->name, adm_access, subpool));

      /* Create a subsubpool for the inner loop...
         No, just kidding.  There are typically just one or two wcprops
         per entry... */
      for (hj = apr_hash_first(subpool, wcprops); hj; hj = apr_hash_next(hj))
        {
          const void *key2;
          void *val2;
          const char *propname;
          svn_string_t *propval;

          apr_hash_this(hj, &key2, NULL, &val2);
          propname = key2;
          propval = val2;
          SVN_ERR(svn_wc__loggy_modify_wcprop(&log_accum, adm_access,
                                              full_path, propname,
                                              propval->data,
                                              subpool));
        }
    }

  return SVN_NO_ERROR;
}

/* Maybe upgrade the working copy directory represented by ADM_ACCESS
   to the latest 'SVN_WC__VERSION'.  ADM_ACCESS must contain a write
   lock.  Use POOL for all temporary allocation.

   Not all upgrade paths are necessarily supported.  For example,
   upgrading a version 1 working copy results in an error.

   Sometimes the format file can contain "0" while the administrative
   directory is being constructed; calling this on a format 0 working
   copy has no effect and returns no error. */
static svn_error_t *
maybe_upgrade_format(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
{
  SVN_ERR(svn_wc__check_format(adm_access->wc_format,
                               adm_access->path,
                               pool));

  /* We can upgrade all formats that are accepted by
     svn_wc__check_format. */
  if (adm_access->wc_format < SVN_WC__VERSION)
    {
      svn_boolean_t cleanup_required;
      svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);

      /* Don't try to mess with the WC if there are old log files left. */
      SVN_ERR(svn_wc__adm_is_cleanup_required(&cleanup_required,
                                              adm_access, pool));
      if (cleanup_required)
        return SVN_NO_ERROR;

      /* First, loggily upgrade the format file. */
      SVN_ERR(svn_wc__loggy_upgrade_format(&log_accum, SVN_WC__VERSION, pool));

      /* Possibly convert an old WC that doesn't use propcaching. */
      if (adm_access->wc_format <= SVN_WC__NO_PROPCACHING_VERSION)
        SVN_ERR(introduce_propcaching(log_accum, adm_access, pool));

      /* If the WC uses one file per entry for wcprops, give back some inodes
         to the poor user. */
      if (adm_access->wc_format <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
        SVN_ERR(convert_wcprops(log_accum, adm_access, pool));

      SVN_ERR(svn_wc__write_log(adm_access, 0, log_accum, pool));

      if (adm_access->wc_format <= SVN_WC__WCPROPS_MANY_FILES_VERSION)
        {
          /* Remove wcprops directory, dir-props, README.txt and empty-file
             files.
             We just silently ignore errors, because keeping these files is
             not catastrophic. */

          svn_error_clear(svn_io_remove_dir2(
              svn_wc__adm_child(adm_access->path, SVN_WC__ADM_WCPROPS, pool),
              FALSE, NULL, NULL, pool));
          svn_error_clear(svn_io_remove_file(
              svn_wc__adm_child(adm_access->path, SVN_WC__ADM_DIR_WCPROPS,
                                pool),
              pool));
          svn_error_clear(svn_io_remove_file(
              svn_wc__adm_child(adm_access->path, SVN_WC__ADM_EMPTY_FILE, pool),
              pool));
          svn_error_clear(svn_io_remove_file(
              svn_wc__adm_child(adm_access->path, SVN_WC__ADM_README, pool),
              pool));
        }

      SVN_ERR(svn_wc__run_log(adm_access, NULL, pool));
    }

  return SVN_NO_ERROR;
}

#else

/* Alternate version of the above for use when working copy upgrades
   are disabled.  Return an error if the working copy described by
   ADM_ACCESS is not at the latest 'SVN_WC__VERSION'.  Use POOL for all
   temporary allocation.  */
static svn_error_t *
maybe_upgrade_format(svn_wc_adm_access_t *adm_access, apr_pool_t *pool)
{
  SVN_ERR(svn_wc__check_format(adm_access->wc_format,
                               adm_access->path,
                               pool));

  if (adm_access->wc_format != SVN_WC__VERSION)
    {
      return svn_error_createf(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL,
                               "Would upgrade working copy '%s' from old "
                               "format (%d) to current format (%d), "
                               "but automatic upgrade has been disabled",
                               svn_path_local_style(adm_access->path, pool),
                               adm_access->wc_format, SVN_WC__VERSION);
    }

  return SVN_NO_ERROR;
}

#endif


/* Create a physical lock file in the admin directory for ADM_ACCESS.

   Note: most callers of this function determine the wc_format for the
   lock soon afterwards.  We recommend calling maybe_upgrade_format()
   as soon as you have the wc_format for a lock, since that's a good
   opportunity to drag old working directories into the modern era. */
static svn_error_t *
create_lock(const char *path, apr_pool_t *pool)
{
  const char *lock_path = svn_wc__adm_child(path, SVN_WC__ADM_LOCK, pool);
  svn_error_t *err;
  apr_file_t *file;

  err = svn_io_file_open(&file, lock_path,
                         APR_WRITE | APR_CREATE | APR_EXCL,
                         APR_OS_DEFAULT,
                         pool);
  if (err == NULL)
    return svn_io_file_close(file, pool);

  if (APR_STATUS_IS_EEXIST(err->apr_err))
    {
      svn_error_clear(err);
      return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
                               _("Working copy '%s' locked"),
                               svn_path_local_style(path, pool));
    }

  return err;
}


/* An APR pool cleanup handler.  This handles access batons that have not
   been closed when their pool gets destroyed.  The physical locks
   associated with such batons remain in the working copy if they are
   protecting a log file. */
static apr_status_t
pool_cleanup(void *p)
{
  svn_wc_adm_access_t *lock = p;
  svn_boolean_t cleanup;
  svn_error_t *err;

  if (lock->type == svn_wc__adm_access_closed)
    return SVN_NO_ERROR;

  err = svn_wc__adm_is_cleanup_required(&cleanup, lock, lock->pool);
  if (!err)
    err = do_close(lock, cleanup, TRUE, lock->pool);

  /* ### Is this the correct way to handle the error? */
  if (err)
    {
      apr_status_t apr_err = err->apr_err;
      svn_error_clear(err);
      return apr_err;
    }
  else
    return APR_SUCCESS;
}

/* An APR pool cleanup handler.  This is a child handler, it removes the
   main pool handler. */
static apr_status_t
pool_cleanup_child(void *p)
{
  svn_wc_adm_access_t *lock = p;
  apr_pool_cleanup_kill(lock->pool, lock, pool_cleanup);
  return APR_SUCCESS;
}

/* Allocate from POOL, initialise and return an access baton. TYPE and PATH
   are used to initialise the baton.  */
static svn_error_t *
adm_access_alloc(svn_wc_adm_access_t **adm_access,
                 enum svn_wc__adm_access_type type,
                 const char *path,
                 apr_pool_t *pool)
{
  svn_wc_adm_access_t *lock = apr_palloc(pool, sizeof(*lock));

  lock->type = type;
  lock->entries_all = NULL;
  lock->wcprops = NULL;
  lock->wc_format = 0;
  lock->shared = NULL;
  lock->lock_exists = FALSE;
  lock->set_owner = FALSE;
  lock->path = apr_pstrdup(pool, path);
  lock->pool = pool;

  *adm_access = lock;

  if (type == svn_wc__adm_access_write_lock)
    {
      SVN_ERR(create_lock(path, pool));
      lock->lock_exists = TRUE;
    }
  else
    lock->lock_exists = FALSE;

  return SVN_NO_ERROR;
}

/* Add LOCK into the SHARED set, for the specified PATH. The lock will
   be updated to refer to SHARED, since it is now part of that set. */
static void
add_to_shared(const char *path,
              svn_wc_adm_access_t *lock,
              svn_wc__adm_shared_t *shared)
{
  apr_hash_set(shared->set, path, APR_HASH_KEY_STRING, lock);

  if (lock != &missing)
    lock->shared = shared;
}

static void
adm_ensure_set(svn_wc_adm_access_t *adm_access)
{
  if (adm_access->shared == NULL)
    adm_access->shared = apr_pcalloc(adm_access->pool,
                                     sizeof(*adm_access->shared));

  if (adm_access->shared->set == NULL)
    {
      adm_access->set_owner = TRUE;
      adm_access->shared->set = apr_hash_make(adm_access->pool);

      add_to_shared(adm_access->path, adm_access, adm_access->shared);
    }
}

static svn_error_t *
probe(const char **dir,
      const char *path,
      int *wc_format,
      apr_pool_t *pool)
{
  svn_node_kind_t kind;

  SVN_ERR(svn_io_check_path(path, &kind, pool));
  if (kind == svn_node_dir)
    SVN_ERR(svn_wc_check_wc(path, wc_format, pool));
  else
    *wc_format = 0;

  /* a "version" of 0 means a non-wc directory */
  if (kind != svn_node_dir || *wc_format == 0)
    {
      /* Passing a path ending in "." or ".." to svn_path_dirname() is
         probably always a bad idea; certainly it is in this case.
         Unfortunately, svn_path_dirname()'s current signature can't
         return an error, so we have to insert the protection in this
         caller, as making the larger API change would be very
         destabilizing right now (just before 1.0).  See issue #1617. */
      const char *base_name = svn_dirent_basename(path, pool);
      if ((strcmp(base_name, "..") == 0)
          || (strcmp(base_name, ".") == 0))
        {
          return svn_error_createf
            (SVN_ERR_WC_BAD_PATH, NULL,
             _("Path '%s' ends in '%s', "
               "which is unsupported for this operation"),
             svn_path_local_style(path, pool), base_name);
        }

      *dir = svn_dirent_dirname(path, pool);
    }
  else
    *dir = path;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__adm_steal_write_lock(svn_wc_adm_access_t **adm_access,
                             const char *path,
                             apr_pool_t *pool)
{
  svn_error_t *err;
  svn_wc_adm_access_t *lock;

  err = adm_access_alloc(&lock, svn_wc__adm_access_write_lock, path, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_WC_LOCKED)
        {
          svn_error_clear(err);  /* Steal existing lock */
          lock->lock_exists = TRUE;  /* Seriously. We have the lock. */
        }
      else
        return err;
    }

  /* We have a write lock.  If the working copy has an old
     format, this is the time to upgrade it. */
  SVN_ERR(svn_wc_check_wc(path, &lock->wc_format, pool));
  SVN_ERR(maybe_upgrade_format(lock, pool));

  *adm_access = lock;
  return SVN_NO_ERROR;
}

/* This is essentially the guts of svn_wc_adm_open3.
 *
 * If the working copy is already locked, return SVN_ERR_WC_LOCKED; if
 * it is not a versioned directory, return SVN_ERR_WC_NOT_DIRECTORY.
 */
static svn_error_t *
do_open(svn_wc_adm_access_t **adm_access,
        const char *path,
        svn_boolean_t write_lock,
        int levels_to_lock,
        svn_cancel_func_t cancel_func,
        void *cancel_baton,
        apr_pool_t *pool)
{
  svn_wc_adm_access_t *lock;
  int wc_format;
  svn_error_t *err;
  apr_pool_t *subpool = svn_pool_create(pool);

  err = svn_wc_check_wc(path, &wc_format, subpool);

  if (wc_format == 0 || (err && APR_STATUS_IS_ENOENT(err->apr_err)))
    {
      return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, err,
                               _("'%s' is not a working copy"),
                               svn_path_local_style(path, pool));
    }
  svn_error_clear(err);

  /* Need to create a new lock */
  SVN_ERR(adm_access_alloc(&lock,
                           write_lock
                             ? svn_wc__adm_access_write_lock
                             : svn_wc__adm_access_unlocked,
                           path, pool));
  lock->wc_format = wc_format;
  if (write_lock)
    SVN_ERR(maybe_upgrade_format(lock, subpool));

  if (levels_to_lock != 0)
    {
      apr_hash_t *entries;
      apr_hash_index_t *hi;

      /* Reduce levels_to_lock since we are about to recurse */
      if (levels_to_lock > 0)
        levels_to_lock--;

      SVN_ERR(svn_wc_entries_read(&entries, lock, FALSE, subpool));

      if (apr_hash_count(entries) > 0)
        {
          /* All the batons will accumulate on <lock>. */
          adm_ensure_set(lock);
        }

      /* Open the tree */
      for (hi = apr_hash_first(subpool, entries); hi; hi = apr_hash_next(hi))
        {
          void *val;
          const svn_wc_entry_t *entry;
          svn_wc_adm_access_t *entry_access;
          const char *entry_path;

          /* See if someone wants to cancel this operation. */
          if (cancel_func)
            {
              err = cancel_func(cancel_baton);
              if (err)
                {
                  svn_error_clear(svn_wc_adm_close2(lock, subpool));
                  svn_pool_destroy(subpool);
                  return err;
                }
            }

          apr_hash_this(hi, NULL, NULL, &val);
          entry = val;
          if (entry->kind != svn_node_dir
              || ! strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR))
            continue;

          /* Also skip the excluded subdir. */
          if (entry->depth == svn_depth_exclude)
            continue;

          entry_path = svn_dirent_join(path, entry->name, subpool);

          /* Don't use the subpool pool here, the lock needs to persist */
          err = do_open(&entry_access, entry_path, write_lock,
                        levels_to_lock, cancel_func, cancel_baton,
                        lock->pool);
          if (err == NULL)
            join_batons(lock->shared, entry_access, subpool);

          if (err)
            {
              if (err->apr_err != SVN_ERR_WC_NOT_DIRECTORY)
                {
                  /* See comment above regarding this assignment. */
                  svn_error_clear(svn_wc_adm_close2(lock, subpool));
                  svn_pool_destroy(subpool);
                  return err;
                }

              /* It's missing or obstructed, so store a placeholder */
              svn_error_clear(err);
              add_to_shared(apr_pstrdup(lock->pool, entry_path),
                            (svn_wc_adm_access_t *)&missing,
                            lock->shared);
            }

          /* ### what is the comment below all about? */
          /* ### Perhaps we should verify that the parent and child agree
             ### about the URL of the child? */
        }
    }

  /* It's important that the cleanup handler is registered *after* at least
     one UTF8 conversion has been done, since such a conversion may create
     the apr_xlate_t object in the pool, and that object must be around
     when the cleanup handler runs.  If the apr_xlate_t cleanup handler
     were to run *before* the access baton cleanup handler, then the access
     baton's handler won't work. */
  apr_pool_cleanup_register(lock->pool, lock, pool_cleanup,
                            pool_cleanup_child);
  *adm_access = lock;

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_adm_open3(svn_wc_adm_access_t **adm_access,
                 svn_wc_adm_access_t *associated,
                 const char *path,
                 svn_boolean_t write_lock,
                 int levels_to_lock,
                 svn_cancel_func_t cancel_func,
                 void *cancel_baton,
                 apr_pool_t *pool)
{
  svn_error_t *err;

  /* Make sure that ASSOCIATED has a set of access batons, so that we can
     glom a reference to self into it. */
  if (associated)
    {
      svn_wc_adm_access_t *lock;

      adm_ensure_set(associated);
      lock = apr_hash_get(associated->shared->set, path, APR_HASH_KEY_STRING);
      if (lock && lock != &missing)
        /* Already locked.  The reason we don't return the existing baton
           here is that the user is supposed to know whether a directory is
           locked: if it's not locked call svn_wc_adm_open, if it is locked
           call svn_wc_adm_retrieve.  */
        return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
                                 _("Working copy '%s' locked"),
                                 svn_path_local_style(path, pool));
    }

  err = do_open(adm_access, path,
                write_lock, levels_to_lock, cancel_func, cancel_baton, pool);

  if (err == NULL && associated != NULL)
    join_batons(associated->shared, *adm_access, pool);

  return err;
}

svn_error_t *
svn_wc__adm_pre_open(svn_wc_adm_access_t **adm_access,
                     const char *path,
                     apr_pool_t *pool)
{
  svn_wc_adm_access_t *lock;

  SVN_ERR(adm_access_alloc(&lock, svn_wc__adm_access_write_lock, path, pool));

  apr_pool_cleanup_register(lock->pool, lock, pool_cleanup,
                            pool_cleanup_child);
  *adm_access = lock;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_adm_probe_open3(svn_wc_adm_access_t **adm_access,
                       svn_wc_adm_access_t *associated,
                       const char *path,
                       svn_boolean_t write_lock,
                       int levels_to_lock,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *pool)
{
  svn_error_t *err;
  const char *dir;
  int wc_format;

  SVN_ERR(probe(&dir, path, &wc_format, pool));

  /* If we moved up a directory, then the path is not a directory, or it
     is not under version control. In either case, the notion of
     levels_to_lock does not apply to the provided path.  Disable it so
     that we don't end up trying to lock more than we need.  */
  if (dir != path)
    levels_to_lock = 0;

  err = svn_wc_adm_open3(adm_access, associated, dir, write_lock,
                         levels_to_lock, cancel_func, cancel_baton, pool);
  if (err)
    {
      svn_error_t *err2;

      /* If we got an error on the parent dir, that means we failed to
         get an access baton for the child in the first place.  And if
         the reason we couldn't get the child access baton is that the
         child is not a versioned directory, then return an error
         about the child, not the parent. */
      svn_node_kind_t child_kind;
      if ((err2 = svn_io_check_path(path, &child_kind, pool)))
        {
          svn_error_compose(err, err2);
          return err;
        }

      if ((dir != path)
          && (child_kind == svn_node_dir)
          && (err->apr_err == SVN_ERR_WC_NOT_DIRECTORY))
        {
          svn_error_clear(err);
          return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,
                                   _("'%s' is not a working copy"),
                                   svn_path_local_style(path, pool));
        }
      else
        {
          return err;
        }
    }

  if (wc_format && ! (*adm_access)->wc_format)
    (*adm_access)->wc_format = wc_format;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__adm_retrieve_internal(svn_wc_adm_access_t **adm_access,
                              svn_wc_adm_access_t *associated,
                              const char *path,
                              apr_pool_t *pool)
{
  if (associated->shared && associated->shared->set)
    *adm_access = apr_hash_get(associated->shared->set,
                               path, APR_HASH_KEY_STRING);
  else if (! strcmp(associated->path, path))
    *adm_access = associated;
  else
    *adm_access = NULL;

  if (*adm_access == &missing)
    *adm_access = NULL;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_adm_retrieve(svn_wc_adm_access_t **adm_access,
                    svn_wc_adm_access_t *associated,
                    const char *path,
                    apr_pool_t *pool)
{
  SVN_ERR(svn_wc__adm_retrieve_internal(adm_access, associated, path, pool));

  /* Most of the code expects access batons to exist, so returning an error
     generally makes the calling code simpler as it doesn't need to check
     for NULL batons. */
  if (! *adm_access)
    {
      const char *wcpath;
      const svn_wc_entry_t *subdir_entry;
      svn_node_kind_t wckind;
      svn_node_kind_t kind;
      svn_error_t *err;

      err = svn_wc_entry(&subdir_entry, path, associated, TRUE, pool);

      /* If we can't get an entry here, we are in pretty bad shape,
         and will have to fall back to using just regular old paths to
         see what's going on.  */
      if (err)
        {
          svn_error_clear(err);
          subdir_entry = NULL;
        }

      err = svn_io_check_path(path, &kind, pool);

      /* If we can't check the path, we can't make a good error
         message.  */
      if (err)
        {
          return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, err,
                                   _("Unable to check path existence for '%s'"),
                                   svn_path_local_style(path, pool));
        }

      if (subdir_entry)
        {
          if (subdir_entry->kind == svn_node_dir
              && kind == svn_node_file)
            {
              const char *err_msg = apr_psprintf
                (pool, _("Expected '%s' to be a directory but found a file"),
                 svn_path_local_style(path, pool));
              return svn_error_create(SVN_ERR_WC_NOT_LOCKED,
                                      svn_error_create
                                        (SVN_ERR_WC_NOT_DIRECTORY, NULL,
                                         err_msg),
                                      err_msg);
            }
          else if (subdir_entry->kind == svn_node_file
                   && kind == svn_node_dir)
            {
              const char *err_msg = apr_psprintf
                (pool, _("Expected '%s' to be a file but found a directory"),
                 svn_path_local_style(path, pool));
              return svn_error_create(SVN_ERR_WC_NOT_LOCKED,
                                      svn_error_create(SVN_ERR_WC_NOT_FILE,
                                                       NULL, err_msg),
                                      err_msg);
            }
        }

      wcpath = svn_wc__adm_child(path, NULL, pool);
      err = svn_io_check_path(wcpath, &wckind, pool);

      /* If we can't check the path, we can't make a good error
         message.  */
      if (err)
        {
          return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, err,
                                   _("Unable to check path existence for '%s'"),
                                   svn_path_local_style(wcpath, pool));
        }

      if (kind == svn_node_none)
        {
          const char *err_msg = apr_psprintf(pool,
                                             _("Directory '%s' is missing"),
                                             svn_path_local_style(path, pool));
          return svn_error_create(SVN_ERR_WC_NOT_LOCKED,
                                  svn_error_create(SVN_ERR_WC_PATH_NOT_FOUND,
                                                   NULL, err_msg),
                                  err_msg);
        }

      else if (kind == svn_node_dir && wckind == svn_node_none)
        return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
                                 _("Directory '%s' containing working copy admin area is missing"),
                                 svn_path_local_style(wcpath, pool));

      else if (kind == svn_node_dir && wckind == svn_node_dir)
        return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
                                 _("Unable to lock '%s'"),
                                 svn_path_local_style(path, pool));

      /* If all else fails, return our useless generic error.  */
      return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
                               _("Working copy '%s' is not locked"),
                               svn_path_local_style(path, pool));
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc_adm_probe_retrieve(svn_wc_adm_access_t **adm_access,
                          svn_wc_adm_access_t *associated,
                          const char *path,
                          apr_pool_t *pool)
{
  const char *dir;
  const svn_wc_entry_t *entry;
  int wc_format;
  svn_error_t *err;

  SVN_ERR(svn_wc_entry(&entry, path, associated, TRUE, pool));

  if (! entry)
    /* Not a versioned item, probe it */
    SVN_ERR(probe(&dir, path, &wc_format, pool));
  else if (entry->kind != svn_node_dir)
    dir = svn_dirent_dirname(path, pool);
  else
    dir = path;

  err = svn_wc_adm_retrieve(adm_access, associated, dir, pool);
  if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
    {
      /* We'll receive a NOT LOCKED error for various reasons,
         including the reason we'll actually want to test for:
         The path is a versioned directory, but missing, in which case
         we want its parent's adm_access (which holds minimal data
         on the child) */
      svn_error_clear(err);
      SVN_ERR(probe(&dir, path, &wc_format, pool));
      SVN_ERR(svn_wc_adm_retrieve(adm_access, associated, dir, pool));
    }
  else
    return err;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_adm_probe_try2(svn_wc_adm_access_t **adm_access,
                      svn_wc_adm_access_t *associated,
                      const char *path,
                      svn_boolean_t write_lock,
                      int levels_to_lock,
                      apr_pool_t *pool)
{
  return svn_wc_adm_probe_try3(adm_access, associated, path, write_lock,
                               levels_to_lock, NULL, NULL, pool);
}

svn_error_t *
svn_wc_adm_probe_try3(svn_wc_adm_access_t **adm_access,
                      svn_wc_adm_access_t *associated,
                      const char *path,
                      svn_boolean_t write_lock,
                      int levels_to_lock,
                      svn_cancel_func_t cancel_func,
                      void *cancel_baton,
                      apr_pool_t *pool)
{
  svn_error_t *err;

  err = svn_wc_adm_probe_retrieve(adm_access, associated, path, pool);

  /* SVN_ERR_WC_NOT_LOCKED would mean there was no access baton for
     path in associated, in which case we want to open an access
     baton and add it to associated. */
  if (err && (err->apr_err == SVN_ERR_WC_NOT_LOCKED))
    {
      svn_error_clear(err);
      err = svn_wc_adm_probe_open3(adm_access, associated,
                                   path, write_lock, levels_to_lock,
                                   cancel_func, cancel_baton,
                                   svn_wc_adm_access_pool(associated));

      /* If the path is not a versioned directory, we just return a
         null access baton with no error.  Note that of the errors we
         do report, the most important (and probably most likely) is
         SVN_ERR_WC_LOCKED.  That error would mean that someone else
         has this area locked, and we definitely want to bail in that
         case. */
      if (err && (err->apr_err == SVN_ERR_WC_NOT_DIRECTORY))
        {
          svn_error_clear(err);
          *adm_access = NULL;
          err = NULL;
        }
    }

  return err;
}

/* A helper for svn_wc_adm_open_anchor.  Add all the access batons in the
   T_ACCESS set, including T_ACCESS, into the DST_SHARED set. */
static void join_batons(svn_wc__adm_shared_t *dst_shared,
                        svn_wc_adm_access_t *t_access,
                        apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  if (t_access->shared == NULL || t_access->shared->set == NULL)
    {
      add_to_shared(t_access->path, t_access, dst_shared);
      return;
    }

  for (hi = apr_hash_first(pool, t_access->shared->set);
       hi;
       hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;

      apr_hash_this(hi, &key, NULL, &val);
      add_to_shared(key, val, dst_shared);
    }
  t_access->set_owner = FALSE;
}

svn_error_t *
svn_wc_adm_open_anchor(svn_wc_adm_access_t **anchor_access,
                       svn_wc_adm_access_t **target_access,
                       const char **target,
                       const char *path,
                       svn_boolean_t write_lock,
                       int levels_to_lock,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *pool)
{
  const char *base_name = svn_dirent_basename(path, pool);

  if (svn_path_is_empty(path)
      || svn_dirent_is_root(path, strlen(path))
      || ! strcmp(base_name, ".."))
    {
      SVN_ERR(do_open(anchor_access, path, write_lock, levels_to_lock,
                      cancel_func, cancel_baton, pool));
      *target_access = *anchor_access;
      *target = "";
    }
  else
    {
      svn_error_t *err;
      svn_wc_adm_access_t *p_access = NULL;
      svn_wc_adm_access_t *t_access = NULL;
      const char *parent = svn_dirent_dirname(path, pool);
      svn_error_t *p_access_err = SVN_NO_ERROR;

      /* Try to open parent of PATH to setup P_ACCESS */
      err = do_open(&p_access, parent, write_lock, 0,
                    cancel_func, cancel_baton, pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
            {
              svn_error_clear(err);
              p_access = NULL;
            }
          else if (write_lock && (err->apr_err == SVN_ERR_WC_LOCKED
                                  || APR_STATUS_IS_EACCES(err->apr_err)))
            {
              /* If P_ACCESS isn't to be returned then a read-only baton
                 will do for now, but keep the error in case we need it. */
              svn_error_t *err2 = do_open(&p_access, parent, FALSE, 0,
                                          cancel_func, cancel_baton, pool);
              if (err2)
                {
                  svn_error_clear(err2);
                  return err;
                }
              p_access_err = err;
            }
          else
            return err;
        }

      /* Try to open PATH to setup T_ACCESS */
      err = do_open(&t_access, path, write_lock, levels_to_lock,
                    cancel_func, cancel_baton, pool);
      if (err)
        {
          if (! p_access || err->apr_err != SVN_ERR_WC_NOT_DIRECTORY)
            {
              if (p_access)
                svn_error_clear(svn_wc_adm_close2(p_access, pool));
              svn_error_clear(p_access_err);
              return err;
            }

          svn_error_clear(err);
          t_access = NULL;
        }

      /* At this stage might have P_ACCESS, T_ACCESS or both */

      /* Check for switched or disjoint P_ACCESS and T_ACCESS */
      if (p_access && t_access)
        {
          const svn_wc_entry_t *t_entry, *p_entry, *t_entry_in_p;

          err = svn_wc_entry(&t_entry_in_p, path, p_access, FALSE, pool);
          if (! err)
            err = svn_wc_entry(&t_entry, path, t_access, FALSE, pool);
          if (! err)
            err = svn_wc_entry(&p_entry, parent, p_access, FALSE, pool);
          if (err)
            {
              svn_error_clear(p_access_err);
              svn_error_clear(svn_wc_adm_close2(p_access, pool));
              svn_error_clear(svn_wc_adm_close2(t_access, pool));
              return err;
            }

          /* Disjoint won't have PATH in P_ACCESS, switched will have
             incompatible URLs */
          if (! t_entry_in_p
              ||
              (p_entry->url && t_entry->url
               && (strcmp(svn_uri_dirname(t_entry->url, pool), p_entry->url)
                   || strcmp(svn_path_uri_encode(base_name, pool),
                             svn_uri_basename(t_entry->url, pool)))))
            {
              /* Switched or disjoint, so drop P_ACCESS */
              err = svn_wc_adm_close2(p_access, pool);
              if (err)
                {
                  svn_error_clear(p_access_err);
                  svn_error_clear(svn_wc_adm_close2(t_access, pool));
                  return err;
                }
              p_access = NULL;
            }
        }

      if (p_access)
        {
          if (p_access_err)
            {
              /* Need P_ACCESS, so the read-only temporary won't do */
              if (t_access)
                svn_error_clear(svn_wc_adm_close2(t_access, pool));
              svn_error_clear(svn_wc_adm_close2(p_access, pool));
              return p_access_err;
            }
          else if (t_access)
            {
              adm_ensure_set(p_access);
              join_batons(p_access->shared, t_access, pool);
            }
        }
      svn_error_clear(p_access_err);

      if (! t_access)
         {
          const svn_wc_entry_t *t_entry;
          err = svn_wc_entry(&t_entry, path, p_access, FALSE, pool);
          if (err)
            {
              svn_error_clear(svn_wc_adm_close2(p_access, pool));
              return err;
            }
          if (t_entry && t_entry->kind == svn_node_dir)
            {
              adm_ensure_set(p_access);
              add_to_shared(apr_pstrdup(p_access->pool, path),
                            (svn_wc_adm_access_t *)&missing,
                            p_access->shared);
            }
        }

      *anchor_access = p_access ? p_access : t_access;
      *target_access = t_access ? t_access : p_access;

      if (! p_access)
        *target = "";
      else
        *target = base_name;
    }

  return SVN_NO_ERROR;
}


/* Does the work of closing the access baton ADM_ACCESS.  Any physical
   locks are removed from the working copy if PRESERVE_LOCK is FALSE, or
   are left if PRESERVE_LOCK is TRUE.  Any associated access batons that
   are direct descendants will also be closed.

   ### FIXME: If the set has a "hole", say it contains locks for the
   ### directories A, A/B, A/B/C/X but not A/B/C then closing A/B will not
   ### reach A/B/C/X .
 */
static svn_error_t *
do_close(svn_wc_adm_access_t *adm_access,
         svn_boolean_t preserve_lock,
         svn_boolean_t recurse,
         apr_pool_t *scratch_pool)
{
  if (adm_access->type == svn_wc__adm_access_closed)
    return SVN_NO_ERROR;

  /* Close descendant batons */
  if (recurse && adm_access->shared && adm_access->shared->set)
    {
      int i;
      apr_array_header_t *children
        = svn_sort__hash(adm_access->shared->set,
                         svn_sort_compare_items_as_paths,
                         scratch_pool);

      /* Go backwards through the list to close children before their
         parents. */
      for (i = children->nelts - 1; i >= 0; --i)
        {
          svn_sort__item_t *item = &APR_ARRAY_IDX(children, i,
                                                  svn_sort__item_t);
          const char *path = item->key;
          svn_wc_adm_access_t *child = item->value;

          if (child == &missing)
            {
              /* We don't close the missing entry, but get rid of it from
                 the set. */
              apr_hash_set(adm_access->shared->set,
                           path, APR_HASH_KEY_STRING, NULL);
              continue;
            }

          if (! svn_dirent_is_ancestor(adm_access->path, path)
              || strcmp(adm_access->path, path) == 0)
            continue;

          SVN_ERR(do_close(child, preserve_lock, FALSE, scratch_pool));
        }
    }

  /* Physically unlock if required */
  if (adm_access->type == svn_wc__adm_access_write_lock)
    {
      if (adm_access->lock_exists && ! preserve_lock)
        {
          /* Remove the physical lock in the admin directory for
             PATH. It is acceptable for the administrative area to
             have disappeared, such as when the directory is removed
             from the working copy.  It is an error for the lock to
             have disappeared if the administrative area still exists. */

          svn_error_t *err = svn_wc__remove_adm_file(adm_access,
                                                     SVN_WC__ADM_LOCK,
                                                     scratch_pool);
          if (err)
            {
              if (svn_wc__adm_area_exists(adm_access, scratch_pool))
                return err;
              svn_error_clear(err);
            }

          adm_access->lock_exists = FALSE;
        }
    }

  /* Reset to prevent further use of the lock. */
  adm_access->type = svn_wc__adm_access_closed;

  /* Detach from set */
  if (adm_access->shared && adm_access->shared->set)
    {
      apr_hash_set(adm_access->shared->set,
                   adm_access->path, APR_HASH_KEY_STRING,
                   NULL);

      SVN_ERR_ASSERT(! adm_access->set_owner
                     || apr_hash_count(adm_access->shared->set) == 0);
    }

  /* Close the underlying wc_db. */
  if (adm_access->set_owner)
    {
      SVN_ERR_ASSERT(apr_hash_count(adm_access->shared->set) == 0);
      if (adm_access->shared->db)
        SVN_ERR(svn_wc__db_close(adm_access->shared->db, scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_adm_close2(svn_wc_adm_access_t *adm_access, apr_pool_t *scratch_pool)
{
  return do_close(adm_access, FALSE, TRUE, scratch_pool);
}

svn_boolean_t
svn_wc_adm_locked(const svn_wc_adm_access_t *adm_access)
{
  return adm_access->type == svn_wc__adm_access_write_lock;
}

svn_error_t *
svn_wc__adm_write_check(const svn_wc_adm_access_t *adm_access,
                        apr_pool_t *scratch_pool)
{
  if (adm_access->type == svn_wc__adm_access_write_lock)
    {
      if (adm_access->lock_exists)
        {
          /* Check physical lock still exists and hasn't been stolen.  This
             really is paranoia, I have only ever seen one report of this
             triggering (from someone using the 0.25 release) and that was
             never reproduced.  The check accesses the physical filesystem
             so it is expensive, but it only runs when we are going to
             modify the admin area.  If it ever proves to be a bottleneck
             the physical check could be removed, just leaving the logical
             check. */
          svn_boolean_t locked;

          SVN_ERR(svn_wc_locked(&locked, adm_access->path, scratch_pool));
          if (! locked)
            return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
                                     _("Write-lock stolen in '%s'"),
                                     svn_path_local_style(adm_access->path,
                                                          scratch_pool));
        }
    }
  else
    {
      return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
                               _("No write-lock in '%s'"),
                               svn_path_local_style(adm_access->path,
                                                    scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_locked(svn_boolean_t *locked, const char *path, apr_pool_t *pool)
{
  svn_node_kind_t kind;
  const char *lockfile = svn_wc__adm_child(path, SVN_WC__ADM_LOCK, pool);

  SVN_ERR(svn_io_check_path(lockfile, &kind, pool));
  if (kind == svn_node_file)
    *locked = TRUE;
  else if (kind == svn_node_none)
    *locked = FALSE;
  else
    return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
                             _("Lock file '%s' is not a regular file"),
                             svn_path_local_style(lockfile, pool));

  return SVN_NO_ERROR;
}


const char *
svn_wc_adm_access_path(const svn_wc_adm_access_t *adm_access)
{
  return adm_access->path;
}


apr_pool_t *
svn_wc_adm_access_pool(const svn_wc_adm_access_t *adm_access)
{
  return adm_access->pool;
}


svn_error_t *
svn_wc__adm_is_cleanup_required(svn_boolean_t *cleanup,
                                const svn_wc_adm_access_t *adm_access,
                                apr_pool_t *pool)
{
  if (adm_access->type == svn_wc__adm_access_write_lock)
    {
      svn_node_kind_t kind;
      const char *log_path = svn_wc__adm_child(adm_access->path,
                                               SVN_WC__ADM_LOG, pool);

      /* The presence of a log file demands cleanup */
      SVN_ERR(svn_io_check_path(log_path, &kind, pool));
      *cleanup = (kind == svn_node_file);
    }
  else
    *cleanup = FALSE;

  return SVN_NO_ERROR;
}


void
svn_wc__adm_access_set_entries(svn_wc_adm_access_t *adm_access,
                               apr_hash_t *entries)
{
  adm_access->entries_all = entries;
}


apr_hash_t *
svn_wc__adm_access_entries(svn_wc_adm_access_t *adm_access,
                           apr_pool_t *pool)
{
  return adm_access->entries_all;
}

void
svn_wc__adm_access_set_wcprops(svn_wc_adm_access_t *adm_access,
                        apr_hash_t *wcprops)
{
  adm_access->wcprops = wcprops;
}

apr_hash_t *
svn_wc__adm_access_wcprops(const svn_wc_adm_access_t *adm_access)
{
  return adm_access->wcprops;
}


int
svn_wc__adm_wc_format(const svn_wc_adm_access_t *adm_access)
{
  return adm_access->wc_format;
}

void
svn_wc__adm_set_wc_format(svn_wc_adm_access_t *adm_access,
                          int format)
{
  adm_access->wc_format = format;
}

svn_error_t *
svn_wc__adm_get_db(svn_wc__db_t **db, svn_wc_adm_access_t *adm_access,
                   apr_pool_t *scratch_pool)
{
  adm_ensure_set(adm_access);

  if (adm_access->shared->db == NULL)
    {
      const char *abspath;
      svn_wc__db_openmode_t mode;

      /* ### need to determine mode based on callers' needs. */
      mode = svn_wc__db_openmode_default;

      SVN_ERR(svn_dirent_get_absolute(&abspath, adm_access->path,
                                      scratch_pool));
      SVN_ERR(svn_wc__db_open(&adm_access->shared->db,
                              mode,
                              abspath,
                              NULL /* ### need the config */,
                              adm_access->pool, scratch_pool));
    }

  *db = adm_access->shared->db;
  return SVN_NO_ERROR;
}

svn_boolean_t
svn_wc__adm_missing(const svn_wc_adm_access_t *adm_access,
                    const char *path)
{
  if (adm_access->shared
      && adm_access->shared->set
      && apr_hash_get(adm_access->shared->set,
                      path, APR_HASH_KEY_STRING) == &missing)
    return TRUE;

  return FALSE;
}


/* Extend the scope of the svn_wc_adm_access_t * passed in as WALK_BATON
   for its entire WC tree.  An implementation of
   svn_wc_entry_callbacks2_t's found_entry() API. */
static svn_error_t *
extend_lock_found_entry(const char *path,
                        const svn_wc_entry_t *entry,
                        void *walk_baton,
                        apr_pool_t *pool)
{
  /* If PATH is a directory, and it's not already locked, lock it all
     the way down to its leaf nodes. */
  if (entry->kind == svn_node_dir &&
      strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) != 0)
    {
      svn_wc_adm_access_t *anchor_access = walk_baton, *adm_access;
      svn_boolean_t write_lock =
        (anchor_access->type == svn_wc__adm_access_write_lock);
      svn_error_t *err = svn_wc_adm_probe_try3(&adm_access, anchor_access,
                                               path, write_lock, -1,
                                               NULL, NULL, pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_WC_LOCKED)
            /* Good!  The directory is *already* locked... */
            svn_error_clear(err);
          else
            return err;
        }
    }
  return SVN_NO_ERROR;
}


/* WC entry walker callbacks for svn_wc__adm_extend_lock_to_tree(). */
static const svn_wc_entry_callbacks2_t extend_lock_walker =
  {
    extend_lock_found_entry,
    svn_wc__walker_default_error_handler
  };


svn_error_t *
svn_wc__adm_extend_lock_to_tree(svn_wc_adm_access_t *adm_access,
                                apr_pool_t *pool)
{
  return svn_wc_walk_entries3(adm_access->path, adm_access,
                              &extend_lock_walker, adm_access,
                              svn_depth_infinity, FALSE, NULL, NULL, pool);
}

