mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 08:53:48 +00:00

Storing flushes in the refs vector doesn't let us recognize when the remote is empty, as we'd always introduce at least one element into it. These flushes aren't necessary, so we can simply ignore them.
111 lines
2.4 KiB
C
111 lines
2.4 KiB
C
/*
|
|
* Copyright (C) 2009-2012 the libgit2 contributors
|
|
*
|
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
*/
|
|
#include "common.h"
|
|
#include "protocol.h"
|
|
#include "pkt.h"
|
|
#include "buffer.h"
|
|
|
|
int git_protocol_store_refs(git_transport *t, int flushes)
|
|
{
|
|
gitno_buffer *buf = &t->buffer;
|
|
git_vector *refs = &t->refs;
|
|
int error, flush = 0, recvd;
|
|
const char *line_end;
|
|
git_pkt *pkt;
|
|
|
|
do {
|
|
if (buf->offset > 0)
|
|
error = git_pkt_parse_line(&pkt, buf->data, &line_end, buf->offset);
|
|
else
|
|
error = GIT_EBUFS;
|
|
|
|
if (error < 0 && error != GIT_EBUFS)
|
|
return -1;
|
|
|
|
if (error == GIT_EBUFS) {
|
|
if ((recvd = gitno_recv(buf)) < 0)
|
|
return -1;
|
|
|
|
if (recvd == 0 && !flush) {
|
|
giterr_set(GITERR_NET, "Early EOF");
|
|
return -1;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
gitno_consume(buf, line_end);
|
|
if (pkt->type == GIT_PKT_ERR) {
|
|
giterr_set(GITERR_NET, "Remote error: %s", ((git_pkt_err *)pkt)->error);
|
|
git__free(pkt);
|
|
return -1;
|
|
}
|
|
|
|
if (pkt->type != GIT_PKT_FLUSH && git_vector_insert(refs, pkt) < 0)
|
|
return -1;
|
|
|
|
if (pkt->type == GIT_PKT_FLUSH) {
|
|
flush++;
|
|
git_pkt_free(pkt);
|
|
}
|
|
} while (flush < flushes);
|
|
|
|
return flush;
|
|
}
|
|
|
|
int git_protocol_detect_caps(git_pkt_ref *pkt, git_transport_caps *caps)
|
|
{
|
|
const char *ptr;
|
|
|
|
/* No refs or capabilites, odd but not a problem */
|
|
if (pkt == NULL || pkt->capabilities == NULL)
|
|
return 0;
|
|
|
|
ptr = pkt->capabilities;
|
|
while (ptr != NULL && *ptr != '\0') {
|
|
if (*ptr == ' ')
|
|
ptr++;
|
|
|
|
if(!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) {
|
|
caps->common = caps->ofs_delta = 1;
|
|
ptr += strlen(GIT_CAP_OFS_DELTA);
|
|
continue;
|
|
}
|
|
|
|
if(!git__prefixcmp(ptr, GIT_CAP_MULTI_ACK)) {
|
|
caps->common = caps->multi_ack = 1;
|
|
ptr += strlen(GIT_CAP_MULTI_ACK);
|
|
continue;
|
|
}
|
|
|
|
if(!git__prefixcmp(ptr, GIT_CAP_INCLUDE_TAG)) {
|
|
caps->common = caps->include_tag = 1;
|
|
ptr += strlen(GIT_CAP_INCLUDE_TAG);
|
|
continue;
|
|
}
|
|
|
|
/* Keep side-band check after side-band-64k */
|
|
if(!git__prefixcmp(ptr, GIT_CAP_SIDE_BAND_64K)) {
|
|
caps->common = caps->side_band_64k = 1;
|
|
ptr += strlen(GIT_CAP_SIDE_BAND_64K);
|
|
continue;
|
|
}
|
|
|
|
if(!git__prefixcmp(ptr, GIT_CAP_SIDE_BAND)) {
|
|
caps->common = caps->side_band = 1;
|
|
ptr += strlen(GIT_CAP_SIDE_BAND);
|
|
continue;
|
|
}
|
|
|
|
|
|
/* We don't know this capability, so skip it */
|
|
ptr = strchr(ptr, ' ');
|
|
}
|
|
|
|
return 0;
|
|
}
|