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

📄 adm_files.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * adm_files.c: helper routines for handling files & dirs in the *              working copy administrative area (creating, *              deleting, opening, and closing).  This is the only *              code that actually knows where administrative *              information is kept.   * * ==================================================================== * 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 <stdarg.h>#include <assert.h>#include <apr_pools.h>#include <apr_file_io.h>#include <apr_strings.h>#include "svn_types.h"#include "svn_error.h"#include "svn_io.h"#include "svn_path.h"#include "svn_wc.h"#include "wc.h"#include "adm_files.h"#include "entries.h"#include "lock.h"#include "svn_private_config.h"/*** File names in the adm area. ***//* The default name of the WC admin directory. This name is always   checked by svn_wc_is_adm_dir. */static const char default_adm_dir_name[] = ".svn";/* The name that is actually used for the WC admin directory.  The   commonest case where this won't be the default is in Windows   ASP.NET development environments, which choke on ".svn". */static const char *adm_dir_name = default_adm_dir_name;svn_boolean_tsvn_wc_is_adm_dir(const char *name, apr_pool_t *pool){  return (0 == strcmp(name, adm_dir_name)          || 0 == strcmp(name, default_adm_dir_name));}const char *svn_wc_get_adm_dir(apr_pool_t *pool){  return adm_dir_name;}svn_error_t *svn_wc_set_adm_dir(const char *name, apr_pool_t *pool){  /* This is the canonical list of administrative directory names.     FIXME:     An identical list is used in       libsvn_subr/opt.c:svn_opt_args_to_target_array2(),     but that function can't use this list, because that use would     create a circular dependency between libsvn_wc and libsvn_subr.     Make sure changes to the lists are always synchronized! */  static const char *valid_dir_names[] = {    default_adm_dir_name,    "_svn",    NULL  };  const char **dir_name;  for (dir_name = valid_dir_names; *dir_name; ++dir_name)    if (0 == strcmp(name, *dir_name))      {        /* Use the pointer to the statically allocated string           constant, to avoid potential pool lifetime issues. */        adm_dir_name = *dir_name;        return SVN_NO_ERROR;      }  return svn_error_createf    (SVN_ERR_BAD_FILENAME, NULL,     _("'%s' is not a valid administrative directory name"),     svn_path_local_style(name, pool));}/* Return the path to something in PATH's administrative area. * * First, the adm subdir is appended to PATH as a component, then the * "tmp" directory is added iff USE_TMP is set, then each of the * varargs in AP (char *'s) is appended as a path component.  The list * must be terminated with a NULL argument. * * Adding an empty component results in no effect (i.e., the separator * char is not doubled). * * If EXTENSION is non-null, it will be appended to the final string * without a separator character. */static const char *v_extend_with_adm_name(const char *path,                       const char *extension,                       svn_boolean_t use_tmp,                       apr_pool_t *pool,                       va_list ap){  const char *this;  /* Tack on the administrative subdirectory. */  path = svn_path_join(path, adm_dir_name, pool);  /* If this is a tmp file, name it into the tmp area. */  if (use_tmp)    path = svn_path_join(path, SVN_WC__ADM_TMP, pool);  /* Tack on everything else. */  while ((this = va_arg(ap, const char *)) != NULL)    {      if (this[0] == '\0')        continue;      path = svn_path_join(path, this, pool);    }  if (extension)    path = apr_pstrcat(pool, path, extension, NULL);  return path;}/* See v_extend_with_adm_name() for details. */static const char *extend_with_adm_name(const char *path,                     const char *extension,                     svn_boolean_t use_tmp,                     apr_pool_t *pool,                     ...){  va_list ap;  va_start(ap, pool);  path = v_extend_with_adm_name(path, extension, use_tmp, pool, ap);  va_end(ap);  return path;}const char *svn_wc__adm_path(const char *path,                 svn_boolean_t tmp,                 apr_pool_t *pool,                  ...){  va_list ap;  va_start(ap, pool);  path = v_extend_with_adm_name(path, NULL, tmp, pool, ap);  va_end(ap);  return path;}svn_boolean_tsvn_wc__adm_path_exists(const char *path,                        svn_boolean_t tmp,                        apr_pool_t *pool,                         ...){  svn_node_kind_t kind;  svn_error_t *err;  va_list ap;  va_start(ap, pool);  path = v_extend_with_adm_name(path, NULL, tmp, pool, ap);  va_end(ap);  err = svn_io_check_path(path, &kind, pool);  if (err)    {      svn_error_clear(err);      /* Return early, since kind is undefined in this case. */      return FALSE;    }  if (kind == svn_node_none)    return FALSE;  else    return TRUE;}/*** Making and using files in the adm area. ***//* Create an empty THING in the adm area with permissions set to PERMS.  * If TMP is non-zero, then create THING in the tmp dir. * * Does not check if THING already exists, so be careful -- THING will * be empty after this no matter what. */svn_error_t *svn_wc__make_adm_thing(svn_wc_adm_access_t *adm_access,                       const char *thing,                       svn_node_kind_t type,                       apr_fileperms_t perms,                       svn_boolean_t tmp,                       apr_pool_t *pool){  svn_error_t *err = SVN_NO_ERROR;  apr_file_t *f = NULL;  const char *path;  SVN_ERR(svn_wc__adm_write_check(adm_access));  path = extend_with_adm_name(svn_wc_adm_access_path(adm_access),                              NULL, tmp, pool, thing, NULL);  if (type == svn_node_file)    {      SVN_ERR(svn_io_file_open(&f, path,                               (APR_WRITE | APR_CREATE | APR_EXCL),                               perms,                               pool));      /* Creation succeeded, so close immediately. */      SVN_ERR(svn_io_file_close(f, pool));    }  else if (type == svn_node_dir)    {      SVN_ERR(svn_io_dir_make(path, perms, pool));    }  else   /* unknown type argument, wrongness */    {      /* We're only capturing this here because there wouldn't be a         segfault or other obvious indicator that something went         wrong.  Even so, not sure if it's appropriate.  Thoughts? */      err = svn_error_create         (0, NULL, _("Bad type indicator"));    }  return err;}/*** Syncing files in the adm area. ***/static svn_error_t *sync_adm_file(const char *path,              const char *extension,              apr_pool_t *pool,              ...){  /* Some code duplication with close_adm_file() seems unavoidable,     given how C va_lists work. */  const char *tmp_path;  va_list ap;    /* Extend tmp name. */  va_start(ap, pool);  tmp_path = v_extend_with_adm_name(path, extension, 1, pool, ap);  va_end(ap);    /* Extend real name. */  va_start(ap, pool);  path = v_extend_with_adm_name(path, extension, 0, pool, ap);  va_end(ap);    /* Rename. */  SVN_ERR(svn_io_file_rename(tmp_path, path, pool));  SVN_ERR(svn_io_set_file_read_only(path, FALSE, pool));  return SVN_NO_ERROR;}/* Rename a tmp text-base file to its real text-base name.   The file had better already be closed. */svn_error_t *svn_wc__sync_text_base(const char *path, apr_pool_t *pool){  const char *parent_path, *base_name;  svn_path_split(path, &parent_path, &base_name, pool);  return sync_adm_file(parent_path,                       SVN_WC__BASE_EXT,                       pool,                       SVN_WC__ADM_TEXT_BASE,                       base_name,                       NULL);}const char *svn_wc__text_base_path(const char *path,                       svn_boolean_t tmp,                       apr_pool_t *pool){  const char *newpath, *base_name;  svn_path_split(path, &newpath, &base_name, pool);  return extend_with_adm_name(newpath,                              SVN_WC__BASE_EXT,                              tmp,                              pool,                              SVN_WC__ADM_TEXT_BASE,                              base_name,                              NULL);}const char *svn_wc__text_revert_path(const char *path,                         svn_boolean_t tmp,                         apr_pool_t *pool){  const char *newpath, *base_name;  svn_path_split(path, &newpath, &base_name, pool);  return extend_with_adm_name(newpath,                              SVN_WC__REVERT_EXT,                              tmp,                              pool,                              SVN_WC__ADM_TEXT_BASE,                              base_name,                              NULL);}/* Kind for prop_path_internal. */typedef enum prop_path_kind_t{  prop_path_kind_base = 0,  prop_path_kind_revert,  prop_path_kind_wcprop,  prop_path_kind_working} prop_path_kind_t;static svn_error_t *prop_path_internal(const char **prop_path,                   const char *path,                   svn_node_kind_t kind,                   prop_path_kind_t path_kind,                   svn_boolean_t tmp,                   apr_pool_t *pool){  if (kind == svn_node_dir)  /* It's a working copy dir */    {      static const char * names[] = {        SVN_WC__ADM_DIR_PROP_BASE,    /* prop_path_kind_base */        SVN_WC__ADM_DIR_PROP_REVERT,  /* prop_path_kind_revert */        SVN_WC__ADM_DIR_WCPROPS,      /* prop_path_kind_wcprop */        SVN_WC__ADM_DIR_PROPS         /* prop_path_kind_working */      };      *prop_path = extend_with_adm_name        (path,         NULL,         tmp,         pool,         names[path_kind],         NULL);    }  else  /* It's a file */    {      static const char * extensions[] = {        SVN_WC__BASE_EXT,     /* prop_path_kind_base */        SVN_WC__REVERT_EXT,   /* prop_path_kind_revert */        SVN_WC__WORK_EXT,     /* prop_path_kind_wcprop */        SVN_WC__WORK_EXT      /* prop_path_kind_working */      };      static const char * dirs[] = {        SVN_WC__ADM_PROP_BASE,  /* prop_path_kind_base */        SVN_WC__ADM_PROP_BASE,  /* prop_path_kind_revert */        SVN_WC__ADM_WCPROPS,    /* prop_path_kind_wcprop */        SVN_WC__ADM_PROPS       /* prop_path_kind_working */      };      const char *base_name;      svn_path_split(path, prop_path, &base_name, pool);      *prop_path = extend_with_adm_name        (*prop_path,         extensions[path_kind],         tmp,         pool,         dirs[path_kind],         base_name,

⌨️ 快捷键说明

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