⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 add.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * add.c:  wrappers around wc add/mkdir functionality.
 *
 * ====================================================================
 * Copyright (c) 2000-2004 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/.
 * ====================================================================
 */

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



/*** 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_path.h"
#include "svn_io.h"
#include "svn_config.h"
#include "client.h"

#include "svn_private_config.h"



/*** Code. ***/

/* This structure is used as baton for enumerating the config entries
   in the auto-props section.
*/
typedef struct
{
  /* the file name for which properties are searched */
  const char *filename;

  /* when this flag is set the hash contains svn:executable */
  svn_boolean_t have_executable;

  /* when mimetype is not NULL is set the hash contains svn:mime-type */
  const char *mimetype;

  /* the hash table for storing the property name/value pairs */
  apr_hash_t *properties;

  /* a pool used for allocating memory */
  apr_pool_t *pool;
} auto_props_baton_t;

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

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

/* For one auto-props config entry (NAME, VALUE), if the filename pattern
   NAME matches BATON->filename then add the properties listed in VALUE
   into BATON->properties.  BATON must point to an auto_props_baton_t.
*/
static svn_boolean_t
auto_props_enumerator (const char *name,
                       const char *value,
                       void *baton)
{
  auto_props_baton_t *autoprops = baton;
  char *property;
  char *last_token;
  int len;

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

  /* check if filename matches and return if it doesn't */
  if (apr_fnmatch (name, autoprops->filename, 0) == APR_FNM_NOMATCH)
    return TRUE;
  
  /* parse the value (we dup it first to effectively lose the
     'const', and to avoid messing up the original value) */
  property = apr_pstrdup (autoprops->pool, value);
  property = apr_strtok (property, ";", &last_token);
  while (property)
    {
      char *this_value;

      this_value = strchr (property, '=');
      if (this_value)
        {
          *this_value = '\0';
          this_value++;
          trim_string (&this_value);
        }
      else
        {
          this_value = (char *)"";
        }
      trim_string (&property);
      len = strlen (property);
      if (len > 0)
        {
          svn_string_t *propval = apr_pcalloc (autoprops->pool,
                                               sizeof (*propval));
          propval->data = this_value;
          propval->len = strlen (this_value);

          apr_hash_set (autoprops->properties, property, len, propval);
          if (strcmp (property, SVN_PROP_MIME_TYPE) == 0)
            autoprops->mimetype = this_value;
          else if (strcmp (property, SVN_PROP_EXECUTABLE) == 0)
            autoprops->have_executable = TRUE;
        }
      property = apr_strtok (NULL, ";", &last_token);
    }
  return TRUE;
}

svn_error_t *
svn_client__get_auto_props (apr_hash_t **properties,
                            const char **mimetype,
                            const char *path,
                            svn_client_ctx_t *ctx,
                            apr_pool_t *pool)
{
  svn_config_t *cfg;
  svn_boolean_t use_autoprops;
  auto_props_baton_t autoprops;

  /* initialisation */
  autoprops.properties = apr_hash_make (pool);
  autoprops.filename = svn_path_basename (path, pool);
  autoprops.pool = pool;
  autoprops.mimetype = NULL;
  autoprops.have_executable = FALSE;
  *properties = autoprops.properties;

  cfg = ctx->config ? apr_hash_get (ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
                                    APR_HASH_KEY_STRING) : NULL;

  /* check that auto props is enabled */
  SVN_ERR (svn_config_get_bool (cfg, &use_autoprops,
                                SVN_CONFIG_SECTION_MISCELLANY,
                                SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));

  /* search for auto props */
  if (use_autoprops)
    svn_config_enumerate (cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
                          auto_props_enumerator, &autoprops);

  /* if mimetype has not been set check the file */
  if (! autoprops.mimetype)
    {
      SVN_ERR (svn_io_detect_mimetype (&autoprops.mimetype, path, pool));
      if (autoprops.mimetype)
        apr_hash_set (autoprops.properties, SVN_PROP_MIME_TYPE,
                      strlen (SVN_PROP_MIME_TYPE), 
                      svn_string_create (autoprops.mimetype, pool));
    }

  /* if executable has not been set check the file */
  if (! autoprops.have_executable)
    {
      svn_boolean_t executable = FALSE;
      SVN_ERR (svn_io_is_file_executable (&executable, path, pool));
      if (executable)
        apr_hash_set (autoprops.properties, SVN_PROP_EXECUTABLE,
                      strlen (SVN_PROP_EXECUTABLE), 
                      svn_string_create ("", pool));
    }

  *mimetype = autoprops.mimetype;
  return SVN_NO_ERROR;
}

