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