props.c

来自「subversion-1.4.3-1.tar.gz 配置svn的源码」· C语言 代码 · 共 1,949 行 · 第 1/5 页

C
1,949
字号
      else        wcprops = NULL;      if (wcprops && apr_hash_count(wcprops) > 0)        {          apr_hash_set(all_wcprops, name, APR_HASH_KEY_STRING, NULL);          write_needed = TRUE;        }    }  if (write_needed)    SVN_ERR(svn_wc__wcprops_write(adm_access, pool));  if (recurse)    {      apr_hash_t *entries;      apr_hash_index_t *hi;      apr_pool_t *subpool = svn_pool_create(pool);      /* Read PATH's entries. */      SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, subpool));      /* Recursively loop over all children. */      for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))        {          const void *key;          void *val;          const char *entryname;          const svn_wc_entry_t *current_entry;          const char *child_path;          svn_wc_adm_access_t *child_access;          apr_hash_this(hi, &key, NULL, &val);          entryname = key;          current_entry = val;          /* Ignore files and the "this dir" entry. */          if (current_entry->kind != svn_node_dir              || ! strcmp(entryname, SVN_WC_ENTRY_THIS_DIR))            continue;          svn_pool_clear(subpool);          child_path = svn_path_join(svn_wc_adm_access_path(adm_access),                                     entryname, subpool);          SVN_ERR(svn_wc_adm_retrieve(&child_access, adm_access, child_path,                                      subpool));          SVN_ERR(svn_wc__remove_wcprops(child_access, NULL, TRUE, subpool));        }        /* Cleanup */        svn_pool_destroy(subpool);    }  return SVN_NO_ERROR;}/*------------------------------------------------------------------*//*** Public Functions ***/svn_error_t *svn_wc_prop_list(apr_hash_t **props,                 const char *path,                 svn_wc_adm_access_t *adm_access,                 apr_pool_t *pool){  const svn_wc_entry_t *entry;  SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, pool));  /* if there is no entry, 'path' is not under version control and     therefore has no props */  if (! entry)    {      *props = apr_hash_make(pool);      return SVN_NO_ERROR;    }  if (entry->kind == svn_node_dir)    SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, path, pool));  else    SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access,                                svn_path_dirname(path, pool), pool));  return svn_wc__load_props(NULL, props, adm_access, entry->name, pool);}/* Return true if NAME is the name of a boolean svn: namespace   property.  */static svn_boolean_tis_boolean_property(const char *name){  /* If we end up with more than 3 of these, we should probably put     them in a table and use bsearch.  With only three, it doesn't     make any speed difference.  */  if (strcmp(name, SVN_PROP_EXECUTABLE) == 0)    return TRUE;  else if (strcmp(name, SVN_PROP_NEEDS_LOCK) == 0)    return TRUE;  else if (strcmp(name, SVN_PROP_SPECIAL) == 0)    return TRUE;  return FALSE;}/* If NAME is a boolean svn: namespace property, return the value that   represents true for that property.  The result is allocated in   POOL. */static svn_string_t *value_of_boolean_prop(const char *name, apr_pool_t *pool){  if (strcmp(name, SVN_PROP_EXECUTABLE) == 0)    return svn_string_create(SVN_PROP_EXECUTABLE_VALUE, pool);  else if (strcmp(name, SVN_PROP_NEEDS_LOCK) == 0)    return svn_string_create(SVN_PROP_NEEDS_LOCK_VALUE, pool);  else if (strcmp(name, SVN_PROP_SPECIAL) == 0)    return svn_string_create(SVN_PROP_SPECIAL_VALUE, pool);  return NULL;}/* Determine if PROPNAME is contained in the list of space separated   values STRING.  */static svn_boolean_tstring_contains_prop(const char *string, const char *propname){  const char *place = strstr(string, propname);  int proplen = strlen(propname);  if (!place)    return FALSE;    while (place)    {            if (place[proplen] == ' ' || place[proplen] == 0)        return TRUE;      place = strstr(place + 1, propname);    }  return FALSE;}svn_error_t *svn_wc_prop_get(const svn_string_t **value,                const char *name,                const char *path,                svn_wc_adm_access_t *adm_access,                apr_pool_t *pool){  svn_error_t *err;  apr_hash_t *prophash;  enum svn_prop_kind kind = svn_property_kind(NULL, name);  const svn_wc_entry_t *entry;  SVN_ERR(svn_wc_entry(&entry, path, adm_access, TRUE, pool));  if (entry == NULL)    {      *value = NULL;      return SVN_NO_ERROR;    }  if (entry->cachable_props      && string_contains_prop(entry->cachable_props, name))    {      /* We separate these two cases so that we can return the correct         value for booleans if they exist in the string.  */      if (!entry->present_props          || !string_contains_prop(entry->present_props, name))        {          *value = NULL;          return SVN_NO_ERROR;        }      if (is_boolean_property(name))        {          *value = value_of_boolean_prop(name, pool);          assert(*value != NULL);          return SVN_NO_ERROR;        }    }  if (kind == svn_prop_wc_kind)    {      return wcprop_get(value, name, path, adm_access, pool);    }  if (kind == svn_prop_entry_kind)    {      return svn_error_createf   /* we don't do entry properties here */        (SVN_ERR_BAD_PROP_KIND, NULL,         _("Property '%s' is an entry property"), name);    }  else  /* regular prop */    {      err = svn_wc_prop_list(&prophash, path, adm_access, pool);      if (err)        return          svn_error_quick_wrap          (err, _("Failed to load properties from disk"));            *value = apr_hash_get(prophash, name, APR_HASH_KEY_STRING);      return SVN_NO_ERROR;    }}/* The special Subversion properties are not valid for all node kinds.   Return an error if NAME is an invalid Subversion property for PATH which   is of kind NODE_KIND. */static svn_error_t *validate_prop_against_node_kind(const char *name,                                const char *path,                                svn_node_kind_t node_kind,                                apr_pool_t *pool){  const char *file_prohibit[] = { SVN_PROP_IGNORE,                                  SVN_PROP_EXTERNALS,                                  NULL };  const char *dir_prohibit[] = { SVN_PROP_EXECUTABLE,                                 SVN_PROP_KEYWORDS,                                 SVN_PROP_EOL_STYLE,                                 SVN_PROP_MIME_TYPE,                                 SVN_PROP_NEEDS_LOCK,                                 NULL };  const char **node_kind_prohibit;  switch (node_kind)    {    case svn_node_dir:      node_kind_prohibit = dir_prohibit;      while (*node_kind_prohibit)        if (strcmp(name, *node_kind_prohibit++) == 0)          return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,                                   _("Cannot set '%s' on a directory ('%s')"),                                   name, svn_path_local_style(path, pool));      break;    case svn_node_file:      node_kind_prohibit = file_prohibit;      while (*node_kind_prohibit)        if (strcmp(name, *node_kind_prohibit++) == 0)          return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,                                   _("Cannot set '%s' on a file ('%s')"),                                   name,                                   svn_path_local_style(path, pool));      break;    default:      return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,                               _("'%s' is not a file or directory"),                               svn_path_local_style(path, pool));    }  return SVN_NO_ERROR;}                             static svn_error_t *validate_eol_prop_against_file(const char *path,                                svn_wc_adm_access_t *adm_access,                               apr_pool_t *pool){  apr_file_t *fp;  svn_stream_t *read_stream, *write_stream;  svn_error_t *err;  const svn_string_t *mime_type;  /* See if this file has been determined to be binary. */  SVN_ERR(svn_wc_prop_get(&mime_type, SVN_PROP_MIME_TYPE, path, adm_access,                          pool));  if (mime_type && svn_mime_type_is_binary(mime_type->data))    return svn_error_createf       (SVN_ERR_ILLEGAL_TARGET, NULL,       _("File '%s' has binary mime type property"),       svn_path_local_style(path, pool));  /* Open PATH. */  SVN_ERR(svn_io_file_open(&fp, path,                            (APR_READ | APR_BINARY | APR_BUFFERED),                           0, pool));  /* Get a READ_STREAM from the file we just opened. */  read_stream = svn_stream_from_aprfile(fp, pool);  /* Now, make an empty WRITE_STREAM. */  write_stream = svn_stream_empty(pool);  /* Do a newline translation.  Of course, all we really care about     here is whether or not the function fails on inconsistent line     endings.  The function is "translating" to an empty stream.  This     is sneeeeeeeeeeeaky. */  err = svn_subst_translate_stream3(read_stream, write_stream,                                    "", FALSE, NULL, FALSE, pool);  if (err && err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL)    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, err,                             _("File '%s' has inconsistent newlines"),                             svn_path_local_style(path, pool));  else if (err)    return err;  SVN_ERR(svn_io_file_close(fp, pool));  return SVN_NO_ERROR;}svn_error_t *svn_wc_prop_set2(const char *name,                 const svn_string_t *value,                 const char *path,                 svn_wc_adm_access_t *adm_access,                 svn_boolean_t skip_checks,                 apr_pool_t *pool){  svn_error_t *err;  apr_hash_t *prophash, *base_prophash;  svn_stringbuf_t *new_value = NULL;  enum svn_prop_kind prop_kind = svn_property_kind(NULL, name);  const char *base_name;  svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);  const svn_wc_entry_t *entry;  if (prop_kind == svn_prop_wc_kind)    return svn_wc__wcprop_set(name, value, path, adm_access, TRUE, pool);  else if (prop_kind == svn_prop_entry_kind)    return svn_error_createf   /* we don't do entry properties here */      (SVN_ERR_BAD_PROP_KIND, NULL,       _("Property '%s' is an entry property"), name);  /* Else, handle a regular property: */  /* Get the entry and name for this path. */  SVN_ERR(svn_wc_entry(&entry, path, adm_access, FALSE, pool));  if (! entry)    return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,                             _("'%s' is not under version control"),                             svn_path_local_style(path, pool));  base_name = entry->name;  /* Get the access baton for the entry's directory. */  if (entry->kind == svn_node_dir)    SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, path, pool));  else    SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access,                                svn_path_dirname(path, pool), pool));  /* Setting an inappropriate property is not allowed (unless     overridden by 'skip_checks', in some circumstances).  Deleting an     inappropriate property is allowed, however, since older clients     allowed (and other clients possibly still allow) setting it in     the first place. */  if (value)    {      SVN_ERR(validate_prop_against_node_kind(name, path, entry->kind,                                              pool));      if (!skip_checks && (strcmp(name, SVN_PROP_EOL_STYLE) == 0))        {          new_value = svn_stringbuf_create_from_string(value, pool);          svn_stringbuf_strip_whitespace(new_value);          SVN_ERR(validate_eol_prop_against_file(path, adm_access, pool));        }      else if (!skip_checks && (strcmp(name, SVN_PROP_MIME_TYPE) == 0))        {          new_value = svn_stringbuf_create_from_string(value, pool);          svn_stringbuf_strip_whitespace(new_value);          SVN_ERR(svn_mime_type_validate(new_value->data, pool));        }      else if (strcmp(name, SVN_PROP_IGNORE) == 0               || strcmp(name, SVN_PROP_EXTERNALS) == 0)        {          /* Make sure that the last line ends in a newline */          if (value->data[value->len - 1] != '\n')            {              new_value = svn_stringbuf_create_from_string(value, pool);              svn_stringbuf_appendbytes(new_value, "\n", 1);            }          /* Make sure this is a valid externals property.  Do not             allow 'skip_checks' to override, as there is no circumstance in             which this is proper (because there is no circumstance in             which Subversion can handle it). */          if (strcmp(name, SVN_PROP_EXTERNALS) == 0)            {              /* We don't allow "." nor ".." as target directories in                 an svn:externals line.  As it happens, our parse code                 checks for this, so all we have to is invoke it --                 we're not interested in the parsed result, only in                 whether or the parsing errored. */              SVN_ERR(svn_wc_parse_externals_description2

⌨️ 快捷键说明

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