/*
 * add.c:  wrappers around wc add/mkdir functionality.
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include <string.h>
#include <apr_lib.h>
#include <apr_fnmatch.h>
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_string.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_io.h"
#include "svn_config.h"
#include "svn_props.h"
#include "svn_hash.h"
#include "svn_sorts.h"
#include "client.h"
#include "svn_ctype.h"

#include "private/svn_client_private.h"
#include "private/svn_wc_private.h"
#include "private/svn_ra_private.h"
#include "private/svn_sorts_private.h"
#include "private/svn_magic.h"

#include "svn_private_config.h"



/*** Code. ***/

/* Remove leading and trailing white space from a C string, in place. */
static void
trim_string(char **pstr)
{
  char *str = *pstr;
  size_t i;

  while (svn_ctype_isspace(*str))
    str++;
  *pstr = str;
  i = strlen(str);
  while ((i > 0) && svn_ctype_isspace(str[i-1]))
    i--;
  str[i] = '\0';
}

/* Remove leading and trailing single- or double quotes from a C string,
 * in place. */
static void
unquote_string(char **pstr)
{
  char *str = *pstr;
  size_t i = strlen(str);

  if (i > 0 && ((*str == '"' && str[i - 1] == '"') ||
                (*str == '\'' && str[i - 1] == '\'')))
    {
      str[i - 1] = '\0';
      str++;
    }
  *pstr = str;
}

/* Split PROPERTY and store each individual value in PROPS.
   Allocates from POOL. */
static void
split_props(apr_array_header_t **props,
            const char *property,
            apr_pool_t *pool)
{
  apr_array_header_t *temp_props;
  char *new_prop;
  int i = 0;
  int j = 0;

  temp_props = apr_array_make(pool, 4, sizeof(char *));
  new_prop = apr_palloc(pool, strlen(property)+1);

  for (i = 0; property[i] != '\0'; i++)
    {
      if (property[i] != ';')
        {
          new_prop[j] = property[i];
          j++;
        }
      else if (property[i] == ';')
        {
          /* ";;" becomes ";" */
          if (property[i+1] == ';')
            {
              new_prop[j] = ';';
              j++;
              i++;
            }
          else
            {
              new_prop[j] = '\0';
              APR_ARRAY_PUSH(temp_props, char *) = new_prop;
              new_prop += j + 1;
              j = 0;
            }
        }
    }
  new_prop[j] = '\0';
  APR_ARRAY_PUSH(temp_props, char *) = new_prop;
  *props = temp_props;
}

