xref: /csrg-svn/usr.bin/tn3270/api/api_exch.c (revision 31460)
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