bundle: add parse_bundle_header() helper function

Move most of the code from read_bundle_header() to parse_bundle_header() that takes a file descriptor that is already opened for reading, and make the former responsible only for opening the file and noticing errors. As a logical consequence of this, is_bundle() helper function can be implemented as a non-complaining variant of read_bundle_header() that does not return an open file descriptor, and can be used to tighten the check used to decide the use of bundle transport in transport_get() function. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Oct 13, 2011 at 15:19 UTC 2727b71f0547f5181653940d279854e7924788fb
3 files changed +33 -9
bundle.c
+31 -8
@@ -40,19 +40,18 @@ static int strbuf_readline_fd(struct strbuf *sb, int fd)
40 return 0;
41 }
42
43 -int read_bundle_header(const char *path, struct bundle_header *header)
43 +static int parse_bundle_header(int fd, struct bundle_header *header,
44 + const char *report_path)
45 {
46 struct strbuf buf = STRBUF_INIT;
46 - int fd = open(path, O_RDONLY);
47 int status = 0;
48
49 - if (fd < 0)
50 - return error("could not open '%s'", path);
51 -
49 /* The bundle header begins with the signature */
50 if (strbuf_readline_fd(&buf, fd) ||
51 strcmp(buf.buf, bundle_signature)) {
55 - error("'%s' does not look like a v2 bundle file", path);
52 + if (report_path)
53 + error("'%s' does not look like a v2 bundle file",
54 + report_path);
55 status = -1;
56 goto abort;
57 }
@@ -77,8 +76,9 @@ int read_bundle_header(const char *path, struct bundle_header *header)
76 if (get_sha1_hex(buf.buf, sha1) ||
77 (40 <= buf.len && !isspace(buf.buf[40])) ||
78 (!is_prereq && buf.len <= 40)) {
80 - error("unrecognized header: %s%s (%d)",
81 - (is_prereq ? "-" : ""), buf.buf, (int)buf.len);
79 + if (report_path)
80 + error("unrecognized header: %s%s (%d)",
81 + (is_prereq ? "-" : ""), buf.buf, (int)buf.len);
82 status = -1;
83 break;
84 } else {
@@ -98,6 +98,29 @@ int read_bundle_header(const char *path, struct bundle_header *header)
98 return fd;
99 }
100
101 +int read_bundle_header(const char *path, struct bundle_header *header)
102 +{
103 + int fd = open(path, O_RDONLY);
104 +
105 + if (fd < 0)
106 + return error("could not open '%s'", path);
107 + return parse_bundle_header(fd, header, path);
108 +}
109 +
110 +int is_bundle(const char *path, int quiet)
111 +{
112 + struct bundle_header header;
113 + int fd = open(path, O_RDONLY);
114 +
115 + if (fd < 0)
116 + return 0;
117 + memset(&header, 0, sizeof(header));
118 + fd = parse_bundle_header(fd, &header, quiet ? NULL : path);
119 + if (fd >= 0)
120 + close(fd);
121 + return (fd >= 0);
122 +}
123 +
124 static int list_refs(struct ref_list *r, int argc, const char **argv)
125 {
126 int i;
bundle.h
+1
@@ -14,6 +14,7 @@ struct bundle_header {
14 struct ref_list references;
15 };
16
17 +int is_bundle(const char *path, int quiet);
18 int read_bundle_header(const char *path, struct bundle_header *header);
19 int create_bundle(struct bundle_header *header, const char *path,
20 int argc, const char **argv);
transport.c
+1 -1
@@ -913,7 +913,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
913 ret->fetch = fetch_objs_via_rsync;
914 ret->push = rsync_transport_push;
915 ret->smart_options = NULL;
916 - } else if (is_local(url) && is_file(url)) {
916 + } else if (is_local(url) && is_file(url) && is_bundle(url, 1)) {
917 struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
918 ret->data = data;
919 ret->get_refs_list = get_refs_from_bundle;