48
49
static void die_initial_contact(int unexpected)
50
{
51
+ /*
52
+ * A hang-up after seeing some response from the other end
53
+ * means that it is unexpected, as we know the other end is
54
+ * willing to talk to us. A hang-up before seeing any
55
+ * response does not necessarily mean an ACL problem, though.
56
+ */
57
if (unexpected)
58
die(_("The remote end hung up upon initial contact"));
59
else
62
"and the repository exists."));
63
}
64
65
+static enum protocol_version discover_version(struct packet_reader *reader)
66
+{
67
+ enum protocol_version version = protocol_unknown_version;
68
+
69
+ /*
70
+ * Peek the first line of the server's response to
71
+ * determine the protocol version the server is speaking.
72
+ */
73
+ switch (packet_reader_peek(reader)) {
74
+ case PACKET_READ_EOF:
75
+ die_initial_contact(0);
76
+ case PACKET_READ_FLUSH:
77
+ case PACKET_READ_DELIM:
78
+ version = protocol_v0;
79
+ break;
80
+ case PACKET_READ_NORMAL:
81
+ version = determine_protocol_version_client(reader->line);
82
+ break;
83
+ }
84
+
85
+ switch (version) {
86
+ case protocol_v1:
87
+ /* Read the peeked version line */
88
+ packet_reader_read(reader);
89
+ break;
90
+ case protocol_v0:
91
+ break;
92
+ case protocol_unknown_version:
93
+ BUG("unknown protocol version");
94
+ }
95
+
96
+ return version;
97
+}
98
+
99
static void parse_one_symref_info(struct string_list *symref, const char *val, int len)
100
{
101
char *sym, *target;
149
string_list_clear(&symref, 0);
150
}
151
112
-/*
113
- * Read one line of a server's ref advertisement into packet_buffer.
114
- */
115
-static int read_remote_ref(int in, char **src_buf, size_t *src_len,
116
- int *responded)
152
+static void process_capabilities(const char *line, int *len)
153
{
118
- int len = packet_read(in, src_buf, src_len,
119
- packet_buffer, sizeof(packet_buffer),
120
- PACKET_READ_GENTLE_ON_EOF |
121
- PACKET_READ_CHOMP_NEWLINE);
122
- const char *arg;
123
- if (len < 0)
124
- die_initial_contact(*responded);
125
- if (len > 4 && skip_prefix(packet_buffer, "ERR ", &arg))
126
- die("remote error: %s", arg);
127
-
128
- *responded = 1;
129
-
130
- return len;
131
-}
132
-
133
-#define EXPECTING_PROTOCOL_VERSION 0
134
-#define EXPECTING_FIRST_REF 1
135
-#define EXPECTING_REF 2
136
-#define EXPECTING_SHALLOW 3
137
-
138
-/* Returns 1 if packet_buffer is a protocol version pkt-line, 0 otherwise. */
139
-static int process_protocol_version(void)
140
-{
141
- switch (determine_protocol_version_client(packet_buffer)) {
142
- case protocol_v1:
143
- return 1;
144
- case protocol_v0:
145
- return 0;
146
- default:
147
- die("server is speaking an unknown protocol");
148
- }
149
-}
150
-
151
-static void process_capabilities(int *len)
152
-{
153
- int nul_location = strlen(packet_buffer);
154
+ int nul_location = strlen(line);
155
if (nul_location == *len)
156
return;
156
- server_capabilities = xstrdup(packet_buffer + nul_location + 1);
157
+ server_capabilities = xstrdup(line + nul_location + 1);
158
*len = nul_location;
159
}
160
160
-static int process_dummy_ref(void)
161
+static int process_dummy_ref(const char *line)
162
{
163
struct object_id oid;
164
const char *name;
165
165
- if (parse_oid_hex(packet_buffer, &oid, &name))
166
+ if (parse_oid_hex(line, &oid, &name))
167
return 0;
168
if (*name != ' ')
169
return 0;
172
return !oidcmp(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
173
}
174
174
-static void check_no_capabilities(int len)
175
+static void check_no_capabilities(const char *line, int len)
176
{
176
- if (strlen(packet_buffer) != len)
177
+ if (strlen(line) != len)
178
warning("Ignoring capabilities after first line '%s'",
178
- packet_buffer + strlen(packet_buffer));
179
+ line + strlen(line));
180
}
181
181
-static int process_ref(int len, struct ref ***list, unsigned int flags,
182
- struct oid_array *extra_have)
182
+static int process_ref(const char *line, int len, struct ref ***list,
183
+ unsigned int flags, struct oid_array *extra_have)
184
{
185
struct object_id old_oid;
186
const char *name;
187
187
- if (parse_oid_hex(packet_buffer, &old_oid, &name))
188
+ if (parse_oid_hex(line, &old_oid, &name))
189
return 0;
190
if (*name != ' ')
191
return 0;
201
**list = ref;
202
*list = &ref->next;
203
}
203
- check_no_capabilities(len);
204
+ check_no_capabilities(line, len);
205
return 1;
206
}
207
207
-static int process_shallow(int len, struct oid_array *shallow_points)
208
+static int process_shallow(const char *line, int len,
209
+ struct oid_array *shallow_points)
210
{
211
const char *arg;
212
struct object_id old_oid;
213
212
- if (!skip_prefix(packet_buffer, "shallow ", &arg))
214
+ if (!skip_prefix(line, "shallow ", &arg))
215
return 0;
216
217
if (get_oid_hex(arg, &old_oid))
219
if (!shallow_points)
220
die("repository on the other end cannot be shallow");
221
oid_array_append(shallow_points, &old_oid);
220
- check_no_capabilities(len);
222
+ check_no_capabilities(line, len);
223
return 1;
224
}
225
226
+enum get_remote_heads_state {
227
+ EXPECTING_FIRST_REF = 0,
228
+ EXPECTING_REF,
229
+ EXPECTING_SHALLOW,
230
+ EXPECTING_DONE,
231
+};
232
+
233
/*
234
* Read all the refs from the other end
235
*/
239
struct oid_array *shallow_points)
240
{
241
struct ref **orig_list = list;
242
+ int len = 0;
243
+ enum get_remote_heads_state state = EXPECTING_FIRST_REF;
244
+ struct packet_reader reader;
245
+ const char *arg;
246
234
- /*
235
- * A hang-up after seeing some response from the other end
236
- * means that it is unexpected, as we know the other end is
237
- * willing to talk to us. A hang-up before seeing any
238
- * response does not necessarily mean an ACL problem, though.
239
- */
240
- int responded = 0;
241
- int len;
242
- int state = EXPECTING_PROTOCOL_VERSION;
247
+ packet_reader_init(&reader, in, src_buf, src_len,
248
+ PACKET_READ_CHOMP_NEWLINE |
249
+ PACKET_READ_GENTLE_ON_EOF);
250
+
251
+ discover_version(&reader);
252
253
*list = NULL;
254
246
- while ((len = read_remote_ref(in, &src_buf, &src_len, &responded))) {
255
+ while (state != EXPECTING_DONE) {
256
+ switch (packet_reader_read(&reader)) {
257
+ case PACKET_READ_EOF:
258
+ die_initial_contact(1);
259
+ case PACKET_READ_NORMAL:
260
+ len = reader.pktlen;
261
+ if (len > 4 && skip_prefix(reader.line, "ERR ", &arg))
262
+ die("remote error: %s", arg);
263
+ break;
264
+ case PACKET_READ_FLUSH:
265
+ state = EXPECTING_DONE;
266
+ break;
267
+ case PACKET_READ_DELIM:
268
+ die("invalid packet");
269
+ }
270
+
271
switch (state) {
248
- case EXPECTING_PROTOCOL_VERSION:
249
- if (process_protocol_version()) {
250
- state = EXPECTING_FIRST_REF;
251
- break;
252
- }
253
- state = EXPECTING_FIRST_REF;
254
- /* fallthrough */
272
case EXPECTING_FIRST_REF:
256
- process_capabilities(&len);
257
- if (process_dummy_ref()) {
273
+ process_capabilities(reader.line, &len);
274
+ if (process_dummy_ref(reader.line)) {
275
state = EXPECTING_SHALLOW;
276
break;
277
}
278
state = EXPECTING_REF;
279
/* fallthrough */
280
case EXPECTING_REF:
264
- if (process_ref(len, &list, flags, extra_have))
281
+ if (process_ref(reader.line, len, &list, flags, extra_have))
282
break;
283
state = EXPECTING_SHALLOW;
284
/* fallthrough */
285
case EXPECTING_SHALLOW:
269
- if (process_shallow(len, shallow_points))
286
+ if (process_shallow(reader.line, len, shallow_points))
287
break;
271
- die("protocol error: unexpected '%s'", packet_buffer);
272
- default:
273
- die("unexpected state %d", state);
288
+ die("protocol error: unexpected '%s'", reader.line);
289
+ case EXPECTING_DONE:
290
+ break;
291
}
292
}
293