Code

Merge branch 'jc/format-patch-encoding'
[git.git] / sideband.c
1 #include "pkt-line.h"
2 #include "sideband.h"
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)
15 {
16         char buf[7 + LARGE_PACKET_MAX + 1];
17         strcpy(buf, "remote:");
18         while (1) {
19                 int band, len;
20                 len = packet_read_line(in_stream, buf+7, LARGE_PACKET_MAX);
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                 }
28                 band = buf[7] & 0xff;
29                 len--;
30                 switch (band) {
31                 case 3:
32                         buf[7] = ' ';
33                         buf[8+len] = '\n';
34                         safe_write(err, buf, 8+len+1);
35                         return SIDEBAND_REMOTE_ERROR;
36                 case 2:
37                         buf[7] = ' ';
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                         }
54                         continue;
55                 case 1:
56                         safe_write(out, buf+8, len);
57                         continue;
58                 default:
59                         len = sprintf(buf,
60                                       "%s: protocol error: bad band #%d\n",
61                                       me, band);
62                         safe_write(err, buf, len);
63                         return SIDEBAND_PROTOCOL_ERROR;
64                 }
65         }
66         return 0;
67 }
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;
78         while (sz) {
79                 unsigned n;
80                 char hdr[5];
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 }