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

📄 lock.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
      if ((val = hash_fetch(hash, EXPIRATION_DATE_KEY, pool)))        SVN_ERR(svn_time_from_cstring(&(lock->expiration_date), val, pool));      lock->comment = hash_fetch(hash, COMMENT_KEY, pool);      *lock_p = lock;    }  /* If our caller cares, see if we have any children for this path. */  val = hash_fetch(hash, CHILDREN_KEY, pool);  if (val && children_p)    {      apr_array_header_t *kiddos = svn_cstring_split(val, "\n", FALSE, pool);      int i;      for (i = 0; i < kiddos->nelts; i++)        {          apr_hash_set(*children_p, APR_ARRAY_IDX(kiddos, i, const char *),                       APR_HASH_KEY_STRING, (void *)1);        }    }  return SVN_NO_ERROR;}/*** Lock helper functions (path here are still FS paths, not on-disk     schema-supporting paths) ***//* Write LOCK in FS to the actual OS filesystem. */static svn_error_t *set_lock(svn_fs_t *fs,         svn_lock_t *lock,         apr_pool_t *pool){  svn_stringbuf_t *this_path = svn_stringbuf_create(lock->path, pool);  svn_stringbuf_t *last_child = svn_stringbuf_create("", pool);  apr_pool_t *subpool;  assert(lock);  /* Iterate in reverse, creating the lock for LOCK->path, and then     just adding entries for its parent, until we reach a parent     that's already listed in *its* parent. */   subpool = svn_pool_create(pool);  while (1729)    {      const char *digest_path, *parent_dir, *digest_file;      apr_hash_t *this_children;      svn_lock_t *this_lock;      svn_pool_clear(subpool);      /* Calculate the DIGEST_PATH for the currently FS path, and then         split it into a PARENT_DIR and DIGEST_FILE basename. */      digest_path = digest_path_from_path(fs, this_path->data, subpool);      svn_path_split(digest_path, &parent_dir, &digest_file, subpool);      SVN_ERR(read_digest_file(&this_children, &this_lock, fs,                                digest_path, subpool));      /* We're either writing a new lock (first time through only) or         a new entry (every time but the first). */      if (lock)        {          this_lock = lock;          lock = NULL;          svn_stringbuf_set(last_child, digest_file);        }      else        {          /* If we already have an entry for this path, we're done. */          if (apr_hash_get(this_children, last_child->data, last_child->len))            break;          apr_hash_set(this_children, last_child->data,                        last_child->len, (void *)1);        }      SVN_ERR(write_digest_file(this_children, this_lock, fs,                                 digest_path, subpool));      /* Prep for next iteration, or bail if we're done. */      if ((this_path->len == 1) && (this_path->data[0] == '/'))        break;      svn_stringbuf_set(this_path,                         svn_path_dirname(this_path->data, subpool));    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* Delete LOCK from FS in the actual OS filesystem. */static svn_error_t *delete_lock(svn_fs_t *fs,             svn_lock_t *lock,            apr_pool_t *pool){  svn_stringbuf_t *this_path = svn_stringbuf_create(lock->path, pool);  svn_stringbuf_t *child_to_kill = svn_stringbuf_create("", pool);  apr_pool_t *subpool;  assert(lock);  /* Iterate in reverse, deleting the lock for LOCK->path, and then     pruning entries from its parents. */  subpool = svn_pool_create(pool);  while (1729)    {      const char *digest_path, *parent_dir, *digest_file;      apr_hash_t *this_children;      svn_lock_t *this_lock;      svn_pool_clear(subpool);      /* Calculate the DIGEST_PATH for the currently FS path, and then         split it into a PARENT_DIR and DIGEST_FILE basename. */      digest_path = digest_path_from_path(fs, this_path->data, subpool);      svn_path_split(digest_path, &parent_dir, &digest_file, subpool);      SVN_ERR(read_digest_file(&this_children, &this_lock, fs,                                digest_path, subpool));      /* If we are supposed to drop the last entry from this path's         children list, do so. */      if (child_to_kill->len)        apr_hash_set(this_children, child_to_kill->data,                      child_to_kill->len, NULL);              /* Delete the lock (first time through only). */      if (lock)        {          this_lock = NULL;          lock = NULL;        }      if (! (this_lock || apr_hash_count(this_children) != 0))        {          /* Special case:  no goodz, no file.  And remember to nix             the entry for it in its parent. */          svn_stringbuf_set(child_to_kill,                             svn_path_basename(digest_path, subpool));          SVN_ERR(svn_io_remove_file(digest_path, subpool));        }      else        {          SVN_ERR(write_digest_file(this_children, this_lock, fs,                                     digest_path, subpool));          svn_stringbuf_setempty(child_to_kill);        }      /* Prep for next iteration, or bail if we're done. */      if ((this_path->len == 1) && (this_path->data[0] == '/'))        break;      svn_stringbuf_set(this_path,                         svn_path_dirname(this_path->data, subpool));    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* Set *LOCK_P to the lock for PATH in FS.  HAVE_WRITE_LOCK should be   TRUE if the caller (or one of its callers) has taken out the   repository-wide write lock, FALSE otherwise.  Use POOL for   allocations. */static svn_error_t *get_lock(svn_lock_t **lock_p,         svn_fs_t *fs,         const char *path,         svn_boolean_t have_write_lock,         apr_pool_t *pool){  svn_lock_t *lock;  const char *digest_path = digest_path_from_path(fs, path, pool);  SVN_ERR(read_digest_file(NULL, &lock, fs, digest_path, pool));  if (! lock)    return svn_fs_fs__err_no_such_lock(fs, path);  /* Don't return an expired lock. */  if (lock->expiration_date && (apr_time_now() > lock->expiration_date))    {      /* Only remove the lock if we have the write lock.         Read operations shouldn't change the filesystem. */      if (have_write_lock)        SVN_ERR(delete_lock(fs, lock, pool));      *lock_p = NULL;      return svn_fs_fs__err_lock_expired(fs, lock->token);     }    *lock_p = lock;  return SVN_NO_ERROR;}/* Set *LOCK_P to the lock for PATH in FS.  HAVE_WRITE_LOCK should be   TRUE if the caller (or one of its callers) has taken out the   repository-wide write lock, FALSE otherwise.  Use POOL for   allocations. */static svn_error_t *get_lock_helper(svn_fs_t *fs,                svn_lock_t **lock_p,                const char *path,                svn_boolean_t have_write_lock,                apr_pool_t *pool){  svn_lock_t *lock;  svn_error_t *err;    err = get_lock(&lock, fs, path, have_write_lock, pool);  /* We've deliberately decided that this function doesn't tell the     caller *why* the lock is unavailable.  */  if (err && ((err->apr_err == SVN_ERR_FS_NO_SUCH_LOCK)              || (err->apr_err == SVN_ERR_FS_LOCK_EXPIRED)))    {      svn_error_clear(err);      *lock_p = NULL;      return SVN_NO_ERROR;    }  else    SVN_ERR(err);  *lock_p = lock;  return SVN_NO_ERROR;}/* A recursive function that calls GET_LOCKS_FUNC/GET_LOCKS_BATON for   all locks in and under PATH in FS.   HAVE_WRITE_LOCK should be true if the caller (directly or indirectly)   has the FS write lock. */static svn_error_t *walk_digest_files(svn_fs_t *fs,                   const char *digest_path,                  svn_fs_get_locks_callback_t get_locks_func,                  void *get_locks_baton,                  svn_boolean_t have_write_lock,                  apr_pool_t *pool){  apr_hash_t *children;  svn_lock_t *lock;  apr_hash_index_t *hi;  apr_pool_t *subpool;  /* First, send up any locks in the current digest file. */  SVN_ERR(read_digest_file(&children, &lock, fs, digest_path, pool));  if (lock)    {      /* Don't report an expired lock. */      if (lock->expiration_date == 0          || (apr_time_now() <= lock->expiration_date))        {          if (get_locks_func)            SVN_ERR(get_locks_func(get_locks_baton, lock, pool));        }      else        {          /* Only remove the lock if we have the write lock.             Read operations shouldn't change the filesystem. */          if (have_write_lock)            SVN_ERR(delete_lock(fs, lock, pool));        }    }  /* Now, recurse on this thing's child entries (if any; bail otherwise). */  if (! apr_hash_count(children))    return SVN_NO_ERROR;  subpool = svn_pool_create(pool);  for (hi = apr_hash_first(pool, children); hi; hi = apr_hash_next(hi))     {      const void *key;      svn_pool_clear(subpool);      apr_hash_this(hi, &key, NULL, NULL);      SVN_ERR(walk_digest_files               (fs, digest_path_from_digest(fs, key, subpool),               get_locks_func, get_locks_baton, have_write_lock, subpool));    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* Utility function:  verify that a lock can be used.  Interesting   errors returned from this function:      SVN_ERR_FS_NO_USER: No username attached to FS.      SVN_ERR_FS_LOCK_OWNER_MISMATCH: FS's username doesn't match LOCK's owner.      SVN_ERR_FS_BAD_LOCK_TOKEN: FS doesn't hold matching lock-token for LOCK. */static svn_error_t *verify_lock(svn_fs_t *fs,            svn_lock_t *lock,            apr_pool_t *pool){  if ((! fs->access_ctx) || (! fs->access_ctx->username))    return svn_error_createf       (SVN_ERR_FS_NO_USER, NULL,       _("Cannot verify lock on path '%s'; no username available"),       lock->path);    else if (strcmp(fs->access_ctx->username, lock->owner) != 0)    return svn_error_createf       (SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,       _("User %s does not own lock on path '%s' (currently locked by %s)"),       fs->access_ctx->username, lock->path, lock->owner);  else if (apr_hash_get(fs->access_ctx->lock_tokens, lock->token,                        APR_HASH_KEY_STRING) == NULL)    return svn_error_createf       (SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,       _("Cannot verify lock on path '%s'; no matching lock-token available"),       lock->path);    

⌨️ 快捷键说明

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