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