date and time created 87/06/11 15:27:12 by minshall
authorGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Fri, 12 Jun 1987 06:27:12 +0000 (22:27 -0800)
committerGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Fri, 12 Jun 1987 06:27:12 +0000 (22:27 -0800)
SCCS-vsn: usr.bin/tn3270/api/api_exch.c 1.1

usr/src/usr.bin/tn3270/api/api_exch.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/tn3270/api/api_exch.c b/usr/src/usr.bin/tn3270/api/api_exch.c
new file mode 100644 (file)
index 0000000..84e5d24
--- /dev/null
@@ -0,0 +1,163 @@
+#include <stdio.h>
+
+#include "api_exch.h"
+
+static char ibuffer[40], *ibuf_next, *ibuf_last;
+#define        IBUFADDED(i)            ibuf_last += (i)
+#define        IBUFAVAILABLE()         (ibuf_last -ibuf_next)
+#define        IBUFFER()               ibuffer
+#define        IBUFGETCHAR()           (*ibuf_next++)
+#define        IBUFGETSHORT()          ((*ibuf_next++<<8)|(*ibuf_next++&0xff))
+#define        IBUFRESET()             (ibuf_next = ibuf_last = ibuffer)
+
+char obuffer[40], *obuf_next;
+#define        OBUFADDBYTES(w,l)       { memcpy(obuf_next, w, l); obuf_next += l; }
+#define        OBUFADDCHAR(c)          (*obuf_next++ = c)
+#define        OBUFADDSHORT(s)         {*obuf_next++ = (s)>>8; *obuf_next++ = s; }
+#define        OBUFAVAILABLE()         (obuf_next - obuffer)
+#define        OBUFFER()               obuffer
+#define        OBUFRESET()             obuf_next = obuffer
+#define        OBUFROOM()              (obuffer+sizeof obuffer-obuf_next)
+
+
+static int
+outflush()
+{
+    int length = OBUFAVAILABLE();
+
+    if (length != 0) {
+       if (write(sock, OBUFFER(), length) != length) {
+           perror("writing to API client");
+           return -1;
+       }
+       OBUFRESET();
+    }
+    return 0;                          /* All OK */
+}
+
+
+static int
+infill(count)
+int count;
+{
+    int i;
+
+    if (OBUFAVAILABLE()) {
+       if (outflush() == -1) {
+           return -1;
+       }
+    }
+    if (ibuf_next == ibuf_last) {
+       IBUFRESET();
+    }
+    while (count) {
+       if ((i = read(sock, IBUFFER(), count)) < 0) {
+           perror("reading from API client");
+           return -1;
+       }
+       count -= i;
+       IBUFADDED(i);
+    }
+    return 0;
+}
+
+static int
+api_exch_incommand(command)
+int command;
+{
+    int i;
+
+    if (IBUFAVAILABLE() < 1) {
+       if (infill(1) == -1) {
+           return -1;
+       }
+    }
+    i = IBUFGETCHAR();
+    if (i != command) {
+       fprintf(stderr, "Expected API command 0x%x, got API command 0x%x.\n",
+                               command, i);
+       return -1;
+    }
+    return 0;
+}
+
+
+static int
+api_exch_outcommand(command)
+int command;
+{
+    if (OBUFROOM() < 1) {
+       if (outflush() == -1) {
+           return -1;
+       }
+    }
+    OBUFADDCHAR(command);
+    return 0;
+}
+
+
+static int
+api_exch_outtype(type, length, location)
+int
+    type,
+    length;
+char
+    *location;
+{
+    int netleng = htons(length);
+
+    if (OBUFROOM() < 3) {
+       if (outflush() == -1) {
+           return -1;
+       }
+    }
+    OBUFADDCHAR(type);
+    OBUFADDSHORT(netleng);
+    if (OBUFROOM() > length) {
+       OBUFADDBYTES(location, length);
+    } else {
+       if (outflush() == -1) {
+           return -1;
+       }
+       if (write(sock, location, length) != length) {
+           perror("writing to API client");
+           return -1;
+       }
+    }
+}
+
+
+static int
+api_exch_intype(type, length, location)
+int
+    type,
+    length;
+char
+    *location;
+{
+    int i, netleng = htons(length);
+
+    if (IBUFAVAILABLE() < 3) {
+       if (infill(3) == -1) {
+           return -1;
+       }
+    }
+    if ((i = IBUFGETCHAR()) != type) {
+       fprintf(stderr, "Expected type 0x%x, got type 0x%x.\n", type, i);
+       return -1;
+    }
+    if ((i = IBUFGETSHORT()) != netleng) {
+       fprintf(stderr, "Type 0x%x - expected length %d, received length %d.\n",
+               type, length, ntohs(i));
+       return -1;
+    }
+    while (length) {
+       if ((i = read(sock, location, length)) < 0) {
+           perror("reading from API client");
+           return -1;
+       }
+       length -= i;
+       location += i;
+    }
+    return 0;
+}