xref: /csrg-svn/usr.bin/tn3270/api/api_exch.c (revision 31467)
131460Sminshall #include <stdio.h>
231460Sminshall 
331460Sminshall #include "api_exch.h"
431460Sminshall 
5*31467Sminshall static int sock;		/* Socket number */
6*31467Sminshall 
731460Sminshall static char ibuffer[40], *ibuf_next, *ibuf_last;
831460Sminshall #define	IBUFADDED(i)		ibuf_last += (i)
931460Sminshall #define	IBUFAVAILABLE()		(ibuf_last -ibuf_next)
1031460Sminshall #define	IBUFFER()		ibuffer
1131460Sminshall #define	IBUFGETCHAR()		(*ibuf_next++)
1231460Sminshall #define	IBUFGETSHORT()		((*ibuf_next++<<8)|(*ibuf_next++&0xff))
1331460Sminshall #define	IBUFRESET()		(ibuf_next = ibuf_last = ibuffer)
1431460Sminshall 
1531460Sminshall char obuffer[40], *obuf_next;
1631460Sminshall #define	OBUFADDBYTES(w,l)	{ memcpy(obuf_next, w, l); obuf_next += l; }
1731460Sminshall #define	OBUFADDCHAR(c)		(*obuf_next++ = c)
1831460Sminshall #define	OBUFADDSHORT(s)		{*obuf_next++ = (s)>>8; *obuf_next++ = s; }
1931460Sminshall #define	OBUFAVAILABLE()		(obuf_next - obuffer)
2031460Sminshall #define	OBUFFER()		obuffer
2131460Sminshall #define	OBUFRESET()		obuf_next = obuffer
2231460Sminshall #define	OBUFROOM()		(obuffer+sizeof obuffer-obuf_next)
2331460Sminshall 
2431460Sminshall 
2531460Sminshall static int
2631460Sminshall outflush()
2731460Sminshall {
2831460Sminshall     int length = OBUFAVAILABLE();
2931460Sminshall 
3031460Sminshall     if (length != 0) {
3131460Sminshall 	if (write(sock, OBUFFER(), length) != length) {
3231460Sminshall 	    perror("writing to API client");
3331460Sminshall 	    return -1;
3431460Sminshall 	}
3531460Sminshall 	OBUFRESET();
3631460Sminshall     }
3731460Sminshall     return 0;				/* All OK */
3831460Sminshall }
3931460Sminshall 
4031460Sminshall 
4131460Sminshall static int
4231460Sminshall infill(count)
4331460Sminshall int count;
4431460Sminshall {
4531460Sminshall     int i;
4631460Sminshall 
4731460Sminshall     if (OBUFAVAILABLE()) {
4831460Sminshall 	if (outflush() == -1) {
4931460Sminshall 	    return -1;
5031460Sminshall 	}
5131460Sminshall     }
5231460Sminshall     if (ibuf_next == ibuf_last) {
5331460Sminshall 	IBUFRESET();
5431460Sminshall     }
5531460Sminshall     while (count) {
5631460Sminshall 	if ((i = read(sock, IBUFFER(), count)) < 0) {
5731460Sminshall 	    perror("reading from API client");
5831460Sminshall 	    return -1;
5931460Sminshall 	}
6031460Sminshall 	count -= i;
6131460Sminshall 	IBUFADDED(i);
6231460Sminshall     }
6331460Sminshall     return 0;
6431460Sminshall }
6531460Sminshall 
66*31467Sminshall int
67*31467Sminshall api_exch_inbyte()
68*31467Sminshall {
69*31467Sminshall     if (IBUFAVAILABLE() < 1) {
70*31467Sminshall 	if (infill(1) == -1) {
71*31467Sminshall 	    return -1;
72*31467Sminshall 	}
73*31467Sminshall     }
74*31467Sminshall     return IBUFGETCHAR();
75*31467Sminshall }
76*31467Sminshall 
77*31467Sminshall 
78*31467Sminshall int
7931460Sminshall api_exch_incommand(command)
8031460Sminshall int command;
8131460Sminshall {
8231460Sminshall     int i;
8331460Sminshall 
8431460Sminshall     if (IBUFAVAILABLE() < 1) {
8531460Sminshall 	if (infill(1) == -1) {
8631460Sminshall 	    return -1;
8731460Sminshall 	}
8831460Sminshall     }
8931460Sminshall     i = IBUFGETCHAR();
9031460Sminshall     if (i != command) {
9131460Sminshall 	fprintf(stderr, "Expected API command 0x%x, got API command 0x%x.\n",
9231460Sminshall 				command, i);
9331460Sminshall 	return -1;
9431460Sminshall     }
9531460Sminshall     return 0;
9631460Sminshall }
9731460Sminshall 
9831460Sminshall 
99*31467Sminshall int
10031460Sminshall api_exch_outcommand(command)
10131460Sminshall int command;
10231460Sminshall {
10331460Sminshall     if (OBUFROOM() < 1) {
10431460Sminshall 	if (outflush() == -1) {
10531460Sminshall 	    return -1;
10631460Sminshall 	}
10731460Sminshall     }
10831460Sminshall     OBUFADDCHAR(command);
10931460Sminshall     return 0;
11031460Sminshall }
11131460Sminshall 
11231460Sminshall 
113*31467Sminshall int
11431460Sminshall api_exch_outtype(type, length, location)
11531460Sminshall int
11631460Sminshall     type,
11731460Sminshall     length;
11831460Sminshall char
11931460Sminshall     *location;
12031460Sminshall {
12131460Sminshall     int netleng = htons(length);
12231460Sminshall 
12331460Sminshall     if (OBUFROOM() < 3) {
12431460Sminshall 	if (outflush() == -1) {
12531460Sminshall 	    return -1;
12631460Sminshall 	}
12731460Sminshall     }
12831460Sminshall     OBUFADDCHAR(type);
12931460Sminshall     OBUFADDSHORT(netleng);
13031460Sminshall     if (OBUFROOM() > length) {
13131460Sminshall 	OBUFADDBYTES(location, length);
13231460Sminshall     } else {
13331460Sminshall 	if (outflush() == -1) {
13431460Sminshall 	    return -1;
13531460Sminshall 	}
13631460Sminshall 	if (write(sock, location, length) != length) {
13731460Sminshall 	    perror("writing to API client");
13831460Sminshall 	    return -1;
13931460Sminshall 	}
14031460Sminshall     }
14131460Sminshall }
14231460Sminshall 
14331460Sminshall 
144*31467Sminshall int
14531460Sminshall api_exch_intype(type, length, location)
14631460Sminshall int
14731460Sminshall     type,
14831460Sminshall     length;
14931460Sminshall char
15031460Sminshall     *location;
15131460Sminshall {
15231460Sminshall     int i, netleng = htons(length);
15331460Sminshall 
15431460Sminshall     if (IBUFAVAILABLE() < 3) {
15531460Sminshall 	if (infill(3) == -1) {
15631460Sminshall 	    return -1;
15731460Sminshall 	}
15831460Sminshall     }
15931460Sminshall     if ((i = IBUFGETCHAR()) != type) {
16031460Sminshall 	fprintf(stderr, "Expected type 0x%x, got type 0x%x.\n", type, i);
16131460Sminshall 	return -1;
16231460Sminshall     }
16331460Sminshall     if ((i = IBUFGETSHORT()) != netleng) {
16431460Sminshall 	fprintf(stderr, "Type 0x%x - expected length %d, received length %d.\n",
16531460Sminshall 		type, length, ntohs(i));
16631460Sminshall 	return -1;
16731460Sminshall     }
16831460Sminshall     while (length) {
16931460Sminshall 	if ((i = read(sock, location, length)) < 0) {
17031460Sminshall 	    perror("reading from API client");
17131460Sminshall 	    return -1;
17231460Sminshall 	}
17331460Sminshall 	length -= i;
17431460Sminshall 	location += i;
17531460Sminshall     }
17631460Sminshall     return 0;
17731460Sminshall }
178*31467Sminshall 
179*31467Sminshall int
180*31467Sminshall api_exch_init(sock_number)
181*31467Sminshall int sock_number;
182*31467Sminshall {
183*31467Sminshall     sock = sock_number;
184*31467Sminshall 
185*31467Sminshall     IBUFRESET();
186*31467Sminshall     OBUFRESET();
187*31467Sminshall 
188*31467Sminshall     return 0;
189*31467Sminshall }
190