/*
 * 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 overriden
    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;
}
