/* * 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 (git_vector_insert(refs, pkt) < 0) return -1; if (pkt->type == GIT_PKT_FLUSH) flush++; } 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; } /* We don't know this capability, so skip it */ ptr = strchr(ptr, ' '); } return 0; }