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

📄 ra_plugin.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ra_plugin.c : the main RA module for local repository access * * ==================================================================== * 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 "ra_local.h"#include "svn_ra.h"#include "svn_fs.h"#include "svn_delta.h"#include "svn_repos.h"#include "svn_pools.h"#include "svn_time.h"#include "svn_props.h"#include "svn_path.h"#include "svn_private_config.h"#include "../libsvn_ra/ra_loader.h"#define APR_WANT_STRFUNC#include <apr_want.h>#include <assert.h>/*----------------------------------------------------------------*//* The reporter vtable needed by do_update() */typedef struct reporter_baton_t{  svn_ra_local__session_baton_t *session;  void *report_baton;} reporter_baton_t;static void *make_reporter_baton(svn_ra_local__session_baton_t *session,                    void *report_baton,                    apr_pool_t *pool){  reporter_baton_t *rbaton = apr_palloc(pool, sizeof(*rbaton));  rbaton->session = session;  rbaton->report_baton = report_baton;  return rbaton;}static svn_error_t *reporter_set_path(void *reporter_baton,                  const char *path,                  svn_revnum_t revision,                  svn_boolean_t start_empty,                  const char *lock_token,                  apr_pool_t *pool){  reporter_baton_t *rbaton = reporter_baton;  return svn_repos_set_path2(rbaton->report_baton, path,                             revision, start_empty, lock_token, pool);}static svn_error_t *reporter_delete_path(void *reporter_baton,                     const char *path,                     apr_pool_t *pool){  reporter_baton_t *rbaton = reporter_baton;  return svn_repos_delete_path(rbaton->report_baton, path, pool);}static svn_error_t *reporter_link_path(void *reporter_baton,                   const char *path,                   const char *url,                   svn_revnum_t revision,                   svn_boolean_t start_empty,                   const char *lock_token,                   apr_pool_t *pool){  reporter_baton_t *rbaton = reporter_baton;  const char *fs_path = NULL;  const char *repos_url_decoded;  int repos_url_len;  url = svn_path_uri_decode(url, pool);  repos_url_decoded = svn_path_uri_decode(rbaton->session->repos_url, pool);  repos_url_len = strlen(repos_url_decoded);  if (strncmp(url, repos_url_decoded, repos_url_len) != 0)    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,                             _("'%s'\n"                               "is not the same repository as\n"                               "'%s'"), url, rbaton->session->repos_url);  fs_path = url + repos_url_len;  return svn_repos_link_path2(rbaton->report_baton, path, fs_path, revision,                              start_empty, lock_token, pool);}static svn_error_t *reporter_finish_report(void *reporter_baton,                       apr_pool_t *pool){  reporter_baton_t *rbaton = reporter_baton;  return svn_repos_finish_report(rbaton->report_baton, pool);}static svn_error_t *reporter_abort_report(void *reporter_baton,                      apr_pool_t *pool){  reporter_baton_t *rbaton = reporter_baton;  return svn_repos_abort_report(rbaton->report_baton, pool);}static const svn_ra_reporter2_t ra_local_reporter = {  reporter_set_path,  reporter_delete_path,  reporter_link_path,  reporter_finish_report,  reporter_abort_report};static svn_error_t *svn_ra_local__get_file_revs(svn_ra_session_t *session,                            const char *path,                            svn_revnum_t start,                            svn_revnum_t end,                            svn_ra_file_rev_handler_t handler,                            void *handler_baton,                            apr_pool_t *pool){  svn_ra_local__session_baton_t *sbaton = session->priv;  const char *abs_path = sbaton->fs_path->data;  /* Concatenate paths */  abs_path = svn_path_join(abs_path, path, pool);  return svn_repos_get_file_revs(sbaton->repos, abs_path, start, end, NULL,                                 NULL, handler, handler_baton, pool);}/* Pool cleanup handler: Ensure that the access descriptor of the filesystem   DATA is set to NULL. */static apr_status_tcleanup_access(void *data){  svn_error_t *serr;  svn_fs_t *fs = data;  serr = svn_fs_set_access(fs, NULL);  if (serr)    {      apr_status_t apr_err = serr->apr_err;      svn_error_clear(serr);      return apr_err;    }  return APR_SUCCESS;}static svn_error_t *get_username(svn_ra_session_t *session,             apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  svn_auth_iterstate_t *iterstate;  svn_fs_access_t *access_ctx;  /* If we've already found the username don't ask for it again. */  if (! baton->username)    {      /* Get a username somehow, so we have some svn:author property to         attach to a commit. */      if (baton->callbacks->auth_baton)        {          void *creds;          svn_auth_cred_username_t *username_creds;          SVN_ERR(svn_auth_first_credentials(&creds, &iterstate,                                             SVN_AUTH_CRED_USERNAME,                                             baton->uuid, /* realmstring */                                             baton->callbacks->auth_baton,                                             pool));                    /* No point in calling next_creds(), since that assumes that the             first_creds() somehow failed to authenticate.  But there's no             challenge going on, so we use whatever creds we get back on             the first try. */          username_creds = creds;          if (username_creds && username_creds->username)            {              baton->username = apr_pstrdup(session->pool,                                            username_creds->username);              svn_error_clear(svn_auth_save_credentials(iterstate, pool));            }          else            baton->username = "";        }      else        baton->username = "";    }  /* If we have a real username, attach it to the filesystem so that it can     be used to validate locks.  Even if there already is a user context     associated, it may contain irrelevant lock tokens, so always create a new.  */  if (*baton->username)    {      SVN_ERR(svn_fs_create_access(&access_ctx, baton->username,                                   pool));      SVN_ERR(svn_fs_set_access(baton->fs, access_ctx));      /* Make sure this context is disassociated when the pool gets         destroyed. */      apr_pool_cleanup_register(pool, baton->fs, cleanup_access,                                apr_pool_cleanup_null);    }  return SVN_NO_ERROR;}/*----------------------------------------------------------------*//** The RA vtable routines **/#define RA_LOCAL_DESCRIPTION \        N_("Module for accessing a repository on local disk.")static const char *svn_ra_local__get_description(void){  return _(RA_LOCAL_DESCRIPTION);}static const char * const *svn_ra_local__get_schemes(apr_pool_t *pool){  static const char *schemes[] = { "file", NULL };  return schemes;}static svn_error_t *svn_ra_local__open(svn_ra_session_t *session,                   const char *repos_URL,                   const svn_ra_callbacks2_t *callbacks,                   void *callback_baton,                   apr_hash_t *config,                   apr_pool_t *pool){  svn_ra_local__session_baton_t *baton;  const char *fs_path;    /* Allocate and stash the session_baton args we have already. */  baton = apr_pcalloc(pool, sizeof(*baton));  baton->callbacks = callbacks;  baton->callback_baton = callback_baton;    /* Look through the URL, figure out which part points to the     repository, and which part is the path *within* the     repository. */  SVN_ERR_W(svn_ra_local__split_URL(&(baton->repos),                                    &(baton->repos_url),                                    &fs_path,                                    repos_URL,                                    session->pool),            _("Unable to open an ra_local session to URL"));  baton->fs_path = svn_stringbuf_create(fs_path, session->pool);  /* Cache the filesystem object from the repos here for     convenience. */  baton->fs = svn_repos_fs(baton->repos);  /* Cache the repository UUID as well */  SVN_ERR(svn_fs_get_uuid(baton->fs, &baton->uuid, session->pool));  /* Be sure username is NULL so we know to look it up / ask for it */  baton->username = NULL;  session->priv = baton;  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__reparent(svn_ra_session_t *session,                       const char *url,                       apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  svn_stringbuf_set(baton->fs_path,                    svn_path_uri_decode(url + strlen(baton->repos_url),                                        pool));  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__get_latest_revnum(svn_ra_session_t *session,                                svn_revnum_t *latest_revnum,                                apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  SVN_ERR(svn_fs_youngest_rev(latest_revnum, baton->fs, pool));  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__get_dated_revision(svn_ra_session_t *session,                                 svn_revnum_t *revision,                                 apr_time_t tm,                                 apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  SVN_ERR(svn_repos_dated_revision(revision, baton->repos, tm, pool));  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__change_rev_prop(svn_ra_session_t *session,                              svn_revnum_t rev,                              const char *name,                              const svn_string_t *value,                              apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  SVN_ERR(get_username(session, pool));  SVN_ERR(svn_repos_fs_change_rev_prop2(baton->repos, rev, baton->username,                                        name, value, NULL, NULL, pool));  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__get_uuid(svn_ra_session_t *session,                       const char **uuid,                       apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  *uuid = baton->uuid;  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__get_repos_root(svn_ra_session_t *session,                             const char **url,                             apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  *url = baton->repos_url;  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__rev_proplist(svn_ra_session_t *session,                           svn_revnum_t rev,                           apr_hash_t **props,                           apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  SVN_ERR(svn_repos_fs_revision_proplist(props, baton->repos, rev,                                         NULL, NULL, pool));  return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__rev_prop(svn_ra_session_t *session,                       svn_revnum_t rev,                       const char *name,                       svn_string_t **value,                       apr_pool_t *pool){  svn_ra_local__session_baton_t *baton = session->priv;  SVN_ERR(svn_repos_fs_revision_prop(value, baton->repos, rev, name,                                     NULL, NULL, pool));  return SVN_NO_ERROR;}struct deltify_etc_baton{  svn_fs_t *fs;                    /* the fs to deltify in */  svn_repos_t *repos;              /* repos for unlocking */  const char *fs_path;             /* fs-path part of split session URL */  apr_hash_t *lock_tokens;         /* tokens to unlock, if any */  apr_pool_t *pool;                /* pool for scratch work */  svn_commit_callback2_t callback;  /* the original callback */  void *callback_baton;            /* the original callback's baton */};/* This implements 'svn_commit_callback_t'.  Its invokes the original   (wrapped) callback, but also does deltification on the new revision and   possibly unlocks committed paths.   BATON is 'struct deltify_etc_baton *'. */static svn_error_t * deltify_etc(const svn_commit_info_t *commit_info,            void *baton, apr_pool_t *pool){  struct deltify_etc_baton *db = baton;  svn_error_t *err1, *err2;  apr_hash_index_t *hi;  apr_pool_t *iterpool;  /* Invoke the original callback first, in case someone's waiting to     know the revision number so they can go off and annotate an     issue or something. */  err1 = (*db->callback)(commit_info, db->callback_baton, pool);  /* Maybe unlock the paths. */  if (db->lock_tokens)    {      iterpool = svn_pool_create(db->pool);      for (hi = apr_hash_first(db->pool, db->lock_tokens); hi;           hi = apr_hash_next(hi))        {          const void *rel_path;          void *val;          const char *abs_path, *token;

⌨️ 快捷键说明

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