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 */ 14int 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 */ 54ssize_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}