/* PROPVALS is a hash mapping char * property names to const char * property
   values.  PROPERTIES can be empty but not NULL.

   If FILENAME doesn't match the filename pattern PATTERN case insensitively,
   the do nothing.  Otherwise for each 'name':'value' pair in PROPVALS, add
   a new entry mappying 'name' to a svn_string_t * wrapping the 'value' in
   PROPERTIES.  The svn_string_t is allocated in the pool used to allocate
   PROPERTIES, but the char *'s from PROPVALS are re-used in PROPERTIES.
   If PROPVALS contains a 'svn:mime-type' mapping, then set *MIMETYPE to
   the mapped value.  Likewise if PROPVALS contains a mapping for
   svn:executable, then set *HAVE_EXECUTABLE to TRUE.

   Use SCRATCH_POOL for temporary allocations.
*/
static void
get_auto_props_for_pattern(apr_hash_t *properties,
                           const char **mimetype,
                           svn_boolean_t *have_executable,
                           const char *filename,
                           const char *pattern,
                           apr_hash_t *propvals,
                           apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  /* check if filename matches and return if it doesn't */
  if (apr_fnmatch(pattern, filename,
                  APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
    return;

  for (hi = apr_hash_first(scratch_pool, propvals);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      const char *propname = apr_hash_this_key(hi);
      const char *propval = apr_hash_this_val(hi);
      svn_string_t *propval_str =
        svn_string_create_empty(apr_hash_pool_get(properties));

      propval_str->data = propval;
      propval_str->len = strlen(propval);

      svn_hash_sets(properties, propname, propval_str);
      if (strcmp(propname, SVN_PROP_MIME_TYPE) == 0)
        *mimetype = propval;
      else if (strcmp(propname, SVN_PROP_EXECUTABLE) == 0)
        *have_executable = TRUE;
    }
}

svn_error_t *
svn_client__get_paths_auto_props(apr_hash_t **properties,
                                 const char **mimetype,
                                 const char *path,
                                 svn_magic__cookie_t *magic_cookie,
                                 apr_hash_t *autoprops,
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  svn_boolean_t have_executable = FALSE;

  *properties = apr_hash_make(result_pool);
  *mimetype = NULL;

  if (autoprops)
    {
      for (hi = apr_hash_first(scratch_pool, autoprops);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          const char *pattern = apr_hash_this_key(hi);
          apr_hash_t *propvals = apr_hash_this_val(hi);

          get_auto_props_for_pattern(*properties, mimetype, &have_executable,
                                     svn_dirent_basename(path, scratch_pool),
                                     pattern, propvals, scratch_pool);
        }
    }

  /* if mimetype has not been set check the file */
  if (! *mimetype)
    {
      SVN_ERR(svn_io_detect_mimetype2(mimetype, path, ctx->mimetypes_map,
                                      result_pool));

      /* If we got no mime-type, or if it is "application/octet-stream",
       * try to get the mime-type from libmagic. */
      if (magic_cookie &&
          (!*mimetype ||
           strcmp(*mimetype, "application/octet-stream") == 0))
        {
          const char *magic_mimetype;

         /* Since libmagic usually treats UTF-16 files as "text/plain",
          * svn_magic__detect_binary_mimetype() will return NULL for such
          * files. This is fine for now since we currently don't support
          * UTF-16-encoded text files (issue #2194).
          * Once we do support UTF-16 this code path will fail to detect
          * them as text unless the svn_io_detect_mimetype2() call above
          * returns "text/plain" for them. */
          SVN_ERR(svn_magic__detect_binary_mimetype(&magic_mimetype,
                                                    path, magic_cookie,
                                                    result_pool,
                                                    scratch_pool));
          if (magic_mimetype)
            *mimetype = magic_mimetype;
        }

      if (*mimetype)
        apr_hash_set(*properties, SVN_PROP_MIME_TYPE,
                     strlen(SVN_PROP_MIME_TYPE),
                     svn_string_create(*mimetype, result_pool));
    }

  /* if executable has not been set check the file */
  if (! have_executable)
    {
      svn_boolean_t executable = FALSE;
      SVN_ERR(svn_io_is_file_executable(&executable, path, scratch_pool));
      if (executable)
        apr_hash_set(*properties, SVN_PROP_EXECUTABLE,
                     strlen(SVN_PROP_EXECUTABLE),
                     svn_string_create_empty(result_pool));
    }

  return SVN_NO_ERROR;
}

/* Only call this if the on-disk node kind is a file. */
static svn_error_t *
add_file(const char *local_abspath,
         svn_magic__cookie_t *magic_cookie,
         apr_hash_t *autoprops,
         svn_boolean_t no_autoprops,
         svn_client_ctx_t *ctx,
         apr_pool_t *pool)
{
  apr_hash_t *properties;
  const char *mimetype;
  svn_node_kind_t kind;
  svn_boolean_t is_special;

  /* Check to see if this is a special file. */
  SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special, pool));

  /* Determine the properties that the file should have */
  if (is_special)
    {
      mimetype = NULL;
      properties = apr_hash_make(pool);
      svn_hash_sets(properties, SVN_PROP_SPECIAL,
                    svn_string_create(SVN_PROP_BOOLEAN_TRUE, pool));
    }
  else
    {
      apr_hash_t *file_autoprops = NULL;

      /* Get automatic properties */
      /* If we are setting autoprops grab the inherited svn:auto-props and
         config file auto-props for this file if we haven't already got them
         when iterating over the file's unversioned parents. */
      if (!no_autoprops)
        {
          if (autoprops == NULL)
            SVN_ERR(svn_client__get_all_auto_props(
              &file_autoprops, svn_dirent_dirname(local_abspath,pool),
              ctx, pool, pool));
          else
            file_autoprops = autoprops;
        }

      /* This may fail on write-only files:
         we open them to estimate file type. */
      SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
                                               local_abspath, magic_cookie,
                                               file_autoprops, ctx, pool,
                                               pool));
    }

  /* Add the file */
  SVN_ERR(svn_wc_add_from_disk3(ctx->wc_ctx, local_abspath, properties,
                                FALSE /* skip checks */,
                                ctx->notify_func2, ctx->notify_baton2, pool));

  return SVN_NO_ERROR;
}

