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