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

📄 client.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  return SVN_NO_ERROR;}static svn_error_t *ra_svn_delete_path(void *baton, const char *path,                                       apr_pool_t *pool){  ra_svn_reporter_baton_t *b = baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "delete-path", "c", path));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_link_path(void *baton, const char *path,                                     const char *url,                                     svn_revnum_t rev,                                     svn_boolean_t start_empty,                                     const char *lock_token,                                     apr_pool_t *pool){  ra_svn_reporter_baton_t *b = baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "link-path", "ccrb(?c)",                               path, url, rev, start_empty, lock_token));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_finish_report(void *baton,                                         apr_pool_t *pool){  ra_svn_reporter_baton_t *b = baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, b->pool, "finish-report", ""));  SVN_ERR(handle_auth_request(b->sess_baton, b->pool));  SVN_ERR(svn_ra_svn_drive_editor(b->conn, b->pool, b->editor, b->edit_baton,                                  NULL));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, b->pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_abort_report(void *baton,                                        apr_pool_t *pool){  ra_svn_reporter_baton_t *b = baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, b->pool, "abort-report", ""));  return SVN_NO_ERROR;}static svn_ra_reporter2_t ra_svn_reporter = {  ra_svn_set_path,  ra_svn_delete_path,  ra_svn_link_path,  ra_svn_finish_report,  ra_svn_abort_report};static void ra_svn_get_reporter(ra_svn_session_baton_t *sess_baton,                                apr_pool_t *pool,                                const svn_delta_editor_t *editor,                                void *edit_baton,                                const svn_ra_reporter2_t **reporter,                                void **report_baton){  ra_svn_reporter_baton_t *b;  b = apr_palloc(pool, sizeof(*b));  b->sess_baton = sess_baton;  b->conn = sess_baton->conn;  b->pool = pool;  b->editor = editor;  b->edit_baton = edit_baton;  *reporter = &ra_svn_reporter;  *report_baton = b;}/* --- RA LAYER IMPLEMENTATION --- *//* (Note: *ARGV is an output parameter.) */static svn_error_t *find_tunnel_agent(const char *tunnel,                                       const char *hostinfo,                                      const char ***argv,                                      apr_hash_t *config, apr_pool_t *pool){  svn_config_t *cfg;  const char *val, *var, *cmd;  char **cmd_argv;  apr_size_t len;  apr_status_t status;  int n;  /* Look up the tunnel specification in config. */  cfg = config ? apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,                              APR_HASH_KEY_STRING) : NULL;  svn_config_get(cfg, &val, SVN_CONFIG_SECTION_TUNNELS, tunnel, NULL);  /* We have one predefined tunnel scheme, if it isn't overridden by config. */  if (!val && strcmp(tunnel, "ssh") == 0)    val = "$SVN_SSH ssh";  if (!val || !*val)    return svn_error_createf(SVN_ERR_BAD_URL, NULL,                             _("Undefined tunnel scheme '%s'"), tunnel);  /* If the scheme definition begins with "$varname", it means there   * is an environment variable which can override the command. */  if (*val == '$')    {      val++;      len = strcspn(val, " ");      var = apr_pstrmemdup(pool, val, len);      cmd = getenv(var);      if (!cmd)        {          cmd = val + len;          while (*cmd == ' ')            cmd++;          if (!*cmd)            return svn_error_createf(SVN_ERR_BAD_URL, NULL,                                     _("Tunnel scheme %s requires environment "                                       "variable %s to be defined"), tunnel,                                     var);        }    }  else    cmd = val;  /* Tokenize the command into a list of arguments. */  status = apr_tokenize_to_argv(cmd, &cmd_argv, pool);  if (status != APR_SUCCESS)    return svn_error_wrap_apr(status, _("Can't tokenize command '%s'"), cmd);  /* Append the fixed arguments to the result. */  for (n = 0; cmd_argv[n] != NULL; n++)    ;  *argv = apr_palloc(pool, (n + 4) * sizeof(char *));  memcpy(*argv, cmd_argv, n * sizeof(char *));  (*argv)[n++] = svn_path_uri_decode(hostinfo, pool);  (*argv)[n++] = "svnserve";  (*argv)[n++] = "-t";  (*argv)[n] = NULL;  return SVN_NO_ERROR;}/* This function handles any errors which occur in the child process * created for a tunnel agent.  We write the error out as a command * failure; the code in ra_svn_open() to read the server's greeting * will see the error and return it to the caller. */static void handle_child_process_error(apr_pool_t *pool, apr_status_t status,                                       const char *desc){  svn_ra_svn_conn_t *conn;  apr_file_t *in_file, *out_file;  svn_error_t *err;  if (apr_file_open_stdin(&in_file, pool)      || apr_file_open_stdout(&out_file, pool))    return;  conn = svn_ra_svn_create_conn(NULL, in_file, out_file, pool);  err = svn_error_wrap_apr(status, _("Error in child process: %s"), desc);  svn_error_clear(svn_ra_svn_write_cmd_failure(conn, pool, err));  svn_error_clear(svn_ra_svn_flush(conn, pool));}/* (Note: *CONN is an output parameter.) */static svn_error_t *make_tunnel(const char **args, svn_ra_svn_conn_t **conn,                                apr_pool_t *pool){  apr_status_t status;  apr_proc_t *proc;  apr_procattr_t *attr;  status = apr_procattr_create(&attr, pool);  if (status == APR_SUCCESS)    status = apr_procattr_io_set(attr, 1, 1, 0);  if (status == APR_SUCCESS)    status = apr_procattr_cmdtype_set(attr, APR_PROGRAM_PATH);  if (status == APR_SUCCESS)    status = apr_procattr_child_errfn_set(attr, handle_child_process_error);  proc = apr_palloc(pool, sizeof(*proc));  if (status == APR_SUCCESS)    status = apr_proc_create(proc, *args, args, NULL, attr, pool);  if (status != APR_SUCCESS)    return svn_error_wrap_apr(status, _("Can't create tunnel"));  /* Arrange for the tunnel agent to get a SIGKILL on pool   * cleanup.  This is a little extreme, but the alternatives   * weren't working out:   *   - Closing the pipes and waiting for the process to die   *     was prone to mysterious hangs which are difficult to   *     diagnose (e.g. svnserve dumps core due to unrelated bug;   *     sshd goes into zombie state; ssh connection is never   *     closed; ssh never terminates).   *   - Killing the tunnel agent with SIGTERM leads to unsightly   *     stderr output from ssh.   */  apr_pool_note_subprocess(pool, proc, APR_KILL_ALWAYS);  /* APR pipe objects inherit by default.  But we don't want the   * tunnel agent's pipes held open by future child processes   * (such as other ra_svn sessions), so turn that off. */  apr_file_inherit_unset(proc->in);  apr_file_inherit_unset(proc->out);  /* Guard against dotfile output to stdout on the server. */  *conn = svn_ra_svn_create_conn(NULL, proc->out, proc->in, pool);  (*conn)->proc = proc;  SVN_ERR(svn_ra_svn_skip_leading_garbage(*conn, pool));  return SVN_NO_ERROR;}/* Parse URL inot URI, validating it and setting the default port if none   was given.  Allocate the URI fileds out of POOL. */static svn_error_t *parse_url(const char *url, apr_uri_t *uri,                              apr_pool_t *pool){  apr_status_t apr_err;  apr_err = apr_uri_parse(pool, url, uri);    if (apr_err != 0)    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,                             _("Illegal svn repository URL '%s'"), url);    if (! uri->port)    uri->port = SVN_RA_SVN_PORT;  return SVN_NO_ERROR;}/* Open a session to URL, returning it in *SESS_P, allocating it in POOL.   URI is a parsed version of URL.  AUTH_BATON is provided by the caller of   ra_svn_open.  If tunnel_argv is non-null, it points to a program   argument list to use when invoking the tunnel agent. */static svn_error_t *open_session(ra_svn_session_baton_t **sess_p,                                 const char *url,                                 const apr_uri_t *uri,                                 svn_auth_baton_t *auth_baton,                                 const char **tunnel_argv,                                 apr_pool_t *pool){  ra_svn_session_baton_t *sess;  svn_ra_svn_conn_t *conn;  apr_socket_t *sock;  apr_uint64_t minver, maxver;  apr_array_header_t *mechlist, *caplist;    if (tunnel_argv)    SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));  else    {      SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));      conn = svn_ra_svn_create_conn(sock, NULL, NULL, pool);    }  /* Read server's greeting. */  SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "nnll", &minver, &maxver,                                       &mechlist, &caplist));  /* We support protocol versions 1 and 2. */  if (minver > 2)    return svn_error_createf(SVN_ERR_RA_SVN_BAD_VERSION, NULL,                             _("Server requires minimum version %d"),                             (int) minver);  SVN_ERR(svn_ra_svn_set_capabilities(conn, caplist));  sess = apr_palloc(pool, sizeof(*sess));  sess->pool = pool;  sess->conn = conn;  sess->protocol_version = (maxver > 2) ? 2 : maxver;  sess->is_tunneled = (tunnel_argv != NULL);  sess->auth_baton = auth_baton;  sess->user = uri->user;  sess->realm_prefix = apr_psprintf(pool, "<svn://%s:%d>", uri->hostname,                                    uri->port);  sess->tunnel_argv = tunnel_argv;  /* In protocol version 2, we send back our protocol version, our   * capability list, and the URL, and subsequently there is an auth   * request.  In version 1, we send back the protocol version, auth   * mechanism, mechanism initial response, and capability list, and;   * then send the URL after authentication.  do_auth temporarily has   * support for the mixed-style response. */  /* When we punt support for protocol version 1, we should:   * - Eliminate this conditional and the similar one below   * - Remove v1 support from auth_response and inline it into do_auth   * - Remove the (realm == NULL) support from do_auth   * - Inline do_auth into handle_auth_request   * - Remove the protocol version check from handle_auth_request */  if (sess->protocol_version == 1)    {      SVN_ERR(do_auth(sess, mechlist, NULL, pool));      SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "c", url));    }  else    {      SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "n(www)c", (apr_uint64_t) 2,                                     SVN_RA_SVN_CAP_EDIT_PIPELINE,                                     SVN_RA_SVN_CAP_SVNDIFF1,                                     SVN_RA_SVN_CAP_ABSENT_ENTRIES, url));      SVN_ERR(handle_auth_request(sess, pool));    }  /* This is where the security layer would go into effect if we   * supported security layers, which is a ways off. */  /* Read the repository's uuid and root URL. */  SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "c?c", &conn->uuid,                                       &conn->repos_root));  if (conn->repos_root)    {      conn->repos_root = svn_path_canonicalize(conn->repos_root, pool);      /* We should check that the returned string is a prefix of url, since         that's the API guarantee, but this isn't true for 1.0 servers.         Checking the length prevents client crashes. */      if (strlen(conn->repos_root) > strlen(url))        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                                _("Impossibly long repository root from "                                  "server"));    }  *sess_p = sess;  return SVN_NO_ERROR;}#define RA_SVN_DESCRIPTION \  N_("Module for accessing a repository using the svn network protocol.")static const char *ra_svn_get_description(void){  return _(RA_SVN_DESCRIPTION);}static const char * const *ra_svn_get_schemes(apr_pool_t *pool){  static const char *schemes[] = { "svn", NULL };  return schemes;}static svn_error_t *ra_svn_open(svn_ra_session_t *session, const char *url,                                const svn_ra_callbacks2_t *callbacks,                                void *callback_baton,                                apr_hash_t *config,                                apr_pool_t *pool){  apr_pool_t *sess_pool = svn_pool_create(pool);  ra_svn_session_baton_t *sess;  const char *tunnel, **tunnel_argv;  apr_uri_t uri;    SVN_ERR(parse_url(url, &uri, sess_pool));  parse_tunnel(url, &tunnel, pool);  if (tunnel)    SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,

⌨️ 快捷键说明

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