/* Schedule directory DIR_ABSPATH, and some of the tree under it, for
 * addition.  DEPTH is the depth at this point in the descent (it may
 * be changed for recursive calls).
 *
 * If DIR_ABSPATH (or any item below DIR_ABSPATH) is already scheduled for
 * addition, add will fail and return an error unless FORCE is TRUE.
 *
 * Use MAGIC_COOKIE (which may be NULL) to detect the mime-type of files
 * if necessary.
 *
 * If not NULL, CONFIG_AUTOPROPS is a hash representing the config file and
 * svn:auto-props autoprops which apply to DIR_ABSPATH.  It maps
 * const char * file patterns to another hash which maps const char *
 * property names to const char *property values.  If CONFIG_AUTOPROPS is
 * NULL and the config file and svn:auto-props autoprops are required by this
 * function, then such will be obtained.
 *
 * If IGNORES is not NULL, then it is an array of const char * ignore patterns
 * that apply to any children of DIR_ABSPATH.  If REFRESH_IGNORES is TRUE, then
 * the passed in value of IGNORES (if any) is itself ignored and this function
 * will gather all ignore patterns applicable to DIR_ABSPATH itself (allocated in
 * RESULT_POOL).  Any recursive calls to this function get the refreshed ignore
 * patterns.  If IGNORES is NULL and REFRESH_IGNORES is FALSE, then all children of DIR_ABSPATH
 * are unconditionally added.
 *
 * If CTX->CANCEL_FUNC is non-null, call it with CTX->CANCEL_BATON to allow
 * the user to cancel the operation.
 *
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
add_dir_recursive(const char *dir_abspath,
                  svn_depth_t depth,
                  svn_boolean_t force,
                  svn_boolean_t no_autoprops,
                  svn_magic__cookie_t *magic_cookie,
                  apr_hash_t *config_autoprops,
                  svn_boolean_t refresh_ignores,
                  apr_array_header_t *ignores,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  apr_pool_t *iterpool;
  apr_hash_t *dirents;
  apr_hash_index_t *hi;
  svn_boolean_t entry_exists = FALSE;

  /* Check cancellation; note that this catches recursive calls too. */
  if (ctx->cancel_func)
    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

  iterpool = svn_pool_create(scratch_pool);

  /* Add this directory to revision control. */
  err = svn_wc_add_from_disk3(ctx->wc_ctx, dir_abspath, NULL /*props*/,
                              FALSE /* skip checks */,
                              ctx->notify_func2, ctx->notify_baton2,
                              iterpool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
        {
          svn_error_clear(err);
          entry_exists = TRUE;
        }
      else if (err)
        {
          return svn_error_trace(err);
        }
    }

  /* Fetch ignores after adding to handle ignores on the directory itself
     and ancestors via the single db optimization in libsvn_wc */
  if (refresh_ignores)
    SVN_ERR(svn_wc_get_ignores2(&ignores, ctx->wc_ctx, dir_abspath,
                                ctx->config, result_pool, iterpool));

  /* If DIR_ABSPATH is the root of an unversioned subtree then get the
     following "autoprops":

       1) Explicit and inherited svn:auto-props properties on
          DIR_ABSPATH
       2) auto-props from the CTX->CONFIG hash

     Since this set of autoprops applies to all unversioned children of
     DIR_ABSPATH, we will pass these along to any recursive calls to
     add_dir_recursive() and calls to add_file() below.  Thus sparing
     these callees from looking up the same information. */
  if (!entry_exists && config_autoprops == NULL)
    {
      SVN_ERR(svn_client__get_all_auto_props(&config_autoprops, dir_abspath,
                                             ctx, scratch_pool, iterpool));
    }

  SVN_ERR(svn_io_get_dirents3(&dirents, dir_abspath, TRUE, scratch_pool,
                              iterpool));

  /* Read the directory entries one by one and add those things to
     version control. */
  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
    {
      const char *name = apr_hash_this_key(hi);
      svn_io_dirent2_t *dirent = apr_hash_this_val(hi);
      const char *abspath;

      svn_pool_clear(iterpool);

      /* Check cancellation so you can cancel during an
       * add of a directory with lots of files. */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      /* Skip over SVN admin directories. */
      if (svn_wc_is_adm_dir(name, iterpool))
        continue;

      if (ignores
          && svn_wc_match_ignore_list(name, ignores, iterpool))
        continue;

      /* Construct the full path of the entry. */
      abspath = svn_dirent_join(dir_abspath, name, iterpool);

      /* Recurse on directories; add files; ignore the rest. */
      if (dirent->kind == svn_node_dir && depth >= svn_depth_immediates)
        {
          svn_depth_t depth_below_here = depth;
          if (depth == svn_depth_immediates)
            depth_below_here = svn_depth_empty;

          /* When DIR_ABSPATH is the root of an unversioned subtree then
             it and all of its children have the same set of ignores.  So
             save any recursive calls the extra work of finding the same
             set of ignores. */
          if (refresh_ignores && !entry_exists)
            refresh_ignores = FALSE;

          SVN_ERR(add_dir_recursive(abspath, depth_below_here,
                                    force, no_autoprops,
                                    magic_cookie, config_autoprops,
                                    refresh_ignores, ignores, ctx,
                                    result_pool, iterpool));
        }
      else if ((dirent->kind == svn_node_file || dirent->special)
               && depth >= svn_depth_files)
        {
          err = add_file(abspath, magic_cookie, config_autoprops,
                         no_autoprops, ctx, iterpool);
          if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
            svn_error_clear(err);
          else
            SVN_ERR(err);
        }
    }

  /* Destroy the per-iteration pool. */
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* This structure is used as baton for collecting the config entries
   in the auto-props section and any inherited svn:auto-props
   properties.
