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

📄 lock.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* lock.c :  functions for manipulating filesystem locks. * * ==================================================================== * 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/. * ==================================================================== */#include <assert.h>#include "svn_pools.h"#include "svn_error.h"#include "svn_path.h"#include "svn_fs.h"#include "svn_hash.h"#include "svn_time.h"#include "svn_utf.h"#include "svn_md5.h"#include <apr_uuid.h>#include <apr_file_io.h>#include <apr_file_info.h>#include <apr_md5.h>#include "lock.h"#include "tree.h"#include "err.h"#include "fs_fs.h"#include "../libsvn_fs/fs-loader.h"#include "svn_private_config.h"/* Names of special lock directories in the fs_fs filesystem. */#define LOCK_ROOT_DIR "locks"/* Names of hash keys used to store a lock for writing to disk. */#define PATH_KEY "path"#define TOKEN_KEY "token"#define OWNER_KEY "owner"#define CREATION_DATE_KEY "creation_date"#define EXPIRATION_DATE_KEY "expiration_date"#define COMMENT_KEY "comment"#define IS_DAV_COMMENT_KEY "is_dav_comment"#define CHILDREN_KEY "children"/* Number of characters from the head of a digest file name used to   calculate a subdirectory in which to drop that file. */#define DIGEST_SUBDIR_LEN 3/*** Generic helper functions. ***//* Return the MD5 hash of STR. */static const char *make_digest(const char *str,            apr_pool_t *pool){  unsigned char digest[APR_MD5_DIGESTSIZE];  apr_md5(digest, str, strlen(str));  return svn_md5_digest_to_cstring_display(digest, pool);}/* Set the value of KEY (whose size is KEY_LEN, or APR_HASH_KEY_STRING   if unknown) to an svn_string_t-ized version of VALUE (whose size is   VALUE_LEN, or APR_HASH_KEY_STRING if unknown) in HASH.  The value   will be allocated in POOL; KEY will not be duped.  If either KEY or VALUE   is NULL, this function will do nothing. */static voidhash_store(apr_hash_t *hash,           const char *key,           apr_ssize_t key_len,           const char *value,           apr_ssize_t value_len,           apr_pool_t *pool){  if (! (key && value))    return;  if (value_len == APR_HASH_KEY_STRING)    value_len = strlen(value);  apr_hash_set(hash, key, key_len,                svn_string_ncreate(value, value_len, pool));}/* Fetch the value of KEY from HASH, returning only the cstring data   of that value (if it exists). */static const char *hash_fetch(apr_hash_t *hash,           const char *key,           apr_pool_t *pool){  svn_string_t *str = apr_hash_get(hash, key, APR_HASH_KEY_STRING);  return str ? str->data : NULL;}/*** Digest file handling functions. ***//* Return the path of the lock/entries file for which DIGEST is the   hashed repository relative path. */static const char *digest_path_from_digest(svn_fs_t *fs,                        const char *digest,                        apr_pool_t *pool){  return svn_path_join_many(pool, fs->path, LOCK_ROOT_DIR,                             apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),                             digest, NULL);}/* Return the path to the lock/entries digest file associate with   PATH, where PATH is the path to the lock file or lock entries file   in FS. */static const char *digest_path_from_path(svn_fs_t *fs,                      const char *path,                      apr_pool_t *pool){  const char *digest = make_digest(path, pool);  return svn_path_join_many(pool, fs->path, LOCK_ROOT_DIR,                             apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),                             digest, NULL);}/* If directory PATH does not exist, create it and give it the same   permissions as FS->path.*/static svn_error_t *ensure_dir_exists(const char *path,                  svn_fs_t *fs,                  apr_pool_t *pool){  svn_error_t *err = svn_io_dir_make(path, APR_OS_DEFAULT, pool);  if (err && APR_STATUS_IS_EEXIST(err->apr_err))    {      svn_error_clear(err);      return SVN_NO_ERROR;    }  SVN_ERR(err);  /* We successfully created a new directory.  Dup the permissions     from FS->path. */  SVN_ERR(svn_fs_fs__dup_perms(path, fs->path, pool));  return SVN_NO_ERROR;}/* Write to DIGEST_PATH a representation of CHILDREN (which may be   empty, if the versioned path in FS represented by DIGEST_PATH has   no children) and LOCK (which may be NULL if that versioned path is   lock itself locked).  Use POOL for all allocations. */static svn_error_t *write_digest_file(apr_hash_t *children,                  svn_lock_t *lock,                  svn_fs_t *fs,                  const char *digest_path,                  apr_pool_t *pool){  svn_error_t *err = SVN_NO_ERROR;  apr_file_t *fd;  apr_hash_index_t *hi;  apr_hash_t *hash = apr_hash_make(pool);  const char *tmp_path;  SVN_ERR(ensure_dir_exists(svn_path_join(fs->path, LOCK_ROOT_DIR, pool),                             fs, pool));  SVN_ERR(ensure_dir_exists(svn_path_dirname(digest_path, pool), fs, pool));  SVN_ERR(svn_io_open_unique_file2          (&fd, &tmp_path, digest_path, ".tmp", svn_io_file_del_none, pool));  if (lock)    {      const char *creation_date = NULL, *expiration_date = NULL;      if (lock->creation_date)        creation_date = svn_time_to_cstring(lock->creation_date, pool);      if (lock->expiration_date)        expiration_date = svn_time_to_cstring(lock->expiration_date, pool);      hash_store(hash, PATH_KEY, sizeof(PATH_KEY)-1,                 lock->path, APR_HASH_KEY_STRING, pool);       hash_store(hash, TOKEN_KEY, sizeof(TOKEN_KEY)-1,                 lock->token, APR_HASH_KEY_STRING, pool);       hash_store(hash, OWNER_KEY, sizeof(OWNER_KEY)-1,                 lock->owner, APR_HASH_KEY_STRING, pool);       hash_store(hash, COMMENT_KEY, sizeof(COMMENT_KEY)-1,                 lock->comment, APR_HASH_KEY_STRING, pool);       hash_store(hash, IS_DAV_COMMENT_KEY, sizeof(IS_DAV_COMMENT_KEY)-1,                 lock->is_dav_comment ? "1" : "0", 1, pool);      hash_store(hash, CREATION_DATE_KEY, sizeof(CREATION_DATE_KEY)-1,                 creation_date, APR_HASH_KEY_STRING, pool);      hash_store(hash, EXPIRATION_DATE_KEY, sizeof(EXPIRATION_DATE_KEY)-1,                 expiration_date, APR_HASH_KEY_STRING, pool);    }  if (apr_hash_count(children))    {      svn_stringbuf_t *children_list = svn_stringbuf_create("", pool);      for (hi = apr_hash_first(pool, children); hi; hi = apr_hash_next(hi))         {          const void *key;          apr_ssize_t klen;          apr_hash_this(hi, &key, &klen, NULL);          svn_stringbuf_appendbytes(children_list, key, klen);          svn_stringbuf_appendbytes(children_list, "\n", 1);        }      hash_store(hash, CHILDREN_KEY, sizeof(CHILDREN_KEY)-1,                 children_list->data, children_list->len, pool);    }   if ((err = svn_hash_write2(hash,                              svn_stream_from_aprfile(fd, pool),                             SVN_HASH_TERMINATOR, pool)))    {      svn_error_clear(svn_io_file_close(fd, pool));      return svn_error_createf(err->apr_err,                               err,                               _("Cannot write lock/entries hashfile '%s'"),                               svn_path_local_style(tmp_path, pool));    }  SVN_ERR(svn_io_file_close(fd, pool));  SVN_ERR(svn_io_file_rename(tmp_path, digest_path, pool));  SVN_ERR(svn_fs_fs__dup_perms           (digest_path, svn_fs_fs__path_rev(fs, 0, pool), pool));  return SVN_NO_ERROR;}/* Parse the file at DIGEST_PATH, populating the lock LOCK_P in that   file (if it exists, and if *LOCK_P is non-NULL) and the hash of   CHILDREN_P (if any exist, and if *CHILDREN_P is non-NULL).  Use POOL   for all allocations.  */static svn_error_t *read_digest_file(apr_hash_t **children_p,                 svn_lock_t **lock_p,                 svn_fs_t *fs,                 const char *digest_path,                 apr_pool_t *pool){  svn_error_t *err = SVN_NO_ERROR;  svn_lock_t *lock;  apr_hash_t *hash;  apr_file_t *fd;  const char *val;  if (lock_p)    *lock_p = NULL;  if (children_p)    *children_p = apr_hash_make(pool);  err = svn_io_file_open(&fd, digest_path, APR_READ, APR_OS_DEFAULT, pool);  if (err && APR_STATUS_IS_ENOENT(err->apr_err))    {      svn_error_clear(err);      return SVN_NO_ERROR;    }  SVN_ERR(err);  /* If our caller doesn't care about anything but the presence of the     file... whatever. */  if (! (lock_p || children_p))    return svn_io_file_close(fd, pool);  hash = apr_hash_make(pool);  if ((err = svn_hash_read2(hash,                             svn_stream_from_aprfile(fd, pool),                            SVN_HASH_TERMINATOR, pool)))    {      svn_error_clear(svn_io_file_close(fd, pool));      return svn_error_createf(err->apr_err,                               err,                               _("Can't parse lock/entries hashfile '%s'"),                               svn_path_local_style(digest_path, pool));    }  SVN_ERR(svn_io_file_close(fd, pool));  /* If our caller cares, see if we have a lock path in our hash. If     so, we'll assume we have a lock here. */  val = hash_fetch(hash, PATH_KEY, pool);  if (val && lock_p)    {      const char *path = val;      /* Create our lock and load it up. */      lock = svn_lock_create(pool);      lock->path = path;      if (! ((lock->token = hash_fetch(hash, TOKEN_KEY, pool))))        return svn_fs_fs__err_corrupt_lockfile(fs, path);      if (! ((lock->owner = hash_fetch(hash, OWNER_KEY, pool))))        return svn_fs_fs__err_corrupt_lockfile(fs, path);      if (! ((val = hash_fetch(hash, IS_DAV_COMMENT_KEY, pool))))        return svn_fs_fs__err_corrupt_lockfile(fs, path);      lock->is_dav_comment = (val[0] == '1') ? TRUE : FALSE;      if (! ((val = hash_fetch(hash, CREATION_DATE_KEY, pool))))        return svn_fs_fs__err_corrupt_lockfile(fs, path);      SVN_ERR(svn_time_from_cstring(&(lock->creation_date), val, pool));

⌨️ 快捷键说明

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