git
/
protocol-caps.c
115 строк · 2.6 Кб
1#include "git-compat-util.h"2#include "protocol-caps.h"3#include "gettext.h"4#include "hex.h"5#include "pkt-line.h"6#include "hash.h"7#include "hex.h"8#include "object.h"9#include "object-store-ll.h"10#include "repository.h"11#include "string-list.h"12#include "strbuf.h"13
14struct requested_info {15unsigned size : 1;16};17
18/*
19* Parses oids from the given line and collects them in the given
20* oid_str_list. Returns 1 if parsing was successful and 0 otherwise.
21*/
22static int parse_oid(const char *line, struct string_list *oid_str_list)23{
24const char *arg;25
26if (!skip_prefix(line, "oid ", &arg))27return 0;28
29string_list_append(oid_str_list, arg);30
31return 1;32}
33
34/*
35* Validates and send requested info back to the client. Any errors detected
36* are returned as they are detected.
37*/
38static void send_info(struct repository *r, struct packet_writer *writer,39struct string_list *oid_str_list,40struct requested_info *info)41{
42struct string_list_item *item;43struct strbuf send_buffer = STRBUF_INIT;44
45if (!oid_str_list->nr)46return;47
48if (info->size)49packet_writer_write(writer, "size");50
51for_each_string_list_item (item, oid_str_list) {52const char *oid_str = item->string;53struct object_id oid;54unsigned long object_size;55
56if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {57packet_writer_error(58writer,59"object-info: protocol error, expected to get oid, not '%s'",60oid_str);61continue;62}63
64strbuf_addstr(&send_buffer, oid_str);65
66if (info->size) {67if (oid_object_info(r, &oid, &object_size) < 0) {68strbuf_addstr(&send_buffer, " ");69} else {70strbuf_addf(&send_buffer, " %lu", object_size);71}72}73
74packet_writer_write(writer, "%s", send_buffer.buf);75strbuf_reset(&send_buffer);76}77strbuf_release(&send_buffer);78}
79
80int cap_object_info(struct repository *r, struct packet_reader *request)81{
82struct requested_info info = { 0 };83struct packet_writer writer;84struct string_list oid_str_list = STRING_LIST_INIT_DUP;85
86packet_writer_init(&writer, 1);87
88while (packet_reader_read(request) == PACKET_READ_NORMAL) {89if (!strcmp("size", request->line)) {90info.size = 1;91continue;92}93
94if (parse_oid(request->line, &oid_str_list))95continue;96
97packet_writer_error(&writer,98"object-info: unexpected line: '%s'",99request->line);100}101
102if (request->status != PACKET_READ_FLUSH) {103packet_writer_error(104&writer, "object-info: expected flush after arguments");105die(_("object-info: expected flush after arguments"));106}107
108send_info(r, &writer, &oid_str_list, &info);109
110string_list_clear(&oid_str_list, 1);111
112packet_flush(1);113
114return 0;115}
116