*/
typedef struct collect_auto_props_baton_t
{
  /* the hash table for storing the property name/value pairs */
  apr_hash_t *autoprops;

  /* a pool used for allocating memory */
  apr_pool_t *result_pool;
} collect_auto_props_baton_t;

/* Implements svn_config_enumerator2_t callback.

   For one auto-props config entry (NAME, VALUE), stash a copy of
   NAME and VALUE, allocated in BATON->POOL, in BATON->AUTOPROP.
   BATON must point to an collect_auto_props_baton_t.
*/
static svn_boolean_t
all_auto_props_collector(const char *name,
                         const char *value,
                         void *baton,
                         apr_pool_t *pool)
{
  collect_auto_props_baton_t *autoprops_baton = baton;
  apr_array_header_t *autoprops;
  int i;

  /* nothing to do here without a value */
  if (*value == 0)
    return TRUE;

  split_props(&autoprops, value, pool);

  for (i = 0; i < autoprops->nelts; i ++)
    {
      size_t len;
      const char *this_value;
      char *property = APR_ARRAY_IDX(autoprops, i, char *);
      char *equal_sign = strchr(property, '=');

      if (equal_sign)
        {
          *equal_sign = '\0';
          equal_sign++;
          trim_string(&equal_sign);
          unquote_string(&equal_sign);
          this_value = equal_sign;
        }
      else
        {
          this_value = "";
        }
      trim_string(&property);
      len = strlen(property);

      if (len > 0)
        {
          apr_hash_t *pattern_hash = svn_hash_gets(autoprops_baton->autoprops,
                                                   name);
          svn_string_t *propval;

          /* Force reserved boolean property values to '*'. */
          if (svn_prop_is_boolean(property))
            {
              /* SVN_PROP_EXECUTABLE, SVN_PROP_NEEDS_LOCK, SVN_PROP_SPECIAL */
              propval = svn_string_create("*", autoprops_baton->result_pool);
            }
          else
            {
              propval = svn_string_create(this_value,
                                          autoprops_baton->result_pool);
            }

          if (!pattern_hash)
            {
              pattern_hash = apr_hash_make(autoprops_baton->result_pool);
              svn_hash_sets(autoprops_baton->autoprops,
                            apr_pstrdup(autoprops_baton->result_pool, name),
                            pattern_hash);
            }
          svn_hash_sets(pattern_hash,
                        apr_pstrdup(autoprops_baton->result_pool, property),
                        propval->data);
        }
    }
  return TRUE;
}

