📄 client.c
字号:
pool)); else tunnel_argv = NULL; /* We open the session in a subpool so we can get rid of it if we reparent with a server that doesn't support reparenting. */ SVN_ERR(open_session(&sess, url, &uri, callbacks->auth_baton, tunnel_argv, sess_pool)); session->priv = sess; return SVN_NO_ERROR;}static svn_error_t *ra_svn_reparent(svn_ra_session_t *ra_session, const char *url, apr_pool_t *pool){ ra_svn_session_baton_t *sess = ra_session->priv; svn_ra_svn_conn_t *conn = sess->conn; svn_error_t *err; apr_pool_t *sess_pool; ra_svn_session_baton_t *new_sess; apr_uri_t uri; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "reparent", "c", url)); err = handle_auth_request(sess, pool); if (! err) return svn_ra_svn_read_cmd_response(conn, pool, ""); else if (err->apr_err != SVN_ERR_RA_SVN_UNKNOWN_CMD) return err; /* Servers before 1.4 doesn't support this command; try to reconnect instead. */ svn_error_clear(err); /* Create a new subpool of the RA session pool. */ sess_pool = svn_pool_create(ra_session->pool); err = parse_url(url, &uri, sess_pool); if (! err) err = open_session(&new_sess, url, &uri, sess->auth_baton, sess->tunnel_argv, sess_pool); /* We destroy the new session pool on error, since it is allocated in the main session pool. */ if (err) { svn_pool_destroy(sess_pool); return err; } /* We have a new connection, assign it and destroy the old. */ ra_session->priv = new_sess; svn_pool_destroy(sess->pool); return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_latest_rev(svn_ra_session_t *session, svn_revnum_t *rev, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-latest-rev", "")); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "r", rev)); return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_dated_rev(svn_ra_session_t *session, svn_revnum_t *rev, apr_time_t tm, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-dated-rev", "c", svn_time_to_cstring(tm, pool))); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "r", rev)); return SVN_NO_ERROR;}static svn_error_t *ra_svn_change_rev_prop(svn_ra_session_t *session, svn_revnum_t rev, const char *name, const svn_string_t *value, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "change-rev-prop", "rc?s", rev, name, value)); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_uuid(svn_ra_session_t *session, const char **uuid, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; *uuid = conn->uuid; return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_repos_root(svn_ra_session_t *session, const char **url, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; if (!conn->repos_root) return svn_error_create(SVN_ERR_RA_SVN_BAD_VERSION, NULL, _("Server did not send repository root")); *url = conn->repos_root; return SVN_NO_ERROR;}static svn_error_t *ra_svn_rev_proplist(svn_ra_session_t *session, svn_revnum_t rev, apr_hash_t **props, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; apr_array_header_t *proplist; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "rev-proplist", "r", rev)); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "l", &proplist)); SVN_ERR(parse_proplist(proplist, pool, props)); return SVN_NO_ERROR;}static svn_error_t *ra_svn_rev_prop(svn_ra_session_t *session, svn_revnum_t rev, const char *name, svn_string_t **value, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "rev-prop", "rc", rev, name)); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "(?s)", value)); return SVN_NO_ERROR;}static svn_error_t *ra_svn_end_commit(void *baton){ ra_svn_commit_callback_baton_t *ccb = baton; svn_commit_info_t *commit_info = svn_create_commit_info(ccb->pool); SVN_ERR(handle_auth_request(ccb->sess_baton, ccb->pool)); SVN_ERR(svn_ra_svn_read_tuple(ccb->sess_baton->conn, ccb->pool, "r(?c)(?c)?(?c)", &(commit_info->revision), &(commit_info->date), &(commit_info->author), &(commit_info->post_commit_err))); return ccb->callback(commit_info, ccb->callback_baton, ccb->pool);}static svn_error_t *ra_svn_commit(svn_ra_session_t *session, const svn_delta_editor_t **editor, void **edit_baton, const char *log_msg, svn_commit_callback2_t callback, void *callback_baton, apr_hash_t *lock_tokens, svn_boolean_t keep_locks, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; ra_svn_commit_callback_baton_t *ccb; apr_hash_index_t *hi; apr_pool_t *iterpool; /* Tell the server we're starting the commit. */ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(c(!", "commit", log_msg)); if (lock_tokens) { iterpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, lock_tokens); hi; hi = apr_hash_next(hi)) { const void *key; void *val; const char *path, *token; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); path = key; token = val; SVN_ERR(svn_ra_svn_write_tuple(conn, iterpool, "cc", path, token)); } svn_pool_destroy(iterpool); } SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)b)", keep_locks)); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); /* Remember a few arguments for when the commit is over. */ ccb = apr_palloc(pool, sizeof(*ccb)); ccb->sess_baton = sess_baton; ccb->pool = pool; ccb->callback = callback; ccb->callback_baton = callback_baton; /* Fetch an editor for the caller to drive. The editor will call * ra_svn_end_commit() upon close_edit(), at which point we'll fill * in the new_rev, committed_date, and committed_author values. */ svn_ra_svn_get_editor(editor, edit_baton, conn, pool, ra_svn_end_commit, ccb); return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_file(svn_ra_session_t *session, const char *path, svn_revnum_t rev, svn_stream_t *stream, svn_revnum_t *fetched_rev, apr_hash_t **props, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; svn_ra_svn_item_t *item; apr_array_header_t *proplist; unsigned char digest[APR_MD5_DIGESTSIZE]; const char *expected_checksum, *hex_digest; apr_md5_ctx_t md5_context; SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "get-file", "c(?r)bb", path, rev, (props != NULL), (stream != NULL))); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "(?c)rl", &expected_checksum, &rev, &proplist)); if (fetched_rev) *fetched_rev = rev; if (props) SVN_ERR(parse_proplist(proplist, pool, props)); /* We're done if the contents weren't wanted. */ if (!stream) return SVN_NO_ERROR; if (expected_checksum) apr_md5_init(&md5_context); /* Read the file's contents. */ while (1) { SVN_ERR(svn_ra_svn_read_item(conn, pool, &item)); if (item->kind != SVN_RA_SVN_STRING) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Non-string as part of file contents")); if (item->u.string->len == 0) break; if (expected_checksum) apr_md5_update(&md5_context, item->u.string->data, item->u.string->len); SVN_ERR(svn_stream_write(stream, item->u.string->data, &item->u.string->len)); } SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); if (expected_checksum) { apr_md5_final(digest, &md5_context); hex_digest = svn_md5_digest_to_cstring_display(digest, pool); if (strcmp(hex_digest, expected_checksum) != 0) return svn_error_createf (SVN_ERR_CHECKSUM_MISMATCH, NULL, _("Checksum mismatch for '%s':\n" " expected checksum: %s\n" " actual checksum: %s\n"), path, expected_checksum, hex_digest); } return SVN_NO_ERROR;}static svn_error_t *ra_svn_get_dir(svn_ra_session_t *session, apr_hash_t **dirents, svn_revnum_t *fetched_rev, apr_hash_t **props, const char *path, svn_revnum_t rev, apr_uint32_t dirent_fields, apr_pool_t *pool){ ra_svn_session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; svn_revnum_t crev; apr_array_header_t *proplist, *dirlist; int i; svn_ra_svn_item_t *elt; const char *name, *kind, *cdate, *cauthor; svn_boolean_t has_props; apr_uint64_t size; svn_dirent_t *dirent; SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(c(?r)bb(!", "get-dir", path, rev, (props != NULL), (dirents != NULL))); if (dirent_fields & SVN_DIRENT_KIND) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_KIND)); } if (dirent_fields & SVN_DIRENT_SIZE) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_SIZE)); } if (dirent_fields & SVN_DIRENT_HAS_PROPS) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_HAS_PROPS)); } if (dirent_fields & SVN_DIRENT_CREATED_REV) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_CREATED_REV)); } if (dirent_fields & SVN_DIRENT_TIME) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_TIME)); } if (dirent_fields & SVN_DIRENT_LAST_AUTHOR) { SVN_ERR(svn_ra_svn_write_word(conn, pool, SVN_RA_SVN_DIRENT_LAST_AUTHOR)); } SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))")); SVN_ERR(handle_auth_request(sess_baton, pool)); SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "rll", &rev, &proplist, &dirlist)); if (fetched_rev) *fetched_rev = rev; if (props) SVN_ERR(parse_proplist(proplist, pool, props)); /* We're done if dirents aren't wanted. */ if (!dirents) return SVN_NO_ERROR; /* Interpret the directory list. */ *dirents = apr_hash_make(pool); for (i = 0; i < dirlist->nelts; i++) { elt = &((svn_ra_svn_item_t *) dirlist->elts)[i]; if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Dirlist element not a list")); SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, pool, "cwnbr(?c)(?c)", &name, &kind, &size, &has_props, &crev, &cdate, &cauthor)); name = svn_path_canonicalize(name, pool); dirent = apr_palloc(pool, sizeof(*dirent)); SVN_ERR(interpret_kind(kind, pool, &dirent->kind)); dirent->size = size;/* FIXME: svn_filesize_t */ dirent->has_props = has_props;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -