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

📄 lock.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  return SVN_NO_ERROR;}/* This implements the svn_fs_get_locks_callback_t interface, where   BATON is just an svn_fs_t object. */static svn_error_t *get_locks_callback(void *baton,                    svn_lock_t *lock,                    apr_pool_t *pool){  return verify_lock(baton, lock, pool);}/* The main routine for lock enforcement, used throughout libsvn_fs_fs. */svn_error_t *svn_fs_fs__allow_locked_operation(const char *path,                                  svn_fs_t *fs,                                  svn_boolean_t recurse,                                  svn_boolean_t have_write_lock,                                  apr_pool_t *pool){  path = svn_fs_fs__canonicalize_abspath(path, pool);  if (recurse)    {      /* Discover all locks at or below the path. */      const char *digest_path = digest_path_from_path(fs, path, pool);      SVN_ERR(walk_digest_files(fs, digest_path, get_locks_callback,                                fs, have_write_lock, pool));    }  else     {      /* Discover and verify any lock attached to the path. */      svn_lock_t *lock;      SVN_ERR(get_lock_helper(fs, &lock, path, have_write_lock, pool));      if (lock)        SVN_ERR(verify_lock(fs, lock, pool));    }  return SVN_NO_ERROR;}/* Baton used for lock_body below. */struct lock_baton {  svn_lock_t **lock_p;  svn_fs_t *fs;  const char *path;  const char *token;  const char *comment;  svn_boolean_t is_dav_comment;  apr_time_t expiration_date;  svn_revnum_t current_rev;  svn_boolean_t steal_lock;  apr_pool_t *pool;};/* This implements the svn_fs_fs__with_write_lock() 'body' callback   type, and assumes that the write lock is held.   BATON is a 'struct lock_baton *'. */static svn_error_t *lock_body(void *baton, apr_pool_t *pool){  struct lock_baton *lb = baton;  svn_node_kind_t kind;  svn_lock_t *existing_lock;  svn_lock_t *lock;  svn_fs_root_t *root;  svn_revnum_t youngest;  /* Until we implement directory locks someday, we only allow locks     on files or non-existent paths. */  /* Use fs->vtable->foo instead of svn_fs_foo to avoid circular     library dependencies, which are not portable. */  SVN_ERR(lb->fs->vtable->youngest_rev(&youngest, lb->fs, pool));  SVN_ERR(lb->fs->vtable->revision_root(&root, lb->fs, youngest, pool));  SVN_ERR(svn_fs_fs__check_path(&kind, root, lb->path, pool));  if (kind == svn_node_dir)    return svn_fs_fs__err_not_file(lb->fs, lb->path);  /* While our locking implementation easily supports the locking of     nonexistent paths, we deliberately choose not to allow such madness. */  if (kind == svn_node_none)    return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,                             _("Path '%s' doesn't exist in HEAD revision"),                             lb->path);  /* We need to have a username attached to the fs. */  if (!lb->fs->access_ctx || !lb->fs->access_ctx->username)    return svn_fs_fs__err_no_user(lb->fs);  /* Is the caller attempting to lock an out-of-date working file? */  if (SVN_IS_VALID_REVNUM(lb->current_rev))    {      svn_revnum_t created_rev;      SVN_ERR(svn_fs_fs__node_created_rev(&created_rev, root, lb->path,                                          pool));      /* SVN_INVALID_REVNUM means the path doesn't exist.  So         apparently somebody is trying to lock something in their         working copy, but somebody else has deleted the thing         from HEAD.  That counts as being 'out of date'. */           if (! SVN_IS_VALID_REVNUM(created_rev))        return svn_error_createf          (SVN_ERR_FS_OUT_OF_DATE, NULL,           _("Path '%s' doesn't exist in HEAD revision"), lb->path);      if (lb->current_rev < created_rev)        return svn_error_createf          (SVN_ERR_FS_OUT_OF_DATE, NULL,           _("Lock failed: newer version of '%s' exists"), lb->path);    }  /* If the caller provided a TOKEN, we *really* need to see     if a lock already exists with that token, and if so, verify that     the lock's path matches PATH.  Otherwise we run the risk of     breaking the 1-to-1 mapping of lock tokens to locked paths. */  /* ### TODO:  actually do this check.  This is tough, because the     schema doesn't supply a lookup-by-token mechanism. */  /* Is the path already locked?        Note that this next function call will automatically ignore any     errors about {the path not existing as a key, the path's token     not existing as a key, the lock just having been expired}.  And     that's totally fine.  Any of these three errors are perfectly     acceptable to ignore; it means that the path is now free and     clear for locking, because the fsfs funcs just cleared out both     of the tables for us.   */  SVN_ERR(get_lock_helper(lb->fs, &existing_lock, lb->path, TRUE, pool));  if (existing_lock)    {      if (! lb->steal_lock)        {          /* Sorry, the path is already locked. */          return svn_fs_fs__err_path_already_locked(lb->fs, existing_lock);        }      else        {          /* STEAL_LOCK was passed, so fs_username is "stealing" the             lock from lock->owner.  Destroy the existing lock. */          SVN_ERR(delete_lock(lb->fs, existing_lock, pool));        }              }  /* Create our new lock, and add it to the tables.     Ensure that the lock is created in the correct pool. */  lock = svn_lock_create(lb->pool);  if (lb->token)    lock->token = apr_pstrdup(lb->pool, lb->token);  else    SVN_ERR(svn_fs_fs__generate_lock_token(&(lock->token), lb->fs,                                           lb->pool));  lock->path = apr_pstrdup(lb->pool, lb->path);  lock->owner = apr_pstrdup(lb->pool, lb->fs->access_ctx->username);  lock->comment = apr_pstrdup(lb->pool, lb->comment);  lock->is_dav_comment = lb->is_dav_comment;  lock->creation_date = apr_time_now();  lock->expiration_date = lb->expiration_date;  SVN_ERR(set_lock(lb->fs, lock, pool));  *lb->lock_p = lock;  return SVN_NO_ERROR;}/* Baton used for unlock_body below. */struct unlock_baton {  svn_fs_t *fs;  const char *path;  const char *token;  svn_boolean_t break_lock;};/* This implements the svn_fs_fs__with_write_lock() 'body' callback   type, and assumes that the write lock is held.   BATON is a 'struct unlock_baton *'. */static svn_error_t *unlock_body(void *baton, apr_pool_t *pool){  struct unlock_baton *ub = baton;  svn_lock_t *lock;  /* This could return SVN_ERR_FS_BAD_LOCK_TOKEN or SVN_ERR_FS_LOCK_EXPIRED. */  SVN_ERR(get_lock(&lock, ub->fs, ub->path, TRUE, pool));    /* Unless breaking the lock, we do some checks. */  if (! ub->break_lock)    {      /* Sanity check:  the incoming token should match lock->token. */      if (strcmp(ub->token, lock->token) != 0)        return svn_fs_fs__err_no_such_lock(ub->fs, lock->path);      /* There better be a username attached to the fs. */      if (! (ub->fs->access_ctx && ub->fs->access_ctx->username))        return svn_fs_fs__err_no_user(ub->fs);      /* And that username better be the same as the lock's owner. */      if (strcmp(ub->fs->access_ctx->username, lock->owner) != 0)        return svn_fs_fs__err_lock_owner_mismatch          (ub->fs, ub->fs->access_ctx->username, lock->owner);    }    /* Remove lock and lock token files. */  SVN_ERR(delete_lock(ub->fs, lock, pool));  return SVN_NO_ERROR;}/*** Public API implementations ***/svn_error_t *svn_fs_fs__lock(svn_lock_t **lock_p,                svn_fs_t *fs,                const char *path,                const char *token,                const char *comment,                svn_boolean_t is_dav_comment,                apr_time_t expiration_date,                svn_revnum_t current_rev,                svn_boolean_t steal_lock,                apr_pool_t *pool){  struct lock_baton lb;  SVN_ERR(svn_fs_fs__check_fs(fs));  path = svn_fs_fs__canonicalize_abspath(path, pool);  lb.lock_p = lock_p;  lb.fs = fs;  lb.path = path;  lb.token = token;  lb.comment = comment;  lb.is_dav_comment = is_dav_comment;  lb.expiration_date = expiration_date;  lb.current_rev = current_rev;  lb.steal_lock = steal_lock;  lb.pool = pool;  SVN_ERR(svn_fs_fs__with_write_lock(fs, lock_body, &lb, pool));  return SVN_NO_ERROR;}svn_error_t *svn_fs_fs__generate_lock_token(const char **token,                               svn_fs_t *fs,                               apr_pool_t *pool){  SVN_ERR(svn_fs_fs__check_fs(fs));  /* Notice that 'fs' is currently unused.  But perhaps someday, we'll     want to use the fs UUID + some incremented number?  For now, we     generate a URI that matches the DAV RFC.  We could change this to     some other URI scheme someday, if we wish. */  *token = apr_pstrcat(pool, "opaquelocktoken:",                        svn_uuid_generate(pool), NULL);  return SVN_NO_ERROR;}svn_error_t *svn_fs_fs__unlock(svn_fs_t *fs,                  const char *path,                  const char *token,                  svn_boolean_t break_lock,                  apr_pool_t *pool){  struct unlock_baton ub;  SVN_ERR(svn_fs_fs__check_fs(fs));  path = svn_fs_fs__canonicalize_abspath(path, pool);  ub.fs = fs;  ub.path = path;  ub.token = token;  ub.break_lock = break_lock;  SVN_ERR(svn_fs_fs__with_write_lock(fs, unlock_body, &ub, pool));  return SVN_NO_ERROR;}svn_error_t *svn_fs_fs__get_lock(svn_lock_t **lock_p,                    svn_fs_t *fs,                    const char *path,                    apr_pool_t *pool){  SVN_ERR(svn_fs_fs__check_fs(fs));  path = svn_fs_fs__canonicalize_abspath(path, pool);  return get_lock_helper(fs, lock_p, path, FALSE, pool);}svn_error_t *svn_fs_fs__get_locks(svn_fs_t *fs,                     const char *path,                     svn_fs_get_locks_callback_t get_locks_func,                     void *get_locks_baton,                     apr_pool_t *pool){  const char *digest_path;  SVN_ERR(svn_fs_fs__check_fs(fs));  path = svn_fs_fs__canonicalize_abspath(path, pool);  /* Get the top digest path in our tree of interest, and then walk it. */  digest_path = digest_path_from_path(fs, path, pool);  return walk_digest_files(fs, digest_path, get_locks_func,                            get_locks_baton, FALSE, pool);}

⌨️ 快捷键说明

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