/* Go up the directory tree from LOCAL_ABSPATH, looking for a versioned
 * directory.  If found, return its path in *EXISTING_PARENT_ABSPATH.
 * Otherwise, return SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
static svn_error_t *
find_existing_parent(const char **existing_parent_abspath,
                     svn_client_ctx_t *ctx,
                     const char *local_abspath,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind;
  const char *parent_abspath;
  svn_wc_context_t *wc_ctx = ctx->wc_ctx;

  SVN_ERR(svn_wc_read_kind2(&kind, wc_ctx, local_abspath,
                            FALSE, FALSE, scratch_pool));

  if (kind == svn_node_dir)
    {
      *existing_parent_abspath = apr_pstrdup(result_pool, local_abspath);
      return SVN_NO_ERROR;
    }

  if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
    return svn_error_create(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);

  if (svn_wc_is_adm_dir(svn_dirent_basename(local_abspath, scratch_pool),
                        scratch_pool))
    return svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, NULL,
                             _("'%s' ends in a reserved name"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);

  if (ctx->cancel_func)
    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

  SVN_ERR(find_existing_parent(existing_parent_abspath, ctx, parent_abspath,
                               result_pool, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__get_all_auto_props(apr_hash_t **autoprops,
                               const char *path_or_url,
                               svn_client_ctx_t *ctx,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  int i;
  apr_array_header_t *inherited_config_auto_props;
  apr_hash_t *props;
  svn_opt_revision_t rev;
  svn_string_t *config_auto_prop;
  svn_boolean_t use_autoprops;
  collect_auto_props_baton_t autoprops_baton;
  svn_error_t *err = NULL;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  svn_boolean_t target_is_url = svn_path_is_url(path_or_url);
  svn_config_t *cfg = ctx->config ? svn_hash_gets(ctx->config,
                                                  SVN_CONFIG_CATEGORY_CONFIG)
                                  : NULL;
  *autoprops = apr_hash_make(result_pool);
  autoprops_baton.result_pool = result_pool;
  autoprops_baton.autoprops = *autoprops;


  /* Are "traditional" auto-props enabled?  If so grab them from the
    config.  This is our starting set auto-props, which may be overridden
    by svn:auto-props. */
  SVN_ERR(svn_config_get_bool(cfg, &use_autoprops,
                              SVN_CONFIG_SECTION_MISCELLANY,
                              SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
  if (use_autoprops)
    svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
                          all_auto_props_collector, &autoprops_baton,
                          scratch_pool);

  /* Convert the config file setting (if any) into a hash mapping file
     patterns to as hash of prop-->val mappings. */
  if (svn_path_is_url(path_or_url))
    rev.kind = svn_opt_revision_head;
  else
    rev.kind = svn_opt_revision_working;

  /* If PATH_OR_URL is a WC path, then it might be unversioned, in which case
     we find it's nearest versioned parent. */
  do
    {
      err = svn_client_propget5(&props, &inherited_config_auto_props,
                                SVN_PROP_INHERITABLE_AUTO_PROPS, path_or_url,
                                &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
                                scratch_pool, iterpool);
      if (err)
        {
          if (target_is_url || err->apr_err != SVN_ERR_UNVERSIONED_RESOURCE)
            return svn_error_trace(err);

          svn_error_clear(err);
          err = NULL;
          SVN_ERR(find_existing_parent(&path_or_url, ctx, path_or_url,
                                       scratch_pool, iterpool));
        }
      else
        {
          break;
        }
    }
  while (err == NULL);

  /* Stash any explicit PROPS for PARENT_PATH into the inherited props array,
     since these are actually inherited props for LOCAL_ABSPATH. */
  config_auto_prop = svn_hash_gets(props, path_or_url);

  if (config_auto_prop)
    {
      svn_prop_inherited_item_t *new_iprop =
        apr_palloc(scratch_pool, sizeof(*new_iprop));
      new_iprop->path_or_url = path_or_url;
      new_iprop->prop_hash = apr_hash_make(scratch_pool);
      svn_hash_sets(new_iprop->prop_hash, SVN_PROP_INHERITABLE_AUTO_PROPS,
                    config_auto_prop);
      APR_ARRAY_PUSH(inherited_config_auto_props,
                     svn_prop_inherited_item_t *) = new_iprop;
    }

  for (i = 0; i < inherited_config_auto_props->nelts; i++)
    {
      svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
        inherited_config_auto_props, i, svn_prop_inherited_item_t *);
      const svn_string_t *propval =
        svn_hash_gets(elt->prop_hash, SVN_PROP_INHERITABLE_AUTO_PROPS);

        {
          const char *ch = propval->data;
          svn_stringbuf_t *config_auto_prop_pattern;
          svn_stringbuf_t *config_auto_prop_val;

          svn_pool_clear(iterpool);

          config_auto_prop_pattern = svn_stringbuf_create_empty(iterpool);
          config_auto_prop_val = svn_stringbuf_create_empty(iterpool);

          /* Parse svn:auto-props value. */
          while (*ch != '\0')
            {
              svn_stringbuf_setempty(config_auto_prop_pattern);
              svn_stringbuf_setempty(config_auto_prop_val);

              /* Parse the file pattern. */
              while (*ch != '\0' && *ch != '=' && *ch != '\n')
                {
                  svn_stringbuf_appendbyte(config_auto_prop_pattern, *ch);
                  ch++;
                }

              svn_stringbuf_strip_whitespace(config_auto_prop_pattern);

              /* Parse the auto-prop group. */
              while (*ch != '\0' && *ch != '\n')
                {
                  svn_stringbuf_appendbyte(config_auto_prop_val, *ch);
                  ch++;
                }

              /* Strip leading '=' and whitespace from auto-prop group. */
              if (config_auto_prop_val->data[0] == '=')
                svn_stringbuf_remove(config_auto_prop_val, 0, 1);
              svn_stringbuf_strip_whitespace(config_auto_prop_val);

              all_auto_props_collector(config_auto_prop_pattern->data,
                                       config_auto_prop_val->data,
                                       &autoprops_baton,
                                       scratch_pool);

              /* Skip to next line if any. */
              while (*ch != '\0' && *ch != '\n')
                ch++;
              if (*ch == '\n')
                ch++;
            }
        }
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* The main logic of the public svn_client_add5.
 *
 * EXISTING_PARENT_ABSPATH is the absolute path to the first existing
 * parent directory of local_abspath. If not NULL, all missing parents
 * of LOCAL_ABSPATH must be created before LOCAL_ABSPATH can be added. */
static svn_error_t *
add(const char *local_abspath,
    svn_depth_t depth,
    svn_boolean_t force,
    svn_boolean_t no_ignore,
    svn_boolean_t no_autoprops,
    const char *existing_parent_abspath,
    svn_client_ctx_t *ctx,
    apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind;
  svn_error_t *err;
  svn_magic__cookie_t *magic_cookie;
  apr_array_header_t *ignores = NULL;

  SVN_ERR(svn_magic__init(&magic_cookie, ctx->config, scratch_pool));

  if (existing_parent_abspath)
    {
      const char *parent_abspath;
      const char *child_relpath;
      apr_array_header_t *components;
      int i;
      apr_pool_t *iterpool;

      parent_abspath = existing_parent_abspath;
      child_relpath = svn_dirent_is_child(existing_parent_abspath,
                                          local_abspath, NULL);
      components = svn_path_decompose(child_relpath, scratch_pool);
      iterpool = svn_pool_create(scratch_pool);
      for (i = 0; i < components->nelts - 1; i++)
        {
          const char *component;
          svn_node_kind_t disk_kind;

          svn_pool_clear(iterpool);

          if (ctx->cancel_func)
            SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

          component = APR_ARRAY_IDX(components, i, const char *);
          parent_abspath = svn_dirent_join(parent_abspath, component,
                                           scratch_pool);
          SVN_ERR(svn_io_check_path(parent_abspath, &disk_kind, iterpool));
          if (disk_kind != svn_node_none && disk_kind != svn_node_dir)
            return svn_error_createf(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL,
                                     _("'%s' prevents creating parent of '%s'"),
                                     parent_abspath, local_abspath);

          SVN_ERR(svn_io_make_dir_recursively(parent_abspath, scratch_pool));
          SVN_ERR(svn_wc_add_from_disk3(ctx->wc_ctx, parent_abspath,
                                        NULL /*props*/,
                                        FALSE /* skip checks */,
                                        ctx->notify_func2, ctx->notify_baton2,
                                        scratch_pool));
        }
      svn_pool_destroy(iterpool);
    }

  SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
  if (kind == svn_node_dir)
    {
      /* We use add_dir_recursive for all directory targets
         and pass depth along no matter what it is, so that the
         target's depth will be set correctly. */
      err = add_dir_recursive(local_abspath, depth, force,
                              no_autoprops, magic_cookie, NULL,
                              !no_ignore, ignores, ctx,
                              scratch_pool, scratch_pool);
    }
  else if (kind == svn_node_file)
    err = add_file(local_abspath, magic_cookie, NULL,
                   no_autoprops, ctx, scratch_pool);
  else if (kind == svn_node_none)
    {
      svn_boolean_t tree_conflicted;

      /* Provide a meaningful error message if the node does not exist
       * on disk but is a tree conflict victim. */
      err = svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
                                 ctx->wc_ctx, local_abspath,
                                 scratch_pool);
      if (err)
        svn_error_clear(err);
      else if (tree_conflicted)
        return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
                                 _("'%s' is an existing item in conflict; "
                                   "please mark the conflict as resolved "
                                   "before adding a new item here"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));

      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                               _("'%s' not found"),
                               svn_dirent_local_style(local_abspath,
                                                      scratch_pool));
    }
  else
    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                             _("Unsupported node kind for path '%s'"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* Ignore SVN_ERR_ENTRY_EXISTS when FORCE is set.  */
  if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
    {
      svn_error_clear(err);
      err = SVN_NO_ERROR;
    }
  return svn_error_trace(err);
}



