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