1*31460Sminshall #include <stdio.h> 2*31460Sminshall 3*31460Sminshall #include "api_exch.h" 4*31460Sminshall 5*31460Sminshall static char ibuffer[40], *ibuf_next, *ibuf_last; 6*31460Sminshall #define IBUFADDED(i) ibuf_last += (i) 7*31460Sminshall #define IBUFAVAILABLE() (ibuf_last -ibuf_next) 8*31460Sminshall #define IBUFFER() ibuffer 9*31460Sminshall #define IBUFGETCHAR() (*ibuf_next++) 10*31460Sminshall #define IBUFGETSHORT() ((*ibuf_next++<<8)|(*ibuf_next++&0xff)) 11*31460Sminshall #define IBUFRESET() (ibuf_next = ibuf_last = ibuffer) 12*31460Sminshall 13*31460Sminshall char obuffer[40], *obuf_next; 14*31460Sminshall #define OBUFADDBYTES(w,l) { memcpy(obuf_next, w, l); obuf_next += l; } 15*31460Sminshall #define OBUFADDCHAR(c) (*obuf_next++ = c) 16*31460Sminshall #define OBUFADDSHORT(s) {*obuf_next++ = (s)>>8; *obuf_next++ = s; } 17*31460Sminshall #define OBUFAVAILABLE() (obuf_next - obuffer) 18*31460Sminshall #define OBUFFER() obuffer 19*31460Sminshall #define OBUFRESET() obuf_next = obuffer 20*31460Sminshall #define OBUFROOM() (obuffer+sizeof obuffer-obuf_next) 21*31460Sminshall 22*31460Sminshall 23*31460Sminshall static int 24*31460Sminshall outflush() 25*31460Sminshall { 26*31460Sminshall int length = OBUFAVAILABLE(); 27*31460Sminshall 28*31460Sminshall if (length != 0) { 29*31460Sminshall if (write(sock, OBUFFER(), length) != length) { 30*31460Sminshall perror("writing to API client"); 31*31460Sminshall return -1; 32*31460Sminshall } 33*31460Sminshall OBUFRESET(); 34*31460Sminshall } 35*31460Sminshall return 0; /* All OK */ 36*31460Sminshall } 37*31460Sminshall 38*31460Sminshall 39*31460Sminshall static int 40*31460Sminshall infill(count) 41*31460Sminshall int count; 42*31460Sminshall { 43*31460Sminshall int i; 44*31460Sminshall 45*31460Sminshall if (OBUFAVAILABLE()) { 46*31460Sminshall if (outflush() == -1) { 47*31460Sminshall return -1; 48*31460Sminshall } 49*31460Sminshall } 50*31460Sminshall if (ibuf_next == ibuf_last) { 51*31460Sminshall IBUFRESET(); 52*31460Sminshall } 53*31460Sminshall while (count) { 54*31460Sminshall if ((i = read(sock, IBUFFER(), count)) < 0) { 55*31460Sminshall perror("reading from API client"); 56*31460Sminshall return -1; 57*31460Sminshall } 58*31460Sminshall count -= i; 59*31460Sminshall IBUFADDED(i); 60*31460Sminshall } 61*31460Sminshall return 0; 62*31460Sminshall } 63*31460Sminshall 64*31460Sminshall static int 65*31460Sminshall api_exch_incommand(command) 66*31460Sminshall int command; 67*31460Sminshall { 68*31460Sminshall int i; 69*31460Sminshall 70*31460Sminshall if (IBUFAVAILABLE() < 1) { 71*31460Sminshall if (infill(1) == -1) { 72*31460Sminshall return -1; 73*31460Sminshall } 74*31460Sminshall } 75*31460Sminshall i = IBUFGETCHAR(); 76*31460Sminshall if (i != command) { 77*31460Sminshall fprintf(stderr, "Expected API command 0x%x, got API command 0x%x.\n", 78*31460Sminshall command, i); 79*31460Sminshall return -1; 80*31460Sminshall } 81*31460Sminshall return 0; 82*31460Sminshall } 83*31460Sminshall 84*31460Sminshall 85*31460Sminshall static int 86*31460Sminshall api_exch_outcommand(command) 87*31460Sminshall int command; 88*31460Sminshall { 89*31460Sminshall if (OBUFROOM() < 1) { 90*31460Sminshall if (outflush() == -1) { 91*31460Sminshall return -1; 92*31460Sminshall } 93*31460Sminshall } 94*31460Sminshall OBUFADDCHAR(command); 95*31460Sminshall return 0; 96*31460Sminshall } 97*31460Sminshall 98*31460Sminshall 99*31460Sminshall static int 100*31460Sminshall api_exch_outtype(type, length, location) 101*31460Sminshall int 102*31460Sminshall type, 103*31460Sminshall length; 104*31460Sminshall char 105*31460Sminshall *location; 106*31460Sminshall { 107*31460Sminshall int netleng = htons(length); 108*31460Sminshall 109*31460Sminshall if (OBUFROOM() < 3) { 110*31460Sminshall if (outflush() == -1) { 111*31460Sminshall return -1; 112*31460Sminshall } 113*31460Sminshall } 114*31460Sminshall OBUFADDCHAR(type); 115*31460Sminshall OBUFADDSHORT(netleng); 116*31460Sminshall if (OBUFROOM() > length) { 117*31460Sminshall OBUFADDBYTES(location, length); 118*31460Sminshall } else { 119*31460Sminshall if (outflush() == -1) { 120*31460Sminshall return -1; 121*31460Sminshall } 122*31460Sminshall if (write(sock, location, length) != length) { 123*31460Sminshall perror("writing to API client"); 124*31460Sminshall return -1; 125*31460Sminshall } 126*31460Sminshall } 127*31460Sminshall } 128*31460Sminshall 129*31460Sminshall 130*31460Sminshall static int 131*31460Sminshall api_exch_intype(type, length, location) 132*31460Sminshall int 133*31460Sminshall type, 134*31460Sminshall length; 135*31460Sminshall char 136*31460Sminshall *location; 137*31460Sminshall { 138*31460Sminshall int i, netleng = htons(length); 139*31460Sminshall 140*31460Sminshall if (IBUFAVAILABLE() < 3) { 141*31460Sminshall if (infill(3) == -1) { 142*31460Sminshall return -1; 143*31460Sminshall } 144*31460Sminshall } 145*31460Sminshall if ((i = IBUFGETCHAR()) != type) { 146*31460Sminshall fprintf(stderr, "Expected type 0x%x, got type 0x%x.\n", type, i); 147*31460Sminshall return -1; 148*31460Sminshall } 149*31460Sminshall if ((i = IBUFGETSHORT()) != netleng) { 150*31460Sminshall fprintf(stderr, "Type 0x%x - expected length %d, received length %d.\n", 151*31460Sminshall type, length, ntohs(i)); 152*31460Sminshall return -1; 153*31460Sminshall } 154*31460Sminshall while (length) { 155*31460Sminshall if ((i = read(sock, location, length)) < 0) { 156*31460Sminshall perror("reading from API client"); 157*31460Sminshall return -1; 158*31460Sminshall } 159*31460Sminshall length -= i; 160*31460Sminshall location += i; 161*31460Sminshall } 162*31460Sminshall return 0; 163*31460Sminshall } 164