svn_error_t *
svn_client_add5(const char *path,
                svn_depth_t depth,
                svn_boolean_t force,
                svn_boolean_t no_ignore,
                svn_boolean_t no_autoprops,
                svn_boolean_t add_parents,
                svn_client_ctx_t *ctx,
                apr_pool_t *scratch_pool)
{
  const char *parent_abspath;
  const char *local_abspath;
  const char *existing_parent_abspath;
  svn_boolean_t is_wc_root;
  svn_error_t *err;

  if (svn_path_is_url(path))
    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                             _("'%s' is not a local path"), path);

  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));

  /* See if we're being asked to add a wc-root.  That's typically not
     okay, unless we're in "force" mode.  svn_wc__is_wcroot()
     will return TRUE even if LOCAL_ABSPATH is a *symlink* to a working
     copy root, which is a scenario we want to treat differently.  */
  err = svn_wc__is_wcroot(&is_wc_root, ctx->wc_ctx, local_abspath,
                          scratch_pool);
  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
          && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
        {
          return svn_error_trace(err);
        }

      svn_error_clear(err);
      err = NULL; /* SVN_NO_ERROR */
      is_wc_root = FALSE;
    }
  if (is_wc_root)
    {
#ifdef HAVE_SYMLINK
      svn_node_kind_t disk_kind;
      svn_boolean_t is_special;

      SVN_ERR(svn_io_check_special_path(local_abspath, &disk_kind, &is_special,
                                        scratch_pool));

      /* A symlink can be an unversioned target and a wcroot. Lets try to add
         the symlink, which can't be a wcroot. */
      if (is_special)
        is_wc_root = FALSE;
      else
#endif
        {
          if (! force)
            return svn_error_createf(
                                 SVN_ERR_ENTRY_EXISTS, NULL,
                                 _("'%s' is already under version control"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));
        }
    }

  if (is_wc_root)
    parent_abspath = local_abspath; /* We will only add children */
  else
    parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);

  existing_parent_abspath = NULL;
  if (add_parents && !is_wc_root)
    {
      apr_pool_t *subpool;
      const char *existing_parent_abspath2;

      subpool = svn_pool_create(scratch_pool);
      SVN_ERR(find_existing_parent(&existing_parent_abspath2, ctx,
                                   parent_abspath, scratch_pool, subpool));
      if (strcmp(existing_parent_abspath2, parent_abspath) != 0)
        existing_parent_abspath = existing_parent_abspath2;
      svn_pool_destroy(subpool);
    }

  SVN_WC__CALL_WITH_WRITE_LOCK(
    add(local_abspath, depth, force, no_ignore, no_autoprops,
        existing_parent_abspath, ctx, scratch_pool),
    ctx->wc_ctx, (existing_parent_abspath ? existing_parent_abspath
                                          : parent_abspath),
    FALSE /* lock_anchor */, scratch_pool);
  return SVN_NO_ERROR;
}


