gitweb: Remove redundant "commit" from history
[git] / sideband.c
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  */
14 int recv_sideband(const char *me, int in_stream, int out, int err, char *buf, int bufsz)
15 {
16         while (1) {
17                 int len = packet_read_line(in_stream, buf, bufsz);
18                 if (len == 0)
19                         break;
20                 if (len < 1) {
21                         len = sprintf(buf, "%s: protocol error: no band designator\n", me);
22                         safe_write(err, buf, len);
23                         return SIDEBAND_PROTOCOL_ERROR;
24                 }
25                 len--;
26                 switch (buf[0] & 0xFF) {
27                 case 3:
28                         safe_write(err, "remote: ", 8);
29                         safe_write(err, buf+1, len);
30                         safe_write(err, "\n", 1);
31                         return SIDEBAND_REMOTE_ERROR;
32                 case 2:
33                         safe_write(err, "remote: ", 8);
34                         safe_write(err, buf+1, len);
35                         continue;
36                 case 1:
37                         safe_write(out, buf+1, len);
38                         continue;
39                 default:
40                         len = sprintf(buf + 1,
41                                       "%s: protocol error: bad band #%d\n",
42                                       me, buf[0] & 0xFF);
43                         safe_write(err, buf+1, len);
44                         return SIDEBAND_PROTOCOL_ERROR;
45                 }
46         }
47         return 0;
48 }
49
50 /*
51  * fd is connected to the remote side; send the sideband data
52  * over multiplexed packet stream.
53  */
54 ssize_t send_sideband(int fd, int band, const char *data, ssize_t sz, int packet_max)
55 {
56         ssize_t ssz = sz;
57         const char *p = data;
58
59         while (sz) {
60                 unsigned n;
61                 char hdr[5];
62
63                 n = sz;
64                 if (packet_max - 5 < n)
65                         n = packet_max - 5;
66                 sprintf(hdr, "%04x", n + 5);
67                 hdr[4] = band;
68                 safe_write(fd, hdr, 5);
69                 safe_write(fd, p, n);
70                 p += n;
71                 sz -= n;
72         }
73         return ssz;
74 }