static svn_error_t *
add_file (const char *path,
          svn_client_ctx_t *ctx,
          svn_wc_adm_access_t *adm_access,
          apr_pool_t *pool)
{
  apr_hash_t* properties;
  apr_hash_index_t *hi;
  const char *mimetype;
  svn_node_kind_t kind;
  svn_boolean_t is_special;

  /* add the file */
  SVN_ERR (svn_wc_add (path, adm_access, NULL, SVN_INVALID_REVNUM,
                       ctx->cancel_func, ctx->cancel_baton,
                       NULL, NULL, pool));

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

  if (is_special)
    {
      /* This must be a special file. */
      SVN_ERR (svn_wc_prop_set (SVN_PROP_SPECIAL,
                                svn_string_create (SVN_PROP_SPECIAL_VALUE, pool),
                                path, adm_access, pool));
      mimetype = NULL;
    }
  else
    {
      /* get automatic properties */
      SVN_ERR (svn_client__get_auto_props (&properties, &mimetype, path, ctx,
                                           pool));
      if (properties)
        {
          /* loop through the hashtable and add the properties */
          for (hi = apr_hash_first (pool, properties);
               hi != NULL; hi = apr_hash_next (hi))
            {
              const void *pname;
              void *pval;
          
              apr_hash_this (hi, &pname, NULL, &pval);
              SVN_ERR (svn_wc_prop_set (pname, pval, path, adm_access, pool));
            }
        }
    }

  /* Report the addition to the caller. */
  if (ctx->notify_func != NULL)
    (*ctx->notify_func) (ctx->notify_baton, path, svn_wc_notify_add,
                         svn_node_file,
                         mimetype,
                         svn_wc_notify_state_unknown,
                         svn_wc_notify_state_unknown,
                         SVN_INVALID_REVNUM);
  return SVN_NO_ERROR;
}

static svn_error_t *
add_dir_recursive (const char *dirname,
                   svn_wc_adm_access_t *adm_access,
                   svn_boolean_t force,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
{
  apr_dir_t *dir;
  apr_finfo_t this_entry;
  svn_error_t *err;
  apr_pool_t *subpool;
  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
  svn_wc_adm_access_t *dir_access;
  apr_array_header_t *ignores;

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

  /* Add this directory to revision control. */
  err = svn_wc_add (dirname, adm_access,
                    NULL, SVN_INVALID_REVNUM,
                    ctx->cancel_func, ctx->cancel_baton,
                    ctx->notify_func, ctx->notify_baton, pool);
  if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
    svn_error_clear (err);
  else if (err)
    return err;

  SVN_ERR (svn_wc_adm_retrieve (&dir_access, adm_access, dirname, pool));

  SVN_ERR (svn_wc_get_default_ignores (&ignores, ctx->config, pool));

  /* Create a subpool for iterative memory control. */
  subpool = svn_pool_create (pool);

  /* Read the directory entries one by one and add those things to
     revision control. */
  SVN_ERR (svn_io_dir_open (&dir, dirname, pool));
  for (err = svn_io_dir_read (&this_entry, flags, dir, subpool);
       err == SVN_NO_ERROR;
       err = svn_io_dir_read (&this_entry, flags, dir, subpool))
    {
      const char *fullpath;

      /* 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 (strcmp (this_entry.name, SVN_WC_ADM_DIR_NAME) == 0)
        continue;

      /* Skip entries for this dir and its parent.  */
      if (this_entry.name[0] == '.'
          && (this_entry.name[1] == '\0'
              || (this_entry.name[1] == '.' && this_entry.name[2] == '\0')))
        continue;

      if (svn_cstring_match_glob_list (this_entry.name, ignores))
        continue;

      /* Construct the full path of the entry. */
      fullpath = svn_path_join (dirname, this_entry.name, subpool);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -