]>
Commit | Line | Data |
---|---|---|
49a52b1d JH |
1 | #include "pkt-line.h" |
2 | #include "sideband.h" | |
3 | ||
4 | /* | |
5 | * Receive multiplexed output stream over git native protocol. | |
6 | * in_stream is the input stream from the remote, which carries data | |
7 | * in pkt_line format with band designator. Demultiplex it into out | |
8 | * and err and return error appropriately. Band #1 carries the | |
9 | * primary payload. Things coming over band #2 is not necessarily | |
10 | * error; they are usually informative message on the standard error | |
11 | * stream, aka "verbose"). A message over band #3 is a signal that | |
12 | * the remote died unexpectedly. A flush() concludes the stream. | |
13 | */ | |
9ac13ec9 | 14 | int recv_sideband(const char *me, int in_stream, int out, int err) |
49a52b1d | 15 | { |
9ac13ec9 NP |
16 | char buf[7 + LARGE_PACKET_MAX + 1]; |
17 | strcpy(buf, "remote:"); | |
49a52b1d | 18 | while (1) { |
9ac13ec9 | 19 | int band, len; |
ed1902ef | 20 | len = packet_read_line(in_stream, buf+7, LARGE_PACKET_MAX); |
49a52b1d JH |
21 | if (len == 0) |
22 | break; | |
23 | if (len < 1) { | |
24 | len = sprintf(buf, "%s: protocol error: no band designator\n", me); | |
25 | safe_write(err, buf, len); | |
26 | return SIDEBAND_PROTOCOL_ERROR; | |
27 | } | |
9ac13ec9 | 28 | band = buf[7] & 0xff; |
49a52b1d | 29 | len--; |
9ac13ec9 | 30 | switch (band) { |
49a52b1d | 31 | case 3: |
9ac13ec9 NP |
32 | buf[7] = ' '; |
33 | buf[8+len] = '\n'; | |
34 | safe_write(err, buf, 8+len+1); | |
49a52b1d JH |
35 | return SIDEBAND_REMOTE_ERROR; |
36 | case 2: | |
9ac13ec9 | 37 | buf[7] = ' '; |
ed1902ef NP |
38 | len += 8; |
39 | while (1) { | |
40 | int brk = 8; | |
41 | while (brk < len) { | |
42 | brk++; | |
43 | if (buf[brk-1] == '\n' || | |
44 | buf[brk-1] == '\r') | |
45 | break; | |
46 | } | |
47 | safe_write(err, buf, brk); | |
48 | if (brk < len) { | |
49 | memmove(buf + 8, buf + brk, len - brk); | |
50 | len = len - brk + 8; | |
51 | } else | |
52 | break; | |
53 | } | |
49a52b1d JH |
54 | continue; |
55 | case 1: | |
9ac13ec9 | 56 | safe_write(out, buf+8, len); |
49a52b1d JH |
57 | continue; |
58 | default: | |
9ac13ec9 | 59 | len = sprintf(buf, |
49a52b1d | 60 | "%s: protocol error: bad band #%d\n", |
9ac13ec9 NP |
61 | me, band); |
62 | safe_write(err, buf, len); | |
49a52b1d JH |
63 | return SIDEBAND_PROTOCOL_ERROR; |
64 | } | |
65 | } | |
66 | return 0; | |
67 | } | |
958c24b1 JH |
68 | |
69 | /* | |
70 | * fd is connected to the remote side; send the sideband data | |
71 | * over multiplexed packet stream. | |
72 | */ | |
73 | ssize_t send_sideband(int fd, int band, const char *data, ssize_t sz, int packet_max) | |
74 | { | |
75 | ssize_t ssz = sz; | |
76 | const char *p = data; | |
77 | ||
78 | while (sz) { | |
79 | unsigned n; | |
80 | char hdr[5]; | |
81 | ||
82 | n = sz; | |
83 | if (packet_max - 5 < n) | |
84 | n = packet_max - 5; | |
85 | sprintf(hdr, "%04x", n + 5); | |
86 | hdr[4] = band; | |
87 | safe_write(fd, hdr, 5); | |
88 | safe_write(fd, p, n); | |
89 | p += n; | |
90 | sz -= n; | |
91 | } | |
92 | return ssz; | |
93 | } |