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 */ 14intrecv_sideband(const char*me,int in_stream,int out,int err,char*buf,int bufsz) 15{ 16while(1) { 17int len =packet_read_line(in_stream, buf, bufsz); 18if(len ==0) 19break; 20if(len <1) { 21 len =sprintf(buf,"%s: protocol error: no band designator\n", me); 22safe_write(err, buf, len); 23return SIDEBAND_PROTOCOL_ERROR; 24} 25 len--; 26switch(buf[0] &0xFF) { 27case3: 28safe_write(err,"remote: ",8); 29safe_write(err, buf+1, len); 30safe_write(err,"\n",1); 31return SIDEBAND_REMOTE_ERROR; 32case2: 33safe_write(err,"remote: ",8); 34safe_write(err, buf+1, len); 35continue; 36case1: 37safe_write(out, buf+1, len); 38continue; 39default: 40 len =sprintf(buf +1, 41"%s: protocol error: bad band #%d\n", 42 me, buf[0] &0xFF); 43safe_write(err, buf+1, len); 44return SIDEBAND_PROTOCOL_ERROR; 45} 46} 47return0; 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; 57const char*p = data; 58 59while(sz) { 60unsigned n; 61char hdr[5]; 62 63 n = sz; 64if(packet_max -5< n) 65 n = packet_max -5; 66sprintf(hdr,"%04x", n +5); 67 hdr[4] = band; 68safe_write(fd, hdr,5); 69safe_write(fd, p, n); 70 p += n; 71 sz -= n; 72} 73return ssz; 74}