📄 client.c
字号:
if (item->kind == SVN_RA_SVN_WORD && strcmp(item->u.word, "done") == 0) break; /* Either we've got a correct revision or we will error out below. */ had_revision = TRUE; if (item->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Revision entry not a list")); SVN_ERR(svn_ra_svn_parse_tuple(item->u.list, rev_pool, "crll", &p, &rev, &rev_proplist, &proplist)); p = svn_path_canonicalize(p, rev_pool); SVN_ERR(parse_proplist(rev_proplist, rev_pool, &rev_props)); SVN_ERR(parse_prop_diffs(proplist, rev_pool, &props)); /* Get the first delta chunk so we know if there is a delta. */ SVN_ERR(svn_ra_svn_read_item(sess_baton->conn, chunk_pool, &item)); if (item->kind != SVN_RA_SVN_STRING) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Text delta chunk not a string")); has_txdelta = item->u.string->len > 0; SVN_ERR(handler(handler_baton, p, rev, rev_props, has_txdelta ? &d_handler : NULL, &d_baton, props, rev_pool)); /* Process the text delta if any. */ if (has_txdelta) { if (d_handler) stream = svn_txdelta_parse_svndiff(d_handler, d_baton, TRUE, rev_pool); else stream = NULL; while (item->u.string->len > 0) { size = item->u.string->len; if (stream) SVN_ERR(svn_stream_write(stream, item->u.string->data, &size)); svn_pool_clear(chunk_pool); SVN_ERR(svn_ra_svn_read_item(sess_baton->conn, chunk_pool, &item)); if (item->kind != SVN_RA_SVN_STRING) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Text delta chunk not a string")); } if (stream) SVN_ERR(svn_stream_close(stream)); } } SVN_ERR(svn_ra_svn_read_cmd_response(sess_baton->conn, pool, "")); /* Return error if we didn't get any revisions. */ if (!had_revision) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("The get-file-revs command didn't return " "any revisions")); svn_pool_destroy(chunk_pool); svn_pool_destroy(rev_pool); return SVN_NO_ERROR;}/* For each path in PATH_REVS, send a 'lock' command to the server. Used with 1.2.x series servers which support locking, but of only one path at a time. ra_svn_lock(), which supports 'lock-many' is now the default. See svn_ra_lock() docstring for interface details. */static svn_error_t *ra_svn_lock_compat(svn_ra_session_t *session, apr_hash_t *path_revs, const char *comment, svn_boolean_t steal_lock, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ ra_svn_session_baton_t *sess = session->priv; svn_ra_svn_conn_t* conn = sess->conn; apr_array_header_t *list; apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { svn_lock_t *lock; const void *key; const char *path; void *val; svn_revnum_t *revnum; svn_error_t *err, *callback_err = NULL; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); path = key; revnum = val; SVN_ERR(svn_ra_svn_write_cmd(conn, iterpool, "lock", "c(?c)b(?r)", path, comment, steal_lock, *revnum)); /* Servers before 1.2 doesn't support locking. Check this here. */ SVN_ERR(handle_unsupported_cmd(handle_auth_request(sess, pool), _("Server doesn't support " "the lock command"))); err = svn_ra_svn_read_cmd_response(conn, iterpool, "l", &list); if (!err) SVN_ERR(parse_lock(list, iterpool, &lock)); if (err && !SVN_ERR_IS_LOCK_ERROR(err)) return err; if (lock_func) callback_err = lock_func(lock_baton, path, TRUE, err ? NULL : lock, err, iterpool); svn_error_clear(err); if (callback_err) return callback_err; } svn_pool_destroy(iterpool); return SVN_NO_ERROR;}/* For each path in PATH_TOKENS, send an 'unlock' command to the server. Used with 1.2.x series servers which support unlocking, but of only one path at a time. ra_svn_unlock(), which supports 'unlock-many' is now the default. See svn_ra_unlock() docstring for interface details. */static svn_error_t *ra_svn_unlock_compat(svn_ra_session_t *session, apr_hash_t *path_tokens, svn_boolean_t break_lock, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ ra_svn_session_baton_t *sess = session->priv; svn_ra_svn_conn_t* conn = sess->conn; apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi)) { const void *key; const char *path; void *val; const char *token; svn_error_t *err, *callback_err = NULL; svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); path = key; if (strcmp(val, "") != 0) token = val; else token = NULL; SVN_ERR(svn_ra_svn_write_cmd(conn, iterpool, "unlock", "c(?c)b", path, token, break_lock)); /* Servers before 1.2 don't support locking. Check this here. */ SVN_ERR(handle_unsupported_cmd(handle_auth_request(sess, iterpool), _("Server doesn't support the unlock " "command"))); err = svn_ra_svn_read_cmd_response(conn, iterpool, ""); if (err && !SVN_ERR_IS_UNLOCK_ERROR(err)) return err; if (lock_func) callback_err = lock_func(lock_baton, path, FALSE, NULL, err, pool); svn_error_clear(err); if (callback_err) return callback_err; } svn_pool_destroy(iterpool); return SVN_NO_ERROR;}/* Tell the server to lock all paths in PATH_REVS. See svn_ra_lock() for interface details. */static svn_error_t *ra_svn_lock(svn_ra_session_t *session, apr_hash_t *path_revs, const char *comment, svn_boolean_t steal_lock, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ ra_svn_session_baton_t *sess = session->priv; svn_ra_svn_conn_t *conn = sess->conn; apr_hash_index_t *hi; svn_ra_svn_item_t *elt; svn_error_t *err, *callback_err = SVN_NO_ERROR; apr_pool_t *subpool = svn_pool_create(pool); const char *status; svn_lock_t *lock; apr_array_header_t *list = NULL; SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((?c)b(!", "lock-many", comment, steal_lock)); for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { const void *key; const char *path; void *val; svn_revnum_t *revnum; svn_pool_clear(subpool); apr_hash_this(hi, &key, NULL, &val); path = key; revnum = val; SVN_ERR(svn_ra_svn_write_tuple(conn, subpool, "c(?r)", path, *revnum)); } SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))")); err = handle_auth_request(sess, pool); /* Pre-1.3 servers don't support 'lock-many'. If that fails, fall back * to 'lock'. */ if (err && err->apr_err == SVN_ERR_RA_SVN_UNKNOWN_CMD) { svn_error_clear(err); return ra_svn_lock_compat(session, path_revs, comment, steal_lock, lock_func, lock_baton, pool); } if (err) return err; /* Loop over responses to get lock information. */ for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { const void *key; const char *path; apr_hash_this(hi, &key, NULL, NULL); path = key; svn_pool_clear(subpool); SVN_ERR(svn_ra_svn_read_item(conn, subpool, &elt)); /* The server might have encountered some sort of fatal error in the middle of the request list. If this happens, it will transmit "done" to end the lock-info early, and then the overall command response will talk about the fatal error. */ if (elt->kind == SVN_RA_SVN_WORD && strcmp(elt->u.word, "done") == 0) break; if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Lock response not a list")); SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, subpool, "wl", &status, &list)); if (strcmp(status, "failure") == 0) err = svn_ra_svn__handle_failure_status(list, subpool); else if (strcmp(status, "success") == 0) { SVN_ERR(parse_lock(list, subpool, &lock)); err = NULL; } else return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Unknown status for lock command")); if (lock_func) callback_err = lock_func(lock_baton, path, TRUE, err ? NULL : lock, err, subpool); else callback_err = SVN_NO_ERROR; svn_error_clear(err); if (callback_err) return callback_err; } /* If we didn't break early above, and the whole hash was traversed, read the final "done" from the server. */ if (!hi) { SVN_ERR(svn_ra_svn_read_item(conn, pool, &elt)); if (elt->kind != SVN_RA_SVN_WORD || strcmp(elt->u.word, "done") != 0) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Didn't receive end marker for lock " "responses")); } SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "")); svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* Tell the server to unlock all paths in PATH_TOKENS. See svn_ra_unlock() for interface details. */static svn_error_t *ra_svn_unlock(svn_ra_session_t *session, apr_hash_t *path_tokens, svn_boolean_t break_lock, svn_ra_lock_callback_t lock_func, void *lock_baton, apr_pool_t *pool){ ra_svn_session_baton_t *sess = session->priv; svn_ra_svn_conn_t *conn = sess->conn; apr_hash_index_t *hi; apr_pool_t *subpool = svn_pool_create(pool); svn_error_t *err, *callback_err = NULL; svn_ra_svn_item_t *elt; const char *status = NULL; apr_array_header_t *list = NULL; const void *key; const char *path; SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w(b(!", "unlock-many", break_lock)); for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi)) { void *val; const char *token; svn_pool_clear(subpool); apr_hash_this(hi, &key, NULL, &val); path = key; if (strcmp(val, "") != 0) token = val; else token = NULL; SVN_ERR(svn_ra_svn_write_tuple(conn, subpool, "c(?c)", path, token)); } SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!))")); err = handle_auth_request(sess, pool); /* Pre-1.3 servers don't support 'unlock-many'. If unknown, fall back * to 'unlock'. */ if (err && err->apr_err == SVN_ERR_RA_SVN_UNKNOWN_CMD) { svn_error_clear(err); return ra_svn_unlock_compat(session, path_tokens, break_lock, lock_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -