diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2014-05-27 17:51:25 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-05-27 17:51:25 +0200 |
commit | 4625003149d02227f981b53101c7e6be12226382 (patch) | |
tree | ac1a86f48c69d4da0ec14adc4860f0be7ab422ec /src/server.c | |
parent | 16b20526e1580f50b29f0dae87a30ebefe0a3c89 (diff) | |
download | libgit2-cmn/server.tar.gz |
server: handle negotiation linescmn/server
A bit of scaffolding for handling the lines from the client telling us
about its commits.
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/server.c b/src/server.c index 047f8d22e..766726798 100644 --- a/src/server.c +++ b/src/server.c @@ -29,6 +29,8 @@ void git_server_free(git_server *server) if (server == NULL) return; + git_array_clear(server->wants); + git_array_clear(server->common); git__free(server->path); git__free(server); } @@ -98,6 +100,50 @@ cleanup: return error; } +int git_server__negotiation(git_server *server, git_pkt *_pkt) +{ + git_oid *id, *have_id; + git_pkt_have_want *pkt; + git_odb *odb = NULL; + int error; + + if (_pkt->type != GIT_PKT_HAVE && _pkt->type != GIT_PKT_WANT) { + giterr_set(GITERR_NET, "invalid pkt for negotiation"); + return -1; + } + + pkt = (git_pkt_have_want *) _pkt; + + if (pkt->type == GIT_PKT_WANT) { + id = git_array_alloc(server->wants); + GITERR_CHECK_ALLOC(id); + + git_oid_cpy(id, &pkt->id); + return 0; + } + + /* we know it's a 'have', so we check to see if it's common */ + have_id = &pkt->id; + if ((error = git_repository_odb(&odb, server->repo)) < 0) + return error; + + if ((error = git_odb_exists(odb, have_id)) < 0) + goto cleanup; + + if (error == 1) { + error = 0; + id = git_array_alloc(server->common); + GITERR_CHECK_ALLOC(id); + + git_oid_cpy(id, &pkt->id); + } + +cleanup: + git_odb_free(odb); + + return error; +} + int git_server_run(git_server *server) { /* 65535 is the max size of a pkt frame */ |