static svn_error_t *
path_driver_cb_func(void **dir_baton,
                    const svn_delta_editor_t *editor,
                    void *edit_baton,
                    void *parent_baton,
                    void *callback_baton,
                    const char *path,
                    apr_pool_t *pool)
{
  SVN_ERR(svn_path_check_valid(path, pool));
  return editor->add_directory(path, parent_baton, NULL,
                               SVN_INVALID_REVNUM, pool, dir_baton);
}

/* Append URL, and all it's non-existent parent directories, to TARGETS.
   Use TEMPPOOL for temporary allocations and POOL for any additions to
   TARGETS. */
static svn_error_t *
add_url_parents(svn_ra_session_t *ra_session,
                const char *url,
                apr_array_header_t *targets,
                apr_pool_t *temppool,
                apr_pool_t *pool)
{
  svn_node_kind_t kind;
  const char *parent_url = svn_uri_dirname(url, pool);

  SVN_ERR(svn_ra_reparent(ra_session, parent_url, temppool));
  SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
                            temppool));

  if (kind == svn_node_none)
    SVN_ERR(add_url_parents(ra_session, parent_url, targets, temppool, pool));

  APR_ARRAY_PUSH(targets, const char *) = url;

  return SVN_NO_ERROR;
}

static svn_error_t *
mkdir_urls(const apr_array_header_t *urls,
           svn_boolean_t make_parents,
           const apr_hash_t *revprop_table,
           svn_commit_callback2_t commit_callback,
           void *commit_baton,
           svn_client_ctx_t *ctx,
           apr_pool_t *pool)
{
  svn_ra_session_t *ra_session = NULL;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  const char *log_msg;
  apr_array_header_t *targets;
  apr_hash_t *targets_hash;
  apr_hash_t *commit_revprops;
  svn_error_t *err;
  const char *common;
  int i;

  /* Find any non-existent parent directories */
  if (make_parents)
    {
      apr_array_header_t *all_urls = apr_array_make(pool, urls->nelts,
                                                    sizeof(const char *));
      const char *first_url = APR_ARRAY_IDX(urls, 0, const char *);
      apr_pool_t *iterpool = svn_pool_create(pool);

      SVN_ERR(svn_client_open_ra_session2(&ra_session, first_url, NULL,
                                          ctx, pool, iterpool));

      for (i = 0; i < urls->nelts; i++)
        {
          const char *url = APR_ARRAY_IDX(urls, i, const char *);

          svn_pool_clear(iterpool);
          SVN_ERR(add_url_parents(ra_session, url, all_urls, iterpool, pool));
        }

      svn_pool_destroy(iterpool);

      urls = all_urls;
    }

  /* Condense our list of mkdir targets. */
  SVN_ERR(svn_uri_condense_targets(&common, &targets, urls, FALSE,
                                   pool, pool));

  /*Remove duplicate targets introduced by make_parents with more targets. */
  SVN_ERR(svn_hash_from_cstring_keys(&targets_hash, targets, pool));
  SVN_ERR(svn_hash_keys(&targets, targets_hash, pool));

  if (! targets->nelts)
    {
      const char *bname;
      svn_uri_split(&common, &bname, common, pool);
      APR_ARRAY_PUSH(targets, const char *) = bname;

      if (*bname == '\0')
        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                 _("There is no valid URI above '%s'"),
                                 common);
    }
  else
    {
      svn_boolean_t resplit = FALSE;

      /* We can't "mkdir" the root of an editor drive, so if one of
         our targets is the empty string, we need to back everything
         up by a path component. */
      for (i = 0; i < targets->nelts; i++)
        {
          const char *path = APR_ARRAY_IDX(targets, i, const char *);
          if (! *path)
            {
              resplit = TRUE;
              break;
            }
        }
      if (resplit)
        {
          const char *bname;

          svn_uri_split(&common, &bname, common, pool);

          if (*bname == '\0')
             return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                      _("There is no valid URI above '%s'"),
                                      common);

          for (i = 0; i < targets->nelts; i++)
            {
              const char *path = APR_ARRAY_IDX(targets, i, const char *);
              path = svn_relpath_join(bname, path, pool);
              APR_ARRAY_IDX(targets, i, const char *) = path;
            }
        }
    }

  svn_sort__array(targets, svn_sort_compare_paths);

  /* ### This reparent may be problematic in limited-authz-to-common-parent
     ### scenarios (compare issue #3242).  See also issue #3649. */
  if (ra_session)
    SVN_ERR(svn_ra_reparent(ra_session, common, pool));

  /* Create new commit items and add them to the array. */
  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
    {
      svn_client_commit_item3_t *item;
      const char *tmp_file;
      apr_array_header_t *commit_items
        = apr_array_make(pool, targets->nelts, sizeof(item));

      for (i = 0; i < targets->nelts; i++)
        {
          const char *path = APR_ARRAY_IDX(targets, i, const char *);

          item = svn_client_commit_item3_create(pool);
          item->url = svn_path_url_add_component2(common, path, pool);
          item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
          APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
        }

      SVN_ERR(svn_client__get_log_msg(&log_msg, &tmp_file, commit_items,
                                      ctx, pool));

      if (! log_msg)
        return SVN_NO_ERROR;
    }
  else
    log_msg = "";

  SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                           log_msg, ctx, pool));

  /* Open an RA session for the URL. Note that we don't have a local
     directory, nor a place to put temp files. */
  if (!ra_session)
    SVN_ERR(svn_client_open_ra_session2(&ra_session, common, NULL, ctx,
                                        pool, pool));
  else
    SVN_ERR(svn_ra_reparent(ra_session, common, pool));


  /* Fetch RA commit editor */
  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
                        svn_client__get_shim_callbacks(ctx->wc_ctx, NULL,
                                                       pool)));
  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                    commit_revprops,
                                    commit_callback,
                                    commit_baton,
                                    NULL, TRUE, /* No lock tokens */
                                    pool));

  /* Call the path-based editor driver. */
  err = svn_error_trace(
        svn_delta_path_driver3(editor, edit_baton, targets, TRUE,
                               path_driver_cb_func, NULL, pool));

  if (err)
    {
      /* At least try to abort the edit (and fs txn) before throwing err. */
      return svn_error_compose_create(
                err,
                svn_error_trace(editor->abort_edit(edit_baton, pool)));
    }

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;
      notify = svn_wc_create_notify_url(common,
                                        svn_wc_notify_commit_finalizing,
                                        pool);
      ctx->notify_func2(ctx->notify_baton2, notify, pool);
    }

  /* Close the edit. */
  return svn_error_trace(editor->close_edit(edit_baton, pool));
}



