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 15#define PREFIX"remote:" 16 17#define ANSI_SUFFIX"\033[K" 18#define DUMB_SUFFIX" " 19 20#define FIX_SIZE 10/* large enough for any of the above */ 21 22intrecv_sideband(const char*me,int in_stream,int out) 23{ 24unsigned pf =strlen(PREFIX); 25unsigned sf; 26char buf[LARGE_PACKET_MAX +2*FIX_SIZE]; 27char*suffix, *term; 28int skip_pf =0; 29 30memcpy(buf, PREFIX, pf); 31 term =getenv("TERM"); 32if(term &&strcmp(term,"dumb")) 33 suffix = ANSI_SUFFIX; 34else 35 suffix = DUMB_SUFFIX; 36 sf =strlen(suffix); 37 38while(1) { 39int band, len; 40 len =packet_read_line(in_stream, buf + pf, LARGE_PACKET_MAX); 41if(len ==0) 42break; 43if(len <1) { 44fprintf(stderr,"%s: protocol error: no band designator\n", me); 45return SIDEBAND_PROTOCOL_ERROR; 46} 47 band = buf[pf] &0xff; 48 len--; 49switch(band) { 50case3: 51 buf[pf] =' '; 52 buf[pf+1+len] ='\0'; 53fprintf(stderr,"%s\n", buf); 54return SIDEBAND_REMOTE_ERROR; 55case2: 56 buf[pf] =' '; 57do{ 58char*b = buf; 59int brk =0; 60 61/* 62 * If the last buffer didn't end with a line 63 * break then we should not print a prefix 64 * this time around. 65 */ 66if(skip_pf) { 67 b += pf+1; 68}else{ 69 len += pf+1; 70 brk += pf+1; 71} 72 73/* Look for a line break. */ 74for(;;) { 75 brk++; 76if(brk > len) { 77 brk =0; 78break; 79} 80if(b[brk-1] =='\n'|| 81 b[brk-1] =='\r') 82break; 83} 84 85/* 86 * Let's insert a suffix to clear the end 87 * of the screen line if a line break was 88 * found. Also, if we don't skip the 89 * prefix, then a non-empty string must be 90 * present too. 91 */ 92if(brk > (skip_pf ?0: (pf+1+1))) { 93char save[FIX_SIZE]; 94memcpy(save, b + brk, sf); 95 b[brk + sf -1] = b[brk -1]; 96memcpy(b + brk -1, suffix, sf); 97fprintf(stderr,"%.*s", brk + sf, b); 98memcpy(b + brk, save, sf); 99 len -= brk; 100}else{ 101int l = brk ? brk : len; 102fprintf(stderr,"%.*s", l, b); 103 len -= l; 104} 105 106 skip_pf = !brk; 107memmove(buf + pf+1, b + brk, len); 108}while(len); 109continue; 110case1: 111safe_write(out, buf + pf+1, len); 112continue; 113default: 114fprintf(stderr,"%s: protocol error: bad band #%d\n", 115 me, band); 116return SIDEBAND_PROTOCOL_ERROR; 117} 118} 119return0; 120} 121 122/* 123 * fd is connected to the remote side; send the sideband data 124 * over multiplexed packet stream. 125 */ 126ssize_t send_sideband(int fd,int band,const char*data, ssize_t sz,int packet_max) 127{ 128 ssize_t ssz = sz; 129const char*p = data; 130 131while(sz) { 132unsigned n; 133char hdr[5]; 134 135 n = sz; 136if(packet_max -5< n) 137 n = packet_max -5; 138sprintf(hdr,"%04x", n +5); 139 hdr[4] = band; 140safe_write(fd, hdr,5); 141safe_write(fd, p, n); 142 p += n; 143 sz -= n; 144} 145return ssz; 146}