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

📄 main.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * ==================================================================== * Copyright (c) 2005-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 "svn_cmdline.h"#include "svn_config.h"#include "svn_pools.h"#include "svn_delta.h"#include "svn_path.h"#include "svn_props.h"#include "svn_auth.h"#include "svn_opt.h"#include "svn_ra.h"#include "svn_private_config.h"#include <apr_network_io.h>#include <apr_signal.h>#include <apr_uuid.h>static svn_opt_subcommand_t initialize_cmd,                            synchronize_cmd,                            copy_revprops_cmd,                            help_cmd;enum {  svnsync_opt_non_interactive = SVN_OPT_FIRST_LONGOPT_ID,  svnsync_opt_no_auth_cache,  svnsync_opt_auth_username,  svnsync_opt_auth_password,  svnsync_opt_config_dir,  svnsync_opt_version};#define SVNSYNC_OPTS_DEFAULT svnsync_opt_non_interactive, \                             svnsync_opt_no_auth_cache, \                             svnsync_opt_auth_username, \                             svnsync_opt_auth_password, \                             svnsync_opt_config_dirstatic const svn_opt_subcommand_desc_t svnsync_cmd_table[] =  {    { "initialize", initialize_cmd, { "init" },      N_("usage: svnsync initialize DEST_URL SOURCE_URL\n"         "\n"         "Initialize a destination repository for synchronization from\n"         "another repository.\n"         "\n"         "The destination URL must point to the root of a repository with\n"         "no committed revisions.  The destination repository must allow\n"         "revision property changes.\n"         "\n"         "You should not commit to, or make revision property changes in,\n"         "the destination repository by any method other than 'svnsync'.\n"         "In other words, the destination repository should be a read-only\n"         "mirror of the source repository.\n"),      { SVNSYNC_OPTS_DEFAULT } },    { "synchronize", synchronize_cmd, { "sync" },      N_("usage: svnsync synchronize DEST_URL\n"         "\n"         "Transfer all pending revisions from source to destination.\n"),      { SVNSYNC_OPTS_DEFAULT } },    { "copy-revprops", copy_revprops_cmd, { 0 },      N_("usage: svnsync copy-revprops DEST_URL REV\n"         "\n"         "Copy all revision properties for revision REV from source to\n"         "destination.\n"),      { SVNSYNC_OPTS_DEFAULT } },    { "help", help_cmd, { "?", "h" },      N_("usage: svnsync help [SUBCOMMAND...]\n"         "\n"         "Describe the usage of this program or its subcommands.\n"),      { 0 } },    { NULL, NULL, { 0 }, NULL, { 0 } }   };static const apr_getopt_option_t svnsync_options[] =  {    {"non-interactive", svnsync_opt_non_interactive, 0,                       N_("do no interactive prompting") },    {"no-auth-cache",  svnsync_opt_no_auth_cache, 0,                       N_("do not cache authentication tokens") },    {"username",       svnsync_opt_auth_username, 1,                       N_("specify a username ARG") },    {"password",       svnsync_opt_auth_password, 1,                       N_("specify a password ARG") },    {"config-dir",     svnsync_opt_config_dir, 1,                       N_("read user configuration files from directory ARG")},    {"version",        svnsync_opt_version, 0,                       N_("show program version information")},    {"help",           'h', 0,                       N_("show help on a subcommand")},    {NULL,             '?', 0,                       N_("show help on a subcommand")},    { 0, 0, 0, 0 }  };typedef struct {  svn_auth_baton_t *auth_baton;  svn_boolean_t non_interactive;  svn_boolean_t no_auth_cache;  const char *auth_username;  const char *auth_password;  const char *config_dir;  apr_hash_t *config;  svn_boolean_t version;  svn_boolean_t help;} opt_baton_t;/*** Helper functions ***//* Global record of whether the user has requested cancellation. */static volatile sig_atomic_t cancelled = FALSE;/* Callback function for apr_signal(). */static voidsignal_handler(int signum){  apr_signal(signum, SIG_IGN);  cancelled = TRUE;}/* Cancellation callback function. */static svn_error_t *check_cancel(void *baton){  if (cancelled)    return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));  else    return SVN_NO_ERROR;}/* Check that the version of libraries in use match what we expect. */static svn_error_t *check_lib_versions(void){  static const svn_version_checklist_t checklist[] =    {      { "svn_subr",  svn_subr_version },      { "svn_delta", svn_delta_version },      { "svn_ra",    svn_ra_version },      { NULL, NULL }    };  SVN_VERSION_DEFINE(my_version);  return svn_ver_check_list(&my_version, checklist);}/* Acquire a lock (of sorts) on the repository associated with the * given RA SESSION. */static svn_error_t *get_lock(svn_ra_session_t *session, apr_pool_t *pool){  char hostname_str[APRMAXHOSTLEN + 1] = { 0 };  svn_string_t *mylocktoken, *reposlocktoken;  apr_status_t apr_err;  apr_pool_t *subpool;  int i;  apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);  if (apr_err)    return svn_error_wrap_apr(apr_err, _("Can't get local hostname"));  mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,                                    svn_uuid_generate(pool));  subpool = svn_pool_create(pool);  for (i = 0; i < 10; ++i)    {      svn_pool_clear(subpool);      SVN_ERR(svn_ra_rev_prop(session, 0, SVNSYNC_PROP_LOCK, &reposlocktoken,                              subpool));      if (reposlocktoken)        {          /* Did we get it?   If so, we're done, otherwise we sleep. */          if (strcmp(reposlocktoken->data, mylocktoken->data) == 0)            return SVN_NO_ERROR;          else            {              SVN_ERR(svn_cmdline_printf                      (pool, _("Failed to get lock on destination "                               "repos, currently held by '%s'\n"),                       reposlocktoken->data));              apr_sleep(apr_time_from_sec(1));            }        }      else        {          SVN_ERR(svn_ra_change_rev_prop(session, 0, SVNSYNC_PROP_LOCK,                                         mylocktoken, subpool));        }    }  return svn_error_createf(APR_EINVAL, NULL,                           "Couldn't get lock on destination repos "                           "after %d attempts\n", i);}typedef svn_error_t *(*with_locked_func_t)(svn_ra_session_t *session,                                           void *baton,                                           apr_pool_t *pool);/* Lock the repository associated with RA SESSION, then execute the * given FUNC/BATON pair while holding the lock.  Finally, drop the * lock once it finishes. */static svn_error_t *with_locked(svn_ra_session_t *session,            with_locked_func_t func,            void *baton,            apr_pool_t *pool){  svn_error_t *err, *err2;  SVN_ERR(get_lock(session, pool));  err = func(session, baton, pool);  err2 = svn_ra_change_rev_prop(session, 0, SVNSYNC_PROP_LOCK, NULL, pool);  if (err2 && err)    {      svn_error_clear(err2); /* XXX what to do here? */      return err;    }  else if (err2)    {      return err2;    }  else    {      return err;    }}/* Callback function for the RA session's open_tmp_file() * requirements. */static svn_error_t *open_tmp_file(apr_file_t **fp, void *callback_baton, apr_pool_t *pool){  const char *path;  SVN_ERR(svn_io_temp_dir(&path, pool));  path = svn_path_join(path, "tempfile", pool);  SVN_ERR(svn_io_open_unique_file2(fp, NULL, path, ".tmp",                                   svn_io_file_del_on_close, pool));  return SVN_NO_ERROR;}/* Return SVN_NO_ERROR iff URL identifies the root directory of the * repository associated with RA session SESS. */static svn_error_t *check_if_session_is_at_repos_root(svn_ra_session_t *sess,                                  const char *url,                                  apr_pool_t *pool){  const char *sess_root;  SVN_ERR(svn_ra_get_repos_root(sess, &sess_root, pool));  if (strcmp(url, sess_root) == 0)    return SVN_NO_ERROR;  else    return svn_error_createf      (APR_EINVAL, NULL,       _("Session is rooted at '%s' but the repos root is '%s'"),       url, sess_root);}/* Copy all the revision properties, except for those that have the * "svn:sync-" prefix, from revision REV of the repository associated * with RA session FROM_SESSION, to the repository associated with RA * session TO_SESSION. * * If SYNC is TRUE, then properties on the destination revision that * do not exist on the source revision will be removed. */static svn_error_t *copy_revprops(svn_ra_session_t *from_session,              svn_ra_session_t *to_session,              svn_revnum_t rev,              svn_boolean_t sync,              apr_pool_t *pool){  apr_pool_t *subpool = svn_pool_create(pool);  apr_hash_t *revprops, *existing_props;  svn_boolean_t saw_sync_props = FALSE;  apr_hash_index_t *hi;  if (sync)    SVN_ERR(svn_ra_rev_proplist(to_session, rev, &existing_props, pool));  SVN_ERR(svn_ra_rev_proplist(from_session, rev, &revprops, pool));  for (hi = apr_hash_first(pool, revprops); hi; hi = apr_hash_next(hi))    {      const void *key;      void *val;      svn_pool_clear(subpool);      apr_hash_this(hi, &key, NULL, &val);      if (strncmp(key, SVNSYNC_PROP_PREFIX,                  sizeof(SVNSYNC_PROP_PREFIX) - 1) == 0)        saw_sync_props = TRUE;      else        SVN_ERR(svn_ra_change_rev_prop(to_session, rev, key, val, subpool));      if (sync)        apr_hash_set(existing_props, key, APR_HASH_KEY_STRING, NULL);    }  if (sync)    {      for (hi = apr_hash_first(pool, existing_props);           hi;           hi = apr_hash_next(hi))        {          const void *name;          svn_pool_clear(subpool);          apr_hash_this(hi, &name, NULL, NULL);          SVN_ERR(svn_ra_change_rev_prop(to_session, rev, name, NULL,                                         subpool));        }    }  if (saw_sync_props)    SVN_ERR(svn_cmdline_printf(subpool,                                _("Copied properties for revision %ld "                                 "(%s* properties skipped).\n"),                               rev, SVNSYNC_PROP_PREFIX));  else    SVN_ERR(svn_cmdline_printf(subpool,                                _("Copied properties for revision %ld.\n"),                                rev));  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/*** `svnsync init' ***/

⌨️ 快捷键说明

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