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

📄 props.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * props.c :  routines dealing with properties in the working copy * * ==================================================================== * Copyright (c) 2000-2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <stdio.h>       /* temporary, for printf() */#include <stdlib.h>#include <string.h>#include <assert.h>#include <apr_pools.h>#include <apr_hash.h>#include <apr_tables.h>#include <apr_file_io.h>#include <apr_strings.h>#include <apr_general.h>#include "svn_types.h"#include "svn_string.h"#include "svn_pools.h"#include "svn_path.h"#include "svn_xml.h"#include "svn_error.h"#include "svn_props.h"#include "svn_io.h"#include "svn_hash.h"#include "svn_wc.h"#include "svn_utf.h"#include "wc.h"#include "log.h"#include "adm_files.h"#include "entries.h"#include "props.h"#include "translate.h"#include "questions.h"#include "lock.h"#include "svn_private_config.h"/*---------------------------------------------------------------------*//*** Deducing local changes to properties ***//*---------------------------------------------------------------------*//*** Reading/writing property hashes from disk ***//* The real functionality here is part of libsvn_subr, in hashdump.c.   But these are convenience routines for use in libsvn_wc. *//* If PROPFILE_PATH exists (and is a file), assume it's full of   properties and load this file into HASH.  Otherwise, leave HASH   untouched.  */svn_error_t *svn_wc__load_prop_file(const char *propfile_path,                       apr_hash_t *hash,                       apr_pool_t *pool){  svn_error_t *err;  apr_file_t *propfile = NULL;  err = svn_io_file_open(&propfile, propfile_path,                         APR_READ | APR_BUFFERED, APR_OS_DEFAULT,                         pool);  if (err && (APR_STATUS_IS_ENOENT(err->apr_err)              || APR_STATUS_IS_ENOTDIR(err->apr_err)))    {      svn_error_clear(err);      return SVN_NO_ERROR;    }  SVN_ERR(err);  SVN_ERR_W(svn_hash_read(hash, propfile, pool),            apr_psprintf(pool, _("Can't parse '%s'"),                         svn_path_local_style(propfile_path, pool)));  SVN_ERR(svn_io_file_close(propfile, pool));  return SVN_NO_ERROR;}/* Given a HASH full of property name/values, write them to a file   located at PROPFILE_PATH.  */svn_error_t *svn_wc__save_prop_file(const char *propfile_path,                       apr_hash_t *hash,                       apr_pool_t *pool){  apr_file_t *prop_tmp;  SVN_ERR(svn_io_file_open(&prop_tmp, propfile_path,                           (APR_WRITE | APR_CREATE | APR_TRUNCATE                            | APR_BUFFERED),                            APR_OS_DEFAULT, pool));  if (apr_hash_count(hash) != 0)    SVN_ERR_W(svn_hash_write(hash, prop_tmp, pool),              apr_psprintf(pool,                            _("Can't write property hash to '%s'"),                           svn_path_local_style(propfile_path, pool)));  SVN_ERR(svn_io_file_close(prop_tmp, pool));  return SVN_NO_ERROR;}/*---------------------------------------------------------------------*//*** Misc ***//* Opens reject temporary file for FULL_PATH. */static svn_error_t *open_reject_tmp_file(apr_file_t **fp, const char **reject_tmp_path,                     const char *full_path,                     svn_wc_adm_access_t *adm_access,                     svn_boolean_t is_dir, apr_pool_t *pool){  const char *tmp_path, *tmp_name;  /* Get path to /temporary/ local prop file */  SVN_ERR(svn_wc__prop_path(&tmp_path, full_path,                            is_dir ? svn_node_dir : svn_node_file,                            TRUE, pool));  /* Reserve a .prej file based on it.  */  SVN_ERR(svn_io_open_unique_file2(fp, reject_tmp_path, tmp_path,                                   SVN_WC__PROP_REJ_EXT,                                   svn_io_file_del_none, pool));  /* reject_tmp_path is an absolute path at this point,     but that's no good for us.  We need to convert this     path to a *relative* path to use in the logfile. */  tmp_name = svn_path_basename(*reject_tmp_path, pool);  if (is_dir)    {      /* Dealing with directory "path" */      *reject_tmp_path = svn_wc__adm_path("", TRUE, /* use tmp */ pool,                                          tmp_name, NULL);    }  else    {      /* Dealing with file "path/name" */      *reject_tmp_path = svn_wc__adm_path("", TRUE, pool, SVN_WC__ADM_PROPS,                                          tmp_name, NULL);    }  return SVN_NO_ERROR;}/* Assuming FP is a filehandle already open for appending, write   CONFLICT_DESCRIPTION to file. */static svn_error_t *append_prop_conflict(apr_file_t *fp,                     const svn_string_t *conflict_description,                     apr_pool_t *pool){  /* TODO:  someday, perhaps prefix each conflict_description with a     timestamp or something? */  apr_size_t written;  const char *conflict_description_native =    svn_utf_cstring_from_utf8_fuzzy(conflict_description->data, pool);  SVN_ERR(svn_io_file_write_full(fp, conflict_description_native,                                 strlen(conflict_description_native),                                 &written, pool));  return SVN_NO_ERROR;}/* Look up the entry NAME within ADM_ACCESS and see if it has a `current'   reject file describing a state of conflict.  Set *REJECT_FILE to the   name of that file, or to NULL if no such file exists. */static svn_error_t *get_existing_prop_reject_file(const char **reject_file,                              svn_wc_adm_access_t *adm_access,                              const char *name,                              apr_pool_t *pool){  apr_hash_t *entries;  const svn_wc_entry_t *the_entry;  SVN_ERR(svn_wc_entries_read(&entries, adm_access, FALSE, pool));  the_entry = apr_hash_get(entries, name, APR_HASH_KEY_STRING);  if (! the_entry)    return svn_error_createf      (SVN_ERR_ENTRY_NOT_FOUND, NULL,       _("Can't find entry '%s' in '%s'"),       name,       svn_path_local_style(svn_wc_adm_access_path(adm_access), pool));  *reject_file = the_entry->prejfile     ? apr_pstrdup(pool, the_entry->prejfile)                 : NULL;  return SVN_NO_ERROR;}/*---------------------------------------------------------------------*//* Build a space separated list of properties that are contained in   the hash PROPS and which we want to cache.   The string is allocated in POOL. */static const char *build_present_props(apr_hash_t *props, apr_pool_t *pool){  apr_array_header_t *cachable;  svn_stringbuf_t *present_props = svn_stringbuf_create("", pool);  int i;    if (apr_hash_count(props) == 0)    return present_props->data;  cachable = svn_cstring_split(SVN_WC__CACHABLE_PROPS, " ", TRUE, pool);  for (i = 0; i < cachable->nelts; i++)    {      const char *proptolookfor = APR_ARRAY_IDX(cachable, i,                                                 const char *);      if (apr_hash_get(props, proptolookfor, APR_HASH_KEY_STRING) != NULL)        {          svn_stringbuf_appendcstr(present_props, proptolookfor);          svn_stringbuf_appendcstr(present_props, " ");        }    }  /* Avoid returning a string with a trailing space. */  svn_stringbuf_chop(present_props, 1);  return present_props->data;}/*** Loading regular properties. ***/svn_error_t *svn_wc__load_props(apr_hash_t **base_props_p,                   apr_hash_t **props_p,                   svn_wc_adm_access_t *adm_access,                   const char *name,                   apr_pool_t *pool){  const char *full_path;  const char *access_path = svn_wc_adm_access_path(adm_access);  svn_node_kind_t kind;  svn_boolean_t has_propcaching =    svn_wc__adm_wc_format(adm_access) > SVN_WC__NO_PROPCACHING_VERSION;  const svn_wc_entry_t *entry;  apr_hash_t *base_props = NULL; /* Silence uninitialized warning. */  if (strcmp(name, SVN_WC_ENTRY_THIS_DIR) == 0)    {      full_path = access_path;      kind = svn_node_dir;    }  else    {      full_path = svn_path_join(access_path, name, pool);      kind = svn_node_file;    }  SVN_ERR(svn_wc_entry(&entry, full_path, adm_access, FALSE, pool));  /* If there is no entry, we just return empty hashes, since the     property merging can use this function when there is no entry. */  if (! entry)    {      if (base_props_p)        *base_props_p = apr_hash_make(pool);      if (props_p)        *props_p = apr_hash_make(pool);      return SVN_NO_ERROR;    }  /* We will need the base props if the user requested them, OR,     our WC has prop caching, the user requested working props and there are no     prop mods. */  if (base_props_p      || (has_propcaching && ! entry->has_prop_mods && entry->has_props))    {      const char *prop_base_path;      SVN_ERR(svn_wc__prop_base_path(&prop_base_path, full_path,                                     kind, FALSE, pool));      base_props = apr_hash_make(pool);      SVN_ERR(svn_wc__load_prop_file(prop_base_path, base_props, pool));      if (base_props_p)        *base_props_p = base_props;    }  if (props_p)    {      if (has_propcaching && ! entry->has_prop_mods && entry->has_props)        *props_p = apr_hash_copy(pool, base_props);      else if (! has_propcaching || entry->has_props)        {          const char *prop_path;          SVN_ERR(svn_wc__prop_path(&prop_path, full_path,                                    kind, FALSE, pool));          *props_p = apr_hash_make(pool);          SVN_ERR(svn_wc__load_prop_file(prop_path, *props_p, pool));        }      else        *props_p = apr_hash_make(pool);    }        return SVN_NO_ERROR;}/*---------------------------------------------------------------------*//*** Installing new properties. ***/svn_error_t *svn_wc__install_props(svn_stringbuf_t **log_accum,                      svn_wc_adm_access_t *adm_access,                      const char *name,                      apr_hash_t *base_props,                      apr_hash_t *working_props,                      svn_boolean_t write_base_props,                      apr_pool_t *pool){  const char *working_propfile_path, *working_prop_tmp_path;  const char *tmp_props, *real_props;        const char *full_path;  const char *access_path = svn_wc_adm_access_path(adm_access);  int access_len = strlen(access_path);  apr_array_header_t *prop_diffs;  svn_wc_entry_t tmp_entry;  svn_node_kind_t kind;  /* Non-empty path without trailing slash need an extra slash removed */  if (access_len != 0 && access_path[access_len - 1] != '/')    access_len++;  if (strcmp(name, SVN_WC_ENTRY_THIS_DIR) == 0)    {      kind = svn_node_dir;      full_path = access_path;    }  else    {      kind = svn_node_file;      full_path = svn_path_join(access_path, name, pool);    }  /* Check if the props are modified. */  SVN_ERR(svn_prop_diffs(&prop_diffs, working_props, base_props, pool));  tmp_entry.has_prop_mods = (prop_diffs->nelts > 0);  tmp_entry.has_props = (apr_hash_count(working_props) > 0);  tmp_entry.cachable_props = SVN_WC__CACHABLE_PROPS;  tmp_entry.present_props = build_present_props(working_props, pool);  SVN_ERR(svn_wc__loggy_entry_modify(log_accum, adm_access, name, &tmp_entry,                                     SVN_WC__ENTRY_MODIFY_HAS_PROPS                                     | SVN_WC__ENTRY_MODIFY_HAS_PROP_MODS                                      | SVN_WC__ENTRY_MODIFY_CACHABLE_PROPS                                     | SVN_WC__ENTRY_MODIFY_PRESENT_PROPS,                                     pool));  /* Write our property hashes into temporary files.  Notice that the     paths computed are ABSOLUTE pathnames, which is what our disk     routines require. */  SVN_ERR(svn_wc__prop_path(&working_propfile_path, full_path,                            kind, FALSE, pool));   real_props = apr_pstrdup(pool, working_propfile_path + access_len);  if (tmp_entry.has_prop_mods)    {

⌨️ 快捷键说明

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