svn_error_t *
svn_client__make_local_parents(const char *local_abspath,
                               svn_boolean_t make_parents,
                               svn_client_ctx_t *ctx,
                               apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  svn_node_kind_t orig_kind;
  SVN_ERR(svn_io_check_path(local_abspath, &orig_kind, scratch_pool));
  if (make_parents)
    SVN_ERR(svn_io_make_dir_recursively(local_abspath, scratch_pool));
  else
    SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));

  err = svn_client_add5(local_abspath, svn_depth_empty, FALSE, FALSE, FALSE,
                        make_parents, ctx, scratch_pool);

  /* If we created a new directory, but couldn't add it to version
     control, then delete it. */
  if (err && (orig_kind == svn_node_none))
    {
      err = svn_error_compose_create(err,
                                     svn_io_remove_dir2(local_abspath, FALSE,
                                                        NULL, NULL,
                                                        scratch_pool));
    }

  return svn_error_trace(err);
}


svn_error_t *
svn_client_mkdir4(const apr_array_header_t *paths,
                  svn_boolean_t make_parents,
                  const apr_hash_t *revprop_table,
                  svn_commit_callback2_t commit_callback,
                  void *commit_baton,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
{
  if (! paths->nelts)
    return SVN_NO_ERROR;

  SVN_ERR(svn_client__assert_homogeneous_target_type(paths));

  if (svn_path_is_url(APR_ARRAY_IDX(paths, 0, const char *)))
    {
      SVN_ERR(mkdir_urls(paths, make_parents, revprop_table, commit_callback,
                         commit_baton, ctx, pool));
    }
  else
    {
      /* This is a regular "mkdir" + "svn add" */
      apr_pool_t *iterpool = svn_pool_create(pool);
      int i;

      for (i = 0; i < paths->nelts; i++)
        {
          const char *path = APR_ARRAY_IDX(paths, i, const char *);

          svn_pool_clear(iterpool);

          /* See if the user wants us to stop. */
          if (ctx->cancel_func)
            SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

          SVN_ERR(svn_dirent_get_absolute(&path, path, iterpool));

          SVN_ERR(svn_client__make_local_parents(path, make_parents, ctx,
                                                 iterpool));
        }
      svn_pool_destroy(iterpool);
    }

  return SVN_NO_ERROR;
}
